How to get the end-user seen text of an <option> [duplicate] - javascript

This question already has answers here:
Getting an option text/value with JavaScript
(4 answers)
Closed 8 years ago.
I have this code, with books of the bible all within a element:
<option value="1">Genesis</option>
<option value="2">Exodus</option>
<option value="3">Leviticus</option>
<option value="4">Numbers</option>
<option value="5">Deuteronomy</option>
<option value="6">Joshua</option>
<option value="7">Judges</option>
To further explain, I have the value as the book ID, so when I go to fetch all the verses from my Database I can just refer to them by the book number.
But doing that, I have no way of getting the user viewed friendly name like "Genesis", so that I can format it like that.
How do I fetch this (the one currently selected, i.e. "Genesis" not '1') from JavaScript?

Save the result of your getElementById to a variable like sel, and then do this:
var text = sel.options[sel.selectedIndex].text;
Select elements have an .options property that gives you an array-like collection of all of its nested option elements. They also have a .selectedIndex property, which returns the index of the currently selected element.
Using the two of these, you can get the currently selected option. Then simply use .text to get the text content of the selected option.
If you don't need to support IE6/7, you can use document.querySelector() to make things a little shorter.
var text = document.querySelector("#the_select_id option:selected").text;
The querySelector() method returns a single element, or null if none was found. There's also a querySelectorAll() method that will return a collection of elements, useful for when your selector should match multiple elements.

If your parent element has name="books" as an attribute, and is a select element, then you can do this using jQuery:
var bookName = $('select[name="books"] option:selected').text();
If your parent element has an id="books" as an attribute, and is a select element, then you can do this using plain JavaScript (can probably be improved upon):
var books = document.getElementById('books');
var bookName = books.options[books.selectedIndex].text;

Related

Nightwatch dropdowns handling by passing value

Below is the approach I have used in order to select values from a dropdown using nightwatch.As you can see this is not a good approach. We can't select the specific value from dropdown unless we click on the exact element.
this.useXpath();
this.click('(//td[#class="styles_selectDropdownContainer__2Vrns"])[1]')
this.useCss();
this.click('#react-select-6-option-1')
In selenium java there is a very good option like below
Select fruits = new Select(driver.findElement(By.id("fruits")));
fruits.selectByVisibleText("Banana");
I want to know of there is a similar approach can be used in nightwatch as well?
This is not built up using Select and Option tag so inbuilt selenium functions wouldn't work. Work around would be to click first on the parent span and then in list store every div (which is option), iterate the loop and for each web element if text matches with your desired text you can click on it.
Code :
this.useCss();
this.click("span[aria-live='polite']")
Now store options in a list :
var elements = document.querySelectorAll('.elements'); // use
//div[contains(#class,'option')] as element selector.
Now iterate the list :
// Iterate over them.
[].forEach.call(elements, function (element) {
// Manipulate each element.
element.click();
});
});

jQuery .not() doesn't remove element?

