5

I have responsive DataTable in Form. DataTables generate child rows on small devices. In this rows I have some Input controls. And that causes two problems.

First problem:** Values from hidden child rows does not get into Form data.**

Second problem:** Values disappear after editing this inputs and hide row.**

Can someone please help me out?

Thanks

Update

Simplified tbody before .DataTable()

<tbody>
    <tr>
        <td>System Architect</td>
        <td>Edinburgh</td>
        <td>61</td>
        <td>
            <input name="1" type="text"/>
        </td>
        <td>
            <input name="2" type="text"/>
        </td>
        <td>
            <input name="3" type="text" value="example"/>
        </td>
    </tr>               
</tbody>

After .DataTable()

<tbody>    
    <tr role="row" class="odd">
        <td class="sorting_1">System Architect</td>
        <td>Edinburgh</td>
        <td>61</td>
    </tr>
</tbody>

And expanded

<tbody>  
  <tr role="row" class="odd parent">
    <td class="sorting_1">System Architect</td>
    <td>Edinburgh</td>
    <td>61</td>              
  </tr>
  <tr class="child">
    <td class="child" colspan="3">
      <ul data-dtr-index="0">
        <li data-dtr-index="3">
          <span class="dtr-title">Age:</span>
          <span class="dtr-data">
            <input name="1" type="text" style="background-image: ; background-       attachment: scroll; background-position: 100% 50%; background-repeat: no-repeat;">
          </span>
         </li>
         <li data-dtr-index="4">
           <span class="dtr-title">Start date:</span>
           <span class="dtr-data">
             <input name="2" type="text"></span>
         </li>
         <li data-dtr-index="5">
           <span class="dtr-title">Salary:</span>
           <span class="dtr-data">
             <input name="3" type="text" value="example">
           </span>
         </li>
       </ul>
     </td>
  </tr>
</tbody>

All simplified code looks like this fiddle.

Annotation

For some our internal problems I cannot use DataTables Ajax method - it would be very slow and against application logic. Thats why I am trying pass data from DataTable by classic Form.

Syscall
  • 19,327
  • 10
  • 37
  • 52
Daniel Treml
  • 75
  • 1
  • 6
  • This cannot be asnwered without seeing the code where you create the child rows. – davidkonrad Oct 28 '15 at 13:26
  • 1
    I just updated my question. I suggest to look at code at fiddle and try submit it un/expanded. – Daniel Treml Oct 28 '15 at 14:17
  • That's a very good question, I think I may have an answer. If you don't mind waiting a day or two, I will post a solution here. – Gyrocode.com Oct 29 '15 at 13:42
  • Thank you very much, I will be glad for any clue. So now, I have only idea to resolve second problem by these steps: get input value(on focusout) -> get data from table by DT.data() -> change value this specific input in this data -> DT.clear() -> DT.rows.add(edited data) -> DT.draw()... but this solution collapse table rows on every edit – Daniel Treml Oct 29 '15 at 15:26

1 Answers1

5

SOLUTION

Below is not an ideal solution but at least it works. I haven't tested hidden form elements and also this solution will not work with multiple form elements in the same cell.

You need to use columnDefs to target all columns containing form element and using render option define a function that will return HTML containing current form field value. This is necessary to render correct form field in child row.

In addition, parent form field needs to be updated when user changes value of the form field in child row.

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

DEMO

See this jsFiddle for code and demonstration.

LINKS

Gyrocode.com
  • 57,606
  • 14
  • 150
  • 185
  • 1
    It has the potential of being formalized and turned into a plugin. Not because it is die hard programming, but because many, many people need that feature - I guess. – davidkonrad Nov 01 '15 at 20:19
  • @davidkonrad, I'm thinking about it but I wanted to produce an answer before I come up with a plug-in. – Gyrocode.com Nov 01 '15 at 21:08
  • @Gyrocode.com, Thanks for the solution, it works great for second problem. I split my question into two separate questions so I could mark this as answer. I have the only one suggestion, If you are going to turn this into the plugin. It would be great if you could also include support for more than one input/select/textarea in the cell. – Daniel Treml Nov 02 '15 at 10:51
  • @DanielTreml, I haven't tested hidden form elements and also this will not work with multiple form elements in a cell. I will be refining this solution to support that as well. – Gyrocode.com Nov 02 '15 at 12:01
  • @DanielTreml, no problem. Can you explain the problem with hidden elements. Do you modify the value dynamically? Can you share an example, since the question you posted doesn't have hidden elements? – Gyrocode.com Nov 03 '15 at 16:58
  • @Gyrocode.com, my bad, I mean "collapsed child rows" by "hidden child rows" and Im trying resolved it with _fnGetHiddenNodes_. – Daniel Treml Nov 03 '15 at 18:34
  • @DanielTreml, I think with `fnGetHiddenNodes` you will not be able to access collapsed child rows. – Gyrocode.com Nov 03 '15 at 18:50
  • @Gyrocode.com, you're right. That wasn't right way. – Daniel Treml Nov 05 '15 at 08:32
  • Maybe someone here can help me with this similar problem: https://stackoverflow.com/questions/52313856/jquery-datatables-parent-and-child-rows-posted-to-server-as-one-record-instead-o – Dusan Sep 13 '18 at 12:52