jQuery DataTables: Responsive extension and form inputs

Problem

Table below demonstrates the problem with table containing form elements and Responsive extension.

To replicate the problem, perform the following steps:

  • Select a different office from the drop-down in the last column of the first row, for example Edinburgh.
  • Reduce window size so that Office column becomes hidden.
  • Click on green (+) icon to show additional details and original value Tokyo will be shown instead of the new one Edinburgh.

The same problem occurs with input and textearea elements.

Name Age Position Office Selected Comments
Name Age Position Office Selected Comments
Tiger Nixon
Garrett Winters
Ashton Cox
Cedric Kelly
Airi Satou
Brielle Williamson
Herrod Chandler
Rhona Davidson
Colleen Hurst
Sonya Frost
Jena Gaines
Quinn Flynn

Solution

Name Age Position Office Selected Comments
Name Age Position Office Selected Comments
Tiger Nixon
Garrett Winters
Ashton Cox
Cedric Kelly
Airi Satou
Brielle Williamson
Herrod Chandler
Rhona Davidson
Colleen Hurst
Sonya Frost
Jena Gaines
Quinn Flynn
$(document).ready(function (){
   var table = $('#example').DataTable({
      'columnDefs': [
         {
            'targets': [1, 2, 3, 4, 5],
            'render': function(data, type, row, meta){
               if(type === 'display'){
                  var api = new $.fn.dataTable.Api(meta.settings);

                  var $el = $('input, select, textarea', api.cell({ row: meta.row, column: meta.col }).node());

                  var $html = $(data).wrap('<div/>').parent();

                  if($el.prop('tagName') === 'INPUT'){
                     $('input', $html).attr('value', $el.val());
                     if($el.prop('checked')){
                        $('input', $html).attr('checked', 'checked');
                     }
                  } else if ($el.prop('tagName') === 'TEXTAREA'){
                     $('textarea', $html).html($el.val());

                  } else if ($el.prop('tagName') === 'SELECT'){
                     $('option:selected', $html).removeAttr('selected');
                     $('option', $html).filter(function(){
                        return ($(this).attr('value') === $el.val());
                     }).attr('selected', 'selected');
                  }

                  data = $html.html();
               }

               return data;
            }
         }
      ],
      'responsive': true
   });

   // Update original input/select on change in child row
   $('#example tbody').on('keyup change', '.child input, .child select, .child textarea', function(e){
       var $el = $(this);
       var rowIdx = $el.closest('ul').data('dtr-index');
       var colIdx = $el.closest('li').data('dtr-index');
       var cell = table.cell({ row: rowIdx, column: colIdx }).node();
       $('input, select, textarea', cell).val($el.val());
       if($el.is(':checked')){ 
          $('input', cell).prop('checked', true);
       } else {
          $('input', cell).removeProp('checked');
       }
   });
});

In addition to the above code, the following Javascript library files are loaded for use in this example:

//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js
https://cdn.datatables.net/r/dt/dt-1.10.9,r-1.0.7/datatables.min.js

The following CSS library files are loaded for use in this example to provide the styling of the table:

https://cdn.datatables.net/r/dt/dt-1.10.9,r-1.0.7/datatables.min.css

Edit on jsFiddle

Other examples

You Might Also Like

Comments

      1. Hi Michael,

        I noticed that for devices with smaller screens, when you click on the green icon to open the row and change any of the child inputs and then close the row,the value is reset to its default value ,any fix for this?

        1. That is exactly the problem my code solves. I just checked the table in SOLUTION section and it works as expected, all the values are retained. Make sure you’re using the table in the SOLUTION section and not in the PROBLEM section where it doesn’t work and is there to demonstrate the problem.

  1. Wow! This is exactly what I was looking for. Worked like a charm.

    I noticed that the form elements that are collapsed in the responsive tables post a null value which cannot be inserted into a database upon submission of the form, is there a workaround for this?

    Thanks for getting back to me.

    1. Use the code below to submit the form via Ajax. There might be a way to submit the form directly, but the code would be more complex.

      $('#frm-example').on('submit', function(e){
         var $form = $('<form></form>');
         
         table.cells().every( function () {
            $('input, select, textarea', $(this.node())).each(function(){
               $form.append($(this).clone());
            });
         });
         
         // Submit data via Ajax
         $.ajax({
            url: '/path/to/your/script',
            data: $form.serialize()
         });      
          
         // Prevent actual form submission
         e.preventDefault();
      });
      
      1. Thank you so much for your time.
        I really don’t know much about ajax but I’ll google and see how i can integrate your helpful script with my php script,oh and will i need any other third party plugin for posting data via ajax?

        1. It still doesn’t submit the hidden rows and columns after submitting the form via Ajax. Here’s my code.

          $('#form').submit(function(event) {
             var $form = $('<form><.form>');
          
             table.cells().every(function() {
                $('input, select, textarea', $(this.node())).each(function() {
                   $form.append($(this).clone());
                });
             });
          
             var formData = $("form").serialize();
          
             // process the form
             $.ajax({
                type: 'POST', // define the type of HTTP verb we want to use (POST for our form)
                url: baseurl + 'admin/bulk', // the url where we want to POST
                data: formData, // our data object
                dataType: 'json', // what type of data do we expect back from the server
                encode: true
             })
          
             // using the done promise callback
             .done(function(data) {
               // log data to the console so we can see
               console.log(data);
             })
          
             // using the fail promise callback
             .fail(function(data) {
                // show any errors
                // best to remove for production
                console.log(data);
             });
          
             // stop the form from submitting the normal way and refreshing the page
             event.preventDefault();
          });
          
            1. Hi,

              Sorry for this late reply but i would like to thank you for your help, the code now works perfectly,
              Have a good day

  2. Hi Michael,
    How would i implement this with bootstrap datetimepicker? I tried initializing the datetimepicker like this but it doesn’t work.

     function initDataTableCtrl(container) {
        $('table select', container).select2();
        $('.datepicker',container).datetimepicker({
           format:'YYYY-MM-DD'
        });
    }
    

    Is there any workaround to this?
    Thanks.

  3. not working with checkbox

    in full width if checkbox is selected than in responsive checkbox is not getting selected

  4. It doesn’t work properly on ‘select’ items. For instance:

    1. Get in responsive mode and show hiding columns
    2. Select the checkbox
    3. Hide columns
    4. Show columns

    –> Then the chexbox item in not selected

    ┬┐Any solution?

    Thanks!

    1. Jose, thanks for your comment.

      Are you trying the steps above in the table under “Solution” heading? Because it works correctly for me.

      However I discovered that it wasn’t remembering unchecked checkboxes when it appeared in the child row. I have corrected the code so it should now work as expected.

      1. Michael, can you tell what is the fix for remembering the unchecked checkboxes when the checkbox appears in the child row. This is happening for me too.

  5. I have a multiselect checkbox in place of the single in a similar implementation of this article. But the below line ends up checking all my checkboxs for the same name if first checkbox is checked. It just doesn’t get the other elements.

    
         if($el.prop('checked')){
             $('input', $html).attr('checked', 'checked');
         } 
    
    
    
    
    
    

    Can you please help me? Thanks.

Leave a Reply

You may use simple HTML to add links or lists to your comment. Also use <pre><code class="language-*">...</code></pre> to mark up code snippets. We support language-js, language-markup and language-css for comments.
(Optional)

This site uses Akismet to reduce spam. Learn how your comment data is processed.