Search code examples
javascriptqbo3

QBO V3 Behavior order of operations


I'm running into a problem creating a "depends" behavior where the object to depend on is an <option/> tag that has not loaded up yet because it loads up via an ajax call. There appears to be a race condition where the depends behavior is trying to load up before the ajax call is complete. Here is the element markup that failing to load the depends behavior:

<div class="control-group" data-behavior="Depend" data-depend-options="{{'depends': 'W9', 'required': true}}">

"W9" will be the ID of the <option/> tag. This option tag will be loaded up by the following code:

<select name="ProfessionalLicenseType" id="ProfessionalLicenseType" class="required" data-behavior="Dropdown" data-dropdown-options="{{ 'type': 'ObjectType', 'data': {{ 'Object': 'ProfessionalLicense' }}, 'selected': '{AttachmentType}', 'id': 'ObjectType' }}">

Should I not use the HTML markup to create the dependency behavior? Should I instead try to use javascript to create this dependency?

Thanks in advance.


Solution

  • The Depend behavior support binding to a select tag's value, rather than an option tag:

    <div class="control-group" data-behavior="Depend" data-depend-options="{{'depends': 'ProfessionalLicenseType=W9', 'required': true}}">
    

    The Depend behavior, on initialization, will check the value of ProfessionalLicenseType, and find that it's empty, disabling/hiding your dependent div tag. It will also add a change event handler to the ProfessionalLicenseType dropdown (qbo.Depends.js line 45):

    source.addEvent('change', qbo3.dependencyCheck.pass([source, element, options, depends]));
    

    The Dropdown behavior will later (asynchronously) load your options via AJAX, and if the behavior's options.selected is set, will set the matching option.selected=true (qbo.Dropdown.js line 105):

    if ((row[value] || row) == options.selected) {
      target.options[target.options.length - 1].selected = true;
      target.defaultIndex = target.options.length - 1;
      target.fireEvent('change');
    }
    

    The to this working is the target.fireEvent('change') noted above; that will trigger the Depend behavior to re-evaluate the dependency and react appropriately.