I am grabbing a copy of some info from a page, but I do not want to include certain <option> elements that appear inside <select> elements on the page.
Therefore, while I grab all the elements I want and am storing them in the variable fields, I check to see if each element is a <select> and if they have the specific <option> that I don't want.
var field = allFields[i].innerHTML; //allFields is the raw HTML I'm iterating through
if ($(field).find("select").length > 0) { //If the element we're looking at contains a select
console.log("Found a select. It is in " + field);
console.log($(field).find(".bad-option");
field = $(field).not(".bad-option").prop("outerHTML"); //Use .not() to remove the elements which have the .bad-option class
// (and .prop("outerHTML") is just there to convert it back to a String instead of a jQuery object)
}
console.log("Adding " + field);
fields[i] = field; //Add the HTML, free of any unwanted options, to the `fields` variable
Based on jQuery's documentation, I would expect the .not() function to remove any elements out of field which have the bad-option class. Yet that is not the case at all. When I log field before and after using .not(), it prints out the same thing. See the console output from the code above:
Found a select. It is in <label>Description: <select><option>thing1</option><option class="bad-option">thing2</option></select></label>
-----------------
[jQuery list object size 1, containing an object called option.bad-option]
-----------------
Adding <label>Description: <select><option>thing1</option><option class="bad-option">thing2</option></select></label>
So what's going on? How do I remove an option with a certain class from from within a jQuery object? Why isn't .not() working?
If I need to clarify anything, please let me know. I tried to make this question as specific as possible and would be happy to elaborate on any details further.
The documentation is perhaps a bit confusing: not removes elements from the selection, not the DOM. If you want to remove the elements, then just filter and remove:
const processed = $(field);
processed.filter(".bad-option").remove();
field = processed.prop("outerHTML");

Why does converting a select element to an array return an array of children elements?

I found something interesting when I accidentally used querySelector instead of querySelectorAll while selecting some elements from the page. I normally convert static node lists to an array directly after the query. But since querySelector just returns the first matching node it finds, and not a NodeList, my script attempted to convert the select node to an array. Instead of returning an empty array, it returned the children of the select element.
Why does converting a select element to an array return the children nodes? This does not work for other elements like div:
var selectParent = document.querySelector('.selectParent');
var selectArray = Array.from(selectParent);
console.log(selectArray);
var divParent = document.querySelector('.divParent');
var divArray = Array.from(divParent);
console.log(divArray);
<select class="selectParent">
<option>Option 1</option>
<option>Option 2</option>
</select>
<div class="divParent">
<div>Div 1</div>
<div>Div 2</div>
</div>
It's mostly a historic compatibiilty thing. HTMLSelectElement has the two key things it needs to be array-like:
A length
Index-style access
...and those two things relate to its options: length is the number of option elements in the box, and [0], [1], etc. access those option elements.
The key quotes from the link above are:
The options collection is also mirrored on the HTMLSelectElement object. The supported property indices at any instant are the indices supported by the object returned by the options attribute at that instant.
and
The length IDL attribute must return the number of nodes represented by the options collection...

javascript elements/tags array DOM node access

what's the different between using:
// assuming using elements/tags 'span' creates an array and want to access its first node
1) var arrayAccess = document.getElementsByTagName('elementName')[0]; // also tried property items()
vs
// assuming I assign an id value to the first span element/tag
// specifically calling a node by using it's id value
2) var idAccess = document.getElementById('idValue');
then if I want to change the text node....when using example 1) it will not work, for example:
arrayAccess.firstChild.nodeValue = 'some text';
or
arrayAccess.innerText/innerHTML/textContent = 'some text';
If I "access" the node through its id value then it seems to work fine....
Why is it that when using array it does not work? I'm new to javascript and the book I'm reading does not provide an answer.
Both are working,
In your first case you need to pass the tag name instead of the element name. Then only it will work.
There might be a case that you trying to set input/form elements using innerHTML. At that moment you need to use .value instead of innerHTML.
InnerHTML should be used for div, span, td and similar elements.
So your html markup example:
<div class="test">test</div>
<div class="test">test1</div>
<span id="test">test2</span>
<button id="abc" onclick="renderEle();">Change Text</button>
Your JS code:
function renderEle() {
var arrayAccess = document.getElementsByTagName('div')[0];
arrayAccess.innerHTML = "changed Text";
var idEle = document.getElementById('test');
idEle.innerHTML = "changed this one as well";
}
Working Fiddle
When you use document.getElementsByTagName('p'), the browser traverses the rendered DOM tree and returns a node list (array) of all elements that have the matching tag.
When you use document.getElementById('something'), the browser traverses the rendered DOM tree and returns a single node matching the ID if it exists (since html ID's are unique).
There are many differences when to use which, but one main factor will be speed (getElementById is much faster since you're only searching for 1 item).
To address your other question, you already have specified that you want the first element in the returned nodeList (index [0]) in your function call:
var arrayAccess = document.getElementsByTagName('elementName')[0];
Therefore, arrayAccess is already set to the first element in the returned query. You should be able to access the text by the following. The same code should work if you used document.getElementById to get the DOM element:
console.log(arrayAccess.textContent);
Here's a fiddle with an example:
http://jsfiddle.net/qoe30w2w/
Hope this helps!

Leading Zeros Getting Dropped Using jQuery

Using jQuery, I am copying a select into a ul for use in a mobile app. Some of the values in the select options have leading 0s. I'm using a custom attribute in the li elements to mimick the values in the select's options.
When I copy the value into the li:value, it loses the leading 0. I've even tried creating the whole li as a liter string that I append to the outer ul.
html:
<select id="seltest">
<option value="011111">good bye</option>
</select>
<div id="container"></div>
javascript:
$("#container").append("<ul id='thefilter'></ul>");
$("#seltest option").each(function () {
var optval = $(this).val();
var strvar = '<li value=\"' + String(optval) + '\">' + $(this).text() + '</li>';
alert(strvar);
$("#thefilter").append(strvar);
var lastli = $("#thefilter li:last");
alert(lastli[0].outerHTML); // now the value has lost the leading 0
});
Here's a fiddle to show an example: http://jsfiddle.net/richbuff/4RbH9/7/
Does anyone have an idea how to preserve the leading 0? It seems like jQuery is modifying my text.
TIA!
The browser is actually enforcing the spec. From the Mozilla Developer Network:
The only allowed value for this attribute is a number, even if the list is displayed with Roman numerals or letters.
In my handful of years of web development I've never used the value attribute on a list item. So, some of you might find this additional note of interest:
This attribute was deprecated in HTML4, but reintroduced in HTML5.
I'm using a custom attribute in the li elements
No, you aren't. There is a standard value attribute for LI elements.
I don't think this has anything to do with jQuery (other than it creates confusion between DOM properties and HTML attributes). In the following:
<ol>
<li value="06" onclick="alert(this.value)">Show value property
<li value="06" onclick="alert(this.getAttribute('value'))">Show value attribute
</ol>
both IE and Firefox return 6 for both alerts. The only difference is that in the first case, the value is type number and in the second type string (since getAttribute returns a string).
If you want to preserve the literal value, use a data- attribute on the LI.

Categories

Resources