Select child element from parent data attributes value - javascript

I have this kind of html blocks:
<div data-target="TargeID" data-action="toggle" data-trigger="Yes">
...
<ul>
<li>
<label class="radio">
<input id="cpMainContent_ctl24_rptAnswers_rbAnswer_0" type="radio" name="cpMainContent_ctl24" value="ctl00$cpMainContent$ctl24$rptAnswers$ctl01$rbAnswer">
Yes
</label>
</li>
<li>
<label class="radio">
<input id="cpMainContent_ctl24_rptAnswers_rbAnswer_1" type="radio" name="cpMainContent_ctl24" value="ctl00$cpMainContent$ctl24$rptAnswers$ctl02$rbAnswer">
No
</label>
</li>
<li>
<label class="radio">
<input id="cpMainContent_ctl24_rptAnswers_rbAnswer_2" type="radio" name="cpMainContent_ctl24" value="ctl00$cpMainContent$ctl24$rptAnswers$ctl03$rbAnswer">
maybe
</label>
</li>
</ul>
</div>
I need to select every input inside elements with data-action="toggle"
and Im using this jQuery selector: $('[data-action="toggleQuestions"] :input');
but I need to select those input which text value is equal to the parent data-trigger value.
Is it possible directly with a selector?

The logic is too complex to put in to a single selector. Instead you can use filter() to find the :input elements, then match the text() of their parent label to the data-trigger value on the container. Try this:
var $container = $('[data-action="toggle"]');
var $input = $container.find(':input').filter(function() {
return $(this).closest('label').text().trim() == $container.data('trigger');
})
$input.prop('checked', true);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div data-target="TargeID" data-action="toggle" data-trigger="Yes">
<ul>
<li>
<label class="radio">
<input id="cpMainContent_ctl24_rptAnswers_rbAnswer_0" type="radio" name="cpMainContent_ctl24" value="ctl00$cpMainContent$ctl24$rptAnswers$ctl01$rbAnswer">
Yes
</label>
</li>
<li>
<label class="radio">
<input id="cpMainContent_ctl24_rptAnswers_rbAnswer_1" type="radio" name="cpMainContent_ctl24" value="ctl00$cpMainContent$ctl24$rptAnswers$ctl02$rbAnswer">
No
</label>
</li>
<li>
<label class="radio">
<input id="cpMainContent_ctl24_rptAnswers_rbAnswer_2" type="radio" name="cpMainContent_ctl24" value="ctl00$cpMainContent$ctl24$rptAnswers$ctl03$rbAnswer">
maybe
</label>
</li>
</ul>
</div>

Use the below code
$('[data-action="toggle"]').each(function() {
var triggerValue = $(this).attr("data-trigger");
$(this).find('input[type=radio]').each(function() {
if ($(this).parent().text().trim() === triggerValue) {
$(this).prop("checked", true);
}
});
});

Related

Get selected radio button on selected in function in jQuery

