With webdriver.js, how to get the selected option of a <select>? - javascript

Plenty of answers for java and C#, but I can't find how to do it in javascript. Seems the API are different...

yeah it is possible. Lets say we have the following select element:
<select name="test" id="select">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
You get the current selected option by using getValue and you can change the selection by using click. Here is an simple example:
var webdriverjs = require('webdriverjs'),
client = webdriverjs.remote({desiredCapabilities:{browserName:'phantomjs'}}).init();
client
.url('http://localhost:8080')
.getValue('#select',function(err,val){
console.log(val); // will output "1"
})
.click('//*[#id="select"]/option[3]')
.getValue('#select',function(err,val){
console.log(val); // will output "3"
})
.end();
Hope that helps.
cheers

For those who are just looking for pure WebDriverJS solution and not any framework specific like webdriver.io or protractor, here is the code,
var element = driver.findElement(wd.By.id('mySelect'));
element.getAttribute('value').then(function(selected) {
if(selected === 'the one I expected') {
done();
}
else {
done(new Error('something went wrong');
}
});

If you want the option element, use the return value of then callback:
driver.findElement(By.css('select[name=eventTypes]'))
.then((select) => {
return select.getAttribute('value').then((value) => {
return {select: select, value: value};
});
})
.then((data) => {
return data.select.findElement(By.css('option[value="'+data.value+'"]'));
})
.then((option) => {
//do something.
});

If you have this in your html for an example
<select name="test" id="myId">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
You can select for a example option 3 like this
var driver = new firefox.Driver();
driver.findElement(By.css('#myId>option:nth-child(2)')).click();
Works for me and I am using selenium-webdriver with JavaScript

Although the question has been posted for 7 years, I would like to share my answer that works now. You can get the selected option/value by
let select_value = await driver.findElement(By.css('select')).getAttribute('value')

I did using this
element=await driver.findElement(By.name("quantity")); // here you have to select your element suppose i am using get element by name
// below will help you to get selected value from select option
var SelectedValue=element.getAttribute('value').then(function(selected) { return selected;});

Related

Javascript get value from select option based on label

Using either jQuery or pure JavaScript, how can I get the ID for a select option based on the label? So for example, given the following:
<select id="blah">
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</select>
If I have the label "Two" but I need to know the value associated with it, how can I get that value from this select? I don't want to simply select it, I need to know what the value is.
If the only reference you have is really the actual text content, then you'll have to loop through the elements and check the content of each one. Shown here with jQuery just because it's less to type:
var result;
$("option").each(function() {
if ($(this).text() == "Two") {
result = $(this).attr("value");
return false;
});
});
Another option:
$('#blah').find('option:contains("Two")').val();
(Pun intended?)
Get all the options and then use find to get the one with specific text.
const optionEls = Array.from(document.querySelectorAll("#blah option"));
const hasText = text => el => el.textContent === text;
const optionWithTwo = optionEls.find(hasText("Two"));
console.log(optionWithTwo.value);
<select id=blah>
<option value=1>One</option>
<option value=2>Two</option>
<option value=3>Three</option>
</select>

Filter options of drop down menus with different values

