Setting combobox value with Javascript without triggering wasChanged flag


#1

Hi

On my invoice page of my CRM where you can add labour or parts records, these entries include a combobox for description to allow the selection of pre-typed options such as ‘Callout’, Extra Hour(s)’ to select from, or you can freetype your own.

I have set the following event so the invoice totals are recalculated, updated on screen and then certain buttons are disabled to prevent data corruption upon submission.

descriptionCombo.attachEvent("onSelectionChange", function() {            
            if(populatingRows === false) { refreshTotals(); }        
        } ); 

I am having a problem where the “onChange” and “onSelectionChange” events are fired when I click anywhere on the page after the page has loaded. I need the “onSelectionChange” to be fired only when a user selects/changes a pre-filled option.

My Combobox call

// Convert Description cell into a combobox
descriptionCombo = dhtmlXComboFromSelect('qform['+section+'_items]['+iteration+'][description]');
descriptionCombo.DOMelem_input.id = 'qform['+section+'_items]['+iteration+'][description_combobox]';        
//descriptionCombo.setSize(400);    
descriptionCombo.DOMelem_input.maxLength = 100;    
descriptionCombo.DOMelem_input.required = true;
descriptionCombo.setComboText('');
descriptionCombo.setFontSize("10px","10px");
//descriptionCombo.attachEvent("onChange", function(value, text) { refreshTotals(); } );
descriptionCombo.attachEvent("onSelectionChange", function() {            
    if(populatingRows === false) { refreshTotals(); }        
} );  
dhtmlxEvent(descriptionCombo.DOMelem_input, "keypress", function(e) {
    if(onlyAlphaNumericPunctuation(e)) { return true; }
    e.cancelBubble=true;
    if (e.preventDefault) e.preventDefault();
        return false;
} );

Example Dummy Row

<tr id="dummy_labour_items_row_iteration" class="dummy_item_row olotd4" style="display: none;">
    <td align="left">
        <select id="qform[labour_items][iteration][description]" name="qform[labour_items][iteration][description]" value="" style="width: 100%" disabled="">
            <option value="Callout">Callout</option>
            <option value="Basic Labour">Basic Labour</option>                                                                                            
        </select>
    </td>
    <td align="left"><input id="qform[labour_items][iteration][unit_qty]" name="qform[labour_items][iteration][unit_qty]" style="width: 50px;" size="6" value="1.00" type="text" maxlength="6" required="" disabled="" onkeydown="return onlyNumberPeriod(event);"></td>
    <td align="left">
        <select id="qform[labour_items][iteration][unit_net]" name="qform[labour_items][iteration][unit_net]" class="vatTaxSystem" style="width: 100%;" value="" required="" disabled="">
                <option value="35.00">35.00</option>
                <option value="20.00">20.00</option>
        </select>
    </td>
    <td class="vatTaxSystem salesTaxSystem" align="left" hidden="" style="display: table-cell;"><input id="qform[labour_items][iteration][sub_total_net]" name="qform[labour_items][iteration][sub_total_net]" size="6" value="0.00" type="text" maxlength="6" required="" readonly="" disabled="" onkeydown="return onlyNumberPeriod(event);"></td>
    <td class="vatTaxSystem" align="right" hidden="" style="display: table-cell;">
        <select id="qform[labour_items][iteration][vat_tax_code]" name="qform[labour_items][iteration][vat_tax_code]" value="TNA" style="width: 100%; font-size: 10px;" required="" disabled="">                                                                            
            <option value="TNA" data-taxrate="0.00" hidden="">TNA - Not Applicable @ 0.00%</option>
            <option value="T0" data-taxrate="0.00">T0 - Zero Rate @ 0.00%</option>
            <option value="T1" data-taxrate="20.00">T1 - Standard Rate @ 20.00%</option>
            <option value="T2" data-taxrate="0.00">T2 - Exempt @ 0.00%</option>
            <option value="T4" data-taxrate="0.00">T4 - Sales - Goods - EC VAT Customers @ 0.00%</option>
            <option value="T5" data-taxrate="5.00">T5 - Reduced Rate @ 5.00%</option>
            <option value="T7" data-taxrate="0.00">T7 - Zero Rate Purchases - Goods - EC @ 0.00%</option>
            <option value="T8" data-taxrate="0.00">T8 - Standard Rate Purchases - Goods - EC @ 0.00%</option>
            <option value="T9" data-taxrate="0.00">T9 - Transactions not involving VAT @ 0.00%</option>
            <option value="T20" data-taxrate="0.00">T20 - Reverse Charges @ 0.00%</option>
            <option value="T22" data-taxrate="0.00">T22 - Sales - Services - EC VAT Customers @ 0.00%</option>
            <option value="T23" data-taxrate="0.00">T23 - Zero Rate / Exempt Purchases - Services - EC @ 0.00%</option>
            <option value="T24" data-taxrate="0.00">T24 - Standard Rate Purchases - Services - EC @ 0.00%</option>
            <option value="T25" data-taxrate="0.00">T25 - Flat Rate Capital Asset @ 0.00%</option>                                                                                        
        </select>
    </td>                                                                               
    <td class="vatTaxSystem salesTaxSystem" align="right" hidden="" style="display: table-cell;"><input id="qform[labour_items][iteration][unit_tax_rate]" name="qform[labour_items][iteration][unit_tax_rate]" style="width: 50px;" size="6" value="0.00" type="text" maxlength="6" required="" readonly="" disabled="" onkeydown="return onlyNumberPeriod(event);">%</td>
    <td class="vatTaxSystem salesTaxSystem" align="right" hidden="" style="display: table-cell;"><input id="qform[labour_items][iteration][sub_total_tax]" name="qform[labour_items][iteration][sub_total_tax]" size="6" value="0.00" type="text" maxlength="6" required="" readonly="" disabled="" onkeydown="return onlyNumberPeriod(event);"></td>                                                                                                                                      
    <td class="salesTaxSystem" align="right" hidden=""><input id="qform[labour_items][iteration][sales_tax_exempt]" name="qform[labour_items][iteration][sales_tax_exempt]" type="checkbox" disabled=""></td>
    <td align="right"><input id="qform[labour_items][iteration][sub_total_gross]" name="qform[labour_items][iteration][sub_total_gross]" size="6" value="0.00" type="text" maxlength="6" required="" readonly="" disabled="" onkeydown="return onlyNumberPeriod(event);"></td>
    <td align="right">
        <img src="/projects/qwcrm/src/themes/default/images/icons/delete.gif" alt="" border="0" height="14" width="14" class="confirmDelete" onmouseover="ddrivetip('<b>Delete Labour Record</b>');" onmouseout="hideddrivetip();">
    </td>
