wrong html output from the javascript - javascript

I wrote a script for populating a selectbox with a bunch of options.
Initially the data is in the form of string of a format "key=value;key2=value2;etc...":
//split the string to distinguish between different options to populate a selectbox with
var values = data.split(';');
//reset the length of the selectbox to be populated
document.getElementById(child).options.length = 0;
//create first default option
document.getElementById(child).options[0] = new Option('all', '0');
for(var i = 0; i < values.length; i++){
//check for and remove unnecessary characters
values[i].replace(/\s+/g, '');
//split the option to get the key and value separately
var options = values[i].split('=');
if(!isEmpty(options[0]) && !isEmpty(options[1])){
//insert a new element to the selectbox
document.getElementById(child).options[i+1] = new Option(options[1], options[0]);
}
}
The example above populates a selectbox with the given html output:
<option value="0">all</option>
<option value="
7">Bermuda</option>
<option value="10">British Virgin Islands</option>
<option value="15">Cayman Islands</option>
<option value="42">Jamaica</option>
<option value="74">St. Lucia</option>
<option value="79">Trinidad Tobago</option>
As you can notice above the second option in the selectbox has a corrupted string value. I need to fix that value because because of that cake cannot save this value properly.
If you have any other questions please ask.

You should try to trim values:
document.getElementById(child).options[i+1] = new Option(
options[1].replace(/^\s+|\s+$/g, ''),
options[0].replace(/^\s+|\s+$/g, '')
);
or if you are using jquery:
document.getElementById(child).options[i+1] = new Option(
$.trim(options[1]),
$.trim(options[0])
);
also you should look close on this fragment:
values[i].replace(/\s+/g, '');
because probably it doesn't do what you want. First, it removes all whitespaces from string so "New York City" will become "NewYorkCity". Next thing is that replace method returns new string so your code will take no effect. It should be:
values[i] = values[i].replace(/\s+/g, '');

Related

Find string length from select form field with multiple values with javascript

