filter select by option value jquery - javascript

Im trying to trigger options for a select from another select.
Now I want to check if my options contains the exact value of ex "5" and not also choose "15" and "25" as it does today, because both 15 (1->5<-) and 25 (2->5<--) contains 5 aswell..
console.log(height); // e.g 5, 10, 15, 25, 30
if($('#pa_height').children('option').filter(':contains("'+height+'")')) {
var option = height + 'cm-' + (typeof closestPrice[1] !== 'undefined' ? closestPrice[1] : closestPrice[0]) + 'kr';
console.log('option exists', option);
// some of my options gives me 1 here and other 0
console.log($('#pa_hojd').children('option[value="'+option+'"]').length);
.if($('#pa_height').children('option[value="'+option+'"]').length !== 0) {
$('#pa_height').children('option[value="'+option+'"]').attr('selected', 'selected').siblings().removeAttr('selected').trigger('change');
}
else {
$('#pa_height').children('option').filter(':contains("'+height+'")').last().attr('selected', 'selected').siblings().removeAttr('selected').trigger('change');
console.log('Highest price for this height is set, Price is: ', price);
}
} else {
console.log('Height is not set');
}
These options is custom variations in woocommerce that i've made to set the price of a product depending on how much text you write in a textarea.
Some of my options.length returns 0, even though I can see them in the select. It's like woocommerce don't understand that they are options.
Does anyone know something that can help me? :)
Here is a screenshot
this is the HTML for my variations-select
<select id="pa_height" class="" name="attribute_pa_hojd" data-attribute_name="attribute_pa_hojd">
<option value="">Välj ett alternativ</option>
<option value="5cm-79kr">5cm: 79kr</option>
<option value="5cm-99kr">5cm: 99kr</option>
<option value="5cm-199kr" selected="selected">5cm: 199kr</option>
<option value="5cm-299kr">5cm: 299kr</option>
<option value="5cm-399kr">5cm: 399kr</option>
<option value="5cm-499kr">5cm: 499kr</option>
<option value="10cm-149kr">10cm: 149kr</option>
<option value="10cm-199kr">10cm: 199kr</option>
<option value="10cm-299kr">10cm: 299kr</option>
<option value="10cm-399kr">10cm: 399kr</option>
<option value="10cm-499kr">10cm: 499kr</option>
<option value="10cm-99kr">10cm: 99kr</option>
<option value="15cm-129kr">15cm: 129kr</option>
<option value="15cm-149kr">15cm: 149kr</option>
<option value="15cm-249kr">15cm: 249kr</option>
<option value="15cm-349kr">15cm: 349kr</option>
<option value="15cm-449kr">15cm: 449kr</option>
<option value="15cm-599kr">15cm: 599kr</option>
<option value="20cm-150kr">20cm: 150kr</option>
<option value="20cm-200kr">20cm: 200kr</option>
<option value="20cm-250kr">20cm: 250kr</option>
<option value="20cm-350kr">20cm: 350kr</option>
<option value="25cm-450kr">25cm: 450kr</option>
<option value="25cm-550kr">25cm: 550kr</option>
<option value="25cm-700kr">25cm: 700kr</option>
<option value="25cm-900kr">25cm: 900kr</option>
<option value="30cm-1000kr">30cm: 1000kr</option>
<option value="30cm-150kr">30cm: 150kr</option>
<option value="30cm-200kr">30cm: 200kr</option>
<option value="30cm-250kr">30cm: 250kr</option>
<option value="30cm-350kr">30cm: 350kr</option>
<option value="30cm-550kr">30cm: 550kr</option>
<option value="30cm-750kr">30cm: 750kr</option>
<option value="30cm-850kr">30cm: 850kr</option>
</select>

You can rule out 15 / 25 / 35 etc by restricting your search to 1 character long strings. Then by looking for the number 5, you should get your expected results. E.g;
var options = document.getElementsByTagName('option');
for(var i = 0; i < options.length; i++){
var option_value = options[i].value;
var search_value 5;
if(options_value.length < 1){
// String length = 0(1). This rules out double or triple digit numbers
if(options_value.indexOf(search_value) > -1){
// Found the value 5
console.log('Success!');
}
}
}
Update
Now that I've seen your HTML (after your edit), the above probably won't work. You may be able to modify the method to check if '5' is the first character. If it is, check if it is followed by another number. If it is not, then you've found your number 5.
var options = document.getElementsByTagName('option');
for(var i = 0; i < options.length; i++){
var option_value = options[i].value();
var first_char = option_value.charAt(0);
if(first_char == 5){
// first char = 5, check second
var second_char = option_value.charAt(1);
if(isNaN(second_char)){
// value is not 5
}else{
// not a number, found 5
// do code
}
}
}

