1. Fabrik 3.9 has been released. If you have updated Joomla to 3.9, this is a required update.
    Dismiss Notice

setting a form value (that sticks) with javascript in another element.

Discussion in 'Professional Support' started by skyrun, Jun 19, 2019.

  1. skyrun

    skyrun Active Member

    Level: Community
    i would like to change element B (completeddate) based on the value of element A (status) if B is blank. so i have put the following javascript on element A (status) that fires when the status is changed:

    Code (Javascript):
    /* Set Date Completed if status changed to 3, 4 or 6 AND date completed not set */
    requirejs(['fab/fabrik'], function () {

      /*console.log('status: CHANGE fired');*/

      var wostatus = document.getElementById('srms_work_orders___status');
      var completeddate = document.getElementById('srms_work_orders___completeddate_cal');

      /*console.log('status=' + wostatus.value);
      console.log('completeddate=' + completeddate.value);*/

      if ((wostatus.value == 3 || wostatus.value == 4 || wostatus.value == 6) && (completeddate.value === '' || typeof completeddate.value === 'undefined')) {
        /*console.log('set to todays date');*/
        var today = new Date();
        var dd = String(today.getDate()).padStart(2, '0');
        var mm = String(today.getMonth() + 1).padStart(2, '0'); /*January is 0*/
        var yy = today.getFullYear().toString().substr(-2);
        completeddate.value = mm + "/" + dd + "/" + yy;
        var $completeddate = $('srms_work_orders___completeddate');
        /* Copy value */
        $completeddate.value = mm + "/" + dd + "/" + yy;
        console.log('setting jquery completed date');
        /* Since we changed the value, trigger any change events on the price_used field */
    so this code is on the status element set to fire when status is changed (which works).
    the js code above correctly puts today's date into 'completeddate' (which is a date type element) when i change status to 3, 4 or 6 AND the date is blank. then i can save the form and it all works. that's the 'normal' use-case.

    you'll see that i am attempting to edit the fabrik field using the DOM and using jQuery. i wouldn't need to do both of course, just trying mutiple ways of doing the same thing because of the issue below. this could be related... also note that if i check and update srms_work_orders___completeddate (vs not srms_work_orders___completeddate_cal, adding a _cal, which i can see in the dom is added to that field, probably because it's a calendar?) then it us 'undefined'. i have to put the _cal on there to get data.

    my issue is the following use case that i can't get to work.
    1) i type in a datecompleted of 6/11/19 (for example) on the form and save it.
    2) i open the form to the same record and blank out the datecompleted manually.
    3) then i change status to one of the status' so that datecompleted fills in as today's date (6/19/19 in this case) by the javascript above.

    so far so good. the screen looks right and 06/19/19 is in the datecompleted field... however...

    4) when i press 'save' or 'apply' on the form, the date changes back immediately to the LAST SAVED value '06/11/19' on the screen and it also saves 06/11/19 (not the value that was there when i pressed save) in the table. ignoring the value displayed on the form. if i change the date by typing in 06/19/19 or selecting that on the calendar, then it works. but the .js is not changing something deeper than what's displayed on the form...
    Last edited: Jun 19, 2019
    Heward James likes this.
  2. cheesegrits

    cheesegrits Support Gopher Staff Member

    Level: Community
    Yeah, you need to call the update() method for the Fabrik element object. Just changing the DOM inputs mean that our internal values for the date don't get updated.

    So instead of ...

    Code (Text):

    var completeddate = document.getElementById('srms_work_orders___completeddate_cal');
    completeddate.value = mm + "/" + dd + "/" + yy;
    ... do ...

    Code (Text):

    var completedate = Fabrik.getBlock('form_X').formElements.get('srms_work_orders___completeddate');
    completedate.update(yy + '-' + mm + '-' + dd);
    Note that you have to use Y-m-d format, and the date JS will re-format it with your 'form format' for display. Also that it will assume a time of 00:00:00, which may or may not be what you need (time zones, how you have your date element configured).

    Also, if that JS is in the element JS settings themselves (not in a form_X.js file), you don't need to the requirejs() wrapper. That's only needed when you have code that uses the Fabrik global object, in a separate file like ./components/com_fabrik/js/form_X.js, or in a template file, to make sure Fabrik has been loaded before your code executes. If the code is run from within the element JS event handling, you are guaranteed that Fabrik has already loaded.

    -- hugh
  3. cheesegrits

    cheesegrits Support Gopher Staff Member

    Level: Community
    Oh, also, if the code is in the element JS events, you can do ...

    Code (Text):

    var completedate = this.form.formElements.get('srms_work_orders___completeddate');
    ... rther than Fabrik.getBlock('form_X'), ie. you don't need to hard code the form ID, as 'this' is a reference to the element object, and this.form is a reference to the form object.

    -- hugh
  4. skyrun

    skyrun Active Member

    Level: Community
    that worked, THANKS!

    may want to update that on the wiki about calling the 'update' method, or i can (if you're not picky about it being 100% accurate ;-) or maybe it's there and i just missed it.
  5. cheesegrits

    cheesegrits Support Gopher Staff Member

    Level: Community
    Feel free to update the wiki, you probably won't do any worse than I would. :)

    -- hugh
  6. skyrun

    skyrun Active Member

    Level: Community
    could have sworn this was working, but it's not now.

    WORKS: var completeddate = document.getElementById('srms_work_orders___completeddate_cal'); // returns 07/01/19
    DOES NOT WORK: var completeddate = this.form.formElements.get('srms_work_orders___completeddate'); // returns null
    DOES NOT WORK: var completeddate2 = this.form.formElements.get('srms_work_orders___completeddate_cal'); // returns null
    DOES NOT WORK: var completeddate3 = this.form.formElements.get('srms_work_orders___completeddate_raw'); // returns null

    and with the one that works to get the value (getElementByID), then this line does not work:
    completeddate.update(yyyy + '-' + mm + '-' + dd);

    gives error completeddate.update is not a function.
  7. skyrun

    skyrun Active Member

    Level: Community
    this works, but seems a bit redundant. seems i have to read the value using the DOM and then get the element pointer to call .update method on to update it for fabrik.

    /* only way to read to get current value */
    var completeddate = document.getElementById('srms_work_orders___completeddate_cal');

    /* only way to refer to value and be able to update */
    var completeddate2update = this.form.formElements.get('srms_work_orders___completeddate');
    completeddate2update.update(yyyy + '-' + mm + '-' + dd);
  8. cheesegrits

    cheesegrits Support Gopher Staff Member

    Level: Community
    Works fine for me:


    In case the font isn't readable, what I typed is ...

    Code (Text):

    << Fabrik.blocks.form_2_1.formElements.get('fab_main_test___date_format').getValue()
    >> "2019-07-27 00:00:00"
    << Fabrik.blocks.form_2_1.formElements.get('fab_main_test___date_format').update("2019-07-03")
    >> undefined
    ... which as you can see, gets and sets the value correctly.

    You can replace the "Fabrik.blocks.form_2_1" part with either Fabrik.getBlock() or this.form, as explained previously.

    -- hugh

Share This Page