JavaScript .selectedIndex only changes text value rather than actually selecting option - javascript

*** EDIT - Switching to Chrome from Firefox 52.0.1 (32-bit) solved this problem **
I'm trying to speed up some data entry in some accounting software and have code to input details into a form to generate an invoice. The problem is with the select box.
document.getElementById('invoice_bank_account_id').selectedIndex = 2;
Which correctly sets the option of a dropdown menu to what I need.
However this only changes the text, when I click on the submit button for the form in question it behaves as if I had never changed the selected option and defaults to the first option in the dropdown list. I have to physically select and click for it to 'update' properly.
What do I need to do after selecting my option for it to work on form submission?
I also tried various combinations such as
document.getElementById('invoice_bank_account_id').options[2].selected = true;
... with the same result.
The code of the form is:
<fieldset id="advanced_options_fieldset" class="blockf">
<div id="advanced_options">
<p><label for="invoice_bank_account_id">Bank account</label><select id="invoice_bank_account_id" name="invoice[bank_account_id]">
<option selected="selected" value="385057" data-currency="GBP">Customer Deposits</option>
<option value="164288" data-currency="GBP">Business Current Account</option>
<option value="327151" data-currency="GBP">Deposit Account</option>
</p>
</div>
</fieldset>
I also tried by referencing the value of the option as well but that didn't work. I'm obviously missing something.
Thanks in advance, this is my first post on the forum.

By simply switching to Chrome this solved the problem. I was using Firefox 52.0.1 (32-bit) and Chrome 56.0.2924.87

Change the value instead:
document.getElementById('invoice_bank_account_id').value = "327151";
// (Deposit Account)

Related

Javascript's "selectedIndex" appears to work, but actually doesn't give the same behavior as a real click

I have an HTML form with a Javascript custom dropdown function taken from W3Schools. It replaces the ugly default dropdown with a really neat one, and works in most cases. However, I ran into a problem.
The custom dropdown code uses the function "selectedIndex" in order to define which label should be selected when the user clicks. It seems to work, but I am also using the Sisyphus "save form data" plugin, and when I refresh the page, the user changes are lost.
I know it is not a problem with Sisyphus or my implementation, because if I unhide the default original dropdown, I click on it, and upon refresh the options are saved just fine.
This inquiry shows that the "selectedIndex" function doesn't give exactly the same result as if the user had physically clicked on the label. It appears to change the value but somehow doesn't really register it, spooky....
After reading similar issues on stackoverflow, I added the two following lines under the "selectIndex" function: trying to programmatically set it's "selected" state to "true", and also to trigger a click:
s.selectedIndex = i;
s.options[i].selected = true;
s.options[i].click();
Still no luck. Here is a wider view of the code:
// When an item is clicked, update the original select box, and the selected item
for (i = 0; i < sl; i++) {
if (s.options[i].innerHTML == this.innerHTML) {
//update the original select box
s.selectedIndex = i;
s.options[i].selected = true;
s.options[i].click();
//update the new select box
h.innerHTML = this.innerHTML;
}
}
Here is the HTML:
<div class="dropdown has-label">
<label for="jours_entiers_de_travail">Number of days</label>
<div class="select-wrapper">
<select name="jours_entiers_de_travail" id="jours_entiers_de_travail">
<option value="1">1 day</option>
<option value="2">2 days</option>
<option value="3">3 days</option>
</select>
</div>
</div>
And a full version of the dropdown can be seen on this Codepen:
https://codepen.io/benviatte/pen/OJNYwRy
This codepen appears to work, but again, the issue comes when I try to use the value assigned by selectedIndex, for example with Sisyphus. The value doesn't seem to have been properly assigned.
Thank you dearly for your help
Sisyphus documentation hints that it uses change events to monitor updates of form elements. Source code appears to confirm this in JSDoc markup for the bindSaveDataOnChange function.
Hence try triggering a change event on the select box instead of clicking the option element programmatically. Untested but possibly like
//update the original select box
s.selectedIndex = i;
s.options[i].selected = true;
// s.options[i].click(); // replace with:
$(s).trigger("change"); // trigger change event on select box
Also see Trigger change event <select> using jquery for a variety of ways of triggering change events in both jQuery and plain JavaScript, and trigger() | jQuery API Documentation.

jQuery val() on dropdown returns value "Array"

I'm stumped. I have a dropdown menu where a user selects an item.
<select name="rep-name" type="text" id="rep-name" size="" value="" >
<option value></option>
<option value="alex">alex</option>
<option value="ben">ben</option>
...
</select>
The value is then retrieved...
$('#rep-name').val()
and sent to a database.
Usually it works fine but in some cases, it sends the value 'Array' to the database. Interestingly, in those cases, the serialize function on the form still gets the correct value of the item. So in other words:
$('#run-pma-form').serialize() // works fine
$('#rep-name').val() // fails
It works fine in ~95% of cases and unfortunately, I don't have info on what browsers are being used, etc when it incorrectly returns 'array.' I'm just wondering if anyone has run into this issue or has any clue why it might be happening.
$("#rep-name")[n].val() will get you the value of any given option, but it's not correct to think of a select menu as having a value—what you want is the value of the currently selected option.
http://api.jquery.com/selected-selector/
$("#rep-name option:selected").val() should work.

