How can I get the index of this element with jQuery? - javascript

I am trying to get the index of an element using jQuery to send to a PHP script.
Here is my XHTML
<form action="/accreditation/questions/" method="post" id="questions-form">
<fieldset id="question-0">
<legend>Question</legend>
<h3>What colour is grass?</h3>
<ul>
<li>
<input type="radio" name="answer[0]" value="0" id="radio-0-0" />
<label for="radio-0-0">Green</label>
</li>
<li>
<input type="radio" name="answer[0]" value="1" id="radio-0-1" />
<label for="radio-0-1">Red</label>
</li>
<li>
<input type="radio" name="answer[0]" value="2" id="radio-0-2" />
<label for="radio-0-2">Orange</label>
</li>
</ul>
</fieldset>
<fieldset id="question-1">
<legend>Question</legend>
<h3>how old is alex</h3>
<ul>
<li>
<input type="radio" name="answer[1]" value="0" id="radio-1-0" />
<label for="radio-1-0">21</label>
</li>
<li>
<input type="radio" name="answer[1]" value="1" id="radio-1-1" />
<label for="radio-1-1">11</label>
</li>
<li>
<input type="radio" name="answer[1]" value="2" id="radio-1-2" />
<label for="radio-1-2">23</label>
</li>
</ul>
</fieldset>
</form>
I need to get the index of the fieldset elements. I am currently using this each iterator (which I'd like not to change because it has a lot of other functions inside it).
$('#questions-form ul li').each(function() {
qIndex = $('fieldset').index($('fieldset', $(this).parent()))
});
I'd like qIndex to be the index of fieldset relative to the form. For example, in this case I should have it equal to 0 and 1 (although there would be 6 values because it's looping through the list elements).
I have played around for a while and have been unable to get the correct index. I keep getting not found (-1).
If it helps, here is the code I'm using to get the list item's index relative to it's containing ul element.
index = $('li', $(this).parent()).index(this);
What is wrong with my fieldset index grabbing code?

The LI's parent is UL, not the fieldset.
I think this will set qIndex for you:
qIndex = $('fieldset').index($(this).parents('fieldset'));

You can also get the index using:
$("form fieldset").each(function(I) {
console.log("fieldset index"+ I);
});

Related

How to get values from <li> elements?

I have three different sections for filter and a button and i want to use filter on these sections, I just want to know that
how can i get value of these sections ( inside ul li)
<div id="new-items" class="dropdown">
New Items
<ul class="">
<li><span>New bestsellers</span></li>
<li><span>New releases</span></li>
</ul>
</div>
<div id="buy" class="dropdown">
Buy Now
<ul class="">
<li><span>Wallet</span></li>
<li><span>Website</span></li>
</ul>
</div>
<div id="sort-by" class="dropdown">
Sort By
<ul class="">
<li><span>Low To High Price</span></li>
<li><span>High To Low Price</span></li>
<li><span>View</span></li>
<li><span>View</span></li>
<li><span>Rating</span></li>
<li><span>Sale</span></li>
<li><span>Date</span></li>
</ul>
</div>
<button class="sc-button style letter style-2 filter"><span>Filter</span> </button>
This is how your HTML now renders
You need to convert the <li> to radio buttons.
For example, the sort choices.
<input type="radio" name="sort" value="1"> Low To High Price<br>
<input type="radio" name="sort" value="2"> High To Low Price<br>
<input type="radio" name="sort" value="3"> View<br>
<input type="radio" name="sort" value="4"> View<br>
<input type="radio" name="sort" value="5"> Rating<br>
<input type="radio" name="sort" value="6"> Sale<br>
<input type="radio" name="sort" value="7"> Date<br>
The above looks like this:
It may not be jQuery but it is simple enough in vanilla Javascript. The comments tell you what is happening.
// a global variable to be populated when specific SPAN elements are clicked.
let selection=false;
// bind a delegated listener to the document or suitable ancestor
document.addEventListener('click',e=>{
// If the "click" is on a SPAN of interest, populate the global variable
if( e.target.tagName=='SPAN' && e.target.parentNode.tagName=='LI' ){
selection=e.target;
}
// if the button is clicked, filter ...
if( e.target.tagName=='SPAN' && e.target.parentNode.tagName=='BUTTON' && selection ){
alert(selection.textContent)
}
});
<div id="new-items" class="dropdown">
New Items
<ul class="">
<li><span>New bestsellers</span></li>
<li><span>New releases</span></li>
</ul>
</div>
<div id="buy" class="dropdown">
Buy Now
<ul class="">
<li><span>Wallet</span></li>
<li><span>Website</span></li>
</ul>
</div>
<div id="sort-by" class="dropdown">
Sort By
<ul class="">
<li><span>Low To High Price</span></li>
<li><span>High To Low Price</span></li>
<li><span>View</span></li>
<li><span>View</span></li>
<li><span>Rating</span></li>
<li><span>Sale</span></li>
<li><span>Date</span></li>
</ul>
</div>
<button class="sc-button style letter style-2 filter"><span>Filter</span></button>
get all the li elements inside div, then loop the array
example for the first div:
const newItems = document.querySelectorAll('#new-items li');
newItems.forEach(function(item) {
console.log(item.innerText);
})