Based on this useful topic Use jQuery to change a second select list based on the first select list option I try to adapt the code for my purposes.
My problem is that for some reasons I cannot have the exact same integer values in my 2 selection. I only can provide something close as:
<select name="select1" id="dropDown">
<option value="fruit">Fruit</option>
<option value="animal">Animal</option>
<option value="bird">Bird</option>
<option value="car">Car</option>
</select>
<select name="select2" id="dropDown_2">
<option value="fruit-01">Banana</option>
<option value="fruit-02">Apple</option>
<option value="fruit-03">Orange</option>
<option value="animal-01">Wolf</option>
<option value="animal-02">Fox</option>
<option value="animal-03">Bear</option>
<option value="bird-01">Eagle</option>
<option value="bird-02">Hawk</option>
<option value="car-01">BMW<option>
</select>
The js to be modified is:
$("#dropDown").change( function() {
if ( $(this).data('options') == undefined ) {
/*Taking an array of all options-2 and kind of embedding it on the select1*/
$(this).data( 'options', $("#dropDown_2").find('option').clone() );
}
var id = $(this).val();
var options = $(this).data('options').filter('[value=' + id + ']');
$("#dropDown_2").html(options);
} );
I know that there are some js techniques to subtract substrings and similar stuff. But my skills are not so good to exactly say how. Is there anyone willing to help me? I need to filter the second options with its values based (but not identical) on the values of the first. Hope I explained myself sufficiently. Many many thanks!
EDIT
First of all sorry for not explaining myself sufficiently. I have to add that I cannot change the markUp!
So I inserted an each loop before the code that Shiran kindly delivered me to prepare it like so:
$("#dropDown_2").find('option').each( function() {
var $this = $(this);
var val = $this.val();
var myFilter = val.slice(0,-3)
$this.addClass( myFilter );
// $this.data('filter', myFilter ); does not work don’t know why
} );
Which seems to work at least in principle. Yet, for reasons that remain obscure for me sadly my attempt to attach data-filter to my option elements wasn’t accepted. So I had to go for classes which worked (at least for the loop).
I then tried to modify the code ending up with the following:
$("#dropDown").change(function() {
var filters = [];
if ($(this).attr('class') == "") {
$(this).find("option").each(function(index, option) {
if ($(option).attr('class') != "")
filters.push($(option).attr('class'));
} );
} else {
filters.push($(this).attr('class'));
}
$("#dropDown_2").html("");
$.each(filters, function(index, value) {
$options.find("option." + value ).clone().appendTo($("#dropDown_2"));
} );
} );
But as you can guess this didn’t work. :-(
And I also noted that the values of my filter array are the class (would be analogue to the filter value in the original) of my select not of the options of it. But obviously Shorans code did work well. What did I wrong here?
Please help, I am getting grey hair with this!! Thanks so much in advance!
$(this).data("options") gets:
<select data-options="the data here"> ==> "the data here"
Here's a working version:
(notice how I used data-filter in the second select and in the last each loop in the javascript part)
$(document).ready(function() {
var $options = $("#dropDown_2").clone(); // this will save all initial options in the second dropdown
$("#dropDown").change(function() {
var filters = [];
if ($(this).val() == "") {
$(this).find("option").each(function(index, option) {
if ($(option).val() != "")
filters.push($(option).val());
});
} else {
filters.push($(this).val())
}
$("#dropDown_2").html("");
$.each(filters, function(index, value) {
$options.find("option").each(function(optionIndex, option) { // a second loop that check if the option value starts with the filter value
if ($(option).val().startsWith(value))
$(option).clone().appendTo($("#dropDown_2"));
});
});
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<select name="select1" id="dropDown">
<option value="">All</option>
<option value="fruit">Fruit</option>
<option value="animal">Animal</option>
<option value="bird">Bird</option>
<option value="car">Car</option>
</select>
<select name="select2" id="dropDown_2">
<option value="fruit-01">Banana</option>
<option value="fruit-02">Apple</option>
<option value="fruit-03">Orange</option>
<option value="animal-01">Wolf</option>
<option value="animal-02">Fox</option>
<option value="animal-03">Bear</option>
<option value="bird-01">Eagle</option>
<option value="bird-02">Hawk</option>
<option value="car-01">BMW
<option>
</select>

Change selected item from inside onchange event

In the following select box:
var sval=1;
function foo(v) {
sval=Number(v);
}
...
<select name="sval" onchange="
if (confirm('...?')) foo(this.value); else $(this).val(sval);">
<option value="1">1
<option value="2">2
<option value="3">3
The idea is to confirm the selected item change. If not confirmed to change back to the old value.
if confirm returns true, all is working as expected
if confirm returns false, then the select always gets value 1, regardles of sval
Why changing the selected item does not work from inside the onchange handler?
EDIT: The following code based on ejay_francisco's answer does the proper job:
http://jsfiddle.net/4wCQh/33/
var vals = 1;
$("#svalue").change(function() {
if (confirm('...?'))
vals=Number(this.value);
else
$(this).val(vals);
});
but its not clear what is the reason that the inline code $(this).val(sval) resets the select to 1
I've modified your code and this is how i've done it
Working Fiddle :
Javascript :
$( "#svalue" ).change(function() {
if (confirm('...?')) {
vals =$('#svalue').val();
$('#svalue').val(this.options[this.selectedIndex].value);
}else{
$('#svalue').val(vals);
}
});
HTML :
<select id="svalue">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
EDITED :
here's how its done inline : working Fiddle
HTML:
<select name="sval" onchange="if (confirm('...?')) {foo(this.value);sval=(this.value);} else $(this).val(sval);">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
Javascript :
var sval=1;
function foo(v) {
$('#svalue').val(v);
}
apparently you forgot to change the value of sval to whatever the user has previously clicked. the code is sval=(this.value); on the onchange part.
Try
I think else part is not neccessary
Change to
<select name="sval" onchange="
if (confirm('...?')) foo(this.value);">
Your approach is absolutely horrible.
When ever you inline JavaScript events on elements it just looks ugly.
Why are you wanting to set the select value to the value it has as the currently selected value?
Could you just skip this $(this).val(sval = this.value;); and only have this sval = this.value;
I'm just really a huge fan as to keeping the code and values to a bare minimum where variables are not needed and also where code is not needed.
Give this a shot.
<script type="text/javascript">
var sval = 1;
var foo = function () {
if(confirm('...?')) {
$(this).val(sval = this.value);
}
else
{
$(this).val(sval);
}
};
setTimeout(function () {
document.getElementById('sval').onchange = foo;
}, 100);
</script>
<select id="sval">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
I have found the reason the code is not working.
It came out that there are differences between execution in fiddle and browser which made tracking the problem harder.
In the inline code of the onchange event a variable with the same name as name="sval" gets defined and because the name is the same with the integer variable from the global context, the code is not using the proper value to change select's value.

<select> tag and returning multiple values to javascript method

I have an issue with the data which is sent from a drop down menu, the selector only returns a single value, even when multiple values are selected. I have searched online for a solution to this, but they all use PHP, JQuery or some method outside the scope of the course I am taking; to capture multiple selected items. I have tried .value of the individual options, but that returns all of the options rather than just the ones which are selected. Is there some kind of trick to sending multiple values?
Here is my code for the menu. For example If I select JAVA PROGRAMMING, NETWORKS and VIDEO GAMES, only JAVA PROGRAMMING is sent.
<select multiple id="CK_Expertise">
<option id="CK_Exp1" value="Java programming">JAVA PROGRAMMING</option>
<option id="CK_Exp2" value="Networks">NETWORKS</option>
<option id="CK_Exp3" value="Video game programming">VIDEO GAMES</option>
<option id="CK_Exp4" value="Accounter">ACCOUNTER</option>
<option id="CK_Exp5" value="Help Desk">HELPDESK</option>
<option id="CK_Exp6" value="C++ programming">C++</option>
<option id="CK_Exp7" value="Programming">PROGRAMMING</option>
</select>
I have also tried using the Select Object in the DOM, http://www.w3schools.com/jsref/dom_obj_select.asp
which has a few methods for accessing the options in the dropdown menu. One method in particular called selectedIndex, seemed to be what I am looking for, however it only returns the the index of the first selected option, instead of all of the selected options.
Is there a simple solution to this using just Javascript and the DOM?
Thanks
- Chris
Get the options, iterate and check if they are selected, and add the values to an array
var select = document.getElementById('CK_Expertise'),
options = select.getElementsByTagName('option'),
values = [];
for (var i=options.length; i--;) {
if (options[i].selected) values.push(options[i].value)
}
console.log(values)
FIDDLE
or being a little more fancy
var select = document.getElementById('CK_Expertise'),
values = Array.prototype.filter.call(select.options, function(el) {
return el.selected;
}).map(function(el) {
return el.value;
});
console.log(values)
FIDDLE
You could use the select.selectedOptions property:
select.onchange = function() {
var values = [].map.call(this.selectedOptions, function(opt){
return opt.value;
});
};
document.getElementById('CK_Expertise').onchange = function() {
document.querySelector('pre').textContent = JSON.stringify([].map.call(
this.selectedOptions, function(opt){ return opt.value; }
));
}
<select multiple id="CK_Expertise">
<option id="CK_Exp1" value="Java programming">JAVA PROGRAMMING</option>
<option id="CK_Exp2" value="Networks">NETWORKS</option>
<option id="CK_Exp3" value="Video game programming">VIDEO GAMES</option>
<option id="CK_Exp4" value="Accounter">ACCOUNTER</option>
<option id="CK_Exp5" value="Help Desk">HELPDESK</option>
<option id="CK_Exp6" value="C++ programming">C++</option>
<option id="CK_Exp7" value="Programming">PROGRAMMING</option>
</select>
<pre></pre>
If you can use jQuery, this will give you all the values
$(document).ready(function(){
$('#CK_Expertise').change(function(e){
var values = $('#CK_Expertise').val()
alert(values);
});
});
HTH,
-Ted
You could iterate storing select.selectedIndex in an array and unselecting the corresponding option to get the next one:
select.onchange = function() {
var i, indices=[], values = [];
while((i=this.selectedIndex) > -1) {
indices.push(i);
values.push(this.value);
this.options[i].selected = false;
}
while((i=indices.pop()) > -1)
this.options[i].selected = true;
console.log(values);
}
Demo
This way you avoid iterating over all options, but you must iterate twice over the selected ones (first to unselect them, them to select them again).
Why not using an indexed variable in the SELECT command?
<SELECT MULTIPLE id="stuff" name="stuff[]">
<OPTION value=1>First stuff</option>
<OPTION value=2>Second stuff</option>
<OPTION value=3>Third stuff</option>
</SELECT>
In that case it's easy to read the array:
$out=$_REQUEST['stuff'];
foreach($out AS $thing) {
echo '<br />'.$thing;
}
Sorry for the poor indentation, but I just wanted to show the way I use for solving this case!
var select = document.getElementById('CK_Expertise'),
options = select.selectedOptions,
values = [];
for(let i=0;i<options.length;i++)
{
values.push(options[i].value);
}
console.log(values);

How to filter select options with jQuery?

I am trying to filter the options inside a select box person based on the value selected in another select box invoice_project_id:
<select id="invoice_project_id">
<option value="1">Project A</option>
<option value="2">Project B</option>
<option value="3">Project C</option>
</select>
<select id="person">
<option data-project_ids="[1,2]">Spencer, Eve</option>
<option data-project_ids="[3]">Goodwin, Alisha</option>
<option data-project_ids="[]">Emard, Tito</option>
<option data-project_ids="[2,3]">Bergstrom, Damien</option>
</select>
This is the jQuery I've got so far:
function filterOption(id) {
return $('#person option').filter(function () {
return $.inArray(id, $(this).data('project_ids')) > -1
});
}
$('#invoice_project_id').on('change', function() {
var project = $('#invoice_project_id :selected').val();
var options = filterOption(parseInt(project));
if (options) {
return $('#person').html(options);
} else {
return $('#person').empty();
}
});
The function filterOption() was kindly provided by someone on this forum, however can't manage to integrate it into my code due to my lack of experience in jQuery.
Can anybody help?
Thanks a lot.
Since filterOption function returns a jQuery collection you can hide the options and call the .show() on the returned collection:
$('#invoice_project_id').on('change', function() {
var project = $('#invoice_project_id').val();
$('#person option').hide();
filterOption(+project).show();
});
http://jsfiddle.net/M3Xga/
Please note that not all browsers handle showing/hiding the option elements. Alternatively you can disable/enable the options by modifying disabled properties:
$('#person option').prop('disabled', true);
filterOption(+project).prop('disabled', false)
.first()
.prop('selected', true);
http://jsfiddle.net/PjHc6/1/

Categories

Resources