1

I am using a jQuery DataTables and adding a child row without Ajax. The problem is I display some information in the parent row and when the trigger is clicked reveals some form elements that can be filled to update the post.

I have two problems:

-DataTables strips out all my HTML from the child data.It only keeps the html I put in the function for format:

function format(value) {
    return '<div><form action="#" method="post">' + value + '<input type="submit" value="send"></form></div>';
}

-The child row includes the content from the 3 last elements from the parent row (separated with commas). The child content is stripped of html.

<tr>
<td colspan="8">
<div>
<form method="post" action="#">
999-15-03-02,2015-03-01,92854408,RSG09LECA-ROG09LEC,
<i class=" vis_info fi-alert size-16" title="Det mangler info. Klikk for å fylle ut!" style="color: red;"></i>
,
<i class="fi-print size-16" title="Skriv ut serviceskjema" style="color:#836F6F"></i>
,
<input class="service_dato dato" type="text" rel="2" value="08-03-15" name="service_dato">
<input class="alt_dato" type="hidden" name="alt_dato">
<i class="fi-check size-14" style="display:inline"></i>
,
<input class="fakt_mont dato" type="text" rel="2" value="10-03-15" name="fakt_mont">
<input class="alt_dato" type="hidden" name="alt_dato">
<i class="fi-check size-14" style="display:inline"></i>
 <input type="submit" value="send">
</form>
</div>
</td>
</tr>

Here is my table:

<table class="datatable display compact cell-border" id="servicetable">
    <thead>
       <th>Servicenr.</th>
       <th>Dato</th>
       <th>Mobil</th>
       <th>Pumpe</th>
       <th></th>
       <th></th>
       <th>Utført</th>
       <th>Fakturert</th>
</thead>
<tbody>
    <tr data-child-name="row0" data-child-value='<label for="service_avtalt">Avtalt dato</label><input type="text" name="service_avtalt" value=""><label for="snr_innedel">Serienr. innedel</label><input type="text" name="snr_innedel" value=""><label for="snr_utedel">Avtalt dato</label><input type="text" name="snr_utedel" value=""><label for="reg_nr">Reg.nr.</label><input type="text" name="reg_nr" value=""><label for="sist_service">Tidl.service</label><input type="text" name="sist_service" value=""><label for="sist_feil">Tidlilgere feil</label><input type="text" name="sist_feil" value=""><label for="at_innerdel">Måling av Δt over innerdel i varmedrift</label><input type="text" name="at_innerdel" value=""><label for="trykk_vdrift">Trykk varmedrift</label><input type="text" name="trykk_vdrift" value=""><label for="kommentar">Kommentar</label><input type="text" name="kommentar" value="Toshiba pumpe!!">'>
        <td>999-15-03-02</td>
        <td>2015-03-01</td>
        <td>92854408</td>
        <td>RSG09LECA-ROG09LEC</td>
        <td> <i class=" vis_info fi-alert size-16" style="color: red;" title="Det mangler info. Klikk for å fylle ut!"></i> 
        </td>
        <td class="senter"><i class="fi-print size-16" style="color:#836F6F" title="Skriv ut serviceskjema"></i>
        </td>
        <td>
            <input type="text" name="service_dato" class="service_dato dato" value="08-03-15" rel="2" />
            <input type="hidden" name="alt_dato" class="alt_dato" /> <i class="fi-check size-14" style="display:inline"></i></td>
        <td>
            <input type="text" name="fakt_mont" class="fakt_mont dato" value="10-03-15" rel="2" />
            <input type="hidden" name="alt_dato" class="alt_dato" /> <i class="fi-check size-14" style="display:inline"></i>

        </td>
    </tr>

Here is my example: http://jsfiddle.net/asle/a2p4kmh9/14/

Edited from @davidkonrads suggestion:

What if the link is like this with the rows ID and I pick it up in the click function?

<i class=" vis_info fi-alert" rel="34"></i>

$('#servicetable tbody').on('click', 'i.vis_info', function () {
    var tr = $(this).closest('tr');
    var row = table.row(tr);
    var rid = $(this).attr('rel');

$.post("code/get_child_data.php", {
        id: rid }, 
      function(data) {
        var form = (data);
    });

    if (row.child.isShown()) {
        // This row is already open - close it
        row.child.hide();
        tr.removeClass('shown');
    } else {
        // Open this row and use the data from get_child_data.php
        row.child(form).show();
        tr.addClass('shown');
    }
});

I forgot to say that some fields in the hidden row could have data already so I have to get the existing (if any) data for every row, also to edit current values. That is why I need to insert this dynamicaly.

Edited again and working - thanks @davidkonrads

Here is what works now. I had to move the functions around so I could get to the ajax data. - I attach a click event to the element - Add the rel=row_id from my loop so I can get it later - Post the row_id with ajax and add the content to hidden row and show it

$('#servicetable tbody').on('click', 'i.vis_info', function () {
    var tr = $(this).closest('tr');
    var row = table.row( tr );
    var rid = $(this).attr('rel');

$.post("code/get_service_child.lasso", {
    id: rid }, 
    function(data) {
    var form = (data); 

    if ( row.child.isShown() ) {
        // This row is already open - close it
        row.child.hide();
        tr.removeClass('shown');
    }
    else {
        // Open this row with data from $post call
        row.child(form).show();
        tr.addClass('shown');
    };
});   
} );

I will also be validating the form and posting it with $.post - then changing the alert icon to success icon. This is fun when it works :-)

1 Answer 1

2

I guess you are confusing row.data() with tr.attr('data-child-value')... The child content is not stripped out, it is never inserted - what you actually inserts is the column values from the row itself! row.data() returns an array with column values. Do this instead :

...
} else {
    // Open this row
    row.child(format(tr.attr('data-child-value'))).show();
    tr.addClass('shown');
}

forked fiddle -> http://jsfiddle.net/zyLfuk65/

However, I cannot figure out why you want to do that. It is way to much redundancy without any reasonable cause (sorry if I misunderstand! :) It does not seem that you really want a format() method, just a function that returns the form you want to show. More simple and less code :

var form = '<div><form action="#" method="post">' + 
'<label for="service_avtalt">Avtalt dato</label><input type="text" name="service_avtalt" value=""><br>'+
...
...
} else {
     // Open this row
     row.child(form).show();
     tr.addClass('shown');
}

which also makes it way easier to prepopulate the form with values, eg. $(form).find('input[name="snr_utedel"]').val(someValue); before you insert it to the details row.

demo -> http://jsfiddle.net/9m3vjy8r/

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks that cleared it up a bit for me. I need to populate the "var form" for each row. What about my suggestion above fetching the data with ajax?
I also wonder if I am using the right tool for my task. Maybe I am to obsessed by DataTables fixing everything for me. Should I maybe just use a modal popup or something to accomplish the form part? Or maybe using the jQuerey DataTables Responsive Plugin? So that all the fields are in one <TR> and filled in but the form fields are hidden dynamically like this: datatables.net/extensions/responsive/examples/child-rows/….
@asle Yes, I see your update. As I write it is very easy to populate form data, I did not do that in the example since it is not clear which column value corresponds to which input field. As implied very clearly, you can populate the form like this $(form).find('input[name="snr_utedel"]').val(rov.data()[columnIndex]); but when you are not telling which columns corresponsds to which input fields you must do that yourself. I do not want to waste time to guess.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.