How to set value for a calculated cell without submitting?

How to set value for a calculated cell without submitting?

pisislerpisisler Posts: 125Questions: 24Answers: 1

Hi.

I have some cells that do not have data in the ajax source. I dynamically calculate and display them through a custom rendering function. I need to update it on the fly while the user is in inline mode and he/she presses a key in a specific field. I tried to use editor.field('field').val('new calculation?') (like in here: https://datatables.net/forums/discussion/46864) But it didn't work.

Actually I don't even have a field initiated, because as I said, it's an on-the-fly value by calculation. I just tried field().val() just to test if things work; as well as table.cells(). But I am stuck here now.

{data: price, render: numberRendering}
{name: 'percentage', data: null, render: customRenderer}

I would like to update the value of percentage cell, without submitting, by just using an event listener like;

$(editor.field('price').input()).on('keypress', function (e, d) {
  // What now?
}

This question has accepted answers - jump to:

Answers

  • allanallan Posts: 63,455Questions: 1Answers: 10,465 Site admin
    Answer ✓

    What you would need to do here is to recalculate the value in your keypress event handler and write the new value into the corresponding cell. The underlying data doesn't change until you actually submit the form, so you can't just invalidate the cell unfortunately.

    $(editor.field('price').input()).on('keypress', function (e, d) {
      var id = editor.ids( true )[0];
      var writeTo = table.cell( id, columnIndex ).node();
    
      $(writeTo).html( ... calculation ... );
    } );
    

    Then when the form is submitted and the table re-rendered, the rendering function would take over and write the calculation in.

    Note that this uses the ids() method which was introduced in Editor 1.7.4 yesterday (an easy way to get the row id).

    Allan

  • pisislerpisisler Posts: 125Questions: 24Answers: 1

    Thanks Allan.

    I guess there is no point in recalculating the value if it's not going to update the display. Because when the form is submitted; it will already re-calculate automatically. So why would I update it before submissin. (As I said, it's a column but NOT a field.)

    Wouldn't it be possible to use jQuery selector and update it with .html() ?

  • pisislerpisisler Posts: 125Questions: 24Answers: 1

    I did it this way;

    // Live calculation without submit
    $(editor.field('price').input()).on('input', function (e, d) {
        // Retrieve full row, for re-calculation
        product = table.row(editor.modifier()).data();
        // The cell which is being edited now
        product.price = $(this).val();
        // Update profit against new product price
        // child (9) is the column number of calculated cell
        $(editor.modifier()).parent().children(':nth-child(9)').text(customCalcFunc(product));
    }
    

    By the way on('keyX') events were not accurate, hence I used on('input')

  • allanallan Posts: 63,455Questions: 1Answers: 10,465 Site admin

    That looks good to me - nice one.

    Allan

  • pisislerpisisler Posts: 125Questions: 24Answers: 1
    edited June 2018

    Well, here arises a new problem now. Remember that data manipulation topic? Storing the values before edit; so that I could compare the current and new data for my custom validators. Now that broke. Because product.price is overwritten.

            ajax: {
                url: "data.php?p=<?=$position;?>",
                data: function (d) {
                    if (editor.modifier() != null)
                        d.data_before_edit = table.row(editor.modifier()).data();
            }
    

    data_before_edit as it name suggests; used to store the data before the edit. So I could compare it when the form submitted. But now, product.price is updated, hence I cannot compare the old and new values. I don't understand why JavaScript takes the variable as reference. AFAIK, it should have created a new variable with a new scope in this line;

        // Retrieve full row, for re-calculation
        product = table.row(editor.modifier()).data();
        // The cell which is being edited now
        product.price = $(this).val();
    

    But it seems that it overwrites the value in data_before_edit. Do you have any opinion?

  • allanallan Posts: 63,455Questions: 1Answers: 10,465 Site admin

    Yes - the original object is mutated, which is why you are seeing this behaviour.

    To resolve, create a copy when you create data_before_edit:

    d.data_before_edit = $.extend( true, {}, table.row(editor.modifier()).data() );
    

    should do it.

    Allan

  • pisislerpisisler Posts: 125Questions: 24Answers: 1

    Hi Allan, I replaced the code with that; but it still overwrites; it sends the new value in data_before_edit

  • pisislerpisisler Posts: 125Questions: 24Answers: 1
    Answer ✓

    I solved the problem by copying the data with extend for re-calculation on the fly; rather than sending the data_before_edit as extended.

    I mean in ajax.data I fetch the row data as before;

    d.data_before_edit = table.row(editor.modifier()).data();
    

    Then I extend it to an empty object in input event listener;

    // Retrieve full row, for re-calculation
    product = $.extend(true, {}, table.row(editor.modifier()).data());
    // The cell which is being edited now
    product.price = $(this).val();
    

    This way it doesn't overwrite the old values.

This discussion has been closed.