Changing dropdown values with javascript from another element

Ivan4o0o

Member
Hi guys,
I have a situation I can't figure out how to do it. So I have a Dropdown which loads its elements from the database and a calc field which value changes based on third date field. They are working as expected , but I need to make some options from the dropdown disabled based on the calc element. In fact the Dropdown's options are Available Services and when the user selects a date from the date field the calc element makes its magic and returns the values of the Dropdown's options that are unavailable for the selected date and they has to be disabled. not removed.
So I have tried with Javascript to the calc element but I can't manipulate the Dropdown fieeld. I can "access " it and get his value, but nothing like updating the values or removing them. For example the code

var form = Fabrik.getBlock('form_2');
form.elements.get('queries___service').update('newvalue|-|anothervalue'); - does not work.

Can anyone help me with that.
 
The update() method only allows you to select an existing value.

You'll need to use regular JavaScript on the DOM element to disable or remove options you don't want to allow.

So to disable option with value "2" on my test form, for a dropdown with an id of fab_main_test___dd ...

Code:
jQuery('#fab_main_test___dd option[value="2"]').attr('disabled', 'disabled')

-- hugh
 
I've used something similar to this to show/hide options in a select dropdown element.
In the form_##.js file add an on change event to watch the calc element - which then calls a function that sets the options.

In that function loop though the select options, determine if the value is in the passed array and show/hide the option based on the result.
For example...

JavaScript:
function setOptions(availOpts) {     
    // In the next line(s), as needed, do what needs to be done to convert passed calc availOpts value to javascript array
    var aOpts = availOpts;
    jQuery("#tablename___dbj_dropdown_element option").each( function() {
        curval = jQuery(this).val();
        if ( jQuery.inArray(curval, aOpts) !== -1 ) {
             jQuery(this).show();
        } else {
            jQuery(this).hide();
        } 
    });
}

jQuery('#tablename___available_options').change( function() {
    setOptions( jQuery(this).val() );
});
/* Or maybe you can just call setOptions from the calc element's fabrik javascript change event? */
 
Last edited:
Hi,
Thanks a lot for you replys. I tried this Jquery and it works. I alse find that with a normal JS code it works too:
JavaScript:
var services = document.getElementById("queries___service");
services[i].disabled = true;
But hare another problem comes out. If the user has selected for example option1 and then selects another date where na option1 is not available the selected option stays option1 . If I use
JavaScript:
services[i].selected = false;
the select moves to the firs alailable option, but that change does not trigger onChange event (at least I think so) and this is the problem for me because another Cascading Dropdown is watching this dropdown with the services. So when I manualy change the service the CDD is refreshed and loads the desired values, but if the service is changed trough the JS code the CDD values aren't refreshed.
You helped me with the disabling of the element so maybe I should start another tread for the new problem.
Or if someone knows a solution ... please share.
 
Did you add the dropdown placeholder as a watch element in the calc element?
Did you try (at the end of your JS code) to also trigger the 'change' event on the cdd watch element?
e.g. jQuery(''#queries___cdd_watch_element').trigger('change');
 
Last edited:
Hi Bauer, hugh. I've tried both solutions - the JQuery trigger function and the Fabrik update( ) method but with no luck :) . None of them makes the CDD refresh its values :( No errors in the console. The CDD just does not understand that the watched element has changed its value. I'm starting to think I've done something generally wrong, but what could it be.
 
Could it be because the dropdown value itself hasn't changed? (You just changed the options visibility)
You should always re-set the dropdown value to 'Please select' (assuming you have that set in the configuration) before you run the code to show/hide the options.

But then again, if the value is already 'Please Select', it hasn't changed either. (That's why I suggested trying to trigger the change event).

So I don't know what else to suggest. :confused:
But I'm still a bit confused'. Is this "dropdown" element a databasejoin element or a cascadingdropdown?

In either case, maybe you could try using the new feature of the databasejoin element rather than using a cascadingdropdown(s)? As of a week or so ago, the databasejoin element will now reset the filters of the dropdown to match any change in the placeholder included in the Where condition. So try making the cascadingdropdown(s) a databasejoin element instead. And in the 'Where' condition include a filter that replicates the old watch element e.g. WHERE {thistable}.id={tablename___old_watch_element_value_raw}

It could just be that the databasejoin and cascading dropdown aren't "playing well" together.
 
I could have sworn I'd added firing the change event to the update() method, but apparently not.

So ... you'll have to fire it by hand ... so in my case, updating the value and then firing the change event for my 'fab_trip_pics___city' element ...

Code:
var el = Fabrik.getBlock('form_1').formElements.get('fab_trip_pics___city');
el.update('12345');
var changeEvent = el.getChangeEvent();
el.element.fireEvent(changeEvent, new Event.Mock(el.element, changeEvent));

You could just hard code 'change' instead of dynamically getting changeEvent(), but doing it this way means it'll work regardless of how the element you are changing is rendered. So for example, if you run this on a join rendered as an autocomplete, it needs to be 'blur', not 'change' ... and the getChangeEvent() will return the right thing.

At some point I may just add firing the "change event" as part of update() ... but I need to remember why I haven't done it already ... there may well be a reason ...

-- hugh
 
Thank you for that information it was very usefull. Just please let me know if you add firing the "change event" as part of update().
 
I'm pretty sure I won't. I have a vague memory of trying it a while back, then finding that this caused some kind of infinite looping somewhere in the code, where things do an update(), it fired a change, which caused some events somewhere to do another update(), yada yada.

What I may do is add an updateAndFireChange() or some such, just as a convenience method.

-- hugh
 
We are in need of some funding.
More details.

Thank you.

Members online

Back
Top