Manually trigger change event on editor field

Manually trigger change event on editor field

kaustubh.agrawal2000kaustubh.agrawal2000 Posts: 88Questions: 39Answers: 2

I want to manually trigger change event on an editor field so that the logic in

editor.dependent("", )...

Logic is re-executed.

Is it possible ?? how can I do that ?

This question has accepted answers - jump to:

Answers

  • Tester2017Tester2017 Posts: 145Questions: 23Answers: 17
    edited March 2018

    You could try a trick like this:

    editor.on(`open`, function(e, mode, action)
    {
        oldValue = editor.field(`myField`).val();
        editor.field(`myField`).val(`someValueToTriggerDependentEvent`);
    });
    
    editor.dependent(`myField`, function(val, data, callback) {
            console.log(`value ` + val + ` oldValue was: ` + oldValue);
            // reset the value to the original value
            editor.field(`myField`).val(oldValue);
            // and do what you want
    });
    

    Although the above code will trigger the "dependent" event, it does not make a lot of sense if you are using an event for something that is not really happening, so maybe you can explain why you want this kind of approach? Maybe there are better ways to drive....

  • allanallan Posts: 61,726Questions: 1Answers: 10,109 Site admin
    Answer ✓

    You can use field().input() to get the input element and then trigger a change event on it:

    editor.field('myField').input().trigger('change');
    

    Allan

  • mclowdmclowd Posts: 3Questions: 0Answers: 1

    Hi Allan,

    The above answer doesn't work when the field that has the dependent is initialised as a hidden field.

    At the moment, that ends up meaning that hidden fields need to have dependent values sourced and then updated manually on a per-field basis.

    If you have a complex dependent return data source that updates multiple fields options, show, hide etc, this workaround ends up needing a lot more code to do the same job, because instead of the dependent just updating all the various things that are returned automatically, you have to go and manually update each one via the editor field api calls.

    Is the dependent not triggering or being able to be triggered for hidden fields intentional? Is there a workaround that I could use that doesn't involve manually updating every field that the dependent would normally update automatically?

    DEMOS:

    Demonstration where a readonly field triggers the dependent call:
    http://live.datatables.net/zacizofe/1/edit?js,output

    Demonstration where a hidden field does not trigger the dependent call:
    http://live.datatables.net/muvojoko/1/edit?js,output

    Demonstration with a workaround to force the update of the options based on the hidden field value:
    http://live.datatables.net/fitehiqa/2/edit?js,output

    Code with workaround for hidden field active (for easier reading in the context of this thread):

    $(document).ready(function () {
    
      var editor = new $.fn.dataTable.Editor({
        table: '#example',
        idSrc: 'DT_RowId',
        language: {
          url: '//cdn.datatables.net/plug-ins/1.10.19/i18n/English.json'
        },
        fields: [{
          name: 'office',
          type: 'hidden',
          // type: 'readonly',
        }, {
          label: 'Positions Available',
          name: 'positions',
          type: 'select',
        }, ],
      });
    
      editor.on('open', function (e, mode, action) {
        // suggested answer to trigger a dependent
        editor.field('office').input().trigger('change');
    
        // workaround required for updating based on the value of a hidden field
        editor.field('positions').update(getPositions(editor.field('office').val()));
      });
    
      editor.dependent('office', function (val, data, callback) {
        var positions = getPositions(val);
    
        return {
          "options": {
            "positions": positions
          }
        };
    
      });
    
      var table = $('#example').DataTable({
        data: [{
          'DT_RowId': '1',
          'name': 'Tiger Nixon',
          'position': 'System Architect',
          'office': 'Edinburgh',
          'extn': '5421',
          'start_date': '2011/04/25',
          'salary': '$320,800'
        }, {
          'DT_RowId': '2',
          'name': 'Garrett Winters',
          'position': 'Accountant',
          'office': 'Tokyo',
          'extn': '8422',
          'start_date': '2011/07/25',
          'salary': '$170,750'
        }, {
          "DT_RowId": "3",
          "name": "Ashton Cox",
          "position": "Junior Technical Author",
          "office": "San Francisco",
          "extn": "1562",
          "start_date": "2009/01/12",
          "salary": "$86,000"
        }, {
          "DT_RowId": "4",
          "name": "Cedric Kelly",
          "position": "Senior Javascript Developer",
          "office": "Edinburgh",
          "extn": "6224",
          "start_date": "2012/03/29",
          "salary": "$433,060"
        }, {
          "DT_RowId": "5",
          "name": "Airi Satou",
          "position": "Accountant",
          "office": "Tokyo",
          "extn": "5407",
          "start_date": "2008/11/28",
          "salary": "$162,700"
        }, ],
        rowId: 'DT_RowId',
        columns: [{
          data: "DT_RowId",
          render: function (data, type, row) {
            return '<a href="#" class="editor_edit">Edit Record ' + data + '</a>';
          }
        }, {
          data: "name",
          title: "Name"
        }, {
          data: "position",
          title: "Position"
        }, {
          data: "office",
          title: "Office"
        }, {
          data: "extn",
          title: "Extn."
        }, {
          data: "start_date",
          title: "Start date"
        }, {
          data: "salary",
          title: "Salary "
        }]
      });
    
      table.on('click', 'a.editor_edit', function (e) {
        e.preventDefault();
    
        editor.edit($(this).closest('tr'), {
          title: 'Edit record',
          buttons: 'Update'
        });
    
      });
    
      function getPositions(val) {
        var positions;
    
        switch (val) {
          case 'Tokyo':
            positions = [
              'System Architect',
              'Technical Author'
            ];
            break;
    
          case 'San Francisco':
            positions = [
              'Javascript Developer',
              'Software Engineer',
              'Technical Author',
            ];
            break;
    
          case 'New York':
            positions = [
              'Regional Director',
            ];
            break;
    
          case 'Edinburgh':
            positions = [
              'No Positions available',
            ];
            break;
        }
        return positions;
      }
    
    });
    
  • allanallan Posts: 61,726Questions: 1Answers: 10,109 Site admin
    Answer ✓

    No - that's not intentional. At least it wasn't! The reason for it is that the hidden input type doesn't actually create a <input type="hidden"> element at all. It will just store the value in Javascript which is why a DOM event triggered on it does nothing.

    I've just been experimenting with some code to make it work, and while it does, it feels very hacky. But while doing so I thought of a better option - create a field as normal then hide it via the API - e.g.

    var editor = new $.fn.dataTable.Editor( {
      fields: [
        {
          name: 'myHiddenField'
        }
      ]
    } );
    
    editor.hide( 'myHiddenField' );
    

    That way its a regular DOM input element so events will work, but the end user can't see it.

    Allan

  • mclowdmclowd Posts: 3Questions: 0Answers: 1
    edited February 2019 Answer ✓

    Thank you for the speedy reply!

    Your response reminded me of the attr property, so setting up the field as type: 'text' with the attr: {type: 'hidden'} creates a DOM element, and this works with triggering the dependent, while still having the field hidden from the get go, and not having to make any additional api calls to hide it!

    Still a little hacky, but I think it's cleaner in communicating the intent of the field to always be hidden, while still having its value be available for dependent triggers.

    // ...
    fields: [{
          name: 'office',
          type: 'text',
          attr: {
            type: 'hidden'
          }
        },
    //...
    ]
    
This discussion has been closed.