</tr>

NB: populatingRows is a true/false variable I use to detect if the page is running functions on the JQuery Dom Ready statement, so can effectively be ignored because the event trigger should not even be called.

The Way my code works is as follows:

  • I am using smarty template system which builds the html outptut including some lists in dummy rows. These rows are set to style=“display: none;”. There is one dummy row for labour and one for parts, these different sections perform exactly the same.
  • At the top of the page I have some JSON (passed from the database when the page is built) containing records to populate the rows with. 1 record per row.
  • on ‘Document ready’, I cycle through the JSON records and do the following for each section (Labour, Parts):
    i) copy a dummy row to a parts or labour table
    ii) make the row visible
    iii) assign event bindings to the various rows (all page events are rebound .off.on)
    iv) initialise the comboboxes by using descriptionCombo = dhtmlXComboFromSelect(‘qform[’+section+’_items][’+iteration+’][description]’);
    v) populate the new row input fields with data from the JSON using $(’#qform\[’+section+’_items\]\[’+iteration+’\]\[’+fieldName+’\]’).val(record[realName]);
  • So now, when I populate a combobox input field using JQuery, this is flagging as change in dhtmlxcombo and as a consequence the events are triggered when I click anywhere on the page after load.

    I would like to prevent the flag being set so I can populate the rows with data vi javascript without combobox thinking there is a change. I would also prefer to keep using JQuery to populate all values rather than using a seperate call for setting the value of a combobox

    I cannot set the values before initialising the combobox because the value might not exist in the list

    The console.trace when I click after the page has loaded is as follows.

    edit?invoice_id=14:517 console.trace
    refreshTotals @ edit?invoice_id=14:517
    (anonymous) @ edit?invoice_id=14:439
    obj.callEvent @ dhtmlxcommon.js:1000
    dhtmlXCombo._confirmSelect @ dhtmlxcombo.js:1661
    _doOnBodyMouseDown @ dhtmlxcombo.js:566
    

    The flag which determines wheather the combobox has been changed is in the function ‘dhtmlXCombo._confirmSelect’ and in particular the variable ‘wasChanged’

    There must be a way to keep the change flag from being set when populating the combobox input fields using javascript?

    Possible Bug/Improvement

    if your first value is “” or one not set by the list that is transformed then a change is always triggered?
    wasChanged = wasChanged||(this.conf.last_text != this.base.firstChild.value);

    Any help would be appreciated.

    thanks

    shoulders

    p.s. I can update my code to my github repo and post the link here to the whole page that generates the page if I am allowed.