CasperJS fails to set select list values - javascript

I've got a select list that looks like this:
<select id="ListingType" name="Criteria/ListingTypeID" onchange="Search.toggleListingType(this);">
<option selected="selected" value="1">RH1</option>
<option value="2">BC4</option>
<option value="3">RR3</option>
<option value="4">RH2</option>
<option value="5">RE0</option>
</select>
I'm trying to set the value to 3. I've unsuccessfully tried 3 ways to do this.
1.
this.evaluate(function(value) {
document.querySelector('select#ListingType').value = value;
return true;
}, '3');
// insure the onChange JS is run
this.evaluate(function() {
var element = document.querySelector('select#ListingType');
var evt = document.createEvent('HTMLEvents');
evt.initEvent('change', false, true);
element.dispatchEvent(evt);
});
This appears to work (throws no errors), but the value doesn't get changed.
2.
this.fillSelectors('select#ListingType', {
'select[name="Criteria/ListingTypeID"]' : "3"
}, true);
This throws the error message: ``CasperError: Errors encountered while filling form: no field matching css selector "select[name="Criteria/ListingTypeID"]" in form''
What's wrong with my selector?
3.
// In desperation...
this.sendKeys('select#ListingType', 'RR3');
This also seems to work (no errors), but again the value is unchanged.
Just for completeness, I've tried sending the "change" event after each of the variations. I also dump out the attributes of the selected element after each, and it never shows the value as being set.
Note the page that this selector is on has a ton of JS code on it, and this <select> element is not wrapped in a <form> element.
I'm sure I'm making some really stupid mistake, but after hacking on this code for the last several days, I've not made any progress. What's a working way to do this?

You can use slimerJS (it opens firefox) to easily check a change in value.
this.fillSelectors('form#id_form', {
'select[name="Criteria/ListingTypeID"]' : "3"
}, false);
this.wait(6000,function(){
this.echo("i saw my new value");
});
And if you want to fill the option by its text and not value (i find it easier): use this function :
casper.fillSelectOptionByText = function (selectSelector,text){
this.evaluate(function(sel,setByText) {
$(sel + " > option").each(function() {
if($(this).text() === setByText) {
$(this).attr('selected', 'selected');
}
});
},selectSelector,text);
};
And in your test :
this.fillSelectOptionByText("select[name='year of birth']","1991");
The page has to have jquery of course, or you inject it.

Related

.change() adds two values at the same time

