custom DataTable.ext.editorFields to show icon and text depending on data

custom DataTable.ext.editorFields to show icon and text depending on data

pingcrosbypingcrosby Posts: 29Questions: 4Answers: 1
edited February 2017 in Free community support

I am trying to display an icon and associated data in a datatable editor. To achieve this i am trying to create a custom plugin ( though am not entirely sure this is the correct way to go about this )

I am struggling to understand how to get the actual editor value in order dynamically render the correct icon and text

On line 34 /* how do i get the value of the data to display */ --> what do i need to do in order to display the text of the data.

I want the editor to say [State] {icon} TheUserState, where TheUserState is and integer and the real text is stored elsewhere in the datatable field.

Please note that my editor form is readonly i just want to be able to display the icon and text associated with a data value (1,2,3)

I would really appreciate some help on this one.

Thanks in advance

Image of what i am trying to achieve

/*** My plugin ***/
 (function ($, DataTable) {

            if (!DataTable.ext.editorFields) {
                DataTable.ext.editorFields = {};
            }

            var Editor = DataTable.Editor;
            var _fieldTypes = DataTable.ext.editorFields;

/** looking to acheive this kind of thing inside the plugin to display icon and text depending on data 
   if (data == 1)
       return '<span class="rowcolordatatable gray"><i class="icon-pen"></i> <span>' + row.Status + '</span></span>';
    if (data == 2) 
       return '<span class="rowcolordatatable green"><i class="icon-check-mark"></i> <span>' + row.Status + '</span></span>';                        
    if (data == 3) 
        return '<span class="rowcolordatatable red"><i class="icon-cross"></i> <span>' + row.Status + '</span></span>';
    **/

            _fieldTypes.RowStatus = {
                create: function (conf) {
                    var that = this;

                    var iconInfo = [{ colour: "grey", icon: "icon-pen" },
                                     { colour: "green", icon: "icon-check-mark" },
                                     { colour: "red", icon: "icon-cross" }];

                    var _iconInfo = iconInfo[0]; // i need the value of the row_status  (id) in here
                   
                    // Create the elements to use for the input
                    conf._input = $(

                        '<div class="rowcolordatatable ' + _iconInfo.colour + '"><i class="' + _iconInfo.icon + '"></i><div>' +
                          + /* how do i get the value of the data to display */ +
                         '</div></div>');
                                   
                    return conf._input;
                }
            };

        })(jQuery, jQuery.fn.dataTable);
editor = new $.fn.dataTable.Editor({
                "idSrc": "Id",
                "table": "#SearchResultTable",
                "fields":
                [                   
                    {
                        label: "Status:",
                        name: "Status",
                        type: "RowStatus" /* custom plugin to show icon and status */
                    },                  
                ]
            });
 var table = $('#SearchResultTable').DataTable({
                "proccessing": true,
                "serverSide": true,
                "columns": [
                  {
                      "data": "RegistrationStatusId", render: function (data, type, row) {
                          if (data == 1) {
                              return '<span class="rowcolordatatable gray"><i class="icon-pen"></i> <span>' + row.Status + '</span></span>';
                          }
                          if (data == 2) {
                              return '<span class="rowcolordatatable green"><i class="icon-check-mark"></i> <span>' + row.Status + '</span></span>';
                          }
                          if (data == 3) {
                              return '<span class="rowcolordatatable red"><i class="icon-cross"></i> <span>' + row.Status + '</span></span>';
                          }
                          return data;
                      }
                  },                 
                ]
            });

This question has an accepted answers - jump to answer

