As part of my populating selectbox function I am clearing the contents of the populated select box and then inserting options to a empty box. Although the select box is not being cleared correctly and a lot of options are not removed. I am using the following code to clear the contents of the select box:
for(var i = 0; i < document.getElementById(selectbox).options.length; i++)
document.getElementById(selectbox).options[i] = null;
Why not all the options are removed from the selectbox?
You can simply do
document.getElementById(selectbox).options.length = 0;
You could also have removed the elements one by one, almost like you did, but you must take into account the fact the length of options changes when you iterate. The correct way to remove while iterating would have been
for (var i=document.getElementById(selectbox).options.length; i-->0;)
document.getElementById(selectbox).options[i] = null;
But the first solution is simpler of course.
var selectbox = document.getElementById(selectbox);
document.getElementById("emptyBox").innerHTML = selectbox.innerHTML;
selectbox.innerHTML = "";
As an alternative and more terse method of clearing all options of a select list, we can take advantage of JavaScript's falsey value of zero and then simply remove the option from the Dom:
function clearSelectList(list) {
// when length is 0, the evaluation will return false.
while (list.options.length) {
// continue to remove the first option until no options remain.
list.remove(0);
}
}
Usage would then be:
var list = document.getElementById("selectbox");
clearSelectList(list);
Or more succinctly:
clearSelectList(document.getElementById("selectbox"));
this example with new generation JavaScript. I do recommend to use.
[...cbrCenterSelectbox.options].forEach(option => option.remove())
Related
I am developing a Chrome Extension that, when the user leaves the page, saves all the text from the textboxes on that page and outputs it to a file.
If I knew the IDs of the textboxes on the page, then it wouldn't be a problem, but the issue is that I need the extension to get the values of all of the textboxes on the page without knowing the IDs, as it will be a different website each time the extension is used.
Also, how would the information be collected? In a string? It would be nice to go down the page and add each textbox to a file, one by one, instead of one huge string.
I've never used jQuery or understood it, and there's probably a solution in it staring me in the face. If anyone suggests using it, please could you explain it a little bit?
Thanks in advance. I would post my code, but I don't know where to start - ergo I don't have any.
you could store it in array using $.each, as :
var valsArr = [];
$("input[type=text]").each(function() {
valsArr.push( $(this).val() );
});
or create object with name as key and value as its value, like:
var valsObj = {};
$("input[type=text]").each(function() {
valsObj[this.name] = $(this).val();
});
You can do it like this:
function onClick(){
var areas = document.getElementsByTagName("textarea");
for(var i = 0; i < areas.length; i++){
alert(areas[i].value);
}
}
<textarea></textarea>
<textarea></textarea>
<button onclick="onClick()">Gather information</button>
Also see this regarding your "save to a file" question Using HTML5/Javascript to generate and save a file
Use the selector and apply it in an each cycle.
$(":text").each(function(){
alert($(this).val());
});
Make a for loop
for(i=0; i < $("input[type='text']").length; i++){
$("input[type='text']").index(i).value();
}
You can use .map() : It returns an array.
var arr = $(":text").map(function() {
return this.value
}).get(); //add join(',') after get() to get a simple comma separated list.
Instead of input[type="text"] you could also use :text pseudo selector.
Demo
I have a .net page that contains a huge amount of always the same dropdownlist in a repeater. The rendering performance of this site is...dispappointing.
I played around with delivering only the values and display texts for the dropdownlist to the page and then filling the selects with javascript. Works well, but I can't really see an improvement. In the end the page spends a lot of time with appending the options to the select tags.
Can someone with more experience tell me if it is theoretically possible to be faster than just filling the select tags in markup. Feels to me as if the browser has to "create" it at least once per select tag anyway, so it may not matter where the options come from. But maybe my javascript solution is just not very performat
Load time isnt't really a concern - it is for an intranet page.
here is what I did in the end:
I create an option list of 1 element for every select control to preserve the preselected values. If a select is focused or hovered over, I check if it contains onyl one element. If yes, I fill it dynamically from a collection of key values. It works without delay even for very large option lists.
I register an event listener for every select box and call this function
function fillDDL(ddl, arr) {
var i, len;
var optVals;
if (ddl.options.length === 1) {
var val = ddl.options[ddl.selectedIndex].value;
var docfrag = document.createDocumentFragment();
var opt;
ddl.remove(0);
opt = new Option("", "", true, false);
docfrag.appendChild(opt);
for (i = 0, len = arr.length; i < len; i++) {
optVals = arr[i];
opt = new Option(optVals[1], optVals[0], false, optVals[0] === val);
docfrag.appendChild(opt);
}
ddl.appendChild(docfrag);
}
Maybe innerHTML would be even faster, but right now I get instant results anyway.
This may seem a cack-handed way of doing things, but I'm experimenting with this.
I have a list of UK counties, and a list of US states. When the user selects "UK" or "US" from the dropdown, it repopulates the second select list. (I DID get this to work by submitting the form each time the select options were changed, and rebuilding the HTML form ... but realised that was a somewhat server intensive mode, so now want to do it via Javascript)
I began by reading the text file into a javascript array, (actually, a PERL script reads the file, turns it into code, and then prints out the HTML) So I end up with:
var state_opt = new Array('1','2','3','4',' ...
var state_title = new Array('Alabama','Alaska','Arizona','Arkansas' ...
I then use a loop to load the second array:
for (x=0; x<state_opt.length; x++){
document.userChoice.c_s.options[x]=new Option(state_title[x],state_opt[x])
}
That works fine ... until I try the second array which features <optgroup></optgroup> The above loop automatically makes them into options!! Here are the arrays:
var county_opt = new Array('-','2','3','4', ...
var county_title = new Array('<optgroup label="England">','Bedfordshire','Berkshire','Bristol' ...
** Notice I have made the <optgroup> value into "-" so it can be distinguished. (When writing in PERL, this is the concept I used:
If ($county_opt[$x] eq "-"){
$option.=$county_title[$x];
}
else{
$option.="<option value=\"$county_opt[$x]\">$country_title[$x]";
}
And then write "<select>$option</select>
So what I'm seeking is code something like this:
for (x=0; x<county_opt.length; x++){
var str=county_title[x];
if (str.match(/optgroup/g)){
// ?? document.userChoice.c_s.options[x]=county_title[x];
// ie print the value as is without making it into an option
}
else{
document.userChoice.c_s.options[x]=new Option(county_title[x],county_opt[x])
}
}
Any SIMPLE ideas? If it can't be done, I'll just have to remove the labels
Hmmm ... that was a 'challenging' morning! The solution might be technically wrong in parts ... but it works.
I found a way to add the tags without making them into selectable options, but because they were not options, when changing to another option list, I could not remove these <optgroup> tags by using a loop that removed option elements!! (Does that make sense?)
Instead, the crude way I ended up doing it was to use innerHTML to set the text within the <select> form option to null. I then (incorrectly?) created a string built up with ≤optgroup><option> tags and values, and used innerHTML to replace it again
The "ind2" other option is the (correct) way to replace all option fields.
Hope this helps someone.
Incidentally, you'll also notice the "Not Available" have values of "-". Quite simply, if the user selects this option, an error trap routine sees these values, and simply returns to the form with a false value.
function checkCountry(){
document.userChoice.c_s.innerHTML=''
var ind=document.userChoice.countryChoice.selectedIndex;
// set 1 for UK, 2 for US
//'Please select a Country' has an option value of '0'
if (ind == 0){ // resets 2nd / 3rd option list if don't select US or UK
document.userChoice.c_s.options[0]=new Option("NOT AVAILABLE","-");
document.userChoice.service.options[0]=new Option("NOT AVAILABLE","-");
}
if (ind == 1){
var t='<option value="-">Please select a County</option>';
for (x=0; x<county_opt.length; x++){
var str=county_opt[x];
if (str.match(/-/)){
t+=county_title[x]; // Sets the <optgroup> tag with no option value
}
else{
t+='<option value="'+county_opt[x]+'">'+county_title[x];
}
}
document.userChoice.c_s.innerHTML=t;
}
if (ind == 2){ // preferred method that won't remove <optgroup> from <select> area
document.userChoice.c_s.options[0]=new Option('Please select a State','-');
for (x=1; x<state_opt.length; x++){
document.userChoice.c_s.options[x]=new Option(state_title[x],state_opt[x])
}
}
}
</script>
I have a variable ddEmail having value
<option value="cp#cp.ljj" selected="">cp#cp.ljj</option>.
When I try to put it in select element using
document.getElementById("txtEmail").innerHTML = ddEmail;
then in Firefox document.getElementById("txtEmail").innerHTML shows me the same value as of ddEmail while in IE it shows cp#cp.ljj</option>
Is there any way to resolve it?
As you've discovered, you can't reliably use innerHTML to set the options of an existing select.
The best way it through the select's options property:
var option = new Option("cb#cb.ljj", "cb#cb.ljj");
// Option text --------^ ^---- option value
option.selected = true;
document.getElementById("txtEmail").options.add(option);
Note that for historical reasons, it's add, not push. push works on lots of browsers, but not all of them.
Also note that the above assumes that either there are no options in the select, or you just want to add this one, not replace all of the ones already there with it. If you want to remove the previous options:
var sel = document.getElementById("txtEmail");
sel.options.length = 0;
sel.options.add(option);
i want to check the first element of multiple radiobutton groups.
I'm using Firebug, which is why i do not want, yes i know there is firequery, but there must be a way like they did it in the old days :)
Any help yould be great, thx in advance.
Loop backwards over document.getElementsByTagName('input') and set checked to true if type is equal to "radio".
If you try to check multiple buttons in the same group, the last one will hold.
Thus, looping backwards will end up checking the first option in each group.
Update
Feeling a bit silly here, you said you were using Firebug, and thus Firefox, and so we have querySelector available. Thus checking the first radio button in any given group is a one-liner:
document.querySelector('input[type="radio"][name="theGroupName"]').checked = true;
Live example
querySelector returns the first matching element, and so the above will return the first input element with type="radio" and name="theGroupName". Then we just set its checked to true.
Granted that doesn't do the first of all groups, but it gives you more control and is (again) a one-liner — handy for Firebug.
Original answer
You can use getElementsByTagName to get all input elements in document order. Then loop through them, only processing the ones with type="radio" and remembering the last name you encoutered; mark checked = true for the first of each name.
E.g.:
var inputs = document.getElementsByTagName('input');
var lastName, index, input;
for (index = 0; index < inputs.length; ++index) {
input = inputs.item(index);
if (input.type.toLowerCase() === "radio") {
if (input.name !== lastName) {
lastName = input.name;
input.checked = true;
}
}
}
Live example
If you want to limit that to some container, you can use the element version of getElementsByTagName.