Good day,
In my code, I need to use a drop-down list that has two values, say 1 and 2. When I click the #action-link link I append the corresponding text of the value into a textarea (#main-reply). I use Jquery .change() method to determine when selected value changed. Works ok unless I switch options several times and then it starts to add multiple values at a time even though I need insert in textarea only the corresponding value.
Here is a simple snippet of the code I use:
$("#action-link").click(function() {
if ($("#option").val() == 1) {
$("#main-reply").append("One");
}
});
$("#option").change(function() {
if ($(this).val() == 2) {
$("#action-link").click(function() {
$("#main-reply").append("Two");
});
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select id="option"><option value='1' selected>One</option><option value='2'>Two</option></select>
Add Value to textarea
<br>
<textarea id="main-reply"></textarea>
How can I solve this? Thanks!
Code adds another on-click listener when the value of the option was changed to '2' Link. Therefore the append() statament was being called multiple times, one from each listener.
$("#action-link").click(function() {
var option = $("#option").val();
if (option == 1) $("#main-reply").append("One");
else if(option == 2) $("#main-reply").append("Two");
});
Most of the times, this issue occurs when you load the same js file twice.
When JS file gets loaded twice, 2 on change events will get attached to the same event. Hence the actions will happen twice
Check your code and make sure that the JS file is not loaded twice
If it's not loaded twice and somehow this issue is still occurring, then use below code
$("#option").off().on("change",function() {
if ($(this).val() == 2) {
$("#action-link").click(function() {
$("#main-reply").append("Two");
});
}
});
This will remove any events attached to the change event and then adds the function
In your code click event is added on every change event for option value 2, which is not a good way as well.
You can write code as below
$("#action-link").click(function() {
if ($("#option").val() == 1) {
$("#main-reply").append("One");
} else if ($("#option").val() == 2) {
$("#main-reply").append("Two");
}
});
$("#option").change(function() {
// Just trigger click on change which handle other stuff
$("#action-link").trigger("click);
// You can write use below code as well.
// $("#action-link").click();
});
OR you can make it very simple as below which is dynamic regardless of any option value which will adds selected option value.
$("#action-link").click(function() {
appendOptionValue($("#option").val());
});
$("#option").change(function() {
appendOptionValue($("#option").val());
});
function appendOptionValue(optionValue){
$("#main-reply").append(optionValue);
}
this is it :
var val = $("#option").val();
$("#action-link").click(function() {
$("#main-reply").append(val);
});
$("#option").change(function() {
val = $(this).val();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select id="option">
<option value='One' selected>One</option>
<option value='Two'>Two</option>
</select>
Add Value to textarea
<br>
<textarea id="main-reply"></textarea>
this might helpful to you. Use text() instead of append
$(document).ready(function(){
$('#action-link').click(function(event) {
if($('#option').val()==1){
$('#main-reply').text('one');
}else{
$('#main-reply').text('two');
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select id="option"><option value='1' selected>One</option><option value='2'>Two</option></select>
Add Value to textarea
<br>
<textarea id="main-reply"></textarea>

Checking value of an html select with jQuery

I have the following select box:
<select id="choose">
<option value=1>A</option>
<option value=2>B</option>
<option value=3>C</option>
</select>
<div id="hide-me">hide me!</div>
How can I hide an element when I select option "B"? I tried this:
<script type="text/javascript">
if ("#chose option:selected").val(2) {
$("#hide-me").hide();
};
</script>
I think I'm close, but nothing happens when I select option "B". Anyone have any suggestions?
You need to attach change event to select element to detect the option change. then use .toggle() with argument value not equal to 2 for making show/hide decision :
$('#choose').change(function(){
$("#hide-me").toggle($(this).val() != "2");
})
Working Demo
Listen to the change event of the #choose element, and add your conditional logic there.
Example Here
$('#choose').on('change', function () {
if (this.value === "2") {
$("#hide-me").hide();
} else {
$("#hide-me").show();
}
});
..equivalent, but perhaps less readable version:
Example Here
$('#choose').on('change', function () {
$("#hide-me").toggle(this.value !== "2");
});
As a side note, the value of the selected option is a string.
If you wanted to, you could also convert it to a number:
if (parseInt(this.value, 10) === 2) { ... }
or you could use == rather than ===: (not suggested, though. This could lead to logical errors.)
if (this.value == 2) { ... }
Without jQuery:
Example Here
document.querySelector('#choose').addEventListener('change', function () {
var element = document.getElementById('hide-me');
if (this.value === "2") {
element.style.display = 'none';
} else {
element.style.display = 'block';
}
});
The problem with your code is that:
It is not syntactilally correct — ("#chose option:selected").val(2) is an expression, which in turn should be wrapped in parentheses to be a proper condition for if, like this:
if (("#chose option:selected").val(2)) {
However, even after that your code is not correct because you're not actually using jQuery. You're calling method .val() just on a string "#chose option:selected", whereas that string should instead be a jQuery selector passed to jQuery itself:
if ($("#chose option:selected").val(2)) { // $ is the jQuery object that does all the work
However2, even that is incorrect, because you'd just be checking the value of an element right away. What you need is to wait for an element to be changed. Other answers explain very well how to do that.

Javascript add/remove attribute for data-required="true"

HTML
<select name="CustomerType" id="CustomerType" class="form-control" onchange="CustomerTypeChange()">
<option value="#((int)THOS.Utilities.Enumerations.Enumerations.Customer.CustomerType.Company)" selected="#(Model != null ? (Model.CustomerType == (int)THOS.Utilities.Enumerations.Enumerations.Customer.CustomerType.Company):true)">Company</option>
<option value="#((int)THOS.Utilities.Enumerations.Enumerations.Customer.CustomerType.Person)" selected="#(Model != null ? ((Model.CustomerType == (int)THOS.Utilities.Enumerations.Enumerations.Customer.CustomerType.Person)) : false)">Person</option>
</select>
<input type="text" name="TaxNumber" id="TaxNumber" class="form-control parsley-validated">
When CustomerType change below js code runs
Javascript Code:
function CustomerTypeChange() {
var customerType = document.getElementById("CustomerType").value;
if (customerType == 10) {
$('#TaxNumber').attr("data-required", 'false');
}
if (customerType == 20) {
$("#TaxNumber").attr("data-required", 'true');
}
}
When i add TaxNumber attribute true/false attr("data-required", true) or attr("data-required", false) never works .
Edited:
$("#TaxNumber").data('data-required', true); does not work too
$("#TaxNumber").data('required', true); does not work too
If i check browser console there is no any error where i miss exactly ?
Thanks.
Suggested improvements:
When using jQuery avoid connecting events via attributes. Also use jQuery for select value checking (using val()).
Remove the onchange attribute and try this instead:
// Shortcut DOM ready handler
$(function(){
// Listen for change event
$('#CustomerType').change(function(){
// Use jQuery val() to get select values
var customerType = $(this).val();
if (customerType == 10) {
$("#TaxNumber").attr("data-required", 'false');
}
if (customerType == 20) {
$("#TaxNumber").attr("data-required", 'true');
}
});
});
JSFiddle: http://jsfiddle.net/TrueBlueAussie/CmW9e/1/
If you inspect the DOM you will see the data-required attribute is set correctly.
Your original "works" too:
Your original code also works: http://jsfiddle.net/TrueBlueAussie/CmW9e/2/ so it is more likely the problem that your validation framework does not pickup dynamic changes to the required flag. Is the issue actually that you expected the validation rules to update automatically based on that attribute?
Solution:
Most validation frameworks allow you to change the rules client-side (add and remove rules etc), but you will need to provide details of the validation framework you are using to get a specific answer :)

jQuery UI Combobox clear selection event

I have a combo box of which the HTML looks like this:
<select id="myCombo">
<option value=""></option> <!-- Not shown in jQuery UI Combobox because empty value -->
<option value="1">Option 1</option>
<option value="2">Option 2</option>
<option value="3">Option 3</option>
</select>
I've attached the jQuery UI Combobox to I as such:
$("#myCombo").combobox({
select: function () {
if ($("#myCombo").val() == "") {
//DO SOMETHING
}
else {
//DO SOMETHING ELSE
}
}
});
When I select an option by either typing and/or selecting an option, the "DO SOMETHING ELSE" part is triggered like it should, so no issue there.
However, when I clear the selection (this selects the first option of my original combo) by deleting the text or clicking the "x", nothing get's triggered, so I can't execute the "DO SOMETHING" part of my function.
How can I trigger this part? Is there maybe another event that is triggered when clearing a selection?
I have searched and found lots of topic on selecting an item, but none on clearing/deselecting something(that were answered at least).
This can be accomplished with select2.
$("#myCombo").select2({
placeholder: "Select report type",
allowClear: true,
});
$("#myCombo")
.on("select2-selecting", function(e) {
log("selecting val=" + e.val + " choice=" + JSON.stringify(e.choice));
})
.on("select2-removed", function(e) {
log("removed");
})
After looking further into it I've found a way to trigger an event when clearing the text.
For this I had to edit the original custom.combobox widget JS, provided by the example on the jQuery UI site
In this js look for the _removeIfInvalid function and edit it like so
_removeIfInvalid: function (event, ui) {
// Selected an item, nothing to do
if (ui.item) {
return;
}
// Search for a match (case-insensitive)
var value = this.input.val(),
valueLowerCase = value.toLowerCase(),
valid = false;
this.element.children("option").each(function () {
if ($(this).text().toLowerCase() === valueLowerCase) {
this.selected = valid = true;
return false;
}
});
// Found a match, nothing to do
if (valid) {
//**ADD this piece of code**
this._trigger("change", event, {
item: null
});
return;
}
// Remove invalid value
this.input
.val("")
.attr("title", value + " didn't match any item")
.tooltip("open");
this.element.val("");
this._delay(function () {
this.input.tooltip("close").attr("title", "");
}, 2500);
this.input.data("ui-autocomplete").term = "";
//**ADD this piece of code**
this._trigger("change", event, {
item: null
});
}
The added piece of code (I know it's added 2 times, but the code would otherwise jump out of the function before it was ran), will add a change event to the combobox that can be used in your own script. This change event, I can use to run any code I want when the selection is cleared.
$("#myCombo").combobox({
select: function () {
//DO SOMETHING ON SELECT
//IMPORTANT: The other function can't be triggered before the combobox loses focus!!
$(".custom-combobox-input").blur();
},
change:function () {
//DO SOMETHING ON CLEAR
}
});
The removeIfInvalid function is always called by default when an option can't be found and by adding an event to the control when this function is invoked is invoked, we finally have a place to execute our algorithmns.
Hopefully, more people are helped with this small fix.
Empty value cannot be selected in the browser. Hence select() is never called on empty contents.
If you try this, it becomes a bit more clear:
<select id="myCombo">
<option value=""></option> <!-- Not shown in jQuery UI Combobox because empty value -->
<option value="1">Option 1</option>
<option value="2">Option 2</option>
<option value="3">Option 3</option>
<option value="4"></option>
<option value="5">Option 5</option>
</select>
I have slightly modified the javascript, note that I'm empty is never logged.
$("#myCombo").combobox({
select: function(event, ui) {
var idx = $("#myCombo").val();
var txt = $("#myCombo option:selected").text();
alert(idx);
if (idx === undefined) {
console.log("select: I'm empty");
} else {
console.log("select: " + idx + ": " + txt);
}
}
});
Interestingly, none of the other callbacks (search(), change(), response(), focus()) seems to function from autocomplete, so there is no way to detect a zero-ing out of the select.
I had spent what felt like a lot of time trying proposed solutions for this and those did not work for me, then I solved it myself.
Look for the _createAutocomplete function where you created your combobox instance.
Look for the chain of properties being set to this.input.
Then add
.on("focus",function(){
$(this).val('');
})
Anywhere in the chain.
So there are many examples on here of how to do this, but they are all (my opinion) cumbersome. You can clear the selection much easier by doing the following:
1) your _createAutocomplete: function() needs to have the following:
.attr( "title", "mytitle" )
Use any title that you want, or set another attribute (name, id etc)- I just happened to have a use for the title, so this worked for me.
2) whatever function you are running only needs the following to clear:
$("input[title='mytitle']").val('');
$("#combobox").val('');
(You have to clear both).
My need was a form with one of the fields being an autocomplete with minimum number of characters. There's an add entry button that submits, refreshes the entry list and resets the form line for additional entries. Much cleaner.

Function show and hide form elements

I am trying to create a Jquery function to add or remove a drop down menu based on the selection of a different drop down menu,
This is my very first time trying to use Java script, and i need a little help to get it going.
here is what i have done up to now, but i cant seem to get it to work can somone tell me where i have gone wrong?
$(document).ready(function(){
$(function remove() {
$("select#name").val();
if (name == "United Kindom") {
$("select.county").show();
} else {
$("select.county").hide(); });
});
<select name="ab" onchange="remove();">
Firstly, what you're using is a mash-up of Javascript and jQuery(A Javascript Library). You must understand this. Just so you know the below is jQuery, and I'll add the pure JS to the end of the post.
Try This:
$(document).ready(function(){
$(".selectWrapper").on("change", "select#ab", function(){
$("select.county").toggle($(this).val() != "United Kindom");
});
});
<div class="selectWrapper">
<select id="ab">
This is also assuming you have
<select class="country">
somewhere in your code.
//---Pure JS ----
document.getElementById("ab").onchange = function(){
var selects = document.getElementsByTagName("select"), countrySelect;
for(var x in selects){
countrySelect = (selects[x].className == "country")? select[x] : "";
}
countrySelect.style.display = (this.value == "United Kindom")? 'none' : 'block';
};
Your code contains a syntax error, undeclared variables and a scope problem.
Your code can be rewritten more efficiently: $(fn) where fn is a function is equivalent to $(document).ready(fn). Also, the .toggle method can be used instead of if-then-show-else-hide.
Fixed code
The inline handler did not work either, because function remove was defined within the $().ready function.
To fix the code itself, bind the event handler using jQuery, instead of using an inline handler:
$(function() {
$('select[name=ab]').change(function() {
var name = $("select#name").val();
$("select.county").toggle(name == "United Kindom");
});
});
//<select name="ab">
Syntax error revealed
After indenting the code properly, the syntax error can be spotted quite easily
$(document).ready(function () {
$(function remove() {
var name = $("select#name").val(); // Prefixed "var name = "
if (name == "United Kindom") {
$("select.county").show();
} else {
$("select.county").hide();
} // <----------- This one is missing!
});
});
and just a quick hint at how to make easier use of jQuery
Remember, it's the "write less, do more" library:
// Easy jquery way to run when doc loaded
$(function() {
// you dont need to include the tag in an id selector
// remember, any way you can select an element in css, you can do in jQuery
$("#Country").change(function() { // here i use the .change event to know when this select box's value has actually changed to a new value
// i'm not sure exactly what you were trying to hide and show,
// i couldn't fllow where vaiable `name` came from, but this is
// how you could easily show or hide somthing based on this select's value
var $value = $(this).val();
// although, if you're gonna have alot of possible ifs,
// i would suggest a switch statement
switch($value) {
case "United Kingdom":
// here you can choose to show a specific select for UK states/countries/ares (i'm not familiar with how it works, i'm sorry)
$("#UKStates").show();
// if you're going to show specific, prefilled select boxes,
// then it would be advised to include a classname on each one
// that you can refer to in order to hide the rest
$(".select-states").hide();
break;
case "United States":
// do work
break;
default:
// do work
}
// otherwise, if you won't have many if statements,
// just use a regular if statment, like so:
// if ($value == "United Kindom") {
// $(".county").show();
// }
// else {
// $(".county").hide();
// }
})
});
notice in my example, there is alot of commented teaching, but not alota of code. Always remember, jQuery does all the work, just do what you need too.
You could start of by reducing your function to just this, making use of the showOrHide overload of .toggle().
function remove() {
$("select[name='ab']").toggle($("select[name='ab']").val() === "United Kingdom");
}
Since you are loading jQuery, you could as well make use of its event-handling as well, instead of using inline onchange="". Something like this:
$(function(){ // Wait for DOM to be ready
$("select[name='ab']").change(remove); // Attach an change-lister
});
So the complete thing would be:
$(function(){
$("select[name='ab']").change(remove);
});
function remove() {
$("select[name='ab']").toggle($("select[name='ab']").val() === "United Kingdom"));
}

Categories

Resources