I want to alert on when checkbox checked but this code is not working

I'm trying to figure out why the alert boxes and console logs don't work as intended when I check a checkbox.
jquery code
$(document).ready(function(){
$("#location").click(function(){
$("input[name='location']:checked").each(function(){
alert("go");
});
});
});
laravel blade checkbox code
<div class="sidebar-box">
<h5>Location</h5>
<ul class="checkbox-list">
#foreach($store_location as $store_location)
<li class="checkbox">
<label>
<input type="checkbox" class="i-check" id="location" name="location">
{{ $store_location->store_location_name }}
</label>
</li>
#endforeach
</ul>
</div>
First you should answer, if the #foreach loop works fine and renders the ul > li list correctly. I gues it works.
The JS Code
I've rewritten your code and it works even though there is a problem in your code. You really should use non-identical id attributes. You can use classes or what ever multiple times in different HTML tags, but not the id attribute. But this does not cause the problem. Have a look on the example:
Example (in plain JavaScript)
document.querySelectorAll('#location').forEach(locationEl => {
locationEl.addEventListener('click', () => {
document.querySelectorAll('input[name=location]:checked').forEach(el => {
console.log('go');
});
});
});
/*
"Equivalent" to your jQuery Code:
$(document).ready(function(){
$("#location").click(function(){
$("input[name='location']:checked").each(function(){
alert("go");
});
});
});
*/
<ul>
<li>
<input type="checkbox" name="location" id="location">
</li>
<li>
<input type="checkbox" name="location" id="location">
</li>
<li>
<input type="checkbox" name="location" id="location">
</li>
<li>
<input type="checkbox" name="location" id="location">
</li>
</ul>
Better:
document.querySelectorAll('input[name=location]').forEach(locationEl => {
locationEl.addEventListener('click', () => {
document.querySelectorAll('input[name=location]:checked').forEach(el => {
console.log(el.value, 'is checked');
});
});
});
<ul>
<li>
<input type="checkbox" name="location" value="1">
</li>
<li>
<input type="checkbox" name="location" value="2">
</li>
<li>
<input type="checkbox" name="location" value="3">
</li>
<li>
<input type="checkbox" name="location" value="4">
</li>
</ul>
With input[name=location] as a selector you are addressing any input tag with an attribute name with a value of location. And this should just work.
The Blade Template Code
You are using most probably by accident the same variable name for the variable which should be iterated and the output item of each loop. You should try to rename them depending on the name of the variable which holds the array of your desired information:
<div class="sidebar-box">
<h5>Location</h5>
<ul class="checkbox-list">
#foreach($store_location as $location)
<li class="checkbox">
<label>
<input type="checkbox" class="i-check" name="location">
{{ $location->store_location_name }}
</label>
</li>
#endforeach
</ul>
</div>
If this won't work, consider to upload some part of your rendered HTML code. The one you've uploaded is the blade code, right? Or try to debug your variables that you've pushing toward your blade template. Good luck!

Not being able to pre-select desired radio box by default