if($("#pa_height option[value='"+height+"']").length>0) {
//
}

Related

Remove the duplicate values and combinations in html select option

I have a dynamically generated <select> field with <option>.
<select>
<option value=""></option>
<option value=""></option>
<option value=""> False</option>
<option value=""> True</option>
<option value="">False False</option>
<option value="">False True</option>
<option value="">True</option>
<option value="">True True</option>
</select>
I would like to remove the duplicate occurrences and combinations. The final <select> field with <option> should look like :
<select>
<option value=""></option>
<option value="">False</option>
<option value="">True</option>
</select>
Here is how my fiddle looks like. Been trying to solve this for hours.
var values = [];
$("select").children().each(function() {
if (values.length > 0) {
var notExists = false;
for (var x = 0; x < values.length; x++) {
var _text = this.text.replace(/\s/g, "");
var value = values[x].replace(/\s/g, "");
if (values[x].length > _text.length) {
//console.log('>>+', value, ' || ', _text, value.indexOf(_text))
notExists = value.indexOf(_text) > -1 ? true : false;
} else {
//console.log('>>*', value, ' || ', _text, _text.indexOf(value))
notExists = _text.indexOf(value) > -1 ? true : false;
}
}
if (notExists) {
//this.remove();
values.push(this.text);
}
} else {
values.push(this.text);
}
});
Any help to solve this is appreciated.
You can use map() to return all options text and use split() on white-space. Then to remove duplicates you can use reduce() to return object. Then you can empty select and use Object.keys() to loop each property and append to select.
var opt = $("select option").map(function() {
return $(this).text().split(' ')
}).get();
opt = opt.reduce(function(o, e) {return o[e] = true, o}, {});
$('select').empty();
Object.keys(opt).forEach(function(key) {
$('select').append(' <option value="">'+key+'</option>');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select>
<option value=""></option>
<option value=""></option>
<option value="">False</option>
<option value="">True</option>
<option value="">False False</option>
<option value="">False True</option>
<option value="">True</option>
<option value="">True True</option>
</select>
You can loop through each of this children text , then use substring to get the first text & put it in an array.
Once done empty the select element and append the newly created options
var _textHolder=[]; // NA empty array to hold unique text
var _options="";
$("select").children().each(function(item,value) {
var _textVal = $(this).text().trim(); // Remove white space
//get the first text content
var _getText = _textVal.substr(0, _textVal.indexOf(" "));
// if this text is not present in array then push it
if(_textHolder.indexOf(_getText) ==-1){
_textHolder.push(_getText)
}
});
// Create new options with items from _textHolder
_textHolder.forEach(function(item){
_options+='<option value="">'+item+'</option>'
})
// Empty current select element and append new options
$('select').empty().append(_options);
JSFIDDLE
I would do with pure JS ES6 style. This is producing a words array from the whitespace separated options element's innerText value regardless the words are in the front, middle or the end; and it will create a unique options list from that. Basically we are concatenating these arrays and getting it unified by utilizing the new Set object. The code is as follows;
var opts = document.querySelector("select").children,
list = Array.prototype.reduce.call(opts, function(s,c){
text = c.innerText.trim().split(" ");
return new Set([...s].concat(text)) // adding multiple elements to a set
},new Set());
list = [...list]; // turn set to array
for (var i = opts.length-1; i >= 0; i--){ //reverse iteration not to effect indices when an element is deleted
i in list ? opts[i].innerText = list[i]
: opts[i].parentNode.removeChild(opts[i]);
}
<select>
<option value=""></option>
<option value=""></option>
<option value=""> False</option>
<option value=""> True</option>
<option value="">False False</option>
<option value="">False True</option>
<option value="">True</option>
<option value="">True True</option>
</select>

Javascript: dropdown, get first element value LIKE?

Given a dropdown with an unknown number of option elements:
<select id="ddlDropDown">
<option value="text1">Some text</option>
<option value="text2">Some text</option>
<option value="text3">Some text</option>
...
<option value="textN">Some text</option>
And given a textbox where I can type in a value:
<input type=text id="txtTextBox" onkeyup="selectDDL();"/>
And given the script function:
function selectDDL(){
var txtElem = document.getElementById("txtTextBox");
var ddlElem = document.getElementById("ddlDropDown");
var typedText = txtElem.value;
//magic happens here
}
How do I, using purely javascript, get select the first option matching LIKE the text in the text box without iterating through the entire collection?
That is to say, assume that I have 500 dropdown option elements with random values between 500 and 1500, how do I get and select the first option (in the list, not in order) that matches what the user has typed so far?
So if their were three items: 1030, 1012, and 1013 in the dropdown and the user types:
1: 1030 is selected.
10: 1030 is still selected
101: 1012 is selected
1013: 1013 is selected
Clarification: without iterating the collection and similar to jquery's ^= operator
You don't need jQuery to use ^=, just use querySelectorAll with the attribute prefix selector:
var texts = document.querySelectorAll("[value^='text']");
console.log(texts);
<script src="http://gh-canon.github.io/stack-snippet-console/console.min.js"></script>
<select id="ddlDropDown">
<option value="text1">Some text</option>
<option value="text2">Some text</option>
<option value="text3">Some text</option>
<option value="textN">Some text</option>
<option value="notText">123456</option>
</select>
You can use a starts with attribute selector. Only issue with the code is I am not escaping any of the special characters from the selector. So if the user enters in ' it will blow up.
document.querySelector("#x").addEventListener("keyup", function(){
//code to filter out the options
var txt = this.value;
var opts = document.querySelectorAll("#ddlDropDown option[value^='" + txt + "']");
//code to display the options for demo
var out = Array.prototype.slice.call( opts ).map(function (x) {return x.value});
document.querySelector("p").innerHTML = out.join("<br/>");
});
<select id="ddlDropDown">
<option value="text1">Some text</option>
<option value="text2">Some text</option>
<option value="text3">Some text</option>
<option value="text11">Some text</option>
<option value="text21">Some text</option>
<option value="text31">Some text</option>
</select>
<input type="textbox" id="x">
<p></p>
I would use the string#indexOf method to find out if there's a match.
function selectDDL() {
var txtElem = document.getElementById("txtTextBox");
var ddlElem = document.getElementById("ddlDropDown");
var typedText = txtElem.value;
var options = document.querySelectorAll("#ddlDropDown option");
var matches = [];
for (var i = 0; i < 3; i++) {
if (options[i].innerHTML.indexOf(typedText) == 0) {
matches.push(options[i]);
}
}
matches[0].setAttribute("selected", "selected");
}
Those who rely on a selector with [value^=...] will find an option by its value attribute, not by its text.
There is no CSS selector for selecting an option by its text. jQuery supports "has" and "contains", but uses iteration to implement those features.
Just for a fun alternative, but probably not advisable: innerHTML is slow and this will go wrong when the select tag has other tags inside than the options:
var html = ddlElem.innerHTML;
var idx = html.indexOf('>'+typedText);
ddlElem.selectedIndex = idx === -1
? -1
: html.substr(0, idx).match(/\<option/g).length - 1;

Dropdown 1 value automatically selects dropdown 2 value

I am trying to write a JavaScript function where if value 1 from the first dropdown(pcount) automatically selects value 1 for drop down 2(listedname), But then if anything besides value 1 (2,3,4) is chosen I do not want drop down 2 to do anything except default back to please select if value 1 was selected and then changed to another value. I am very new to JavaScript and programming in general and have not been able to find any examples similar to this. So any help will help!
JavaScript Funtion:
<script type="text/javascript">
function leaveChange() {
if (document.getElementById("pcount").value = 1){
document.getElementById("listedname").value = 1;
}else
document.getElementById("listedname").value = 2;
}
}
</script>
Dropdown 1 and 2:
<select id="pcount" onchange="leaveChange()">
<option value="" selected="selected">Please Select</option>
<option value="1">0</option>
<option value="2">1</option>
<option value="3">2</option>
<option value="4">3</option>
</select>
<select id="listedname">
<option value="" selected="selected">Please Select</option>
<option value="1">Business Name</option>
<option value="2">Individual Owner</option>
</select>
If you are doing your if clause with one equals sign, Javascript will check if your element is set to the new value successfully.
Instead, when you do a comparison, use double equal signs (in your case)
if (document.getElementById("pcount").value == 1){
If anyone is looking for the JavaScript function here you go!
<script type="text/javascript">
function leaveChange() {
if (document.getElementById("pcount").value == 1){
document.getElementById("listedname").value = 1;
}
else if (document.getElementById("pcount").value != 1){
document.getElementById("listedname").value = "";
}
}
</script>

Jquery - find the cost based on checking two arrays multiplied by a static number

My first post so I hope I do this right and sorry I am still learning so not sure if I even post this correctly. What I kinda sort of did was pseudo code code what I need but the execution is way off.
So my variables are books, program, and courses.
To find my book cost I need to check to see what group the program falls in (arrays) then multiply it by the number of courses that are being taken.
var programGroup1=["Arts", "Crafts", "Painting"];
var programGroup2=["Zumba", "Ballet", "Jazz"];
var programGroup3=["Math", "Science", "History"];
var books
if(programGroup1){
books = course * 10
}else if(programGroup2){
books = course * 20
}else if(programGroup3){
books = course * 30
}else{
end();
}
<select id="program" name="program" >
<option value="" selected="true">--</option>
<option value="Arts" >Arts</option>
<option value="Crafts" >Crafts</option>
<option value="Painting" >Painting</option>
<option value="Zumba" >Zumba</option>
<option value="Ballet" >Ballet</option>
<option value="Jazz" >Jazz</option>
<option value="Math" >Math</option>
<option value="Science" >Science</option>
<option value="History" >History</option>
</select>
<select id="course" name="course">
<option value="" selected="true">--</option>
<option value="5">5</option>
<option value="4">4</option>
</select>
So then if you took Arts and course 5 your books would be 10 * 5 and it would output $50, or if you took crafts and course 5 it would be 20 * 5 and would output $100.
Thanks for any help I am really trying to learn just need some help.
Something like this:
// If a select changes
$('select').change(function () {
var psel, csel, program, course, total;
// Get the values of both selectors
psel = $('#Program').find('option:selected').val();
csel = $('#course').find('option:selected').val();
// Assign the program var a value depending on the program type
if (psel.indexOf('Arts') > -1) { program = 10; }
if (psel.indexOf('Crafts') > -1) { program = 20; }
// Set the value of course to the value of the selected option
course = csel;
// Add them together
total = program * course;
// And only if they all exists (if both selections have been done), alert the total
if (program && course && total) {
alert('Total ' + total);
}
});
Working demo.
You are best off doing something like this:
For each program, set an action and value, like this: $('option[value="Arts"]').data({ action:'*', value: 10 });
When one of the selects changes, get the value and action, and apply them to the cost.
Sample HTML:
<select id="program" name="program" >
<option value="" selected="true">--</option>
<option value="Arts" >Arts</option>
<option value="Arts2" >Art2s</option>
<option value="Arts3" >Arts3</option>
<option value="Crafts" >Crafts</option>
<option value="Crafts2" >Crafts2</option>
<option value="Crafts3" >Crafts3</option>
</select>
<select id="course" name="course">
<option value="0" selected="true">--</option>
<option value="5">5</option>
<option value="4">4</option>
</select>
Sample JS using jQuery:
$(function() {
$('#program option[value=""]').data({ action:'*', value: 0 });
$('option[value="Arts"]').data({ action:'*', value: 10 });
$('option[value="Arts2"]').data({ action:'*', value: 20 });
$('option[value="Arts3"]').data({ action:'*', value: 30 });
console.log($('option[value=Arts]').data());
$('select').on('change', function() {
var cost = parseFloat($('#course').val());
var program = $('#program').val();
var program_obj = $('#program option[value="'+program+'"');
var action = program_obj.data('action');
var arts_val = parseFloat(program_obj.data('value'));
switch(action) {
case '*':
cost = cost * arts_val;
break;
case '/':
cost = cost / arts_val;
break;
case '+':
cost = cost + arts_val;
break;
case '-':
cost = cost - arts_val;
break;
}
alert(cost);
});
});
Here's a working fiddle

How can I remove options with the same text from a select element?

I have a select element that shows multiple options with the same text:
<select name="tur" id="tur">
<option value="1">a</option>
<option value="2">a</option>
<option value="3">a</option>
<option value="4">a</option>
<option value="5">b</option>
<option value="6">b</option>
<option value="7">c</option>
<option value="8">d</option>
</select>
Using JavaScript, I would like to remove these duplicates so that only one of each is shown:
<select name="tur" id="tur">
<option value="1">a</option>
<option value="5">b</option>
<option value="7">c</option>
<option value="8">d</option>
You can loop through the <option> elements, checking each one to see if its text content is in an array. If it is, remove the <option>. If not, add its content to the array. This will remove options that are redundant in the list.
Try it out: http://jsfiddle.net/FXq8W/
​var array = [];
​$('#tur option').each(function() {
var $th = $(this);
var text = $th.text();
if( $.inArray(text, array) > -1 ) {
$th.remove();
} else {
array.push( text );
}
});​​​​​​​​​​​​​​
http://api.jquery.com/jquery.inarray/
var remove = [], values = {}, value, i;
var options = document.getElementById('tur').getElementsByTagName('option');
for (i=0; i<options.length; i++) {
value = options[i].innerHTML.replace(/^\s*|\s*$/g, '');
if (value in values) remove.push(options[i]);
else values[value] = true;
}
for (i=0; i<remove.length; i++) {
remove[i].parentNode.removeChild(remove[i]);
}

Categories