I have tried several methods only to discover that the usual str.length code is not reading the entire form field contents
Html:
<select id="states1" name="states[]" multiple="multiple">
<option value="AL">AL</option>
<option value="AK">AK</option>
<option value="CA">CA</option>
</option>
No matter how many states I select, the javascript only reads the first state selected. For example, if I have selected all 3 states, the only validation checks that work are found below:
<script>
var slen = document.forms[0].elements['states1'];
function invoice_() {
if(slen.value == "AL"){
alert('true');
return false;
} }
</script>
And to check the length
<script>
var slen = document.forms[0].elements['states1'];
function invoice_() {
if(slen.value.length == 2){
alert('true');
return false;
} }
</script>
In other words, even if the actual length of the form field contents is 6, the only way I have found to check the string length in javascript only returns 2, in my example, because it only reads the first selected state but not the others
I have tried
slen.value.options.length
slen.options.length
To get the right number, but those methods don't work.
How do I get the code to read the entire form field contents to count the length when it is a select multiple option field with multiple options selected?
You can use the .selectedOptions property to get the selected options in the multiple select. Then convert it to an Array, and do a .map().reduce() to total up the values.
var totalLen = Array.from(document.forms[0].states1.selectedOptions)
.map(v => v.value.length)
.reduce((sum, n) => sum + n, 0);
console.log(totalLen);
<form>
<select id="states1" name="states[]" multiple="multiple">
<option value="AL" selected>AL</option>
<option value="AK">AK</option>
<option value="CA" selected>CA</option>
</select>
</form>
If you wanted all the options instead of just the selected ones, then use the .options property instead.
var totalLen = Array.from(document.forms[0].states1.options)
.map(v => v.value.length)
.reduce((sum, n) => sum + n, 0);
console.log(totalLen);
<form>
<select id="states1" name="states[]" multiple="multiple">
<option value="AL" selected>AL</option>
<option value="AK">AK</option>
<option value="CA" selected>CA</option>
</select>
</form>
This was the best solution for someone who might need it:
let uvs = document.forms[0].elements['states1'];
function invoice_() {
var result = [];
var options = uvs && uvs.options;
var opt;
for (var i=0, iLen=options.length; i<iLen; i++) {
opt = options[i];
if (opt.selected) {
result.push(opt.value || opt.text);
}
}
var nst = (result.push(opt.value || opt.text)) - 1;
if(nst > 3){
alert('');
return false;
}
For some reason the raw count of 'result.push(opt.value || opt.text' is +1, so I just added a little math to make the count accurate. I was initially looking to count the number of characters, but finding the number of states selected was even better. Instead of a result of 10 for 5 states I get 5 for 5 states.
The other character count code above was too unstable. Might be a browser issue, hard to say.

Use URL Parameter to Preselect Option by Label not Value

How can I pass the label, not the option, to have javascript preselect from a dropdown?
For example, let's say the URL is page.html?option=name3
and in the form there's a select like this
<select id="select-box">
<option value="1">Name1</option>
<option value="2">Name2</option>
<option value="3">Name3</option>
<option value="4">Name4</option>
</select>
In this example Name3 and 3 are different.
What javascript could be used to preselect the option whose text contents match that of the URL parameter above?
Read the query param from the current page's URL: https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams
const optionParam = new URLSearchParams(window.location.search).get('option'); // "Name3"
and than set the Select value to the option which textContent matches
// const optionParam = new URLSearchParams(window.location.search).get('option');
const optionParam = "Name3"; // (PS: Use the above one instead, this is for demo)
const sel = document.getElementById("select-box");
const opt = [...sel.options].find(op => op.textContent===optionParam);
if (opt) sel.value = opt.value;
<select id="select-box">
<option value="1">Name1</option>
<option value="2">Name2</option>
<option value="3">Name3</option>
<option value="4">Name4</option>
</select>
You need to set the selectedIndex of your element using javascript as follows. First, parse the url to get the desired query option. You can use window.location API to get the url and do your operations on it. Then, iterate through each option of your select element and determine a good match using some logic.
I hope this helps.
<select id="select-box">
<option value="1">Name1</option>
<option value="2">Name2</option>
<option value="3">Name3</option>
<option value="4">Name4</option>
</select>
<script>
// to get option we use some parsing:
function getOption(url) {
var queryString = url ? url.split('?')[1] : window.location.search.slice(1);
if (queryString){
var optionString = queryString.split('=')[1];
// returns string for options if specified.
return optionString;
}
// return null otherwise.
return null;
}
var e = document.getElementById("select-box");
// var o = getOption(window.location.href);
// var o = getOption(document.url) // does not work for Firefox
// replace this with one of the lines above for dynamic solution
var o = getOption('page.html?option=name3');
if(o) {
for(var i=0; i<e.options.length; i++) {
if(o === e.options[i].innerHTML.toLowerCase()){
// be careful about case sensitivity and try to come up
// with your own logic on how you validate this,
document.getElementById("select-box").selectedIndex = i;
}
}
}else {
// if no option default to 0
document.getElementById("select-box").selectedIndex = 0;
}
</script>

two html select conflict

I have two html select element that the second one is disabled at first and only become enable if user choose one option from first select. consider we have 2 options in first select -> a , b if user choose a : in the second select options should be : a1,a2 if user choose b : in the second select options should be : b1,b2 ... I dont know what am i doing wrong that these two select options have conflict with each other !!!
<select id="main-category" required>
<option disabled selected> choose one option </option>
<option value="a"> a </option>
<option value="b"> b </option>
</select>
<select id="sub-category" required disabled> </select>
<!-- empty select -->
<script>
document.getElementById("main-category").onchange = function() {
document.getElementById('sub-category').disabled = false;
var opt0 = document.createElement('option');
var opt1 = document.createElement('option');
if (this.value == 'a') {
//first remove all previous options then add new ones
if (document.getElementById('sub-category').getElementsByTagName('option')[0]) {//check if there is a option then remove it
var opt = document.getElementById('sub-category').getElementsByTagName('option')[0];
document.getElementById('sub-category').removeChild(opt);
}
if (document.getElementById('sub-category').getElementsByTagName('option')[1]) {//check if there is a option then remove it
var opt = document.getElementById('sub-category').getElementsByTagName('option')[1];
document.getElementById('sub-category').removeChild(opt);
}
opt0.value = "a1";
opt0.innerHTML = "a1";
opt1.value = "a2";
opt1.innerHTML = "a2";
document.getElementById('sub-category').appendChild(opt0);
document.getElementById('sub-category').appendChild(opt1);
} else if (this.value == 'b') {
//first remove all previous options then add new ones
if (document.getElementById('sub-category').getElementsByTagName('option')[0]) { //check if there is a option then remove it
var opt = document.getElementById('sub-category').getElementsByTagName('option')[0];
document.getElementById('sub-category').removeChild(opt);
}
if (document.getElementById('sub-category').getElementsByTagName('option')[1]) {//check if there is a option then remove it
var opt = document.getElementById('sub-category').getElementsByTagName('option')[1];
document.getElementById('sub-category').removeChild(opt);
}
opt0.value = "b1";
opt0.innerHTML = "b1";
opt1.value = "b2";
opt1.innerHTML = "b2";
document.getElementById('sub-category').appendChild(opt0);
document.getElementById('sub-category').appendChild(opt1);
}
};
</script>
All you need to do is clear out the previous entries in the second drop down every time a selection is made in the first one.
<select id="main-category" required>
<option disabled selected> choose one option </option>
<option value="a"> a </option>
<option value="b"> b </option>
</select>
<select id="sub-category" required disabled> </select>
<!-- empty select -->
<script>
document.getElementById("main-category").onchange = function() {
// Clear out the second list before adding new items to it
document.getElementById('sub-category').innerHTML = "";
// *******************************************************
document.getElementById('sub-category').disabled = false;
var opt0 = document.createElement('option');
var opt1 = document.createElement('option');
if (this.value == 'a') {
//first remove all previous options then add new ones
if (document.getElementById('sub-category').getElementsByTagName('option')[0]) {//check if there is a option then remove it
var opt = document.getElementById('sub-category').getElementsByTagName('option')[0];
document.getElementById('sub-category').removeChild(opt);
}
if (document.getElementById('sub-category').getElementsByTagName('option')[1]) {//check if there is a option then remove it
var opt = document.getElementById('sub-category').getElementsByTagName('option')[1];
document.getElementById('sub-category').removeChild(opt);
}
opt0.value = "a1";
opt0.innerHTML = "a1";
opt1.value = "a2";
opt1.innerHTML = "a2";
document.getElementById('sub-category').appendChild(opt0);
document.getElementById('sub-category').appendChild(opt1);
} else if (this.value == 'b') {
//first remove all previous options then add new ones
if (document.getElementById('sub-category').getElementsByTagName('option')[0]) { //check if there is a option then remove it
var opt = document.getElementById('sub-category').getElementsByTagName('option')[0];
document.getElementById('sub-category').removeChild(opt);
}
if (document.getElementById('sub-category').getElementsByTagName('option')[1]) {//check if there is a option then remove it
var opt = document.getElementById('sub-category').getElementsByTagName('option')[1];
document.getElementById('sub-category').removeChild(opt);
}
opt0.value = "b1";
opt0.innerHTML = "b1";
opt1.value = "b2";
opt1.innerHTML = "b2";
document.getElementById('sub-category').appendChild(opt0);
document.getElementById('sub-category').appendChild(opt1);
}
};
</script>
But, beyond that, your code needs to be cleaned up quite a bit because you shouldn't be scanning the document for the element you want to work with over and over again when you've already found it before. That's extremely wasteful.
Also, .innerHTML is for passing strings that contain HTML so that the HTML parser can parse the string and update the DOM accordingly. You are just setting plain strings with no HTML in them, so you should be using .textContent instead, which doesn't invoke the HTML parser and is more efficient.
Next (just FYI), if you want the value of an option to be the same as the text that is displayed to the user, you don't need to set a value for that option. The value is the contents of the option element by default.
Really, the entire operation can be made so much simpler by simply making new options in list2 based on the first letter of the option chosen in list1.
// Get references to the elements you'll be working with just once:
var list1 = document.getElementById("main-category");
var list2 = document.getElementById('sub-category');
list1.onchange = function() {
list2.disabled = false;
var newHTML = ""; // A string that will contain the new HTML for the second list
// Loop the amount of times we find <option> elements in list one, but start
// at the second one to account for the first one, which isn't really a true choice
for(var i = 1; i < list1.querySelectorAll("option").length; i++){
// Build up a string that the new option should be made from using the
// first character from the option found in list 1
newHTML += '<option>' + list1.value.substr(0,1) + i + '</option>';
}
// By setting a new value for .innerHTML, the old values get thrown out.
list2.innerHTML = newHTML;
};
<select id="main-category" required>
<option disabled selected> choose one option </option>
<option>a</option>
<option>b</option>
</select>
<select id="sub-category" required disabled> </select>

delete duplicate element in selected option

I have Two selected option: the first is contact and the second is contact2. the element in the first select option will be added to the second list.
the function bellow let me to add all element without problems, but I want to add just the element with unique id, because the first list contain many duplicate option id.
function addAllElement(object){
contacts = document.getElementById('contact');
long = object.options.length;
for (i=0;i<long;i++){
txt = object.options[i].text;
valor = object.options[i].value;
idd=object.options[i].id;
addOption(contact2,i,idd,txt,valor);
}
}
this is an example of the list with duplicate id
<select name="contacts" id="contacts" multiple="">
<option value="7147582,2" id="77">Test</option>
<option value="7189466,2" id="62">test2</option>
<option value="7" id="62">contact3</option>
<option value="72" id="64">ERRZERZE, zerzerze</option>
<option value="71" id="62">contact 5</option>
<option value="72y" id="001">contact 6</option>
</select>
As you see many element with the same id, and the predicted result is a list without duplicate element
I would create an array that stores each id per iteration. If the id has already been created, then do not add that to the second select. Redo your function in this manner:
function addAllElement(object) {
var i, valor, idd, txt;
var long = object.options.length;
var ids = [];
for (i = 0; i < long; i++) {
txt = object.options[i].text;
valor = object.options[i].value;
idd = object.options[i].id;
if (ids.indexOf(idd) == -1) {
addOption("contact2", i, idd, txt, valor);
ids.push(idd);
}
}
}
You can check for the length of element with that id before calling addOption method:
for (i=0;i<long;i++){
txt = object.options[i].text;
valor = object.options[i].value;
idd=object.options[i].id;
if(document.getElementById(idd).length)
addOption(contact2,i,idd,txt,valor);
}

Javascript/jQuery: Set Values (Selection) in a multiple Select

I have a multiple select:
<select name='strings' id="strings" multiple style="width:100px;">
<option value="Test">Test</option>
<option value="Prof">Prof</option>
<option value="Live">Live</option>
<option value="Off">Off</option>
<option value="On">On</option>
</select>
I load data from my database. Then I have a string like this:
var values="Test,Prof,Off";
How can I set this Values in the multiple select? Already tried change the string in an array and put it as value in the multiple, but doesnt work...!
Can someone help me with this? THANKS!!!
Iterate through the loop using the value in a dynamic selector that utilizes the attribute selector.
var values="Test,Prof,Off";
$.each(values.split(","), function(i,e){
$("#strings option[value='" + e + "']").prop("selected", true);
});
Working Example http://jsfiddle.net/McddQ/1/
in jQuery:
$("#strings").val(["Test", "Prof", "Off"]);
or in pure JavaScript:
var element = document.getElementById('strings');
var values = ["Test", "Prof", "Off"];
for (var i = 0; i < element.options.length; i++) {
element.options[i].selected = values.indexOf(element.options[i].value) >= 0;
}
jQuery does significant abstraction here.
Just provide the jQuery val function with an array of values:
var values = "Test,Prof,Off";
$('#strings').val(values.split(','));
And to get the selected values in the same format:
values = $('#strings').val();
Pure JavaScript ES6 solution
Catch every option with a querySelectorAll function and split the values string.
Use Array#forEach to iterate over every element from the values array.
Use Array#find to find the option matching given value.
Set it's selected attribute to true.
Note: Array#from transforms an array-like object into an array and then you are able to use Array.prototype functions on it, like find or map.
var values = "Test,Prof,Off",
options = Array.from(document.querySelectorAll('#strings option'));
values.split(',').forEach(function(v) {
options.find(c => c.value == v).selected = true;
});
<select name='strings' id="strings" multiple style="width:100px;">
<option value="Test">Test</option>
<option value="Prof">Prof</option>
<option value="Live">Live</option>
<option value="Off">Off</option>
<option value="On">On</option>
</select>
var groups = ["Test", "Prof","Off"];
$('#fruits option').filter(function() {
return groups.indexOf($(this).text()) > -1; //Options text exists in array
}).prop('selected', true); //Set selected
Basically do a values.split(',') and then loop through the resulting array and set the Select.
Pure JavaScript ES5 solution
For some reason you don't use jQuery nor ES6? This might help you:
var values = "Test,Prof,Off";
var splitValues = values.split(',');
var multi = document.getElementById('strings');
multi.value = null; // Reset pre-selected options (just in case)
var multiLen = multi.options.length;
for (var i = 0; i < multiLen; i++) {
if (splitValues.indexOf(multi.options[i].value) >= 0) {
multi.options[i].selected = true;
}
}
<select name='strings' id="strings" multiple style="width:100px;">
<option value="Test">Test</option>
<option value="Prof">Prof</option>
<option value="Live">Live</option>
<option value="Off">Off</option>
<option value="On" selected>On</option>
</select>
Use this:
$('#demo').multiselect('select', value);
For multiple values just use a loop
For more properties this page is very good
this is error in some answers for replace |
var mystring = "this|is|a|test";
mystring = mystring.replace(/|/g, "");
alert(mystring);
this correction is correct but the | In the end it should look like this \|
var mystring = "this|is|a|test";
mystring = mystring.replace(/\|/g, "");
alert(mystring);

Categories

Resources