Overwrite cell with input?

Overwrite cell with input?

Chris4712Chris4712 Posts: 11Questions: 2Answers: 0

Hey!

I have an AJAX loaded table, with the following columns:

    "columns": [
        { "data": "School" },
        { "data": "FirstName" },
        { "data": "Name" },
        { "data": "NeedCelluar" },
        { "data": "OrderID" },
        { "render": function (data, type, row, meta) {
            return "<input type=\"text\" onfocusout=\"AssigniPad2User(this, "+row["UserID"]+")\" >";  
        }
      }
    ]

As you can see, the input field has a function that is called on exit.

In this function I do the following:

function AssigniPad2User(Field, UserID) {
  var test = Field.parentElement.parentElement.childNodes;

    RequestTable.cell(test[3]).data("eSIM"); // that works
    test[5].innerHTML = "test"; // that works

    RequestTable.cell(test[5]).data("Test"); // dosent work!
}

For column 3 this also works.
With column 5 I don't get the content overwritten!

Only with test[5].innerHTML = "test"; it works. But then the value is not to be seen, if I export the table as PDF (as an example).

What am I doing wrong?
Greetings

Christian

Replies

  • kthorngrenkthorngren Posts: 21,159Questions: 26Answers: 4,920
    edited February 2021

    Typically you will need to use draw() to fully update the Datatable when using cell().data(). Without the draw() the render function won't run. Something like this:

        RequestTable.cell(test[3]).data("eSIM").draw(); // that works
        test[5].innerHTML = "test"; // that works
     
        RequestTable.cell(test[5]).data("Test").draw(); // dosent work!
    

    EDIT: If you are updating multiple cells you should only use draw() once after all the updates. I added it twice just for example.

    If this doesn't help please provide a test case showing the issue so we can help debug.
    https://datatables.net/manual/tech-notes/10#How-to-provide-a-test-case

    Kevin

  • Chris4712Chris4712 Posts: 11Questions: 2Answers: 0

    OK, I'm one step further:
    Column 5 does not seem to exist!

    When I try to read the content with

    console.log(RequestTable.cell(0, 5).data());

    I get an error.

    So it must be here:

        "columns": [
            { data: "School" },
            { data: "FirstName" },
            { data: "Name" },
            { data: "NeedCelluar" },
            { data: "OrderID" },
            { render: function (data, type, row, meta) {
                return "<input type=\"text\" onfocusout=\"AssigniPad2User(this, "+row["UserID"]+")\" >";  
            }
          }
        ]
    
  • colincolin Posts: 15,237Questions: 1Answers: 2,598

    We're happy to take a look, but as per the forum rules, please link to a test case - a test case that replicates the issue will ensure you'll get a quick and accurate response. Information on how to create a test case (if you aren't able to link to the page you are working on) is available here.

    Cheers,

    Colin

  • Chris4712Chris4712 Posts: 11Questions: 2Answers: 0
    edited February 2021

    Please note post below

    ~~I tried to rebuild it once. It does not quite work: http://live.datatables.net/qiqitome/1/

    With me results
    var row = Field.parentNode.parentNode.childNodes;
    An array with all cells of the column, so that I can address each cell from 0 to 5.

    In the example it is somehow cell 0, 3, 5, 7, 9 and 11.

    But you still see that I can't overwrite the value in the cell of the input field~~

  • Chris4712Chris4712 Posts: 11Questions: 2Answers: 0
    edited February 2021

    I have been able to create a better example: http://live.datatables.net/yalukexe/1/

    As you can see, I can assign the value from the input field to column 4. But not to column 5

  • colincolin Posts: 15,237Questions: 1Answers: 2,598

    That's because it's an input element, so you need to use val() - something like this:

      $(table.cell(Row, 5).node()).find('input').val(UserID + ' ' + 'test');
    

    See updated example here: http://live.datatables.net/yalukexe/3/edit

    Colin

  • Chris4712Chris4712 Posts: 11Questions: 2Answers: 0

    Thanks, but you misunderstood me. Or I have expressed myself incorrectly:
    As soon as you leave the input field, it should disappear and only the entered value should be there.

  • kthorngrenkthorngren Posts: 21,159Questions: 26Answers: 4,920
    edited February 2021

    The columns.render you defined will always show an input. You can add an if statement to determine whether to show the input or to show the value. I don't know the specific if condition to use for your requirements but something like this pseudo code:

        { render: function (data, type, row, meta) {
          if ( showInput ) {
            return "<input type=\"text\" onfocusout=\"AssigniPad2User(this, "+row["UserID"]+")\" >"; 
          }
          return row["UserID"];  // return the value you want to show
        }
    

    Kevin

  • Chris4712Chris4712 Posts: 11Questions: 2Answers: 0

    Hey Kevin,

    sorry, I don't understand what you mean.
    For example, I have 5 columns in my table and a sixth column with an input field.
    But the sixth column is not present in the source file.
    Greetings

    Christian

  • kthorngrenkthorngren Posts: 21,159Questions: 26Answers: 4,920

    If I understand correctly you have a column with input elements. When a user enters something into one of the input elements you want to remove the input and display something else. Is this correct?

    If my understanding is correct then you will need to update the option columns.render function to if you want to display the input element or the "something else". The showInput represents the decision to display the input or a value only. You will need to determine what this is based on your specific implementation.

    The return row["UserID"]; represents the value you want to show in place of the input. Is it a row data value? Is it the value of the input? Is it something else?

    It is possible to use columns.data to define a row data point that is not apart of the fetched data. You can use this to hold row values that aren't in your source data.

    Maybe you can create an event handler for the input and in the event handler update the row data with the value entered into the input. In the render function if the data exists display the data otherwise display the input.

    Sorry I don't have time right now to build an example but if you still need help and this is what you want to do I'll look at putting something together later.

    Kevin

  • kthorngrenkthorngren Posts: 21,159Questions: 26Answers: 4,920

    I created an example that hopefully will help and give you ideas of what you can do.
    http://live.datatables.net/yalukexe/4/edit

    I changed your input to remove the function call and to use an event handler as shown in this example. This is the recommended way to create event handlers. The event handler gets the input value, the cell containing the input and the row and row data. It combines the input value with a column in the row.

    I changed your 6th column to use columns.data. The property is not part of the source data but something used within the Datatables data for the row. Use defaultContent to set the cell to en empty string if the property does not exist.

    The columns.render function checks for an empty string in the cell (defaultContent value) and displays an input element. The change event sets the cell value using table.cell( td ).data(myString).draw();. The render function runs and displays the data not the input.

    HTH,
    Kevin

  • Chris4712Chris4712 Posts: 11Questions: 2Answers: 0

    Kevin, you are my hero!!!

    I have found the "error".
    In the JSON source data I had five column. But the table had six columns (last column the input field).
    Now that I added an empty sixth column to the source data, it worked.

    Thanks and greetings

    Christian

  • pisislerpisisler Posts: 125Questions: 24Answers: 1
    edited February 2022

    I know this is old but I would like to share my experience for the Google'rs. You don't actually need to re-draw the table to reflect the change you made if you just want to update the view only.

    In another way of saying, if you don't want to update the actual data but only manipulate the view, you can use cell() (row-selector in conjunction with column-selector). Let's say you want to manipulate the display of the column which is named "Device". You can do something like:

    // Select the according cell and alter its displayed content with jQuery
    $(table.cell(editor.modifier(), 'Device:name').node()).html('A new laptop');
    

    Since this is a direct manipulation of the DOM, it doesn't need a draw() call. Even your column doesn't need to have actual data.

    Note that you should be using this in an appropriate context like for example inside an event.

  • colincolin Posts: 15,237Questions: 1Answers: 2,598

    @pisisler The problem with that approach is that DataTables won't know about the change, so if you tried searching on that string you updated, it wouldn't match the value now in the DOM. You need to either use the approach described earlier in this thread and use cell().data(), or use your approach, and then invalidate DataTables's internal cache with cell().invalidate(),

    Colin

  • pisislerpisisler Posts: 125Questions: 24Answers: 1
    edited February 2022

    Yes, I ignored searching. That is why I already said "if you want to manipulate the display only, but not the actual data". In fact, that is a production method I am using to calculate profit margin on-the-fly without updating the actual data; allowing the user to decide whether to save or not, with the new margin candidate.

    But your note is of course very much worth to mention; thanks for adding it.

Sign In or Register to comment.