I have the following markup:
<div class="secondary-filter" onclick="searchByFilter()">
<ul class="secondary-filter__list">
<li class="secondary-filter__list-item">
<input type="radio" id="secondaryFilter-all" name="secondaryFilter" value="All">
<label for="secondaryFilter-all">All</label>
</li>
<li class="secondary-filter__list-item">
<input type="radio" id="secondaryFilter-marked" name="secondaryFilter" value="Marked">
<label for="secondaryFilter-quoted">Marked</label>
</li>
<li class="secondary-filter__list-item">
<input type="radio" id="secondaryFilter-pending" name="secondaryFilter" value="Pending">
<label for="secondaryFilter-unquoted">Pending</label>
</li>
</ul>
</div>
How can I obtained the label of the checked radio button in the following function?
function searchByFilter() {
var x = $("input[name='secondaryFilter']").find('input:checked');
console.log(x.val());
}
I'm trying this.. but it's not working. Please help.
Your $("input[name='secondaryFilter']") creates a jQuery object if <input> elements, but .find only searches through descendants - the input elements don't have any descendants, rather you want to get the matching <input> in the current collection.
You should also attach the event listener using Javascript rather than in an HTML attribute. By listening for change events, you'll have events that only fire when one of the inputs change, rather than when anywhere in the container is clicked.
Also, probably best to have the label next to each input have its for attribute match the id of the input - that way, when clicking the label, the input will be checked - eg, change
<input type="radio" id="secondaryFilter-marked" name="secondaryFilter" value="Marked">
<label for="secondaryFilter-quoted">Marked</label>
to
<input type="radio" id="secondaryFilter-marked" name="secondaryFilter" value="Marked">
<label for="secondaryFilter-marked">Marked</label>
^^^^^^
While you could use .filter instead, to find the element in the current jQuery object matching the condition:
$("input[name='secondaryFilter']").on('change', function() {
var x = $("input[name='secondaryFilter']").filter('input:checked');
console.log(x.val());
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="secondary-filter">
<ul class="secondary-filter__list">
<li class="secondary-filter__list-item">
<input type="radio" id="secondaryFilter-all" name="secondaryFilter" value="All">
<label for="secondaryFilter-all">All</label>
</li>
<li class="secondary-filter__list-item">
<input type="radio" id="secondaryFilter-marked" name="secondaryFilter" value="Marked">
<label for="secondaryFilter-marked">Marked</label>
</li>
<li class="secondary-filter__list-item">
<input type="radio" id="secondaryFilter-pending" name="secondaryFilter" value="Pending">
<label for="secondaryFilter-pending">Pending</label>
</li>
</ul>
</div>
It would be easier to just put the :checked into the first selector string:
const checkedInput = $("input[name='secondaryFilter']:checked");
$("input[name='secondaryFilter']").on('change', function() {
var x = $("input[name='secondaryFilter']:checked");
console.log(x.val());
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="secondary-filter">
<ul class="secondary-filter__list">
<li class="secondary-filter__list-item">
<input type="radio" id="secondaryFilter-all" name="secondaryFilter" value="All">
<label for="secondaryFilter-all">All</label>
</li>
<li class="secondary-filter__list-item">
<input type="radio" id="secondaryFilter-marked" name="secondaryFilter" value="Marked">
<label for="secondaryFilter-marked">Marked</label>
</li>
<li class="secondary-filter__list-item">
<input type="radio" id="secondaryFilter-pending" name="secondaryFilter" value="Pending">
<label for="secondaryFilter-pending">Pending</label>
</li>
</ul>
</div>
To make this work attach a change event handler directly to the radio elements. Then you can get $(this).val() from it when the event occurs. You can also use next().text() to get the value shown in the label, although given that the radio value and innerText of the label are the same, this seems a little redundant.
Also note that the for attributes of the label elements need to match the id of the targeted radio, so I've fixed the HTML there too.
$('.secondary-filter :radio').on('change', function() {
var $radio = $(this);
var $label = $radio.next();
console.log(`value: ${$radio.val()}, label: ${$label.text()}`);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="secondary-filter">
<ul class="secondary-filter__list">
<li class="secondary-filter__list-item">
<input type="radio" id="secondaryFilter-all" name="secondaryFilter" value="All">
<label for="secondaryFilter-all">All</label>
</li>
<li class="secondary-filter__list-item">
<input type="radio" id="secondaryFilter-marked" name="secondaryFilter" value="Marked">
<label for="secondaryFilter-marked">Marked</label>
</li>
<li class="secondary-filter__list-item">
<input type="radio" id="secondaryFilter-pending" name="secondaryFilter" value="Pending">
<label for="secondaryFilter-pending">Pending</label>
</li>
</ul>
</div>
Use
input[name='secondaryFilter']:checked" ,'.secondary-filter'
It will check for checked radio button inside the class of the div
function searchByFilter() {
var x = $("input[name='secondaryFilter']:checked" ,'.secondary-filter')
console.log(x.val())
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="secondary-filter" onclick="searchByFilter()">
<ul class="secondary-filter__list">
<li class="secondary-filter__list-item">
<input type="radio" id="secondaryFilter-all" name="secondaryFilter" value="All">
<label for="secondaryFilter-all">All</label>
</li>
<li class="secondary-filter__list-item">
<input type="radio" id="secondaryFilter-marked" name="secondaryFilter" value="Marked">
<label for="secondaryFilter-quoted">Marked</label>
</li>
<li class="secondary-filter__list-item">
<input type="radio" id="secondaryFilter-pending" name="secondaryFilter" value="Pending">
<label for="secondaryFilter-unquoted">Pending</label>
</li>
</ul>
</div>
var x = $('input[name=secondaryFilter]:checked').val()

How to unbind event only from one item in a list

I have a list with 3 input elements. Every element have name attribute with the same value "shipping_method" and have different id values.
<ul>
<li>
<input type="radio" name="shipping_method" id="shipping_method_1" class="shipping_method" checked="checked">
<label for="shipping_method_1">Method 1</label>
</li>
<li>
<input type="radio" name="shipping_method" id="shipping_method_2" class="shipping_method">
<label for="shipping_method_1">Method 2</label>
</li>
<li>
<input type="radio" name="shipping_method" id="shipping_method_3" class="shipping_method">
<label for="shipping_method_1">Method 3</label>
</li>
</ul>
To each element using jquery .on() event bound
$(document).on("change", "input[name^=shipping_method]", shipping_method_selected)
I can't change the code which binds the event! I have to decouple event from the second input element. I have tried to use jquery .off(), but in this case, it unbinds the events of the three elements. What are the options of unbinding events in such situations?
Instead of using off you can specify which element to exclude from a selector, I've used :eq selector to deselect the second element.
$('input[name^=shipping_method]:not(:eq(1))').on("change", shipping_method_selected)
function shipping_method_selected() {
console.log('called');
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li>
<input type="radio" name="shipping_method" id="shipping_method_1" class="shipping_method" checked="checked">
<label for="shipping_method_1">Method 1</label>
</li>
<li>
<input type="radio" name="shipping_method" id="shipping_method_2" class="shipping_method">
<label for="shipping_method_1">Method 2</label>
</li>
<li>
<input type="radio" name="shipping_method" id="shipping_method_3" class="shipping_method">
<label for="shipping_method_1">Method 3</label>
</li>
</ul>
You can do this: Exclude second input from event binding by using :not and the id of the second input.
$(document).on("change", "input[name^=shipping_method]:not(#shipping_method_2)", shipping_method_selected);
function shipping_method_selected() {
console.log('selected');
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li>
<input type="radio" name="shipping_method" id="shipping_method_1" class="shipping_method" checked="checked">
<label for="shipping_method_1">Method 1</label>
</li>
<li>
<input type="radio" name="shipping_method" id="shipping_method_2" class="shipping_method">
<label for="shipping_method_1">Method 2</label>
</li>
<li>
<input type="radio" name="shipping_method" id="shipping_method_3" class="shipping_method">
<label for="shipping_method_1">Method 3</label>
</li>
</ul>

"undefined" Error with onchange Event

I want to make it so when I press a button, it will print a different number depending on which button I press. I want the buttons to look the same. This is what I have:
<div id="radiobuttons" class="container" name="buttons" align=center onchange="myFunction">
<h2>I Want my Building to be Made of:</h2>
<ul>
<li>
<input type="radio" id="brick-option" name="material" value="1">
<label for="brick-option">Bricks</label>
<div class="check"></div>
</li>
<li>
<input type="radio" id="wood-option" name="material" value="3">
<label for="wood-option">Wood</label>
<div class="check"><div class="inside"></div></div>
</li>
<li>
<input type="radio" id="stone-option" name="material" value="2">
<label for="stone-option">Stone</label>
<div class="check"><div class="inside"></div></div>
</li>
</ul>
</div>
<p id="paragraph" align="center">0</p>
<script>
function myFunction() {
var x = document.getElementById("radiobuttons").value;
document.getElementById("paragraph").innerHTML = x;
}
</script>
Although, when I press a button, it says undefined. What does this mean, and how can I fix this?
change event is not invoked for a div element. You will have to attach it to the radio buttons explicitly for them to be invoked.
Also it is a good idea to avoid inline event handlers and attach the handlers in JS to avoid dirtying the HTML
HTML
<div id="radiobuttons" class="container" name="buttons" align=center>
<h2>I Want my Building to be Made of:</h2>
<ul>
<li>
<input type="radio" id="brick-option" name="material" value="1">
<label for="brick-option">Bricks</label>
<div class="check"></div>
</li>
<li>
<input type="radio" id="wood-option" name="material" value="3">
<label for="wood-option">Wood</label>
<div class="check">
<div class="inside"></div>
</div>
</li>
<li>
<input type="radio" id="stone-option" name="material" value="2">
<label for="stone-option">Stone</label>
<div class="check">
<div class="inside"></div>
</div>
</li>
</ul>
</div>
<p id="paragraph" align="center">0</p>
JS
var radioButtons = document.querySelectorAll('input[type=radio]');
for (var i = 0; i < radioButtons.length; i++) {
radioButtons[i].addEventListener('change', function() {
if (this.checked) {
document.getElementById("paragraph").innerHTML = this.value;
}
});
}
Check Fiddle
You're trying to access a property of value on radiobuttons which is a <div> that has no such value, this is why you're getting 'undefined'.
You'll want to modify your code so that myFunction is assigned to the inline event handler onClick of each radio button input instead.

How to select next element using jquery?

I want to apply some design on the next element. But my problem is I am getting this error:
Error: Syntax error, unrecognized expression: [object Object] > label
Here's my selections:
BROWSE BY
<ul class="list-unstyled">
<li>
<input type="radio" id="cat-1" class="category_select" name="category_type" data-category-type="1" value="all_product" checked="checked" />
<label for="cat-1"><span></span>All</label>
</li>
<li>
<input type="radio" id="cat-2" class="category_select" name="category_type" data-category-type="2" value="japanese_tea" />
<label for="cat-2"><span></span>Japanese Tea</label>
</li>
<li>
<input type="radio" id="cat-3" class="category_select" name="category_type" data-category-type="3" value="black_vinegar" />
<label for="cat-3"><span></span>Black Vinegar</label>
</li>
<li>
<input type="radio" id="cat-4" class="category_select" name="category_type" data-category-type="4" value="food" />
<label for="cat-4"><span></span>Food</label>
</li>
<li>
<input type="radio" id="cat-5" class="category_select" name="category_type" data-category-type="5" value="cosmetic_health" />
<label for="cat-5"><span></span>Cosmetic / Health</label>
</li>
<li>
<input type="radio" id="cat-6" class="category_select" name="category_type" date-category-type="6" value="others" />
<label for="cat-6"><span></span>Others</label>
</li>
</ul>
Here's my JS:
$('.category_select').on('change', function() {
var cat = $(this);
var category_type = $(this).data('category-type');
$(cat + ' > label').css({'color':'red'}); //wont apply some css why?
});
Can you help me with this?
You need to use .next() traversal method to get the next sibling of an element
In your code cat is a jQuery object so when used in string concatenation your selector becomes [object Object] > label
$('.category_select').on('change', function() {
var cat = $(this);
var category_type = $(this).data('category-type');
cat.next('label').css({
'color': 'red'
}); //wont apply some css why?
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="list-unstyled">
<li>
<input type="radio" id="cat-1" class="category_select" name="category_type" data-category-type="1" value="all_product" checked="checked" />
<label for="cat-1"><span></span>All</label>
</li>
<li>
<input type="radio" id="cat-2" class="category_select" name="category_type" data-category-type="2" value="japanese_tea" />
<label for="cat-2"><span></span>Japanese Tea</label>
</li>
<li>
<input type="radio" id="cat-3" class="category_select" name="category_type" data-category-type="3" value="black_vinegar" />
<label for="cat-3"><span></span>Black Vinegar</label>
</li>
<li>
<input type="radio" id="cat-4" class="category_select" name="category_type" data-category-type="4" value="food" />
<label for="cat-4"><span></span>Food</label>
</li>
<li>
<input type="radio" id="cat-5" class="category_select" name="category_type" data-category-type="5" value="cosmetic_health" />
<label for="cat-5"><span></span>Cosmetic / Health</label>
</li>
<li>
<input type="radio" id="cat-6" class="category_select" name="category_type" date-category-type="6" value="others" />
<label for="cat-6"><span></span>Others</label>
</li>
</ul>
You can directly select the next label using the id attribute of selected input box
$('.category_select').on('change', function() {
var cat = this.id;
var category_type = $(this).data('category-type');
$("label").css({'color':'black'}) // Remove red color from previously selected item
$("label[for='"+cat+"']").css({'color':'red'}); // Apply red color on selected item
});
JSFIDDLE EXAMPLE
you need to use .next() selector for selecting the next element, instead $(cat + ' > label')
$('.category_select').on('change', function() {
var cat = $(this);
var category_type = $(this).data('category-type');
cat.next('label').css({'color':'red'}); //syntax for selecting next in js
});
Hope this helped you out??

How to show selected value of type="radio" on populate?

On clicking on the Populate Values button the div below the button should populate the values of the selected radio buttons of the preferred and home locations respectively
I want to do it unobtrusively without inline JavaScript
<div id="form_block">
<div class="home-location">
<ul>
<li>Home Location</li>
<li>
<input type="radio" name="home-location" value="india" class="radio" id="home-india" /><label
for="home-india">India</label></li>
<li>
<input type="radio" name="home-location" value="usa" class="radio" id="home-usa" /><label
for="home-usa">USA</label></li>
</ul>
</div>
<div class="prefer-location">
<ul>
<li>Preferred Location</li>
<li>
<input type="radio" name="home-preferred" value="india" class="radio" id="preferred-india" /><label
for="preferred-india">India</label></li>
<li>
<input type="radio" name="home-preferred" value="usa" class="radio" id="preferred-usa" /><label
for="preferred-usa">USA</label></li>
</ul>
</div>
<div class="result">
My Home Location is: <span class="home-location-result"></span>and my preferred
location is: <span class="home-location-result"></span>
</div>
<input type="submit" value="Populate Values" id="ss" class="submit" />
Modified your HTML. Provided an id attribute for your result spans
$(function(){
$("#ss").click(function(){
// Find all input elements with type radio which are descendants of element with id `form`
var filt = $("#form_block input:radio");
// Apply a filter to the above object with `name='home-location'` and checked and get the value
var homeVal = filt.filter("[name='home-location']:checked").val();
// same as above
var preferredVal = filt.filter("[name='home-preferred']:checked").val();
// Set the text of the element width id `home-location-result' with the computed value
$("#home-location-result").text(homeVal);
// same as above
$("#preferred-location-result").text(preferredVal);
return false;
});
});
See a working demo
use this it's works for me
<script>
function test()
{
var home= $('input:radio[name=home-location]:checked').val();
document.getElementById("h1").innerHTML=home;
var preferred= $('input:radio[name=home-preferred]:checked').val();
document.getElementById("h2").innerHTML=preferred;
return false;
}
</script>
<form onsubmit="return test();">
<div id="form_block">
<div class="home-location">
<ul>
<li>Home Location</li>
<li>
<input type="radio" name="home-location" value="india" class="radio" id="home-india" /><label
for="home-india">India</label></li>
<li>
<input type="radio" name="home-location" value="usa" class="radio" id="home-usa" /><label
for="home-usa">USA</label></li>
</ul>
</div>
<div class="prefer-location">
<ul>
<li>Preferred Location</li>
<li>
<input type="radio" name="home-preferred" value="india" class="radio" id="preferred-india" /><label
for="preferred-india">India</label></li>
<li>
<input type="radio" name="home-preferred" value="usa" class="radio" id="preferred-usa" /><label
for="preferred-usa">USA</label></li>
</ul>
</div>
<div class="result">
My Home Location is: <span class="home-location-result" id="h1"></span>and my preferred
location is: <span class="home-location-result" id='h2'></span>
</div>
<input type="submit" value="Populate Values" id="ss" class="submit" />
</form>

Categories

Resources