I am trying to pre-select premium delivery by default. I was looking on the web and really don't understand why it would not pre-select the second radio-box. Please find link to my JSfiddle
My code is also:
jQuery(document).ready(function() {
waitForDelayedContent('#checkout-shipping-method-load .input-checkout-radio .method-title:contains(Take it to my room)', function() {
jQuery('#checkout-shipping-method-load .input-checkout-radio:not(.mtC) .method-title:contains(Take it to my room)').click();
jQuery('#checkout-shipping-method-load .input-checkout-radio:not(.mtC):has(.method-title:contains(Take it to my room)) .radio').click();
jQuery('#checkout-shipping-method-load .input-checkout-radio:has(.method-title:contains(Take it to my room))').addClass('mtC');
});
});
<div id="checkout-shipping-method-load">
<div class="sp-methods">
<h3 class="title">Delivery Option</h3>
<p>You must select a delivery option.</p>
<ul>
<li class="delivery-method">
<div class="input-checkout-radio">
<input checked="checked" class="input-radio" id="s_method_standard" name="shipping_method" type="radio" value="paragon_customrate_standard">
<label class="radio-label" for="s_method_standard"><span class="radio"></span> <span class="method-title">FREE Take it to
my door</span>
</label>
</div>
</li>
<li class="delivery-method">
<div class="input-checkout-radio">
<input class="input-radio" id="s_method_premium" name="shipping_method" type="radio" value="paragon_customrate_premium">
<label class="radio-label" for="s_method_premium"><span class="radio"></span> <span class="method-title"><span class=
"price"><span class="currency">£</span>39</span>Take it to my room</span>
</label>
</div>
</li>
</ul>
</div>
</div>
It is because the first radio box has checked="check". Move that to the second radio box to make it work. No need for JavaScript. See this updated fiddle: http://jsfiddle.net/n5h65n73/
Or, if you really need to do it with JavaScript:
$("#s_method_premium").prop("checked", true)
The issue is within your HTML. You have the checked="checked" attribute set on the first radio input. So if you remove that attribute and move it to the second one, it'll work as you want.
<div id="checkout-shipping-method-load">
<div class="sp-methods">
<h3 class="title">Delivery Option</h3>
<p>You must select a delivery option.</p>
<ul>
<li class="delivery-method">
<div class="input-checkout-radio">
<input class="input-radio" id="s_method_standard" name="shipping_method" type="radio" value="paragon_customrate_standard">
<label class="radio-label" for="s_method_standard"><span class="radio"></span> <span class="method-title">FREE Take it to
my door</span>
</label>
</div>
</li>
<li class="delivery-method">
<div class="input-checkout-radio">
<input checked class="input-radio" id="s_method_premium" name="shipping_method" type="radio" value="paragon_customrate_premium">
<label class="radio-label" for="s_method_premium"><span class="radio"></span> <span class="method-title"><span class=
"price"><span class="currency">£</span>39</span>Take it to my room</span>
</label>
</div>
To do this using jQuery, here's the code snippet:
$('#s_method_premium').attr('checked', 'true');
The basic explanation is that you are using the attr method of jQuery to modify the property (i.e., the first argument) with the desired value (i.e., the second argument). And then necessity for both lines of code is to remove the first checked before setting the second one.
Does that help?

On click function uncheck other radio buttons

