Inline edit : Uncaught TypeError: Cannot read property 'contents' of undefined

Inline edit : Uncaught TypeError: Cannot read property 'contents' of undefined

sreisersreiser Posts: 6Questions: 1Answers: 0

Hello,
I have the following problem:
When I update the row, the row disappears and in the console I get this warning:
Uncaught TypeError: Cannot read property 'contents' of undefined

I use DataTables 1.10.10 and Editor 1.5.3.
I pull and update the data with REST-API and AJAX.

Column definition

Object {data: "emp_id", class: "cell_right_aligned readonly", width: "10%", editField: "emp_id", title: "Pers.Nr."}
Object {data: "emp_name", class: "readonly", width: "30%", editField: "emp_name", title: "Name"}
Object {title: "Steuerung ganze KW", data: "(null)", width: "20%", className: "center", defaultContent: "<a href="" class="editor_set_present">A</a><a href…p">D</a><a href="" class="editor_set_other">S</a>"}
Object {data: "func_day1", editField: "func_day1", title: "Mo", width: "5%", class: "sd_function"…}
Object {data: "func_day2", editField: "func_day2", title: "Di", width: "5%", class: "sd_function"…}
Object {data: "func_day3", editField: "func_day3", title: "Mi", width: "5%", class: "sd_function"…}
Object {data: "func_day4", editField: "func_day4", title: "Do", width: "5%", class: "sd_function"…}
Object {data: "func_day5", editField: "func_day5", title: "Fr", width: "5%", class: "sd_function"…}
Object {data: "sd_sickreason_name", class: "sickreason", width: "30%", visible: false, name: "sd_sickreason_name"…}
        bVisible: true
        class: "sickreason"
        data: "sd_sickreason_name"
        editField: "sd_sickreason"
        mData: "sd_sickreason_name"
        name: "sd_sickreason_name"
        sClass: "sickreason"
        sName: "sd_sickreason_name"
        sTitle: "Krankheitsgrund"
        sWidth: "30%"
        title: "Krankheitsgrund"
        visible: true
        width: "30%",
        }
Object {data: "sd_tripreason", class: "tripreason", width: "30%", visible: true, name: "sd_tripreason"…}

Editor field definition

Object {name: "emp_id", label: "Pers.Nr."}
Object {name: "emp_name", label: "Name"}
Object {name: "func_day1", label: "Mo", def: "-"}
Object {name: "func_day2", label: "Di", def: "-"}
Object {name: "func_day3", label: "Mi", def: "-"}
Object {name: "func_day4", label: "Do", def: "-"}
Object {name: "func_day5", label: "Fr", def: "-"}
Object {type: "select", label: "Krankheitsgründe:", name: "sd_sickreason", options: Array[3]}
Object {name: "sd_tripreason", label: "Reiseziel/grund", default: ""}

JSON-Response from Datatables

data: [{
0: {emp_id: 687, emp_name: "XXXX, Andreas ", sd_sickreason: "2",…}
DT_RowId: "row687"
emp_id: 687
emp_name: "XXXX, Andreas "
func_day1: "D"
func_day2: "D"
func_day3: "A"
func_day4: "D"
func_day5: "D"
sd_sickreason: "2"
sd_sickreason_name: "OP"
sd_tripreason: ""
1: {emp_id: 966, emp_name: "XXXX, Enrico ", sd_sickreason: "1",…}
DT_RowId: "row966"
emp_id: 966
emp_name: "XXXX, Enrico "
func_day1: "K"
func_day2: "K"
func_day3: "K"
func_day4: "K"
func_day5: "K"
sd_sickreason: "1"
sd_sickreason_name: "Erkältung"
sd_tripreason: "g"
2: {emp_id: 1110, emp_name: "XXXX, Kadir ", sd_sickreason: "1",…}
DT_RowId: "row1110"
emp_id: 1110
emp_name: "XXXXX, Kadir "
func_day1: "K"
func_day2: "K"
func_day3: "A"
func_day4: "s"
func_day5: "K"
sd_sickreason: "1"
sd_sickreason_name: "Erkältung"
sd_tripreason: ""
draw: 1
recordsFiltered: 3
recordsTotal: 3}]

JSON-Response after submit

data: [,…]
0: {
DT_RowId: "row966"
emp_id: "966"
emp_name: "XXXX, Enrico "
func_day1: "K"
func_day2: "K"
func_day3: "K"
func_day4: "K"
func_day5: "K"
sd_sickreason: "2"
sd_tripreason: "g"
}

