Html DropDownList not generating events - html

In my web page I use something like this, but when a option is selected, onchange is not fired. I don't know where I have made a mistake. Actually my requirements is that I need to fetch location details based on the city selected, but it is not working here. Is there any other better way to do so?
#Html.DropDownList("cities", ViewBag.cities as SelectList, new { onselect = "getLoca();"});
<script type="text/javascript">
function getLoca() {
alert("yes");
$.post('#Url.Action("getLocations","Home")', { 'id': $("#cities").val() },
function (data) {
$("#loca").html(data).show();
});
}
</script>
EDIT:
This is the generated HTML code
<select id="cities" name="cities" onselect="getLoca()"><option value="0">--City-- </option>
<option value="1">City1</option>
<option value="2">City2</option>
<option value="3">City3</option>
<option value="4">City4</option>
<option value="5">City5</option>
</select>;
<select id="loca" name="loca" style="width: 170px" ></select>

Use onchange instead of onselect.
jsFiddle Demo
onselect does not do what you expect - it fires when the user selects text (you know, by dragging the mouse or holding shift and using the arrow buttons), so it is not applicable to a select box, which has no selectable text. It works on certain input elements (like text) and textareas, or you can use it on the window.
onchange fires when the value of a form element changes - so this is what you need.
Note: using inline event handlers in your HTML is not a good idea most of the time. If you can, use addEventListener instead.

Related

How to use "invalid-feedback" class with selectpicker from Bootstrap-Select?

I'm using Bootstrap to do some form validation on my web app. With a normal select menu, it would be really easy to have an error message pop-up when the field is invalid:
<select class="someClass" required>
<option value="">Select an option</option>
<option>foo</option>
<option>bar</option>
</select>
<div class="invalid-feedback">Please make a selection.</div>
However, I'm using Bootstrap-Select's "selectpicker" class, and the "invalid-feedback" message in the div no longer works. Is there anyway to force Bootstrap-Select to recognize the "invalid-feedback" class or am I going to have to go about this a different way?
I figured out how to do this, and more generally this is an answer for anytime you have to "manually" force an error to work with Bootstrap's native validation system. It's really hacky, but I couldn't find anything else that works.
Say you have a "selectpicker" that looks like this:
<select id="mySelect" class="selectpicker" required>
<option value="">Select an option</option>
<option>foo</option>
<option>bar</option>
</select>
<div id="error" class="invalid-feedback">Please make a selection.</div>
The error message "Please make a selection" will not show, even if the select element is invalid; it will show, however, if it also has the "d-block" class:
<div id="error" class="invalid-feedback d-block">Please make a selection.</div>
So to manually force errors, you have to use JavaScript to check for the ":invalid" CSS pseudo-class; if it has this pseudo-class, then you add the "d-block" class to your div to show the error. You can use the matches() method and classList.add():
var selector = document.getElementById("mySelect");
var errorMsg = document.getElementById("error");
if(selector.matches(":invalid"))
{
errorMsg.classList.add("d-block");
}
You do this to add the message and you can remove it by checking for ":valid" and removing "d-block" from the classList.
I had multiple versions of the bootstrap-select elements in one of my forms and was having a really hard time getting this to work. The method below won't show the checkmark or x on the input, but it will show the invalid-feedback and valid-feedback boxes properly.
Using the advice from secretagentmango's answer, you can create a function that loops through all of your inputs with the "selectpicker" class, grab their parent form-group element, and then find the children "valid-feedback" and "invalid-feedback" elements
to add or remove the d-block class and hide/show them.
function bsSelectValidation() {
if ($("#myForm").hasClass('was-validated')) {
$(".selectpicker").each(function (i, el) {
if ($(el).is(":invalid")) {
$(el).closest(".form-group").find(".valid-feedback").removeClass("d-block");
$(el).closest(".form-group").find(".invalid-feedback").addClass("d-block");
}
else {
$(el).closest(".form-group").find(".invalid-feedback").removeClass("d-block");
$(el).closest(".form-group").find(".valid-feedback").addClass("d-block");
}
});
}
}
Now you need to run this function after form submit, and you can add it directly to the sample code from the Bootstrap Docs:
(function () {
'use strict';
window.addEventListener('load', function () {
// Fetch all the forms we want to apply custom Bootstrap validation styles to
var forms = document.getElementsByClassName('needs-validation');
// Loop over them and prevent submission
var validation = Array.prototype.filter.call(forms, function (form) {
form.addEventListener('submit', function (event) {
if (form.checkValidity() === false) {
event.preventDefault();
event.stopPropagation();
}
form.classList.add('was-validated');
bsSelectValidation();
}, false);
});
}, false);
})();
The only thing different in the above code from bootstrap's sample is the call to our new function, "bsSelectValidation".
Now you need to listen for changes in the form to automatically update the d-block classes and fix the valid/invalid messages as people make changes to the form:
$('#myForm').change(bsSelectValidation);
Now your select menus should properly show the valid-feedback and invalid-feedback divs on form submit or change.
I found that if I simply remove the value="" part of the "option" element, then the validation message shows properly. That is, if I don't select anything from the dropdown, the my "invalid-feedback" message shows up. When I select something, it goes away and I can proceed further. It's worth a try if you haven't tried it.
My first "option" is simply this: <option>(select)</option> -- no 'value' clause is present.
Hope this helps.