Is it possible to trigger JavaScript when a user selects the current option in an HTML select?

I know that you can use the onchange event on the select to trigger a JavaScript function, but what if they choose the option that is currently selected?
The reason for this is I want to have a drop down list of a bunch of websites. This is used as a sort of jumppage, if you will. When the user selects a site the selected site opens in a new window. Now if they close the new tab/window the select is on the last option they selected. If the user wants to go to the same website again the onchange event does not fire.
I know that you can change the select option back to the default option with a null value like this:
html
<select onChange="jsFunction(this.value)" id="selectOpt">
<option value="">1</option>
<option value="websiteURL2">2</option>
<option value="websiteURL3">3</option>
</select>
javascript
function jsFunction(opt){
window.location = opt;
document.getElementById("selectOpt").options[0].selected = true;
}
http://jsfiddle.net/XqLmY/1/
But I was wondering if it could be done without that.
Can I trigger an event using a HTML select without changing its value?
What about using onClick instead
Look here http://jsfiddle.net/9X4Ks/1/
<select onclick="clickFunction(this)" id="selectOpt">
<option value="websiteURL1">1</option>
<option value="websiteURL2">2</option>
<option value="websiteURL3">3</option>
</select>
function clickFunction(o){
alert(o.value)
}
It fires even when user clicks the selected option second time.
Unfortunately it works only in chrome and opera.
Does not work in firefox
Not really an answer, but I just ended up using this method because it was easy and didn't have other dependencies.
function jsFunction(opt){
window.location = opt;
document.getElementById("selectOpt").options[0].selected = true;
}

how to disable an option with msdropdown plugin

Is it possible to disable an option after creating a msDropdown plugin?
I explain my problem better.
I want to put html into each option with icons, text and some other stuff, so first i create an empty select then I add each option with the add function:
dropdown.add({text:$price.html(), value:'normal', className:'normal'});
The problem is that if a certain condition happen I have to disable one option, but there are no way to set an option disabled by using plugin settings.
There is the possibility to make an option disabled only by setting the related parameter disabled=disabled into the select before to call the msDropdown function, but I can't use this solution since I have to put dinamically html into option text.
Is there another way to do it?
Thank you for your help.
I found a solution.
I create my select empty and I fill each option with add function as before, but when that condition happen just do this:
var dropdown = $('select[name="priceType"]').msDropdown().data("dd");
if(credits_error) { // option must be disabled
dropdown.destroy(); // Make it a simple select
$('select[name="priceType"] option').attr('disabled', 'disabled');
dropdown = $('select[name="priceType"]').msDropdown().data("dd");
}
This way first I make it a simple select by calling destroy function, then I set properly the disabled attribute and I create a new msDropdown select.
It works for me, I tested it on IE, FF and Chrome
Yes, it is possibile. It can be done by using the disabled property of the option tag:
<select id="payments" name="payments" style="width:250px;">
<option value="" data-description="Choos your payment gateway">Payment Gateway</option>
<option value="amex" data-image="http://www.marghoobsuleman.com/mywork/jcomponents/image-dropdown/samples/images/msdropdown/icons/Amex-56.png" data-description="My life. My card...">Amex</option>
<option value="Discover" data-image="http://www.marghoobsuleman.com/mywork/jcomponents/image-dropdown/samples/images/msdropdown/icons/Discover-56.png" data-description="It pays to Discover...">Discover</option>
<option value="Mastercard" data-image="http://www.marghoobsuleman.com/mywork/jcomponents/image-dropdown/samples/images/msdropdown/icons/Mastercard-56.png" data-title="For everything else..." data-description="For everything else...">Mastercard</option>
<option value="cash" data-image="http://www.marghoobsuleman.com/mywork/jcomponents/image-dropdown/samples/images/msdropdown/icons/Cash-56.png" data-description="Sorry not available..." disabled="true">Cash on devlivery</option>
<option value="Visa" data-image="http://www.marghoobsuleman.com/mywork/jcomponents/image-dropdown/samples/images/msdropdown/icons/Visa-56.png" data-description="All you need...">Visa</option>
<option value="Paypal" data-image="http://www.marghoobsuleman.com/mywork/jcomponents/image-dropdown/samples/images/msdropdown/icons/Paypal-56.png" data-description="Pay and get paid...">Paypal</option>
</select>
The option 'cash' will be disabled.
Here is a working fiddle: http://jsfiddle.net/NKQRj/1/
EDIT
In this second example data are loaded from JSON data using:
$("#payments").msDropDown({byJson:{data:jsonData, name:'payments2'}}).data("dd");
to fill the elements.
You can define your options as disabled in your JSON data using disabled: true property:
{image:'http://www.marghoobsuleman.com/mywork/jcomponents/image-dropdown/samples/images/msdropdown/icons/Cash-56.png', description:'Sorry not available...', value:'cash', text:'Cash on devlivery', disabled:true},
here is a working fiddle: http://jsfiddle.net/NKQRj/3/