Click event for inline edit

 // Inline editing on click
    $(tablename).on( 'click', 'tbody td:not(:nth-child(3))', function (e) {
  
  
       // console.log('inline');
        editor.inline( this, {submit:'allIfChanged' , submitOnBlur: true} );
    } );

I have tried a lot of things, but nothing solved this problem.
Has somebody a suggestion how to get rid of this exception?

Thank you very much in advance.

Best regards,
Sascha

This question has an accepted answers - jump to answer

Answers

  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin

    When I update the row, the row disappears

    This suggests that the server is not responding with the JSON data that Editor requires. The information you provide above would appear to suggest otherwise though.

    Could you link to the page so I can debug it directly please.

    Allan

  • zachpainter77zachpainter77 Posts: 22Questions: 1Answers: 1

    Check out my fiddle that uses this binding for knockout --> pretty slick for editable datatables!

    https://www.datatables.net/forums/discussion/31797/knockout-js-3-4-custom-binding-for-jquery-datatables-net#latest

    Link to example fiddle in discussion.

  • sreisersreiser Posts: 6Questions: 1Answers: 0

    Dear Allan,
    unfortunately this project only exists on dev system which is not available to public.

    I can provide you the php script which is responsible for updating the row(s)

    <?php
    
    
    require_once('../credentials.php');
    
    $action = $_POST['action'];
    $start_date = $_POST['start_date'];
    $end_date = $_POST['end_date'];
    $department= $_POST['department'];
    
    $db = null;
    $inputdata = $_POST['data']; //Row(s) from editor
    
    $row_ids = array_keys($inputdata);
    $data = [];
    
    
    try
    {
                
        $db = new PDO('mysql:host=' . $servername .';dbname=' . $database, $user, $password);
        $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    
        //Zeichensatz setzen
        try
        {
            $db->query('SET NAMES "utf8"');
    
        }
        catch (PDOException $e)
        {
            die('Could not set codepage: ' . $e->getMessage());
    
        }
    }
    catch (PDOException $e)
    {
        die('Verbindung fehlgeschlagen: ' . $e->getMessage());
    
    }
    
    
    
    foreach($row_ids as $row_id) 
    {  
       $row_to_return = [];
    
      if( isset($inputdata[$row_id]))
      {
            $row = $inputdata[$row_id];
    
            $totaldays = 5;
    
            $toupdate = [];
    
            $date = new DateTime($start_date);
          
            //Create items to update. One row in editor = 5 rows in table in database
            for ($day = 1; $day <= $totaldays; $day++)
            {
    
    
                $item =  [ "sd_emp_id" => $row["emp_id"],
                          "sd_date" => $date->format('Y-m-d'), 
                          "sd_function" => $row['func_day' . $day],
                          "sd_department" => $department,
                          "sd_sickreason" => $row['sd_sickreason'],
                          "sd_tripreason" => $row['sd_tripreason']
                         ];
    
                 array_push($toupdate, $item); 
                 $date->add(new DateInterval('P1D')); //Next day
    
            }
    
            update($db,$toupdate); 
    
            $row_to_return['DT_RowId'] = $row_id; 
    
    
            foreach ($row as $key => $value) 
            {  
                $row_to_return[$key] = $value;     
            }
    
            $data[] = $row_to_return;
      }
    }
    $returndata['data'] = $data;
    
    $db = null;
    
    
    
    echo json_encode($returndata);
    
      
    
    function update($db, $input)
    {
            try
            {
              $sqlbefehl = 'UPDATE staffdeployment
                            SET sd_function = :sd_function,      
                            sd_sickreason = :sd_sickreason,
                            sd_tripreason = :sd_tripreason                      
                            WHERE sd_emp_id = :sd_emp_id
                            AND sd_date =:sd_date 
                            AND sd_department = :sd_department ';
    
    
                //sd_id ist autoinkrement, wird von der Datenbank automatisch vergeben
                $query = $db->prepare($sqlbefehl);
    
    
                $sd_emp_id =0;
                $sd_function = '';
                $sd_date ='';
                $sd_department= '';
                $sd_tripreason= '';
                $sd_sickreason= 0;
    
                $query->bindParam(':sd_emp_id',$sd_emp_id);
                $query->bindParam(':sd_function',$sd_function);
                $query->bindParam(':sd_date',$sd_date);
                $query->bindParam(':sd_department',$sd_department);
                $query->bindParam(':sd_tripreason',$sd_tripreason);
                $query->bindParam(':sd_sickreason',$sd_sickreason);
    
                foreach( $input as $item)
                {  
    
                    $sd_emp_id=$item['sd_emp_id'];
                    $sd_function=$item['sd_function'];
                    $sd_date=$item['sd_date'];
                    $sd_department=$item['sd_department'];
                    $sd_tripreason=$item['sd_tripreason'];
                    $sd_sickreason= intval($item['sd_sickreason']);
    
                    $query->execute();
    
                }
    
            }
            catch (PDOException $e)
            {
                 die('<br> Fehler aufgetreten beim Ausführen der Update-Anweisung: <br>'
                     . $e->getMessage());
            }
    
    }
         
     
    
    <?php
    >
    ```
    ?>
    
    
    and also the initialisation of editor:
    
    

    function init_Editor(fields)
    {

    editor = new $.fn.dataTable.Editor( {
    ajax: {
            create: {
                type: 'POST',
                url:  '../db/datatables/insertStaffDeployment.php',
                data: {
                        start_date : moment(current).day('Monday').format('YYYY-MM-DD'),
                         end_date : moment(current).day('Friday').format('YYYY-MM-DD'),
                         department : selectedCs_ID
                      },
            },
            edit: {
                type: 'POST',
                url:  './db/datatables/editStaffDeployment.php?id=_id_',
                data: {
                         start_date : moment(current).day('Monday').format('YYYY-MM-DD'),
                         end_date : moment(current).day('Friday').format('YYYY-MM-DD'),
                         department : selectedCs_ID
    
                      },
            }
    
        },
    
        table: tablename,
        fields: fields, //array of fields created before
        formOptions:
         {
           main: { onReturn:false} 
    
         }
    } );
    

    }
    ```

  • sreisersreiser Posts: 6Questions: 1Answers: 0

    as such as the initialisation of data tables:


    var row_ids_sickreason = []; function init_DataTable(columns) { table = $(tablename).DataTable( { "ajax": { "url": "./db/datatables/getStaffDeployment.php", "type": "POST", data: function ( d ) { buildParms(d); }, dataSrc : function(json) { handle_SickReason(json.data); return json.data; } }, "language": {url: getLanguageFileForDataTables(language)}, dom: 'Bfrtip', "processing": true, "destroy" : true, "serverSide": true, "scrollX": true, "scrollCollapse": true, "autoWidth": true, "columns" : columns, "order": [], select: { style: 'os', selector: 'td:first-child' }, buttons: [ { extend: 'create', editor: editor }, { extend: 'edit', editor: editor } ], initComplete: function(settings, json) { // applyPermission(); if(json.recordsTotal == 0 && template_created == false) { createTemplate(); } }, createdRow : function(row, data, index) { //ids are collected in handle_SickReason if(row_ids_sickreason.indexOf(data.DT_RowId) != -1) { //Highlight td, in which user has to choose sick reason $('td.sickreason',$(row)).css('background-color','red'); } } }); } function buildParms(d) { d.start_date = moment(current).day('Monday').format('YYYY-MM-DD'); d.end_date = moment(current).day('Friday').format('YYYY-MM-DD'); d.department = selectedCs_ID; } function handle_SickReason(data) { var stringStartsWith = function (string, prefix) { return string.slice(0, prefix.length) == prefix; }; if(data.length > 0) { row_ids_sickreason = []; var found_sick = false; data.forEach(function(element,index, rows) { for(var key in element) { if (stringStartsWith(key, 'func') && (element[key] == 'k' || element[key] == 'K')) { found_sick = true; row_ids_sickreason.push(element['DT_RowId']); break; } } }); if(found_sick == true) { $(tablename).DataTable().column('sd_sickreason_name:name').visible(true); $(tablename).DataTable().column('sd_sickreason:name').visible(true); } else { $(tablename).DataTable().column('sd_sickreason_name:name').visible(false); $(tablename).DataTable().column('sd_sickreason:name').visible(false); } } }

    Here is additionally the detailed output from console:


    Editor.inline @ VM290:2750 (anonymous function) @ VM290:2736 d @ jquery-2.1.4.min.js:3 n.event.dispatch @ jquery-2.1.4.min.js:3 r.handle @ jquery-2.1.4.min.js:3 n.event.trigger @ jquery-2.1.4.min.js:3 n.fn.extend.triggerHandler @ jquery-2.1.4.min.js:3 Editor._event @ VM290:4441 (anonymous function) @ VM290:5120 opts.success @ VM290:3996 j @ jquery-2.1.4.min.js:2 k.fireWith @ jquery-2.1.4.min.js:2 x @ jquery-2.1.4.min.js:4 (anonymous function) @ jquery-2.1.4.min.js:4 XMLHttpRequest.send (async) k.cors.a.crossDomain.send @ jquery-2.1.4.min.js:4 n.extend.ajax @ jquery-2.1.4.min.js:4 Editor._ajax @ VM290:4092 Editor._submit @ VM290:5031 send @ VM290:3375 Editor.submit @ VM290:3397 Editor._blur @ VM290:4138 Editor.blur @ VM290:1751 Editor._tidy @ VM290:5188 Editor.inline @ VM290:2736 (anonymous function) @ VM297:326 n.event.dispatch @ jquery-2.1.4.min.js:3 r.handle @ jquery-2.1.4.min.js:3

    error was thrown at
    var children = node.contents().detach()

    Editor.prototype.inline = function ( cell, fieldName, opts )
    {
        var that = this;
    
        // Argument shifting
        if ( $.isPlainObject( fieldName ) ) {
            opts = fieldName;
            fieldName = undefined;
        }
    
        opts = $.extend( {}, this.s.formOptions.inline, opts );
    
        var editFields = this._dataSource( 'individual', cell, fieldName );
        var node, field;
        var countOuter=0, countInner;
    
        // Read the individual cell information from the editFields object
        $.each( editFields, function ( i, editField ) {
            // Only a single row
            if ( countOuter > 0 ) {
                throw 'Cannot edit more than one row inline at a time';
            }
    
            node = $(editField.attach[0]);
    
            // Only a single item in that row
            countInner = 0;
            $.each( editField.displayFields, function ( j, f ) {
                if ( countInner > 0 ) {
                    throw 'Cannot edit more than one field inline at a time';
                }
    
                field = f;
                countInner++;
            } );
    
            countOuter++;
    
            // If only changed values are to be submitted, then only allow the
            // individual field that we are editing to be edited.
            // This is currently disabled, as I'm not convinced that it is actually
            // useful!
            // if ( opts.submit === 'changed' ) {
            //  editField.fields = editField.displayFields;
            // }
        } );
        
        // Already in edit mode for this cell?
        if ( $('div.DTE_Field', node).length ) {
            return this;
        }
    
        // Some other field in inline edit mode?
        if ( this._tidy( function () { that.inline( cell, fieldName, opts ); } ) ) {
            return this;
        }
    
        // Start a full row edit, but don't display - we will be showing the field
        this._edit( cell, editFields, 'inline' );
        var namespace = this._formOptions( opts );
    
        var ret = this._preopen( 'inline' );
        if ( ! ret ) {
            return this;
        }
     //---> Line 2750
        // Remove from DOM, keeping event handlers, and include text nodes in remove
        var children = node.contents().detach();
    
             ...
       
    
    

    Can I provide you something else?

  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin

    Looking at the JSON response again, it looks like it might be a little wrong although its hard to tell with that formatting. Can you post the raw JSON that is returned from the server, not the code that is formatted by the browser?

    Thanks,
    Allan

  • sreisersreiser Posts: 6Questions: 1Answers: 0

    Hello Allan,
    yes of course:

    {"data":[
    {"DT_RowId":"row966",
    "emp_id":"966",
    "emp_name":"xxx, Enrico ",
    "func_day1":"U",
    "func_day2":"U",
    "func_day3":"U",
    "func_day4":"U",
    "func_day5":"U",
    "sd_sickreason":"1","sd_tripreason":""}
    ]}
    
  • sreisersreiser Posts: 6Questions: 1Answers: 0

    I think it belongs on the editor field with type 'select'.
    If i replace this field with a simple input field the error does not appear.

  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin
    Answer ✓

    Thanks for the details!

    Interestingly someone else just posted almost exactly the same issue - I've written up a detailed reply with how to fix it. Exactly the same fix will apply here - you need to pass the index into inline() rather than the node (this).

    Regards,
    Allan

  • sreisersreiser Posts: 6Questions: 1Answers: 0

    Hello Allan,
    no problem.
    Thank you for helping me.

    Best regards,

    Sascha

This discussion has been closed.