How to change a global variable inside jQuery selectors? - javascript

I'm developing a website, which is using jQuery.Inside this code I need to change the value of a variable inside a Jquery selector and get the changed value after it.Is it possible to do that?How can I achieve this?If possible, could show me a snippet/example code?
I've tried declaring the variable global, but without success too.
var index;
$(document).ready( function(){
$("#myButton1").click(function(){ //selector number 1
index = 1;
});
$("#myButton2").click(function(){//selector number 2
index = 2;
});
//after, i need the value of the index for another selector
//look this next selector is fired at the same time as the previous one!
$("button[id^=myButton"+index+"]").click( function(){ //selector number 3
...
}
}
How can I make the selector number 1 or 2 fire after the selector number 3?Is it possible?

Javascript executes code asynchronously. In other words, whole code executes at the "same time." So first, it will execute var index;. Since the jQuery .click is waiting for you to click the button, it will skip both of the .click functions and move on to the alert. Since index is undefined, it will say index=undefined. To fix that, move the alert's inside the .click function so that the alert will execute after you click the button.
var index;
$("#button1").click(function() {
index = 1;
alert("index = " + index);
});
$("#button2").click(function() {
index = 2;
alert("index = " + index);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="button1"></button>
<button id="button2"></button>
Or you could do it this way:
var index = 0;
$("#button1").click(function() {
index = 1;
});
$("#button2").click(function() {
index = 2;
});
setTimeout(function() {
alert("index = " + index);
}, 5000);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="button1"></button>
<button id="button2"></button>
The above method basically executes the alert after 5 seconds, so you can change the value of index as many times as you want in those 5 seconds. The default value is 0, but if you click the first button within those 5 seconds, the value of index changes to 1. Same for the second button.

The things that happen when you click one of the buttons are those you define inside the click-handler function (see here):
$("#button1").click(function(){
window.index = 1; // only this line!!!
});
Your call to alert() resides inside the ready-funtion and is therefore only called when the page is loaded. You need to put the alert inside the click handlers to call it "on click". Doing so, all three versions should work. Should look like this:
$("#button1").click(function(){
index = 1;
alert(index);
});
After your edit:
Same thing here: the selector string after you comment is created at the time of the page load, before any button is clicked. and never again after that.
At that moment, it evaluates to "button[id^=myButtonundefined]" because index has no defined value yet. T## is function therfore will be executed whenever you click a button whose ID starts with myButtonundefined - probably never.
Everything you want to achieve, for which you need the value of index you need to execute inside the click-handler function. e.g.:
$(document).ready( function(){
$("#button1").click(function(){
$("button[id^=myButton1]").click( function(){
...
});
});
$("#button2").click(function(){
$("button[id^=myButton2]").click( function(){
...
});
});
}
or you could try the following approach, which installs a click-handler on all myButton...'s and therein checks if the corresponding button... has been clicked before:
var index;
$(document).ready( function(){
$("#button1").click(function(){
index = 1;
});
$("#button2").click(function(){
index = 2;
});
//after, i need the value of the index for another selector:
$("button[id^=myButton]").click( function(){
if (this.id == 'myButton'+index) {
...
}
}
}

How to change a global variable inside jQuery selectors?
Don't use a global variable in this instance. You have a chance of a variable collision with any other code (jQuery or any other script you use). You can simply place index inside your document ready and use it in your example code and it will work without any chance of collision.
$(document).ready( function(){
var index;
$("#button1").click(function(){
index = 1;
});
$("#button2").click(function(){
index = 2;
});
//after, i need the value of the index for another selector:
$("button[id^=myButton"+index+"]").click( function(){
});
$('.js-getcurrentvalue').on('click', function() {
$('#currentvalue').val(index);
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="button" class="js-getcurrentvalue" value="Get Current Value of Index"/><input type="text" id="currentvalue" /><br/>
<input type="button" id="button1" value="button1" /><br/>
<input type="button" id="button2" value="button1" /><br/>
But at the same time, the selector $("button[id^=myButton"+index+"]").click( function(){ }); fires.So, both are executed at the same time.I need that the second selector execute always after the first selector.Do u know how can I accomplish this?
This is not the original question you asked. Please read what an XY Problem is so your future questions can be answer correctly.
Highly recommended reading: Decouple your HTML, CSS and Javascript.
First we need to understand that each of these statements that attach an event handler onto an element all run before the event handler can be executed. So in my previous example the following events are registered:
$("#button1").click()
$("#button2").click()
$("button[id^=myButton]").click();
$('.js-getcurrentvalue').on('click')
You'll notice that I've done what any compiler would do and reduce the variable into it's actual value. At the time the event handler is attached, index has no value. Since this isn't what you want, you could write it like:
$("button").click(function() {
var $this = $(this);
var id = $this.prop(id);
if ($this.is("[id^=myButton"+index+"]") {
// do something as index changes
}
});
But it's really ugly and introduces an abstraction of a value to used to compare. It's also very tightly coupled, that is we have to place an event on any object we want to change index and we have to write more code for each button. Yikes. Instead we can use classes and the data-attribute with data() to simplify and make this more robust.
$(document).ready( function(){
var selector;
$(".js-enable-button").on('click', function(){
selector = $(this).data('selector');
});
$('.js-enable-me').on('click', function() {
var $this = $(this);
if ($this.is(selector)) {
alert($this.val());
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="button" class="js-enable-button" value="Enable button -->" data-selector="#button1" />
<input type="button" class="js-enable-me" id="button1" value="Am I working?" /><br/>
<input type="button" class="js-enable-button" value="Enable button -->" data-selector="#button2" />
<input type="button" class="js-enable-me" id="button2" value="Or am I working?" /><br/>
Now the code is not limited to an Id. It's also not limited to a single selector. You could go crazy and just by adding only html the following continues to work for all elements. Notice I've added no additional code.
$(document).ready( function(){
var selector;
$(".js-enable-button").on('click', function(){
selector = $(this).data('selector');
});
$('.js-enable-me').on('click', function() {
var $this = $(this);
if ($this.is(selector)) {
alert($this.val());
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="button" class="js-enable-button" value="Enable button -->" data-selector="#button1" />
<input type="button" class="js-enable-me" id="button1" value="Am I working?" /><br/>
<input type="button" class="js-enable-button" value="Enable button -->" data-selector="#button2" />
<input type="button" class="js-enable-me" id="button2" value="Or am I working?" /><br/>
<br/>
<input type="button" class="js-enable-button" value="I enable the three below me using id" data-selector="#id1,#id2,#id3" /></br>
<input type="button" class="js-enable-me" id="id1" value="id1" /><br/>
<input type="button" class="js-enable-me" id="id2" value="id2" /><br/>
<input type="button" class="js-enable-me" id="id3" value="id3" /><br/>
<br/>
<input type="button" class="js-enable-button" value="I enable the three below me using a class" data-selector=".enable" /></br>
<input type="button" class="js-enable-me enable" value="I'm .enable 1" /><br/>
<input type="button" class="js-enable-me enable" value="I'm .enable 2" /><br/>
<input type="button" class="js-enable-me enable" value="I'm .enable 3" /><br/>

Related

.change not triggered if change the value by js

In my web page the value of an input is changing by a js application, but what I want is to trigger an event when a value is changed.
The problem is that when the value is changed by the application, no event is triggered because the value is changed by js but if a value is input by the user the event is triggered.
Here is a small example of this, when you click on the change button, the value is changed but the .change event does not trigger.
If you manually input the values .change will trigger.
var i = 0;
$("#id_st").change(function(){
console.log('This is value',$(this).val())
$('#p').html($(this).val());
});
$('#change_btn').click(function(){
i = i+1;
$("#id_st").val(i);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id="id_st" type="text" name="st" value="0">
<br>
<button id="change_btn" type="button" name="button">change value</button>
<br>
<p id="p">value</p>
I searched for my problem and found .trigger('change') but as I already told you that value is changed by an application which I haven't developed so can't use this method.
Please tell me a real solution for my problem.
On button#change_btn click , the change event of the input#id_st wont't be fired. This is because for input element to fire change event, first it's value must change and then it must loose focus. So when you click the button, it's value has changed but it never got focus to loose it later.
So you have to fire the 'change' event manually for which you can just chain trigger() once you set the value of the input with val() as
$("#id_st").val(i).trigger('change')
You can learn more here in MDN
Demo:
var i = 0;
$("#id_st").change(function(){
console.log('This is value',$(this).val())
$('#p').html($(this).val());
});
$('#change_btn').click(function(){
i = i+1;
$("#id_st").val(i).trigger('change');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id="id_st" type="text" name="st" value="0">
<br>
<button id="change_btn" type="button" name="button">change value</button>
<br>
<p id="p">value</p>
EDIT:
Well if you can't use trigger(). You can check for change in value of the input periodically as suggested by #Mohammad.
use .on('input') and trigger('input')
var i = 0;
$("#id_st").on('input',function(){
console.log('This is value',$(this).val())
$('#p').html($(this).val());
// you may need to update i here to start from it after change
i = parseInt($(this).val());
});
$('#change_btn').click(function(){
i = i+1;
$("#id_st").val(i).trigger('input');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id="id_st" type="text" name="st" value="0">
<br>
<button id="change_btn" type="button" name="button">change value</button>
<br>
<p id="p">value</p>
Sorry!! misunderstanding here.. Unfortunately What I know is: you cannot make the change event fire itself without relation between the event/action and the input .. OR you have to use setInterval() to catch any change of input value after each amount of time
This is how to trigger the event using setInterval() without need to trigger the event in the uncontrolled application
var i = 0;
$("#id_st").on('input',function(){
console.log('This is value',$(this).val())
$('#p').html($(this).val());
// you may need to update i here to start from it after change
i = parseInt($(this).val());
});
$('#change_btn').click(function(){
i = i+1;
$("#id_st").val(i);
});
// setInterval every 5 seconds
setInterval(function(){
$("#id_st").trigger('input');
} , 5000);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id="id_st" type="text" name="st" value="0">
<br>
<button id="change_btn" type="button" name="button">change value</button>
<br>
<p id="p">value</p>
After doing some research on MDN web docs, i found some stuff on manually firing events Dispatch Event Function Examples
var i = 0;
$("#id_st").change(function(){
console.log('This is value',$(this).val())
$('#p').html($(this).val());
});
$('#change_btn').click(function(){
var event = new Event('change');
var target = document.getElementById('id_st');
i = i+1;
$("#id_st").val(i);
target.dispatchEvent(event);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id="id_st" type="text" name="st" value="0">
<br>
<button id="change_btn" type="button" name="button">change value</button>
<br>
<p id="p">value</p>
If you're not the one who's changing the value, then I think there's only one way to trigger the change, you'll have to put a setTimOout() function on the input which will take the value of the <p> and check if it's different from the one before.
(In page load capture the <p> value and every time your setTimeOut() runs update that value).
If it's different then trigger the change with jQuery.

jQuery attach onclick function to element

I have four image buttons with onclick events attached to them two pairs of two. I'm trying to replace those image buttons with text buttons and reattach the onclick function to the next text buttons. These buttons are not always on the page and I'm confined to using jQuery 1.4 otherwise .prop would make this a lot easier.
Consider this HTML:
<input type="image" src="path/to/image.gif" class="one" onclick="function()" />
<input type="image" src="path/to/image.gif" class="one" onclick="function()" />
<input type="image" src="path/to/image2.gif" class="two" onclick="function()" />
<input type="image" src="path/to/image2.gif" class="two" onclick="function()" />
I wrote the following jQuery code to get the onclick function, the inputs and rebind the onclick function.
$('input.one').each(function(){
var oneOnClick = $(this).attr('onclick');
$(this).replaceWith('<input type="button" value="one" class="one" onclick="'+oneOnClick+'" />');
)};
And the same for .two. I found out that the way the value of the onclick attribute is returned in jQuery means this cannot be done.
Using some resources online I updated my code to look like this:
var oneOnClick = $('input.one').first().attr('onclick');
var twoOnClick = $('input.two').first().attr('onclick');
$('input.one').each(function(){
$(this).replaceWith('<input type="button" class="one" value="one"/>');
});
$('input.two').each(function(){
$(this).replaceWith('<input type="button" class="two" value="two"/>');
});
$('input.one').live("click", oneOnClick);
$('input.two').live("click", twoOnClick);
But I'm getting an error
TypeError: undefined is not an object (evaluating 'b.split')
when input.one doesn't exist.
How can I make this work?
Please try the following code to bind onClick event
$(document).ready(function(){
$('input.one').each(function(){
$(this).attr('type',"button");
});
});
Well I suggest you to go with your first opted method:
Check this DEMO
function clickOne()
{
alert('hi');
}
function clickTwo()
{
alert('helleo');
}
$(document).ready(function(){
var oneOnClick = $('input.one').first().get(0).attributes.onclick.nodeValue;
var twoOnClick = $('input.two').first().get(0).attributes.onclick.nodeValue;
$('input.one').each(function(){
$(this).replaceWith('<input type="button" value="one" class="one" onclick="'+oneOnClick+'" />');
});
$('input.two').each(function(){
$(this).replaceWith('<input type="button" value="two" class="two" onclick="'+twoOnClick+'" />');
});
$('input.one').live("click", oneOnClick);
$('input.two').live("click", twoOnClick);
});
POINT TO NOTE:
$('input.one').attr('onclick') or $('input.two').attr('onclick') holds the value of the onclick attribute (which is a string). However, because the browsers treat the event attributes in a different way, they are
returned with function onclick() { clickOne() } and you know
about this. Thus, if you want to directly call the function, you'll
have to either strip the
function() {} or call it immediately or get it using
get(0).attributes.onclick.nodeValue
wrap clickOne and clickTwo in head and remaining things on document.ready

Javascript Radio Button Value in URL

I've read variations on this for a few days and can't find a working solution to what I want. And it's probably easier than I'm making out.
I have a set of radio buttons, and want to pass the checked value to part of a URL.
<input type="radio" name="link" value="one" checked="checked">One
<input type="radio" name="link" value="two">Two
<input type="radio" name="link" value="three">Three
And I want the value of whichever one is checked to be passed to a variable such as
dt which then passes to the Submit button which takes you to a url that includes text from the radio buttons.
<input type="button" value="OK" id="ok_button" onclick="parent.location='/testfolder/' + dt;>
But I'm struggling to find out how to get
var dt = document.getElementByName('link').value;
to work for me when I try and apply a for loop to make sure it's checked.
Does my onclick='parent.location.... in the submit button need to be in a function rather than part of the submit button? So the same function can grab the value of the radio button?
So I'm appealing to StackOverflowers for hopefully a bit of guidance... Thanks
First of you want to know which value your combobox has with this easy to use on-liner.
document.querySelector('[name="link"]:checked').value;
I suggest using event handlers to handle the javascript, so don't write it in the onclick attribute.
var btn = document.getElementById('ok_button');
btn.addEventListener('click', function(){ /*handle validations here*/ })
jsfiddle
you can try below code
<input type="button" value="OK" id="ok_button" onclick="functionName();'>
JavaScript Code
<script type="javascript">
function functionName(){
var radios = document.getElementsByName('link'),
value = '';
for (var i = radios.length; i--;) {
if (radios[i].checked) {
value = radios[i].value;
break;
}
}
window.location.href='/testfolder/'+ value
}
</script>
var dt = document.getElementsByName('link')[0].value works for me
you can use it in either the inline onclick handler or a function you define
<input type="radio" id="1" name="link" onchange="WhatToDo()" value="one">One</input>
<input type="radio" id="2" name="link" onchange="WhatToDo()" value="two">Two</input>
<input type="radio" id="3" name="link" onchange="WhatToDo()" value="three">Three</input>
<script type="text/javascript">
function WhatToDo() {
var rButtons = document.getElementsByName('link');
for (var i = 0; i < rButtons.length; i++) {
if (rButtons[i].checked) {
alert(rButtons[i].value);
}
}
}
</script>
Maybe something like this. Use onchange and then loop through your radio buttons. Whilst looping look to see if the radio button is checked. Its a starting point.

Change button class and value for each click

I just made a timer with control, but in the control button i need some help.
Initially there have a button with START value. have to change the class and value to "STOP" for the 1st click and for the 2nd click change the class & value to "RESUME".
DEFAULT. <input class="start" type="button" value="START" />
1st click. <input class="stop" type="button" value="STOP" />
2nd click. <input class="resume" type="button" value="RESUME" />
3rd click. <input class="stop" type="button" value="STOP" />
4th click. <input class="resume" type="button" value="RESUME" />
Can you help me in this? and forgive my bad English.
FYI: i am using JQUERY MOBILE.
I haven't worked in JQuery mobile but this should be the way
JQuery
$(document).ready(function(){
$('input').click(function(){
if($(this).hasClass("start")){
$(this).removeClass("start");
$(this).addClass("stop");
$(this).val("STOP");
}else if($(this).hasClass("resume")){
$(this).removeClass("resume");
$(this).addClass("stop");
$(this).val("STOP");
}else if($(this).hasClass("stop")){
$(this).removeClass("stop");
$(this).addClass("resume");
$(this).val("RESUME");
}
});
})
for reference http://jsfiddle.net/zGMWR/1/
hope it helps
P.S. please put specific selector in jquery for your button.
Your initial value 'start' is irrelevant here as it only appears the very first time. So a simpler solution would be:
$(':button').on('click', function(){
$(this).removeClass('start stop resume');
if (this.value !== 'STOP') {
this.value = 'STOP';
$(this).addClass('stop');
} else {
this.value = 'RESUME';
$(this).addClass('resume');
}
});
An even shorter version would be:
$(':button').on('click', function(){
this.value = this.value !== 'STOP' ? 'STOP' : 'RESUME';
$(this).removeClass('start stop resume')
.addClass(this.value.toLowerCase());
});
Side info: answer from PSK: 376 Bytes; first answer here: 223 Bytes; second answer: 174 Bytes
Of Course you can wrap it in a $(document).ready(function(){ function if necessary
See http://jsfiddle.net/zGMWR/2/ and http://jsfiddle.net/zGMWR/3/ how it works
For a more specific selector and using event delegation you could use:
$('form').on('click', ':button', function(){...
or give the button an even more specific class name such as play-button

trouble with jquery and traversing the DOM to select the appropriate elements

Hello guys i have the below html for a number of products on my website,
it displays a line with product title, price, qty wanted and a checkbox called buy.
qty input is disabled at the moment.
So what i want to do is,
if the checkbox is clicked i want the input qty to set to 1 and i want it to become enabled.
I seem to be having some trouble doing this. Could any one help
Now i can have multiple product i.e there will be multiple table-products divs within my html page.
i have tried using jQuery to change the details but i dont seem to be able to get access to certain elements.
so basically for each table-product i would like to put a click listener on the check box that will set the value of the input-text i.e qty text field.
so of the below there could be 20 on a page.
<div class="table-products">
<div class="table-top-title">
My Spelling Workbook F
</div>
<div class="table-top-price">
<div class="price-box">
<span class="regular-price" id="product-price-1"><span class="price">€6.95</span></span>
</div>
</div>
<div class="table-top-qty">
<fieldset class="add-to-cart-box">
<input type="hidden" name="products[]" value="1"> <legend>Add Items to Cart</legend> <span class="qty-box"><label for="qty1">Qty:</label> <input name="qty1" disabled="disabled" value="0" type="text" class="input-text qty" id="qty1" maxlength="12"></span>
</fieldset>
</div>
<div class="table-top-details">
<input type="checkbox" name="buyMe" value="buy" class="add-checkbox">
</div>
<div style="clear:both;"></div>
</div>
here is the javascript i have tried
jQuery(document).ready(function() {
console.log('hello');
var thischeck;
jQuery(".table-products").ready(function(e) {
//var catTable = jQuery(this);
var qtyInput = jQuery(this).children('.input-text');
jQuery('.add-checkbox').click(function() {
console.log(jQuery(this).html());
thischeck = jQuery(this);
if (thischeck.is(':checked'))
{
jQuery(qtyInput).first().val('1');
jQuery(qtyInput).first().prop('disabled', false);
} else {
}
});
});
// Handler for .ready() called.
});
Not the most direct method, but this should work.
jQuery(document).ready(function() {
jQuery('.add-checkbox').on('click', function() {
jQuery(this)
.parents('.table-products')
.find('input.input-text')
.val('1')
.removeAttr('disabled');
});
});
use
jQuery('.add-checkbox').change(function() {
the problem is one the one hand that you observe click and not change, so use change rather as it really triggers after the state change
var qtyInput = jQuery(this).children('.input-text');
another thing is that the input is no direct child of .table-products
see this fiddle
jQuery('input:checkbox.add-checkbox').on('change', function() {
jQuery(this)
.parent()
.prev('div.table-top-qty')
.find('fieldset input:disabled.qty')
.val(this.checked | 0)
.attr('disabled', !this.checked);
});
This should get you started in the right direction. Based on jQuery 1.7.2 (I saw your prop call and am guessing that's what you're using).
$(document).ready(function() {
var thischeck;
$('.table-products').on('click', '.add-checkbox', function() {
var qtyInput = $(this).parents('.table-products').find('.input-text');
thischeck = $(this);
if (thischeck.prop('checked')) {
$(qtyInput).val('1').prop('disabled', false);
} else {
$(qtyInput).val('0').prop('disabled', true);
}
});
});
Removing the property for some reason tends to prevent it from being re-added. This works with multiple tables. For your conflict, just replace the $'s with jQuery.
Here's the fiddle: http://jsfiddle.net/KqtS7/5/

Categories