Dynamic row selector based on row values

Dynamic row selector based on row values

IMS_PeteIMS_Pete Posts: 21Questions: 4Answers: 0

Hi All,

I've managed to successfully create a dynamic row selector using the rowCallback function

rowCallback: function ( row, data, index ) {
                  var SelectVal = "";
                  SelectVal = data["SELECT_STATUS"];
                  if(SelectVal == null){SelectVal = "";}
                  if(SelectVal == "N") {
                                      $("td:first-child", row).toggleClass('select-checkbox cls_noselect');
                                      }
               },

I had to remove the select all button from my table as I couldn't get it to select only rows with a certain class but it serves it's purpose and seems to be working well.

However, as soon as I enter a value on any row, via inline or row editor, the whole selector column classes get reset. My investigation has lead me to believe this is data table standard behaviour. I could write a function to iterate through the rows and change the class again but I was wondering if I could instead set the data table to set the class using a function in the same way as I've set another column to dynamically show an image:

 { data: "z", render: function (data,type,row) {
        var w = '<img src="/html/images/icon_dummy.png">';
        if (row.MyIconValColumn == 'A' ) {w = '<img src="/html/images/icon_a.png">';}
        if (row.MyIconValColumn == 'B' ) {w = '<img src="/html/images/icon_b.png">';}
        if (row.MyIconValColumn == 'C' ) {w = '<img src="/html/images/icon_c.png">';}
        var x = row.MyIconDescColumn;
        var y = row.MyIconSubDescColumn;
        var z = '';
        if (x == y) {z = w + '&|ensp;' + x;} else {z = w + '&|ensp;' + x + ' - ' + y;}
        return z
        },

Any idea how to stop the returning row data from resetting the selector column class or failing that any idea how to set the field class using a function?

Thanks for you help

This question has an accepted answers - jump to answer

Answers

  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin

    The columns.render option really deals with the contents of the cell. Currently it doesn't offer an option to return a cell itself, and since you want to set the class name of the cell, the rowCallback option is the way to do that.

    However, the class names would only be reset if you are using server-side processing (since each draw is effectively a new node). Is that the case here?

    Allan

  • IMS_PeteIMS_Pete Posts: 21Questions: 4Answers: 0

    Hi Allan

    I had a feeling that the render option was not the correct method but was the best way of explaining the concept.

    By my understanding we're not using sever side processing.

    We have a sever side process that builds the page but once complete the page has everything.
    On update, the page runs an AJAX call which returns the updated row values in JSON format. At this point it resets the class names set by the rowCallback.

    It seems like as part of updating the row it redraws the selector column or perhaps just sets the class for the whole column. If that is the case I'll need to create a function to iterate through the rows setting the class names again which I was hoping to avoid.

    Thanks
    Pete

  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin

    Can you give me a link to the page or show me the whole code for the DataTable and any relevant API calls please?

    Thanks,
    Allan

  • IMS_PeteIMS_Pete Posts: 21Questions: 4Answers: 0

    Hi Allan,

    Something I noticed today the unwanted behavior also occurs when we toggle between 'Show All' and 'Show 5' etc

    I had to anonymise the data/code so hopefully I haven't broken anything in the process.

    I'll need to post this over several posts due to the size

    <!DOCTYPE html>
    <html>
    <head>
     
     <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.15/css/jquery.dataTables.min.css">
     <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/buttons/1.3.1/css/buttons.dataTables.min.css">
     <link rel="stylesheet" type="text/css" href="/ibi_apps/ibi_html/Editor-1.5.6/css/editor.dataTables.min.css">
     <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/select/1.2.2/css/select.dataTables.min.css">
     <script type="text/javascript" language="javascript" src="//code.jquery.com/jquery-1.12.4.min.js"></script>
     <script type="text/javascript" language="javascript" src="//code.jquery.com/jquery-2.2.4.min.js"></script>
     <script type="text/javascript" language="javascript" src="/ibi_apps/ibi_html/Editor-1.5.6/js/jszip.min.js"></script>
     <script type="text/javascript" language="javascript" src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>
     <script type="text/javascript" language="javascript" src="https://cdn.datatables.net/1.10.15/js/jquery.dataTables.min.js"></script>
     <script type="text/javascript" language="javascript" src="https://cdn.datatables.net/buttons/1.3.1/js/dataTables.buttons.min.js"></script>
     <script type="text/javascript" language="javascript" src="https://cdn.datatables.net/buttons/1.3.1/js/buttons.html5.min.js"></script>
     <script type="text/javascript" language="javascript" src="/ibi_apps/ibi_html/Editor-1.5.6/js/dataTables.editor.js"></script>
     <script type="text/javascript" language="javascript" src="https://cdn.datatables.net/select/1.2.2/js/dataTables.select.min.js"></script>
      
    </head>
    
    
  • IMS_PeteIMS_Pete Posts: 21Questions: 4Answers: 0

    post 3


    var PlaData = { }; var GeoData = { }; var ProData = { }; var StaData = { }; var StbData = { }; PlaData = Pla_Data.data; GeoData = Geo_Data.data; ProData = Pro_Data.data; StaData = Sta_Data.data; StbData = Stb_Data.data; myNewEditor = new $.fn.dataTable.Editor( { ajax: "/ibi_apps/run.bip?BIP_REQUEST_TYPE=BIP_RUN&BIP_folder=IBFS%253A%252FWFC%252FRepository&BIP_item=create_new_record.fex", table: "#Tbl", idSrc: "RECORD_ID", fields: [ { label: "Field 3", name: "FIELD3_CODE",type: "select", options: GeoData, optionsPair : { label: 'FIELD3_NAME', value: 'FIELD3_CODE' } }, { label: "Field 4", name: "FIELD4_CODE", type: "select", options: ProData, optionsPair : { label: 'FIELD4_NAME', value: 'FIELD4_CODE' } }, { label: "Record Description", name: "RECORD_DESC" }, { label: "User Entry 1", name: "USER_ENTRY_1", type: 'textarea' }, { label: "Record Status", name: "RECORD_STATUS", type: "select", options: StbData, optionsPair : { label: 'STATUS_DESC', value: 'RECORD_STATUS' } }, { label: "User Entry 2", name: "USER_ENTRY_2", type: 'textarea' }, { label: "User Entry 3", name: "USER_ENTRY_3", type: 'datetime' }, { label: "User Entry 4", name: "USER_ENTRY_4", type: 'textarea' }, ] } ); myNewEditor.field( 'USER_ENTRY_3' ).input().on('keydown',function (e) {e.preventDefault();}); myNewEditor.on('preSubmit',prepParmsNew); myEditor = new $.fn.dataTable.Editor( { ajax: "/ibi_apps/run.bip?BIP_REQUEST_TYPE=BIP_RUN&BIP_folder=IBFS%253A%252FWFC%252FRepository&BIP_item=update_record.fex", table: "#Tbl", idSrc: "RECORD_ID", fields: [ { label: "Field 4", name: "FIELD4_CODE", type: "select", options: ProData, optionsPair : { label: 'FIELD4_NAME', value: 'FIELD4_CODE' } }, { label: "Record Description", name: "RECORD_DESC" }, { label: "User Entry 1", name: "USER_ENTRY_1" }, { label: "Record Status", name: "RECORD_STATUS", type: "select", options: StbData, optionsPair : { label: 'STATUS_DESC', value: 'RECORD_STATUS' } }, { label: "User Entry 2", name: "USER_ENTRY_2" }, { label: "User Entry 3", name: "USER_ENTRY_3", type: 'datetime' }, { label: "User Entry 4", name: "USER_ENTRY_4", type: 'textarea' }, ] } ); myEditor.field( 'USER_ENTRY_3' ).input().on('keydown',function (e) {e.preventDefault();}); myEditor.on('preSubmit',prepParmsUpdate); myAllEditor = new $.fn.dataTable.Editor( { ajax: "/ibi_apps/run.bip?BIP_REQUEST_TYPE=BIP_RUN&BIP_folder=IBFS%253A%252FWFC%252FRepository&BIP_item=update_multi_records.fex", table: "#Tbl", idSrc: "RECORD_ID", fields: [ { label: "Field 1", name: "FIELD1_NAME", type: "readonly"}, { label: "Field 2", name: "FIELD2_NAME", type: "readonly"}, { label: "Field 3", name: "FIELD3_NAME", type: "readonly"}, { label: "Field 4", name: "FIELD4_CODE", type: "select", options: ProData, optionsPair : { label: 'FIELD4_NAME', value: 'FIELD4_CODE' } }, { label: "Record Description", name: "RECORD_DESC" }, { label: "User Entry 1", name: "USER_ENTRY_1", type: 'textarea' }, { label: "Record Status", name: "RECORD_STATUS", type: "select", options: StaData, optionsPair : { label: 'STATUS_DESC', value: 'RECORD_STATUS' } }, { label: "User Entry 2", name: "USER_ENTRY_2", type: 'textarea' }, { label: "User Entry 3", name: "USER_ENTRY_3", type: 'datetime' }, { label: "User Entry 4", name: "USER_ENTRY_4", type: 'textarea' }, ] } ); myAllEditor.hide('FIELD1_NAME'); myAllEditor.hide('FIELD2_NAME'); myAllEditor.hide('FIELD3_NAME'); myAllEditor.field( 'USER_ENTRY_3' ).input().on('keydown',function (e) {e.preventDefault();}); myAllEditor.on('preSubmit',prepParmsUpdateAll);
  • IMS_PeteIMS_Pete Posts: 21Questions: 4Answers: 0

    Post 4

    function prepParmsNew(e,d,a) {
    d['RECORD_ID'] = "0" ;
    d['RPT_LEVEL'] = "'SRA'" ;
    d['RECORD_START'] = "'2018-03'" ;
    for (p in d.data) {
    for (q in d.data[p]) {
    d[q] = d.data[p][q];
    }
    }
    for (r=0;r<GeoData.length;r++) {
    if (GeoData[r].FIELD3_CODE == d['FIELD3_CODE']) {
    d['FIELD3_NAME'] = GeoData[r].FIELD3_NAME;
    d['FIELD2_CODE'] = GeoData[r].FIELD2_CODE;
    d['FIELD2_NAME'] = GeoData[r].FIELD2_NAME;
    d['FIELD1_NAME'] = GeoData[r].FIELD1_NAME;
    d['FIELD1_CODE'] = GeoData[r].FIELD1_CODE;
    }
    }
    for (r=0;r<ProData.length;r++) {
    if (ProData[r].FIELD4_CODE == d['FIELD4_CODE']) {
    d['FIELD4_NAME'] = ProData[r].FIELD4_NAME;
    }
    }
    delete d.data;
    }
     
    function prepParmsUpdate(e,d,a) {
    for (p in d.data) {
    d['RECORD_ID'] = p ;
    var TblRows = $('#Tbl').DataTable().rows().data();
    for (r=0;r<TblRows.length;r++) {
    if (TblRows[r].RECORD_ID == p) {
    d['FIELD1_NAME'] = TblRows[r].FIELD1_NAME;
    d['FIELD2_NAME'] = TblRows[r].FIELD2_NAME;
    d['FIELD3_NAME'] = TblRows[r].FIELD3_NAME;
    d['FIELD4_NAME'] = TblRows[r].FIELD4_NAME;
    }
    }
    for (q in d.data[p]) {
    d[q] = d.data[p][q];
    d['CHANGE_VAR'] = q ;
    }
    if (d.CHANGE_VAR == 'FIELD4_CODE') {
    for (r=0;r<ProData.length;r++) {
    if (ProData[r].FIELD4_CODE == d.FIELD4_CODE) {
    d.FIELD4_NAME = ProData[r].FIELD4_NAME;
    }
    }
    }
    }
    delete d.data;
    }
    
    function prepParmsUpdateAll(e,d,a) {
    d = EncodeParameters(d)
    d['ROWID_LIST'] = '' ;
    for (p in d.data) {
    d['ROWID_LIST'] += '^' + p ;
    for (r=0;r<ProData.length;r++) {
    if (ProData[r].FIELD4_CODE == d.data[p].FIELD4_CODE) {
    d.data[p].FIELD4_NAME = ProData[r].FIELD4_NAME;
    }
    }
    }
    }
    
    function EncodeParameters(d) {
    var stgValue = '' ;
    for (p in d.data) {
    for (q in d.data[p]) {
    stgValue = d.data[p][q];
    stgValue = stgValue.replace(/&/g, "&") ;
    stgValue = stgValue.replace(/'/g, "''") ;
    d.data[p][q] = stgValue;
    }
    }
        return d
        }
     
    function build_child_rows ( d ) {
        var usr_ent_1 = d.USER_ENTRY_1 ;
        var usr_ent_2 = d.USER_ENTRY_2;
        var updte_usr = d.UPDATE_USER;
        var updte_nme = d.UPDATE_NAME;
        var updte_tme = d.UPDATE_TIME;
     
        if(typeof usr_ent_1 == "undefined") { usr_ent_1 = '';};
        if(typeof usr_ent_2 == "undefined") { usr_ent_2 = '';};
        if(typeof updte_usr   == "undefined") { updte_usr = '';};
        if(typeof updte_nme   == "undefined") { updte_nme = '';};
        if(typeof updte_tme   == "undefined") { updte_tme = '';};
     
    return '<table cellpadding="5" cellspacing="0" border="0" style="padding-left:50px;">'+
    '<tr>'+
    '<td>User Entry 1td>'+
    '<td>'+usr_ent_1+'</td>'+
    '</tr>'+
    '<tr>'+
    '<td>User Entry 2:</td>'+
    '<td>'+usr_ent_2+'</td>'+
    '</tr>'+
    '<tr>'+
    '<td>Last Updated By:</td>'+
    '<td>'+updte_nme+' ('+updte_usr+') - '+updte_tme+'</td>'+
    '</tr>'+
    '</table>';
    }
    
  • IMS_PeteIMS_Pete Posts: 21Questions: 4Answers: 0

    Post 5


    $('#Tbl').on( 'click', 'tbody td.cls_dropdown', function (e) { myEditor.inline( this, { buttons: { label: '&rArr;', fn: function () { this.submit(); } } } ); } ); $('#Tbl').on( 'click', 'tbody td.cls_dropdown_prod', function (e) { myEditor.inline( this,'FIELD4_CODE', { buttons: { label: '&rArr;', fn: function () { this.submit(); } } } ); } ); $('#Tbl').on( 'click', 'tbody td.cls_bubble', function (e) { myEditor.bubble( this, {submitOnBlur: true} ); } ); $('#Tbl').on( 'click', 'tbody td.cls_dataentry', function (e) { myEditor.inline( this ); } ); $('#Tbl').on( 'click', 'tbody td.details-control', function () { var tr = $(this).closest('tr'); var row = myTbl.row( tr ); if ( row.child.isShown() ) { // This row is already open - close it row.child.hide(); tr.removeClass('shown'); } else { // Open this row row.child( build_child_rows(row.data()) ).show(); tr.addClass('shown'); } } ); var myTbl = $('#Tbl').DataTable( { paging: false, order: [ 6, 'asc'], responsive: true, dom: "Bfrtip", data: PlaData, lengthMenu: [[5, 10, 20, -1], [5, 10, 20, "All"]], columns: [ { data: "x", defaultContent: '', className: 'select-checkbox', orderable: false, width: "2.5%" }, { data: "y", defaultContent: '', className: 'details-control', orderable: false, width: "2.5%" }, { data: "RECORD_ID", visible: false, searchable: false }, { data: "FIELD1_NAME", visible: false, searchable: false }, { data: "FIELD2_NAME", visible: false, searchable: false }, { data: "RPT_LEVEL", visible: false, searchable: false}, { data: "FIELD3_NAME", visible: false, searchable: false }, { data: "z", render: function (data,type,row) { var w = '<img src="/ibi_apps/ibi_html/images/check_icon16.png">'; if (row.RPT_LEVEL == 'SRA' ) {w = '<img src="/ibi_apps/ibi_html/images/icon2.png">';} if (row.RPT_LEVEL == 'SRB' ) {w = '<img src="/ibi_apps/ibi_html/images/icon3.png">';} if (row.RPT_LEVEL == 'SRC' ) {w = '<img src="/ibi_apps/ibi_html/images/icon4.png">';} var x = row.FIELD2_NAME; var y = row.FIELD3_NAME; var z = ''; if (x == y) {z = w + '&ensp;' + x;} else {z = w + '&ensp;' + x + ' - ' + y;} return z }, width: "20%"}, { data: "FIELD4_NAME", className:' cls_dropdown_prod',width: "10%" }, { data: "RECORD_DESC", className:' cls_dataentry',width: "20%" }, { data: "USER_ENTRY_1", visible: false, className: " cls_dataentry" }, { data: "UPDATE_TIME", visible: false, type: "datetime", format: "DD/MM/YYYY", opts: {momentStrict: true}}, { data: "UPDATE_USER", visible: false }, { data: "UPDATE_NAME", visible: false }, { data: "RECORD_STATUS", className:' cls_dropdown' , width: "5%"}, { data: "USER_ENTRY_2", visible: false, className:' cls_dataentry' }, { data: "USER_ENTRY_3", className:' cls_dataentry', width: "5%" }, { data: "USER_ENTRY_4", className:' cls_bubble', width: "30%" }, { data: "LOCK_STATUS", visible: false }, ], select: { style: 'os', selector: '.select-checkbox' }, buttons: [ { extend: "create", editor: myNewEditor, text: "New Record" }, { extend: "edit", editor: myAllEditor }, { extend: "excelHtml5",exportOptions: { columns: ':visible' } }, { extend: "pageLength" }, 'selectNone' ], language: { buttons: { selectNone: "Clear Selection" } }, rowCallback: function ( row, data, index ) { var LockVal = ""; LockVal = data["LOCK_STATUS"]; if(LockVal == null){LockVal = "";} if(LockVal == "L") {$("td", row).removeClass('cls_dropdown_prod'); $("td", row).removeClass('cls_dataentry'); $("td", row).removeClass('cls_dropdown'); $("td", row).removeClass('cls_bubble'); $("td:first-child", row).toggleClass('select-checkbox cls_noselect'); } }, } ); } ); </script> <div style="width: 100%;" ><span class="rptHead" id="rptHeader">My DataTable</span></div> <div id="dt_wrapper" style="visibility:hidden;"> <table class="cell-border hover" cellpadding="1" id="Tbl"> <thead> <tr> <th > </th> <th > </th> <th > </th> <th > </th> <th > </th> <th > </th> <th > </th> <th > </th> <th > </th> <th > </th> <th > </th> <th > </th> <th > </th> <th > </th> <th > </th> <th > </th> <th > </th> <th > </th> <th > </th> </tr> </thead> </table></br></div> </div> </body> </html>
  • kthorngrenkthorngren Posts: 21,336Questions: 26Answers: 4,951
    edited March 2018 Answer ✓

    I may be misunderstanding what you are trying to do but have a question regarding your rowCallback:

    rowCallback: function ( row, data, index ) {
    var LockVal = "";
    LockVal = data["LOCK_STATUS"];
    if(LockVal == null){LockVal = "";}
    if(LockVal == "L") {$("td", row).removeClass('cls_dropdown_prod');
    $("td", row).removeClass('cls_dataentry');
    $("td", row).removeClass('cls_dropdown');
    $("td", row).removeClass('cls_bubble');
    $("td:first-child", row).toggleClass('select-checkbox cls_noselect');
    }
    },
    

    It looks to me like every time the table is drawn the select checkbox for rows where LockVal == "L" are going to toggle between showing the checkbox and not due to using toggleClass().

    Is this what's happening and what you want to happen?

    Kevin

  • IMS_PeteIMS_Pete Posts: 21Questions: 4Answers: 0

    Hi kthorngren

    I think I understand what you mean and you may be onto something there.

    What I want to do is make the change the class to a specific class based on a value. I don't really want it to toggle back and I think that is what it's doing.

    Thanks I'll investigate this further.

  • IMS_PeteIMS_Pete Posts: 21Questions: 4Answers: 0

    That sorted it out. I'll try to remember not to use toggle inappropriately from now on. :blush:

    I've updated the code to:

    rowCallback: function ( row, data, index ) {
    var LockVal = "";
    LockVal = data["LOCK_STATUS"];
    if(LockVal == null){LockVal = "";}
    if(LockVal == "L") {$("td", row).removeClass('cls_dropdown_prod');
    $("td", row).removeClass('cls_dataentry');
    $("td", row).removeClass('cls_dropdown');
    $("td", row).removeClass('cls_bubble');
    $("td:first-child", row).addClass('cls_noselect');
    $("td:first-child", row).removeClass('select-checkbox');
    }
    },
    
  • IMS_PeteIMS_Pete Posts: 21Questions: 4Answers: 0

    Allan, you may want to move the full page code off to a help section on getting DataTables to work with WebFOCUS. It's a bit hard to understand being disjointed on a discussion page.

This discussion has been closed.