How to get option value of only the selected checkboxes? - javascript

I want to get option value of only selected checkbox, but I am getting value from all the checkboxes.
My HTML code:
<div class= "outer">
<div class="inner" id="inner">
<input type="checkbox" name="machine" value="plane">BBQ Sauce<br>
<select class="weight" name="m2" id="m2">
<option value="1">Light</option>
<option value="2">Normal</option>
<option value="3">Extra</option>
</select>
</div>
<div class="inner" id="inner">
<input type="checkbox" name="machine" value="plane"> Alfredo Sauce<br>
<select class="weight" name="m2" id="m2">
<option value="1">Light</option>
<option value="2">Normal</option>
<option value="3">Extra</option>
</select>
</div>
</div>
<input type="submit" value="Submit">
My JavaScript code:
function myAction(){
var vals = [];
var machine = document.getElementsByName('machine');
var m2 = document.getElementById('m2');
for(var i=0, n= machine.length; i<n; i++){
if(machine[i].checked){
vals.push(m2.value);
}
}
}

IDs must be unique.
Instead, you could use querySelectorAll() on the existing weight classes to grab only the select elements that follow a checked input (using the general sibling selector):
document.querySelectorAll('input:checked ~ .weight')
The select element values will be the same as their selected options' values.
Snippet
document.querySelector('input[type=submit]').addEventListener('click', myAction);
function myAction() {
var vals = [], //no need for new Array()
weights= document.querySelectorAll('input:checked ~ .weight');
for(var i = 0 ; i < weights.length ; i++) {
vals.push(weights[i].value);
}
console.log(vals);
}
<div class="outer">
<div class="inner" id="inner">
<input type="checkbox" name="machine" value="plane">I have a plane
<br>
<select class="weight" name="m2">
<option value="1">Light</option>
<option value="2">Normal</option>
<option value="3">Extra</option>
</select>
</div>
<div class="inner" id="inner">
<input type="checkbox" name="machine" value="plane">I have 2 planes
<br>
<select class="weight" name="m2">
<option value="1">Light</option>
<option value="2">Normal</option>
<option value="3">Extra</option>
</select>
</div>
</div>
<input type="submit" value="Submit">

You have m2 repeated twice in your code. HTML spec specifies undefined behavior when id is repeated (m2). Also your select box isn't a multi-select. You should just be able to get the value from the select box directly if that is the case.

You can use querySelector also on nested nodes,
so you could filter the div.inner blocks which have the input checked and then get the values from there:
function myAction() {
//var vals = new Array();
var inner = [].slice.call(document.querySelectorAll('.inner'));
var checked = inner.filter(function(x) {
var chk = x.querySelector('input');
if (chk.checked) return x;
})
var vals = checked.map(function(x){
var i = x.querySelector('select').value;
return i
});
}
BTW as Rick said your markup contain some errors so I would suggest to pass it through a validator_
for calling your function on click event of the input submit:
document.querySelector('input[type=submit').addEventListener('click', myAction)

Related

Get the value of select class options

I'm working on a test/quiz and I can't solve a problem.
I like to grab the selected value from a option and print it to the result p.
<div class="add">
<div class="add__container">
<select class="add__type">
<option value="0" id="a01" selected>No</option>
<option value="1" id="a02">Ocassionally</option>
<option value="2" id="a03">Yes</option>
</select>
</div>
</div>
<button class="btn" onclick="myValue()">Results</button>
<p id="result">... </p>
And here is my Javascript code where I'm stucked:
function myValue(){
var e = document.getElementById("s01");
var value = e.options[e.selectedIndex].value;
var text = e.options[e.selectedIndex].text;
document.getElementById('result').innerHTML = e;
};
try this code. I think this code work like you requirement.
function myValue(){
var select = document.getElementsByClassName("add__type")[0].value;
document.getElementById('result').innerHTML = select;
};
<div class="add">
<div class="add__container">
<select class="add__type">
<option value="0" id="a01" selected>No</option>
<option value="1" id="a02">Ocassionally</option>
<option value="2" id="a03">Yes</option>
</select>
</div>
</div>
<button class="btn" onclick="myValue()">Results</button>
<p id="result">... </p>
something more..
I think you want to put the actual text of the selected option in the innerHtml instead of the option DOM element:
document.getElementById('result').innerHTML = text;
Maybe you want this? I added the id "s01" on select.
<div class="add">
<div class="add__container">
<select id="s01" class="add__type">
<option value="0" id="a01" selected>No</option>
<option value="1" id="a02">Ocassionally</option>
<option value="2" id="a03">Yes</option>
</select>
</div>
</div>
<button class="btn" onclick="myValue()">Results</button>
<p id="result">... </p>
<script>
function myValue() {
var e = document.getElementById("s01");
var value = e.options[e.selectedIndex].value;
var text = e.options[e.selectedIndex].text;
document.getElementById('result').innerHTML = text;
};
</script>
// Unimportant stuff
const $ = document;
$.get = $.getElementById;
$.get('theOptions').addEventListener('change', function(event) {
// Get the value from the select-element
$.get('out').innerHTML = 'You selected ' + event.target.value; // Or $.get('theOptions').value
});
<select id="theOptions">
<option value="o1">Option 1</option>
<option value="o2">Option 2</option>
<option value="o3">Option 3</option>
</select>
<span id="out">Nothing selected</span>

