I have a select element:
function find() {
var schoolList = document.getElementByID("schoolList");
if (schoolList.hasAttributes("[data attribute value]") {
//modify text in found option
};
};
find();
<div id="SelectWrapper" class="menu">
<form>
<select id="schoolList">
<option value='student' data-tier="student" data->Student 1</option>
<option value="teacher" data-tier="faculty" data->Teacher</option>
</form>
</div>
Using pure Javascript, I want to create an if statement within a function that checks to see if an option has an appropriate data attribute value (for instance, "student" or "faculty") and then adds to or modifies the existing innerHTML/text.
You can use querySelectorAll() to find all the options with a particular data value, then loop over them.
function find() {
var options = document.querySelectorAll("#schoolList option[data-tier=student]");
for (var i = 0; i < options.length; i++) {
options[i].innerHTML += " (something)";
}
}
The example for you
function find() {
var schoolList = document.getElementById("schoolList");
if (schoolList.hasAttributes("[data attribute value]")) {
var opts = schoolList.getElementsByTagName("option");
for (var i = 0, len = opts.length; i < len; i++) {
var option = opts[i];
// modify
if (option["data-tier"] === "student") {
option.text = "new text content"
}
}
// add new
for (var i =0; i < 5; i++) {
var opt = document.createElement("option");
opt.value = i;
opt.innerHTML = "Option " + i;
schoolList.appendChild(opt);
}
};
};
find();
Related
I'm playing around with Javascript as a hobby and I've been having trouble accessing elements that I have dynamically created via another function.
Essentially, I have a link that dynamically creates a couple of dropdown selects with a few options. Then I have a second link which I would try to print some of the selected options onto console.
HTML:
create
collect
<div id="box"><br>
Javascript:
function maker() {
box.appendChild(document.createElement("br"));
for (i = 0; i < 2; i++) {
box.appendChild(document.createTextNode("test " + (i + 1) + " "));
for (k = 0; k < 2; k++) {
var dropdown = document.createElement("select");
box.appendChild(dropdown);
for (j = 0; j < nice.length; j++) {
var option = document.createElement("option");
option.value = nice[j];
option.text = nice[j];
option.id = 'option' + i + k;
console.log(option.id)
dropdown.appendChild(option);
}
}
box.appendChild(document.createElement("br"));
}
}
function getter() {
var test = document.getElementById("option01");
console.log(test.options[test.selectedIndex].value);
}
I've printed to console the option id's as they are created (seems to have no problem printing this), and added them to the DOM via appendChild. However with my second function, I am unable to retrieve the selected value of the options despite explicitly referencing the id.
My guess is that it has something to do with the order the scripts are loaded. Can anyone help me understand what's going on?
Attached is my JSFiddle file,
http://jsfiddle.net/c8h6gx2d/1/
Cheers,
The problem is that <option>s are nested inside of <select>s, and it's the *<select>*s which have a selectedIndex property. So, test.options[test.selectedIndex].value won't work when test is an <option> element. Try using getElementById to get one of the <select>s, for one, and then just access its .value (which is less cumbersome than checking selectedIndex):
var nice = [2, 3, 5];
function maker() {
box.appendChild(document.createElement("br"));
for (i = 0; i < 2; i++) {
box.appendChild(document.createTextNode("test " + (i + 1) + " "));
for (k = 0; k < 2; k++) {
var dropdown = document.createElement("select");
dropdown.id = 'select' + i;
box.appendChild(dropdown);
for (j = 0; j < nice.length; j++) {
var option = document.createElement("option");
option.value = nice[j];
option.text = nice[j];
dropdown.appendChild(option);
}
}
box.appendChild(document.createElement("br"));
}
}
function getter() {
var test = document.getElementById("select0");
console.log(test.value);
// same as:
// console.log(test.options[test.selectedIndex].value);
}
create
collect
<div id="box"><br>
Also note that duplicate IDs in a single document is invalid HTML, so if you ever call maker more than once, for your HTML to be valid, you might have a separate counter outside of maker that gets incremented:
const makeCount = 0;
function maker() {
// ...
dropdown.id = 'select' + makeCount + '_' + i;
// ...
makeCount++;
}
(or, avoid IDs entirely, if at all possible, numeric ID indicies are a code smell - use classes instead)
We need to discriminate between option elements and the select element. The select element is the one with which you want to interact most of the time, and the option elements are simply a collection of possible entries for the select element.
Your code as it stands now generates these sort of elements:
<select>
<option value="2" id="option00">2</option>
<option value="3" id="option00">3</option>
<option value="5" id="option00">5</option>
</select>
As you see all the options receive the same ID - which is generally forbidden in HTML documents. You might consider moving the ID indicator to the select element, which also gives you access to the value of the selected option.
Here is the revised JS code with comments before revisions:
var nice = [2, 3, 5];
function maker() {
box.appendChild(document.createElement("br"));
for (i = 0; i < 2; i++) {
box.appendChild(document.createTextNode("test " + (i + 1) + " "));
for (k = 0; k < 2; k++) {
var dropdown = document.createElement("select");
# Giving the select item an ID instead of each option
dropdown.id = 'select' + i + k;
box.appendChild(dropdown);
for (j = 0; j < nice.length; j++) {
var option = document.createElement("option");
option.value = nice[j];
option.text = nice[j];
option.id = 'option'
console.log(option.id)
dropdown.appendChild(option);
}
}
box.appendChild(document.createElement("br"));
}
}
function getter() {
# Getting the select element instead of the option
var selectElement = document.getElementById("select00");
# The value attribute of the select element is the value of the selected option
console.log(selectElement.value);
}
I have a dropdown that's populated through a loop. The selected attribute should be added when <%if o.getNextPage()%> is equal to i.
<select id="dropDown" onchange="display(this.value)">
var start = 1;
var end = noOfPages;
var options = "";
for (var i = start; i <= end; i++) {
options += "<option>" + i + "</option>";
}
document.getElementById("dropDown").innerHTML = options;
function display(e) {
document.getElementById("hidden").value = e;
document.invoiceForm.submit();
}
You can add value attribute to the option tag.
As suggested by #3Dos in comments you can use ‘document.createElement‘ without needing to insert raw HTML like this:
var start = 1;
var end = noOfPages;
var options = "";
for (var i = start; i <= end; i++) {
var opt = document.createElement('option');
opt.value = i;
opt.innerHTML = i;
document.getElementById('dropDown').appendChild(opt);
}
This is the proper way of generating your dropdown list and preserve performance as you interact with the DOM only once thanks to the documentFragment
// These were not provided by OP but added to actually get this snippet running
var noOfPages = 5;
var start = 1;
var end = noOfPages;
var options = document.createDocumentFragment();
for (var i = start; i <= end; i++) {
var option = document.createElement('option');
option.value = i;
option.textContent = i;
options.appendChild(option);
}
document.getElementById("dropDown").appendChild(options);
<select id="dropDown" onchange="display(this.value)"></select>
I omitted the display function which is irrelevant as it refers to unprovided code.
Here's my try on implementing this:
var select = document.getElementById(key);
var temp = select.value;
select.options.length = 0; // clear out existing items
for (var i = 0; i < data.length; i++) {
select.options.add(new Option(data.Value, data.Key))
}
select.value = temp;
In case of there is no such value anymore I would like to set some default values for selcted option.
This is a simple function called init_select
It clear the selection tag
-remembers the option that was previously selected
if the item that was previously selected item is not in the list of new options..it will select the option that you want (this is the default_opt) parameter
-if the previously item is IN the list it will ignore the default_opt paramater and use the previously selected item.
demo here (previously selected item NOT in list but default_opt is IN list)
function init_select(id,data,default_opt) {
var select = document.getElementById(id);
var temp = select.value;
select.innerHTML="";
for (var i = 0; i < data.length; i++) {
select.options.add(new Option(data[i]))
}
if (data.indexOf(temp) < 0 && data.indexOf(default_opt)>=0 ) {
select.value = default_opt;
console.log('this is select',select.value,default_opt,select);
} else if (data.indexOf(temp) >= 0){
//select.options.add(new Option(temp));
select.value = temp;
console.log(select.value,data.indexOf(temp));
}
}
init_select('key',["New Value", "New Value2", "New Value3", "New Value4"],"New Value2")
<select id="key">
<option>year1</option>
<option>year2</option>
<option>year3</option>
</select>
demo here (previously selected item IN list and default_opt is IN list, default options is ignored and the previously selected item is selected)
function init_select(id,data,default_opt) {
var select = document.getElementById(id);
var temp = select.value;
select.innerHTML="";
for (var i = 0; i < data.length; i++) {
select.options.add(new Option(data[i]))
}
if (data.indexOf(temp) < 0 && data.indexOf(default_opt)>=0 ) {
select.value = default_opt;
console.log('this is select',select.value,default_opt,select);
} else if (data.indexOf(temp) >= 0){
//select.options.add(new Option(temp));
select.value = temp;
console.log(select.value,data.indexOf(temp));
}
}
init_select('key',["New Value", "New Value2", "New Value3", "New Value4","year1"],"New Value2")
<select id="key">
<option>year1</option>
<option>year2</option>
<option>year3</option>
</select>
Your idea of getting the value of select and resetting it was right. You can achieve your wanted result with jQuery like this.
Note that if the old value is not available, select's value will be set to null.
$("button").on("click", function() {
var def = "4. Option";
var temp = $("select").val();
var select = $("select");
select.empty();
for (i = 2; i <= 10; i++) {
$("<option>").text(i + ". Option").appendTo(select);
}
select.val(temp);
if (select.val() == null)
select.val(def);
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select>
<option>1. Option</option>
<option>2. Option</option>
<option>3. Option</option>
<option>4. Option</option>
<option>5. Option</option>
</select>
<button>Clear and Fill Select</button>
I have two sets of data in a JSON file (ACodes and BCodes), which I want to read and display as the options of two different dropdowns in an HTML file. I want to have one common JavaScript function that I can use to get along with the same (shown below) but I am not getting the desired output.
Help about where I am going wrong is much appreciated!
HTML
<script>
var select, option, arr, i;
function loadJSON(var x){
if(x.match == "A"){
array = JSON.parse(ACodes);
select = document.getElementById('dd1');
for (i = 0; i < array.length; i++) {
option = document.createElement('option');
option.text = array[i]["Code"];
select.add(option);
}
}
else if(x.match == "B"){
array = JSON.parse(BCodes);
select = document.getElementById('dd2');
for (i = 0; i < array.length; i++) {
option = document.createElement('option');
option.text = array[i]["Curr"];
select.add(option);
}
}
}
</script>
<body onload="loadJSON('A');laodJSON('B')">
<select id="dd1"></select>
<select id="dd2"></select>
</body>
JSON
ACodes = '[{"Code":"BHAT"}, {"Code":"MALY"}]';
BCodes = '[{"Curr":"CAC"},{"Curr":"CAD"}]';
remove var at loadJSON(var x) => loadJSON(x)
remove .match at x.match == "A", you seems to want to compare x with specific value, not testing it as regexp, so change to x === "A"
laodJSON('B'); at body onload is typo.
There's some reusable codes, you can attract the value depends on x and make the code shorter. This step is not a must do, as it won't cause your origin code unable to work.
<body onload=" loadJSON('A');loadJSON('B');">
<select id="dd1"></select>
<select id="dd2"></select>
<script>
var select, option, arr, i;
var ACodes = '[{"Code":"BHAT"}, {"Code":"MALY"}]';
var BCodes = '[{"Curr":"CAC"},{"Curr":"CAD"}]';
function loadJSON(x){
var array, select, target;
if (x === 'A') {
array = JSON.parse(ACodes);
select = document.getElementById('dd1');
target = 'Code';
} else if (x === 'B') {
array = JSON.parse(BCodes);
select = document.getElementById('dd2');
target = 'Curr';
}
for (i = 0; i < array.length; i++) {
option = document.createElement('option');
option.text = array[i][target];
select.add(option);
}
}
</script>
</body>
Edit: to create it more dynamically, you can make the function accept more params, so you can have more control over it. Demo is on jsfiddle.
// Append options to exist select
function loadJSON(jsonObj, key, selectId) {
var arr = JSON.parse(jsonObj);
// Get by Id
var select = document.querySelector('select#' + selectId);
// Loop through array
arr.forEach(function(item) {
var option = document.createElement('option');
option.text = item[key];
select.add(option);
});
}
// Append select with id to target.
function loadJSON2(jsonObj, key, selectId, appendTarget) {
// Get the target to append
appendTarget = appendTarget ? document.querySelector(appendTarget) : document.body;
var arr = JSON.parse(jsonObj);
// Create select and set id.
var select = document.createElement('select');
if (selectId != null) {
select.id = selectId;
}
// Loop through array
arr.forEach(function(item) {
var option = document.createElement('option');
option.text = item[key];
select.add(option);
});
appendTarget.appendChild(select);
}
<script>
var select, option, arr, i;
var ACodes = '[{"Code":"BHAT"}, {"Code":"MALY"}]';
var BCodes = '[{"Curr":"CAC"},{"Curr":"CAD"}]';
function loadJSON(x){
if(x == "A"){
array = JSON.parse(ACodes);
select = document.getElementById('dd1');
for (i = 0; i < array.length; i++) {
option = document.createElement('option');
option.text = array[i]["Code"];
select.add(option);
}
}
else if(x == "B"){
array = JSON.parse(BCodes);
select = document.getElementById('dd2');
for (i = 0; i < array.length; i++) {
option = document.createElement('option');
option.text = array[i]["Curr"];
select.add(option);
}
}
}
</script>
<body onload='loadJSON("A");loadJSON("B")'>
<select id="dd1"></select>
<select id="dd2"></select>
</body>
Now this code will work.
The match() method searches a string for a match against a regular expression. So match() function will not work here. You have to use equal operator for get this done.
I hope, This will help you.
You were well on your way, you just need to make it more dynamic :)
function loadOptions(json) {
json = JSON.parse(json);
var select = document.createElement('select'), option;
for (var i = 0; i < json.length; i++) {
for (var u in json[i]) {
if (json[i].hasOwnProperty(u)) {
option = document.createElement('option');
option.text = json[i][u];
select.add(option);
break;
}
}
}
return select;
}
And to use it:
document.body.appendChild(loadOptions(ACodes));
document.body.appendChild(loadOptions(BCodes));
FIDDLE
http://jsfiddle.net/owgt1v2w/
The answers above will help you, but im strongly recommend you to check some javascript's frameworks that can help you with that kind of situation.. The one im using is knockout.js (http://knockoutjs.com/)
Take a look in the documentation, also there a lot of topics related in stackoverflow http://knockoutjs.com/documentation/options-binding.html
Regards!
I have the below, it dynamically adds a new value option into a selectbox. The problem i have is that it does not check for duplicate entries before adding new options into the select box.
Is there a way i can make a change to my code so it will alert the user that a duplicate entry is found and to stop adding the same option value?
function refadd() {
var val = document.getElementById('docsref').value
if (val != "") {
var select = document.getElementById('docsref_list');
var option = document.createElement('option');
option.text = value
select.add(option,select.option)
select.selectedIndex = select.options.length - 1;
}
}
Best is to loop through all existing options and check if you had a match.
The loop would be added so it appears BEFORE your IF condition.
If a match is found you could notify the user (e.g. alert ) and then execute a "return" statement.
Something like the below:
function refadd()
{
var value = document.getElementById('docsref').value
if (value != "")
{
var select = document.getElementById('docsref_list');
var option = document.createElement('option');
var flag = 0;
for(var i = 0; i < select.length; i++)
{
if(select[i].value == value)
{
flag = 1;
}
}
if(flag == 1)
{
alert('Value is duplicate.');
}
else
{
option.text = value;
select.add(option,select.option);
select.selectedIndex = select.options.length - 1;
}
}
}
If your HTML is like:
<div>
<input type = "text" name = "docsref" id = "docsref" style = "width:100px;"/>
<input type = "button" name = "addValues" id = "addValues" value = "AddValues" onClick = "refadd();"/>
</br>
<select id = "docsref_list">
<option value = "1">1</option>
<option value = "2">2</option>
</select>
</div>
Hope that helps
using jQuery...
function refadd() {
var val = $("#docsref").val();
if (val != "") {
for(var i = 0; i < select.length; i++)
{
if(select[i].value == value)
{
alert("can't add.");
return false;
}
}
var ob = new Option("option text", "value");
$(ob).html("option text");
$("#selectList").append(ob);
}
}