How to trigger an onchange event in Firefox::Mechanize?

I'm using Firefox::Mechanize to scrape a website. I'm stuck on a dropdown menu which has an onchange event associated with it.
I'm able to select the option I wanted from the pulldown menu, and I'm able to verify this because the pulldown now shows the option I selected. But it doesn't trigger the onchange event associated with it.
I'm thinking I might need a "click" event after selecting my option, but I'm not sure exactly how to incorporate that.
Here is the bit of HTML:
<select class="" id="select20279" name="20279" onchange="selectAction(this, this.options[this.selectedIndex].value, '20279');">
<option value="">please choose</option>
<option value="edit">Edit</option>
<option value="view">View</option>
<option value="delete_now">Delete</option>
</select>
Here is my script:
use WWW::Mechanize::Firefox;
my $mech = WWW::Mechanize::Firefox->new( tab => 'current', autoclose => 0 );
$mech->get('http://www.mywebsite.com/');
$mech->select("20279", "view");
Thanks in advance.
Get the DOM element and then send the change or click event to it:
my $select = $mech->selector('#select20279', only => 1);
$select->__change();
# or
$select->__click();
See also
http://search.cpan.org/~corion/MozRepl-RemoteObject-0.39/lib/MozRepl/RemoteObject.pm

HTML 5 Datalist - How to autoselect if only one option is available

