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); }
   });
});

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

Related posts

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

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)