How do I remove a <select> option once it's been chosen using jQuery?

I'm trying to make it so that once the dropdown option is selected, it'll be removed from the menu, and then once another one is selected the previous removed option will get returned to the menu. Is there a way to do this using jQuery?
I'm new to jQuery and JavaScript, so I'm not too sure what I'm doing, and all my poking around has only further broken code. Thanks!
For reference, this is what my HTML looks like:
<div class="FlightList">
<select id="departureFlightsControl">
<option value="default">No flight chosen</option>
<option value="20121113 17:37:00">November 13, 2012 (5:37pm) - $137.38</option>
<option value="20121119 05:11:00">November 19, 2012 (5:11am) - $121.05</option>
<option value="20121124 19:41:00">November 24, 2012 (7:41pm) - $182.44</option>
<option value="20121208 08:22:00">December 8, 2012 (8:22am) - $140.75</option>
and so on, with more options. Once an option other than default is selected, it is populated down to a "flight information" div, that has a small "X" div "button" to clear it. I want the X button to return it to the list.
You can use this as a base:
<div class="FlightList">
<select id="departureFlightsControl" onchange="addToInfo(this)">
<option value="default" >No flight chosen</option>
<option value="20121113 17:37:00">November 13, 2012 (5:37pm) - $137.38</option>
<option value="20121119 05:11:00">November 19, 2012 (5:11am) - $121.05</option>
<option value="20121124 19:41:00">November 24, 2012 (7:41pm) - $182.44</option>
<option value="20121208 08:22:00">December 8, 2012 (8:22am) - $140.75</option>
</select>
</div>
<div id="flightInformation">
</div>
<script type="text/javascript">
function addToInfo(element){
var opt = $(element).find(":selected").remove();
var span = $('<span style="margin-left:20px;" onclick="addToList(this)"> X</span>');
$(span).data('option', opt);
var div = $('<div>'+$(opt).html()+'</div>')
$(div).append(span);
$('#flightInformation').append(div);
}
function addToList(element){
$('#departureFlightsControl').append($(element).data('option'));
$(element).closest('div').remove();
}
</script>
Here's a solution that caches all the options when page loads. When an option is selected, the options are replaced from the cache with all the options whose values aren't the one just selected
var departSelect=$('#departureFlightsControl');
/* cache clones of all options*/
var departOptions=departSelect.find('option').clone();
departSelect.change(function(){
var currVal=$(this).val();
/* other display logic using currVal*/
/* get new options that don't include current one selected from cache*/
var newOptions= departOptions.clone().filter(function(){
return $(this).val() ! = currVal;
});
$(this).html(newOptions)
})
I came up with script that worked kind of ok, at least in Firefox. The problem with it in Firefox was that the change event doesn't fire until you leave the control (and maybe in other browsers besides), and the click event occurs when you pull out the dropdown, not just when making a selection. This made it very hard to synchronize and to not remove the "no flight chosen" item from the list until after a real flight was chosen.
So, I did a bit of research on the issue and then tried to work up my own jQuery plugin (jsFiddle) for detecting select dropdown and rollup. It gets better, but still doesn't work perfectly in Firefox.
My conclusion is that while you can get such an animal mostly working, you can't get around a few things:
Not all browsers implement things the same way, so they "break" differently.
In Firefox, if you click out of an iframe containing a dropped-down select control, the dropdown rolls up and there is nothing you can do to respond to it. So now the code reports the wrong event for a while until you either leave the control or click elsewhere in the page.
Firefox additionally was throwing script errors in the jQuery library, but not Chrome.
Using keyboard shortcuts such as Alt↓ to pop open the dropdown do not throw mouse events, at least in Firefox. So you'd have to add even more trapping of keyboard events (and are you sure you'll get this right on the Mac? Android? iPhone?)
Note: I am aware that my code in that fiddle is not optimal and has bugs. It is an abandoned prototype, not a finished product. :)
So, may I suggest instead that you use a custom select box, which can do most anything you want it to. Here's one example select box replacement jQuery plugin.
Here's a reasonable solution that keeps it simple and does the job. You can obviously increase the specificity of the function should you desire.
$(document).ready(function () {
var temp = 0;
if ($(':selected')) {
$('select').change(function () {
if (temp !== 0) {
temp.show();
}
temp = $(':selected').hide();
return temp;
});
} else {
('select').show();
}
});

Categories