I have given code
<ul id="payment-method-fields">
<li id="paypal">
<label>
<input checked="checked" id="order_payments_attributes__payment_method_id_5" name="order[payments_attributes][][payment_method_id]" type="radio" value="5">
Test Paypal
</label>
</li>
<li id="adyen">
<label>
<input id="order_payments_attributes__payment_method_id_4" name="order[payments_attributes][][payment_method_id]" type="radio" value="4">
Ali Pay
</label>
</li>
<li id="adyen_encrypted">
<label>
<input id="order_payments_attributes__payment_method_id_16" name="order[payments_attributes][][payment_method_id]" type="radio" value="16">
credit card
</label>
</li>
<li id="cod" >
<label>
<input id="cash-on-delivery" name="cod" type="radio" value="">
Cash on Delivery
</label>
</li>
</ul>
my requirement is when click on other li i.e on Cash on Delivery then paypal gets unchecked. Please guide me how I will write this jquery.
My proposal is:
$('#payment-method-fields :input[type="radio"]').on('change', function(e) {
if (this.id == 'cash-on-delivery') {
$('#payment-method-fields').find('input[type="radio"]:not(#' + this.id + ')').prop('checked', false);
}
});
You can do this:
$('#cash-on-delivery').on('change', function(){
$('input[name="order[payments_attributes][][payment_method_id]"]')
.prop('checked', !this.checked);
});
Simply give them the same name for all input tags
Example:
<input type="radio" name="group_name" />
This ensures only one is selected at any time.
You can give all inputs a same class for example
class="radio_button"
And then you can add code
$(document).ready(function(){
$('.radio_button').on('click',function(){
$('.radio_button').removeAttr('checked');
$(this).prop('checked','checked');
})
}
The last input has a different name <input id="cash-on-delivery" name="cod" type="radio" value=""> than the others so when you check it the others won't automatically uncheck. Give it the same name and it will work fine.
Here is an Example of it working.
Code:
<ul id="payment-method-fields">
<li id="paypal">
<label>
<input checked="checked" id="order_payments_attributes__payment_method_id_5" name="order[payments_attributes][][payment_method_id]" type="radio" value="5">
Test Paypal
</label>
</li>
<li id="adyen">
<label>
<input id="order_payments_attributes__payment_method_id_4" name="order[payments_attributes][][payment_method_id]" type="radio" value="4">
Ali Pay
</label>
</li>
<li id="adyen_encrypted">
<label>
<input id="order_payments_attributes__payment_method_id_16" name="order[payments_attributes][][payment_method_id]" type="radio" value="16">
credit card
</label>
</li>
<li id="cod" >
<label>
<input id="cash-on-delivery" name="order[payments_attributes][][payment_method_id]" type="radio" value="">
Cash on Delivery
</label>
</li>
</ul>
Removing the property 'checked' from the input-elements with the jQuery removeProp function. For your example create two functions and call them in the onClick trigger of your input-elements:
function uncheckTop3() {
$('#order_payments_attributes__payment_method_id_5').removeProp('checked');
$('#order_payments_attributes__payment_method_id_4').removeProp('checked');
$('#order_payments_attributes__payment_method_id_16').removeProp('checked');
}
function uncheckCashOnDelivery() {
$('#cash-on-delivery').removeProp('checked');
}
Here a jfiddle-link to your example.
To check/uncheck a checkbox, use the attribute checked and alter that. With jQuery you can do:
//$('#myCheckbox').attr('checked', true); // Checks it
//$('#myCheckbox').attr('checked', false); // Unchecks it
$('#cash-on-delivery').on('change', function(){
$('input[name="order[payments_attributes][][payment_method_id]"]').attr('checked',true);
});

How to iterate through attributes of child and rename it Jquery?

I have this markup. I am trying to write jquery selectors to get all element inside template order list whose name has Works string. My requirement is that I have multiple ordered list. If I will delete any list I want to rearrange indexes in name attribute.
<ol class="template">
<li>
<span class="label" name="Works[0].Id"></span>
</li>
<li>
<input id="textBox" type="text" value="" name="Works[0].Body">
</li>
<li>
<input type="checkbox" id="checkbox" value="" name="Works[0].IsCompleted">
<input type="button" id="delete" value="Delete">
</li>
</ol>
<ol class="template">
<li>
<span class="label" name="Works[1].Id"></span>
</li>
<li>
<input id="textBox" type="text" value="" name="Works[1].Body">
</li>
<li>
<input type="checkbox" id="checkbox" value="" name="Works[1].IsCompleted">
<input type="button" id="delete" value="Delete">
</li>
</ol>
<ol class="template">
<li>
<span class="label" name="Works[2].Id"></span>
</li>
<li>
<input id="textBox" type="text" value="" name="Works[2].Body">
</li>
<li>
<input type="checkbox" id="checkbox" value="" name="Works[2].IsCompleted">
<input type="button" id="delete" value="Delete">
</li>
</ol>
My approach is to after I will remove any order list i.e. after click of delete button. I will take every ordered list and by iterating through I will change index for 0 to length of list. But I am not getting proper selector to catch elements inside an ordered list whose name attribute has value starts with Works. Please suggest some better selector.
The selector you want is:
$("ol.template [name^=Works]")
This is the jQuery Attribute Starts With selector.
By the way, name is not a valid attribute on <span> elements. It should only be used for the following elements:
<button>, <form>, <fieldset>, <iframe>, <input>, <keygen>, <object>, <output>, <select>, <textarea>, <map>, <meta>, <param>
See https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes
here is pure javascript working with majors browsers
var ol = document.getElementsByTagName('ol');
var temp = ol.getElementsByClassName('template');
for(var i=0;i<temp.length;i++){
if(temp[i].name.indexOf('Works')==0){ // if name attribute start with 'Work'
//if(temp[i].name.indexOf('Works') > -1){ => if name attribute contains 'Work'
//if(temp[i].name.indexOf('Works') == -1){ => if name attribute is not contains 'Work'
//if(temp[i].name.indexOf('Works') == temp[i].name.length - 'Works'.length - 1){ => if name attribute is ended with 'Work'
// now play with with temp[i]
temp[i].style.background = 'yellow';
}
}

Categories