User types into the input box with datalist attached, one option is displayed that they can click on to select. How can I auto select that single option?
Okay so datalist is an HTML5 element that allows for a native autocomplete feature on most modern browsers. That being said it does not provide the ability to set a default or selected option. Additionally it does not have events available so you need to do it using standard events on your elements.
Example
$(document).ready(function () {
var datalist = $('#someCountries');
var opts = datalist.find('option');
console.log(opts.val());
console.log(opts.length);
function checkOpts() {
if (opts.length === 1) {
$('#country').val(opts.val());
}
}
$('#country').on('focusin', checkOpts);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" id="country" list="someCountries" />
<datalist id="someCountries">
<option label="United Stated" value="USA"></option>
</datalist>
You will probably need to modify the focusin event to something more appropriate for your situation, but this should get you on your way.

HTML Select with disabled Option returns wrong selectedIndex in FireFox

I have a Select with a disabled Option wich is the default selected one:
<select name="select" size="1">
<option>0</option>
<option selected disabled>1</option>
<option>2</option>
<option>3</option>
<option>4</option>
</select>
If I get the selected, it returns 1. Everything OK.
But if I open the popup and hover with the cursor over another Option (for Example '4') and Cancel it via ESC or by clicking anywhere else.
The Select input shows the old value 1 but returns on get selected 4.
Example with jsfiddle
It doesn't happen with Chrome only FireFox (4/5)
It appears that the display is not changed when you exit your select this way however firefox is looking for a different selectedValue because it finds the currently selected option as disabled, which in firefox' eyes should be impossible.
The onChange event was not triggered until the onBlur event (which is when the selectedValue would get changed, but this is not what the display is changed to). If we were to reset our value in the onChange event this event might get called again. So by utilising the onBlur event we can provide the following workaround:
onBlur="javascript:document.getElementsByName('select')[0].selectedIndex = document.getElementsByName('select')[0].selectedIndex;"
http://jsfiddle.net/aRMpt/22/
I hope I'm making sense here.
The following code is ugly, but it does exactly what you want (I think). Basically, I am intercepting all onChange events, and only processing them if there is a corresponding onClick event that results in a changed value. ALso note that change events are processed before click events. EDIT: Just relaized this does not work in chrome, so i added some browser detection code so that it only executes in firefox.
NOTE: The current code would not work if the user had tabbed into the select box and made his changes with the error keys, but the method below can be easily adapted to handle that case as well. You'd simply need to process key events like arrow up or arrow down or TAB or ENTER in the same way clicks are processed below, but only when the select box had focus.
NOTE 2: Playing with this more, the behavior is very strange. If you escape out of the select, the onChange event is not triggered, but it is saved up. If at any later time you click anywhere on the screen the onChange event will be triggered for the value you were hovering over when you escaped, even though that value was actually changed as soon as you escaped. So this is getting tricky. I think you may have to handle the 2 cases separately. One case to handle click aways, and one to handle escape outs (which patrick answered).
It's getting hairy and I see no elegant way to code this. How about a note to the user next to the text box saying "Your currently selected option, 1, is no longer available." Then you could have a select box with only the avalable options.
<select name="select" size="1" onChange="handleChange()" onClick="handleClick()" >
<option>0</option>
<option selected disabled>1</option>
<option>2</option>
<option>3</option>
<option>4</option>
</select>
<br />
<script>
var initialValue = document.getElementsByName('select')[0].selectedIndex;
var potentialChange;
var processClick;
function handleClick() {
//ignore this code if not firefox
if (navigator.userAgent.indexOf("Firefox") === -1)
return;
var curVal = document.getElementsByName('select')[0].selectedIndex;
if (!processClick)
return;
// a value change click occured, now we actually process it.
document.getElementsByName('select')[0].value = potentialChange;
}
function handleChange() {
// save the potential change, which will be used if a real click was detected
potentialChange = document.getElementsByName('select')[0].selectedIndex;
processClick = (potentialChange !== initialValue);
// undo the attempted change, in case of an escape or page click
// but only on firefox
if (navigator.userAgent.indexOf("Firefox")!=-1)
document.getElementsByName('select')[0].value = initialValue;
document.getElementsByName('select')[0].value = initialValue;
}
</script>
getSelected
Detect the esc key and reset it, here is an example using jQuery (and a dash of your code)
$('select').keyup(function(e) {
if (e.keyCode == 27) {
document.getElementsByName('select')[0].selectedIndex = 1;
}
});
UPDATE No jQuery Solution
UPDATE 2 Abstracted out finding event and keycode for re-usability.
DEMO: http://wecodesign.com/demos/stackoverflow-6923135.htm
<script type="text/javascript">
function getEvent( event ) {
if ( window.event ) return window.event;
return event;
}
function getKeycode ( event ) {
if ( event.which ) return event.which;
else return event.keyCode;
}
changeToDefaultListener = function( event ) {
theEvent = getEvent( event );
theKeyCode = getKeycode( theEvent );
if( theKeyCode == 27 ) {
document.getElementsByName( 'select' )[0].selectedIndex = 1;
}
};
</script>
<select name="select" size="1">
<option>0</option>
<option selected disabled>1</option>
<option>2</option>
<option>3</option>
<option>4</option>
</select>
getSelected
<script type="text/javascript">
document.getElementsByName('select')[0].onkeyup=changeToDefaultListener;
</script>
The work around I had to use for this is was putting an event listener on the click event of the not selected options in drop down. In the event listener's function I set a global boolean.
var selectChanged = false;
$('#select option:not(:selected)').click(function () {
selectChanged = true;
});
Then in the area of the code where I need the selected value of the drop down, I check the boolean:
if the boolean is true I can then use it's new value
if the boolean is false I can get the value from the Html property (which contains the initial value of the dropdown).
var selectValue = selectChanged ? $('#select').val() : $($('#select').outerHtml()).find('option:selected').val()
This is ugly I know, but this is the only work around I could find.

MooTools - How to use getSelected()

I'm trying to learn MooTools and am a TOTAL javascript noobie so please be gentle with me.
What I'm tying to do is to change the state of a disabled input field (type is text) when a particular option is selected. The html looks a bit like tis:
<select class="wide" id="selectBox" name="option>
<optgroup label="Common">
<option value="one">One<option>
<option value="two">Two<option>
<option value="three">Three<option>
</optgroup>
<optgroup label="Less Common">
<option value="other">Other<option>
</optgroup>
</select>
<input id="other" type="text" disabled="disabled" />
This is what I was HOPING would give me the value to be checked in an if statement that would then change the input disabled to enabled:
window.addEvent('domready', function(){
$$('#selectBox').addEvent('change',function(){
var selection = $$('#selectBox').getSelected();
alert(selection);
});
});
When the code us run (i.e. I select another value in the option box) all I get is [object HTMLOptionElement].
The documentation on mootools for this method is SPARSE and only says:
Element Method: getSelected
Returns the selected options of a
select element.
Returns:
* (array) An array of the selected elements.
Examples:
HTML
<select id="country-select" name="country">
<option value="US">United States</option
<option value ="IT">Italy</option>
</select>
JavaScript
$('country-select').getSelected(); //Returns whatever the user selected.
Note:
This method returns an array, regardless of the multiple attribute of the select element. If the select is single, it will return an array with only one item.
Totally confusing!
Someone please tell me what I'm missing. I've also tried:
var selection = $$('#selectBox').getSelected().value; //and
var selection = $$('#selectBox').getSelected('value'); //and
//a WHOLE bunch of other wild ideas including
var selection = $$('#selectBox').getSelected();
alert(selection[0]);
Nothing comes out properly. In some cases I get undefined and in other cases I get the same [object HTMLOptionElement].
so many things wrong, not sure where to begin.
$$() is a collection operator (alias for document.getElements() which returns multiples based upon a selector) - not appropriate to use for an id.
you want document.id("idhere") or $("idhere")
for mootools 1.2+
document.id('selectBox').addEvent('change',function() {
alert(this.get("value")); // get value
alert(this.getSelected().get("value")); // gets the option that's selected and then it's value
});
make sure you check your markup - you don't close the options, you have a missing " from name="option> as well.
getSelected is there as a method as some selects use multiple selection so doing selectEl.get("value") will not report anything meaningful. any other case, .get("value") is fine.
check it working:
http://www.jsfiddle.net/dimitar/SmShF/
have fun and read the manual :)
late reply but I was facing the same issue and solved it in this (simple) way in Mootools:
$('selectBox').getSelected().get('text')
So Complex!
You don't need to do such a complex thing, this would suffice:
var selection = document.getElementById("selectBox").value;
alert(selection);
That should get you the selected text.
But if you wanted to use mootools, I guess that this would work (I'm not going to try it)
var selection = $('selectBox').getSelected();
alert(selection[0].value);
Also this has some problems:
<select class="wide" id="selectBox" name="option>
You don't need the name attribute, as it is basically the same as id. Also if you do have both, then they should probably be the same. I.e. id="selectBox" and name="selectBox
Your name tag should be closed.
Also in your sample, you had a lot of <option>...<option> which should be <option>...</option>
All you need to do is:
$('country-select').getSelected().get('value')[0];
Quick, hackish way:
alert($('selectBox').value)
Verbose, recommended way:
var selectBox = document.id('selectBox');
alert(selectBox.get('value'));
.getSelected() returns an array. See the docs: http://mootools.net/docs/core/Element/Element#Element:getSelected .
My Code is :
var $obj=$$('#id').getSelected()[0];
alert( $obj.get('text') );
alert( $obj.get('value') );