Jquery multiple selector filter

I have a working example of code I need, but some improvement is required.
$("#filtroSolicitacoes").on("submit", function(){
$("#solicitacoes div").show();
var filter = "";
$(this).find("[data-form]").each(function(){
if( $(this).val() != "" ) filter += ("[" + $(this).attr("data-form") + "='" + $(this).val() + "']");
});
if(filter.length > 0) $("#solicitacoes div").not(filter).hide();
return false;
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="filtros">
<form id="filtroSolicitacoes" type="post" name="filtroSolicitacoes">
Protocolo: <input data-form="id" type="text" name="filtroProtocolo" id="filtroProtocolo" size="5"/>
Solicitante: <input data-form="title" type="text" name="filtroSolicitante" id="filtroSolicitante" size="10"/>
Status:
<select data-form="status" name="filtroStatus" id="filtroStatus">
<option value="">-- Selecione Status--</option>
<option value="3">Aguardando Aprovação</option>
<option value="18">Encaminhado</option>
<option value="2">Iniciado</option>
<option value="1">Não Iniciado</option>
<option value="4">Pendente de Esclarecimento</option>
<option value="16">Reiniciado</option>
<option value="6">Reprovado</option>
</select>
Analista:
<select data-form="analista" name="filtroAnalista" id="filtroAnalista">
<option value="">-- Selecione Analista--</option>
<option value="23">Robert</option>
<option value="46">Allan</option>
<option value="49">Edward</option>
<option value="32">Jake</option>
<option value="14">Stella</option>
</select>
<button type="submit" id="filtrar" style="float:right; margin-right:10px">:: Filtrar ::</button>
</form>
</div>
<div id="solicitacoes">
<div id='1' title='Mike' status='18' analista='23'>Whatever content 1</div>
<div id='2' title='John' status='16' analista='46'>Whatever content 2</div>
<div id='3' title='Tom' status='2' analista='49'>Whatever content 3</div>
<div id='4' title='Mike' status='4' analista='23'>Whatever content 4</div>
<div id='5' title='Kate' status='3' analista='32'>Whatever content 5</div>
<div id='6' title='Steve' status='1' analista='14'>Whatever content 6</div>
</div>
Filterable items have single property:
<div id='6' title='Steve' status='1' analista='14'>Whatever content 6</div>
here status='1' attribute can have only one value (1 in this case). I need to be able add multiple values in one attribute, like so:
<div id='6' title='Steve' status='1 2' analista='14 15'>Whatever content 6</div>
And items with corresponding values must be shown up after filtration.
Unfortunately my knowledge doesn't admit me made that improvement, your help is highly appreciated.
Thank you!
Your main problem lies in how you are constructing your filter:
if( $(this).val() != "" )
filter += ("[" + $(this).attr("data-form") + "='" + $(this).val() + "']");
This means that you can only select a attribute that exacty matches the value, so if you have space separated values in your attributes, e.g. analista='14 15', the filter [analista='14'] or [analista='15'] will never match. Of course, one may find the easy way out of using the *= comparator, but that is very unreliable because that means [analista*='14'] will match any elements that contain analista="14 15" and also analista="140000" for example.
The fix I am proposing is going to slightly rewrite your filtering logic, so do stick with me step-by-step:
Remember to use data- attributes for non-standard attributes, i.e. you can keep id and title, but use data-status and data-analista instead of status and analista respectively.
In your JS, we can cache the $("#solicitacoes").find("div") collection for performance.
Instead of creating a concatenated string of filter, we simply create an empty object. It will serve as a dictionary with contains the attribute stored as the key, and the input field values as the values.
When that dictionary is created, we use the for (var x in ...) syntax to iterate through all keys in your dictionary.
In each iteration, we will have access to the attribute that we want to filter and the value we are interested in. That is your entry of the dictionary.
With this in hand, you can iterate through the cached collection of $("#solicitacoes").find("div"). We want to access the value of the attribute of interest, and then split/explode the string by the space character, so data-analista="14 15" for example will be converted into an array of [14, 15].
Check if the array contains the value in the dictionary entry
See proof-of-concept below: I have added additional space-separated values to the first <div> to illustrate the example.
$("#filtroSolicitacoes").on("submit", function() {
// Cache collection
var $divsToFilter = $("#solicitacoes").find("div");
$divsToFilter.show();
var dictionary = {};
$(this).find("[data-form]").each(function() {
if (this.value)
dictionary[$(this).attr('data-form')] = this.value;
});
// Loop through the dictionary to access individual entries
for (var key in dictionary) {
// We have the key, use it to get the value
var value = dictionary[key];
// Filter the divs
$divsToFilter.filter(function() {
// Explode/split all space-separate values stored in attribute into an array
var dataValues = $(this).attr(key);
// Check if our dictioanry entry's value matches any in the array
// If it is missing, we want to keep it in the filter so that we can hide it
return dataValues.indexOf(value) === -1;
}).hide();
}
return false;
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="filtros">
<form id="filtroSolicitacoes" type="post" name="filtroSolicitacoes">
Protocolo: <input data-form="id" type="text" name="filtroProtocolo" id="filtroProtocolo" size="5" /> Solicitante: <input data-form="title" type="text" name="filtroSolicitante" id="filtroSolicitante" size="10" /> Status:
<select data-form="data-status" name="filtroStatus" id="filtroStatus">
<option value="">-- Selecione Status--</option>
<option value="3">Aguardando Aprovação</option>
<option value="18">Encaminhado</option>
<option value="2">Iniciado</option>
<option value="1">Não Iniciado</option>
<option value="4">Pendente de Esclarecimento</option>
<option value="16">Reiniciado</option>
<option value="6">Reprovado</option>
</select>
Analista:
<select data-form="data-analista" name="filtroAnalista" id="filtroAnalista">
<option value="">-- Selecione Analista--</option>
<option value="23">Robert</option>
<option value="46">Allan</option>
<option value="49">Edward</option>
<option value="32">Jake</option>
<option value="14">Stella</option>
</select>
<button type="submit" id="filtrar" style="float:right; margin-right:10px">:: Filtrar ::</button>
</form>
</div>
<div id="solicitacoes">
<div id='1' title='Mike' data-status='18 16 2' data-analista='23 46 49'>Whatever content 1</div>
<div id='2' title='John' data-status='16' data-analista='46'>Whatever content 2</div>
<div id='3' title='Tom' data-status='2' data-analista='49'>Whatever content 3</div>
<div id='4' title='Mike' data-status='4' data-analista='23'>Whatever content 4</div>
<div id='5' title='Kate' data-status='3' data-analista='32'>Whatever content 5</div>
<div id='6' title='Steve' data-status='1' data-analista='14'>Whatever content 6</div>
</div>
Bonus if you're using ES6: everything can be made slightly simpler. This is when you realise you don't actually need jQuery all the time ;)
document.getElementById('filtroSolicitacoes').addEventListener('submit', e => {
e.preventDefault();
const divsToFilter = document.querySelectorAll('#solicitacoes div');
const userFilters = e.target.querySelectorAll('[data-form]');
Array.from(divsToFilter).forEach(element => element.style.display = 'block');
const dictionary = {};
Array.from(userFilters).forEach(input => {
if (input.value)
dictionary[input.dataset.form] = input.value;
});
for (let key in dictionary) {
const value = dictionary[key];
Array.from(divsToFilter).forEach(element => {
var dataValues = element.getAttribute(key);
if (!dataValues.includes(value))
element.style.display = 'none';
});
}
});
<div id="filtros">
<form id="filtroSolicitacoes" type="post" name="filtroSolicitacoes">
Protocolo: <input data-form="id" type="text" name="filtroProtocolo" id="filtroProtocolo" size="5" /> Solicitante: <input data-form="title" type="text" name="filtroSolicitante" id="filtroSolicitante" size="10" /> Status:
<select data-form="data-status" name="filtroStatus" id="filtroStatus">
<option value="">-- Selecione Status--</option>
<option value="3">Aguardando Aprovação</option>
<option value="18">Encaminhado</option>
<option value="2">Iniciado</option>
<option value="1">Não Iniciado</option>
<option value="4">Pendente de Esclarecimento</option>
<option value="16">Reiniciado</option>
<option value="6">Reprovado</option>
</select>
Analista:
<select data-form="data-analista" name="filtroAnalista" id="filtroAnalista">
<option value="">-- Selecione Analista--</option>
<option value="23">Robert</option>
<option value="46">Allan</option>
<option value="49">Edward</option>
<option value="32">Jake</option>
<option value="14">Stella</option>
</select>
<button type="submit" id="filtrar" style="float:right; margin-right:10px">:: Filtrar ::</button>
</form>
</div>
<div id="solicitacoes">
<div id='1' title='Mike' data-status='18 16 2' data-analista='23 46 49'>Whatever content 1</div>
<div id='2' title='John' data-status='16' data-analista='46'>Whatever content 2</div>
<div id='3' title='Tom' data-status='2' data-analista='49'>Whatever content 3</div>
<div id='4' title='Mike' data-status='4' data-analista='23'>Whatever content 4</div>
<div id='5' title='Kate' data-status='3' data-analista='32'>Whatever content 5</div>
<div id='6' title='Steve' data-status='1' data-analista='14'>Whatever content 6</div>
</div>

How to get all options of a select using jQuery on its class, not ID?

I learned from the famous example how to do this using the ID and I like this solution most of all:
var options = $('#selectBox option');
var values = $.map(options ,function(option) {
return option.value;
});
I have many repeating blocks in a separate containers like this:
<div class="section">
<label><input type="checkbox" name="A" value="2" class="factor-checkbox">A</label>
<select class='helperBox' id='helperBox' >
<option val='AB'>AB</option>
<option val='BCD'>BCD</option>
<option val='C'>C</option>
<option val='AD'>AD</option>
</select>
<label>Result <input type="text" value="10" class="result" ></label>
</div>
<div class="section">
<label><input type="checkbox" name="A" value="2" class="factor-checkbox">A</label>
<select class='helperBox'>
<option val='B'>B</option>
<option val='BD'>BD</option>
<option val='AC'>AC</option>
<option val='C'>C</option>
</select>
<label>Result <input type="text" value="20" class="result" ></label>
</div>
and the following function works:
function loadCombos($section) {
var $section = $(this).closest(".section");
//var $combos = $section.find('.helperBox');
var options = $('#helperBox option');
var combos = $.map(options,function(option) {
return option.value;
});
console.log(combos);
return combos;
}
but only for one helperBox, obviously. How to make it work for many in each section. so that combos arrays are different in different sections ?
You can use the scope for it like (based on assumption that this inside loadCombos here refers to a button inside section div):
function loadCombos() {
var $section = $(this).closest(".section");
var $combos = $section.find('.helperBox'); //<-- only select in this section
var options = $combos.find('option'); //<-- only options of current select
var combos = $.map(options, function(option) {
return option.value;
});
console.log(combos);
return combos;
}
IDs are meant to be unique in CSS.
You either change the ID to classes or have separate IDs and have a common classname.
<div id="helperbox1" class="helperbox"></div>
<div id="helperbox2" class="helperbox"></div>
or use two classes like
<div class="helperbox b1"></div>

Get ID of all child elements and its input/select data

How can I get the id of each child element and its tag name so I can save the data of each column to a string?
<div class="row">
<div class="col-md-4">
<input id="poz-3" placeholder="numv" type="text">
</div>
<div class="col-md-4">
<input id="poz-3" placeholder="numv" type="text">
</div>
<div class="col-md-4">
<select id="poz-3-s">
<option value="1">-Pick-</option>
<option value="2">test2</option>
<option value="3">test3</option>
</select>
</div>
</div>
I've got the loop so far, but I don't know how to get the data depending on the input/select:
for (var j = 0; j < (nCols / nRows); j++) {
}
You could use .find('*') to get all the childs :
$('.row').find('*').each(function(){
//Get the id and value
})
Hope this helps.
$('.row').find('*').each(function(){
if($(this).prop('tagName')!='OPTION')
console.log("id = "+$(this).prop('id')+" / value = "+$(this).val());
else
console.log("id = "+$(this).prop('id')+" / value = "+$(this).text());
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="row">
<div class="col-md-4">
<input id="poz-3" placeholder="numv" type="text" value='first input'>
</div>
<div class="col-md-4">
<input id="poz-3" placeholder="numv" type="text" value='second input'>
</div>
<div class="col-md-4">
<select id="poz-3-s">
<option value="1">-Pick-</option>
<option value="2" selected>test2</option>
<option value="3">test3</option>
</select>
</div>
</div>
If I understood you correctly you can get all input's values simply by iterating through them with jQuery:
$.each($('.col input, .col select'), function(index, item) {
console.log('ELEMENT ID ' + $(item).attr('id') + ' VAL - ' + $(item).val());
});
of simply use serializeArray method like this:
$('input, select').serializeArray()
Working example of both ways here: https://jsfiddle.net/hc882g27/
P.S.: in pure javascript it could be done with querySelectorAll function:
var items = document.querySelectorAll('.col input, .col select');
for (var i = 0; i < items.length; i++) {
console.log(items[i].value);
}

How do I have my drop down selections submit in the HTML form?

I have these conditional drop lists behaving on screen as expected, but I cannot get the selected values from the drop downs to output in the HTML form (I can if I don't include the javascript). Only the text inputs are outputing as per the xml result below (Company & Add1). I want the xml to contain the Location from the first drop down, and the selected city from the conditional 2nd drop down.
<body>
<form action="http://TESTPLANETPRESS:8080/ObtainQuote" method="GET" >
<fieldset>
<legend>Location</legend>
<select id="country" class="source" onchange="updateSelectTarget()">
<option value="England">England</option>
<option value="France">France</option>
<option value="Germany">Germany</option>
</select>
<select id="England">
<option value="Birmingham">Birmingham</option>
<option value="Liverpool">Liverpool</option>
<option value="London">London</option>
</select>
<select id="France" class="hidden">
<option value="Lyon">Lyon</option>
<option value="Marseille">Marseille</option>
<option value="Paris">Paris</option>
</select>
<select id="Germany" class="hidden">
<option value="Berlin">Berlin</option>
<option value="Hamburg">Hamburg</option>
<option value="Munich">Munich</option>
</select>
<label for="Company">Company:</label><input type="text" name="Company" value="Google">
<label for="Add1">Add1:</label><input type="text" name="Add1" value="1 Nowhere Street">
</fieldset>
<input type="submit" value="Submit">
</form>
<script>
function updateSelectTarget () {
var id = this.options[this.selectedIndex].value;
var targets = this.parentNode.getElementsByTagName("select");
var len = targets.length;
for (var i = len - 1; i > 0; --i) {
if (targets[i].id == id) {
targets[i].style.display = "block";
}
else {
targets[i].style.display = "none";
}
}
}
function initChangeHandler () {
var el = document.getElementById("country");
el.onchange = updateSelectTarget;
el.onchange();
}
window.onload = initChangeHandler;
</script>
</body>
Current XML result, (Does not include the results from the two drop downs).
<?xml version="1.0"?>
-<request type="GET">
<paths count="0"/>
-<values count="2">
<Company>Google</Company>
<Add1>1 Nowhere Street</Add1>
</values>
Do you want the value attribute or the text? Based on Get selected value in dropdown list using JavaScript? (similar to the first part), .value should work for the value attribute and .text for the text that is selected.
Also, please make two different questions instead of one question with 2 questions nested inside.

Categories

Resources