Answers

  • allanallan Posts: 63,226Questions: 1Answers: 10,416 Site admin
    • /* how do i get the value of the data to display */ +

    You don't there. In the create function you don't have a value to display since that function is called before you actually do any data editing (it is called when the Editor instance is created).

    The value is given to you in the get function and you would update your HTML to reflect the value in that function.

    Allan

  • pingcrosbypingcrosby Posts: 29Questions: 4Answers: 1

    Allan

    FYI i am not at my dev machine at the moment so cannot try some things out.

    Sorry to sound like a fool but could you provide me with a simple sample or pseudocode - i just want to show the data and icon instead of a input box.

    What is the purpose of "conf._input" does it have meaning or is that just related to the sample?

    In the sample the declaration for get does not get the val should it be get

     get: function (conf) { }, //exampe from sample
      get: function(conf,val) {} ????
    
    
    /* Is this the correct pattern/approach */
    create:
      // stick a label in the field
      return conf._input("<label id="xxx"></label>");
     
    get:
      // get the value from the label
      return $("#xxx").val()
    
    set (conf, val):
      // update the label
      $("#xxx").val(val);
    
  • allanallan Posts: 63,226Questions: 1Answers: 10,416 Site admin

    What is the purpose of "conf._input" does it have meaning or is that just related to the sample?

    The conf object is the only thing that is common between the functions for each specific field. Basically it is a data store. You would typically use the create function to create some standard elements and reuse them for every value shown (for example an input element).

    You need some way to reference that element in the get and set functions, so I typically store it in conf._input, but you could call it anything you want in the conf object.

    I would strongly recommend against using an id. It would work if you only ever used your field once on a page, but if you had two fields using the same field type it would cause them both to have elements with the same id, which is not valid HTML and who knows what would happen!

    Allan

  • pingcrosbypingcrosby Posts: 29Questions: 4Answers: 1
    edited February 2017

    Hi Allan thanks for all your help so far - this is what I have coded up based on my understanding of the documentation and your response.

    However I still am struggling to change the text in the rendered HTML. The selector $(".MyRowStatus") fails in the set/get functions but works perfectly ok if I have the editor form open in the browser and run the selector in a debug console.

    Is there anything obvious I have missed ?

    Really appreciating your help.

    Thanks

    Sample image showing what I have and what I want to achieve

                _fieldTypes.RowStatus = {
                                              
                    create: function (conf) {                  
                          conf._input = $('<div class="MyRowStatus rowcolordatatable red"><i class="icon-check-mark"></i>{ToBeChanged}</div>');
                      
                        return conf._input;
                    },
    
                    set: function (conf, val) { 
                        // this only fires on loading the editor form and at this point the selector fails
                        var elem = $(".MyRowStatus"); /* never found */                
                        elem.text("This should be change the entire div");
                     },
    
                    get: function (conf)
                    {
                        var elem = $(".MyRowStatus"); /* never found */
                        return elem.text();
                    }
                };
    
  • allanallan Posts: 63,226Questions: 1Answers: 10,416 Site admin

    $(".MyRowStatus")

    That's going to have the same issue as the id selector. It will change the value of all elements that are found with that class. So if you have two or more fields it would update them.

    Also it will select only elements that are in the document and the field isn't in attached to the document when initially set.

    Use conf._input.text( val );. i.e. make use of the element that you've stored in conf._input.

    Allan

  • pingcrosbypingcrosby Posts: 29Questions: 4Answers: 1

    Thanks for this - the clue was in conf._input.text( val );

    This my working markup, it works as expected. But am not sure I am supposed to push the complete HTML in the set function.

    Is there a better way?

                _fieldTypes.RowStatus = {
                                              
                    create: function (conf) {                   
                        conf._input = $("<span></span>");                  
                        return conf._input;
                    },
    
                    set: function (conf, val) {
    
                        var iconInfoMap = [
                            { colour: "grey", icon: "icon-pen" },
                            { colour: "green", icon: "icon-check-mark" },
                            { colour: "red", icon: "icon-cross" }
                        ];
                        iconInfo = iconInfoMap[ /* needs to come from table cell */1];
    
                        var html = '<span class="rowcolordatatable ' + iconInfo.colour + '"><i class="' + iconInfo.icon + '"></i><span> ' + val + '</span></span>';
                        conf._input.html(html);            
    
  • allanallan Posts: 63,226Questions: 1Answers: 10,416 Site admin
    Answer ✓

    You can do whatever you want in the set method. As long as any event handlers you had added are delegated so that they work on the new elements, that would be fine. But I don't actually see any event handlers or an input that would let you change the value.

    Allan

This discussion has been closed.