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
Related
I am having an issue pulling the data attributes out of an input when using onclick="javascript()" syntax.
Here is a jsfiddle of what I am trying:
https://jsfiddle.net/123umaon/2/
<div>
<input onclick="Test();" type="button" value="test" data-section="thisSection"/>
</div>
function Test(){
var test = $(this).data('section');
alert(test);
}
I want to be able to pull the value of 'data-section' with the onclick action. But in my example it always comes back undefined.
You need to reference the current event. In the Test() function context, this refers to the window, instead of the DOM element.
$('#testOut').val("TEST TEST");
function Test(){
var test = $(event.currentTarget).data('section');
alert(test);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<input onclick="Test();" type="button" value="test" data-section="thisSection"/>
</div>
Note: The window.event variable I'm using here is frowned upon on new code.
$('#testOut').val("TEST TEST");
function Test(selector){
var test = selector.data('section');
alert(test);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<input onclick="Test($(this));" type="button" value="test" data-section="thisSection"/>
</div>
function Test(btn){
var test = $(btn).attr("data-section");
alert(test);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<input onclick="Test(this);" type="button" value="test" data-section="thisSection" />
</div>
The problem is with your selector. "$(this)" in your example returns a reference to the function Test. Instead pass in this to the function and select off of the passed value.
Also, I would use the jQuery attr() funtion to set and return values on a custom property.
Your function passes in the "Window" object, you'd need to refine what you're passing through.
For getting the data-section attribute, you can use the .getAttribute() method on the element. It works similarly to .setAttribute().
https://www.w3schools.com/jsref/met_element_getattribute.asp
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/>
I have div with generated input fields. After button click I want to refresh div and then set values.
<div>
<input id="1" name="1" type="text" />
<input id="2" name="2" type="text" />
</div>
<button type="button" onClick="change();">Change</button>
Javascript function:
function change(){
$('div').load(' div');
$("input[type='text']").val("some text");
}
Why after load I can't set values for input? How can I solve it? Thanks
.load() is asynchronous. So when you do this:
$('div').load(' div');
$("input[type='text']").val("some text");
That second line executes before the content has been loaded. In order to respond to the completion of the content being loaded, you need to use the callback function:
$('div').load(' div', function () {
$("input[type='text']").val("some text");
});
I'm trying to hide a div when the value = 10
Here is the code and demo working fine:
<script>
$('input[name=test]').keyup(function(){
if($(this).val()<10)
$('#yeah').show();
else
$('#yeah').hide();
});
</script>
<label>Type whatever</label>
<input type="text" name="test"value="10" />
<div id="yeah" style="display:none;">
<input type="submit" />
</div>
But I'm trying to convert that code into Prototype code and I tried this code:
Event.observe(window, 'load', function () {
$('input[name=test]').keyup(function(){
if($(this).val()<10)
$('#yeah').show();
else
$('#yeah').hide();
});
});
I only want to hide the div when input value = 10 into prototype code.
Please somebody can help me?
Give the textbox an ID. For example:
<input type="text" id="txtbox" name="test" value="10" />
Change:
<div id="yeah" style="display:inline;">
To:
<div id="yeah" style="display:none;">
You need to use the $$ function which returns an array.
Event.observe('txtbox', 'keyup', function () {
if ($$('input[name="test"]')[0].value < 10){
$$('#yeah')[0].show();
}
else{
$$('#yeah')[0].hide();
}
});
Note: You could also use .first() instead of [0]
JSFiddle
you have a issue with prototype lib,
the Event.observe function is never triggered, secondly, you seem to still using the jquery api
$().keyup()
and you only load the prototype function.
Now days people rarely uses prototype, people use jquery for dom and underscore/lodash for iterations.
I have a form tag with a progress tag and three submit as following:
<form>
<progress min="0" max="100" value="0"></progress>
<input type="submit" value="submit1">
<input type="submit" value="submit2">
<input type="submit" value="submit3">
</form>
I have a little js code which listens click event and changes the value of progress bar.
;(function(){
document.body.addEventListener('click', function(){
var p = document.querySelector('progress');
var s = document.querySelector('input');
var val;
if(s.value=="submit1"){
val=33;
}
if(s.value=="submit2"){
val=66;
}
if(s.value=="submit3"){
val=100;
}
p.value=val;
}, false);
}());
But the progress bar is not working as expected.
Any point where I can solve this?
About document.querySelector:
Returns the first element within the document (using depth-first pre-order traversal of the document's nodes) that matches the specified group of selectors.
So, the code always will return "submit1", because it is the first element in the document.
Also form's submit make callback to the page, and you can't see the changes, because the code will return to initial stage.
If you doesn't want to do the callback, just change inputs types to "button".
Also, I offer you to attach onclick event to each button and call functionality that you want.
EDIT: The worked code bellow.
<form>
<progress min="0" max="100" value="0" id="progressBar1"></progress>
<input type="button" value="submit1" onclick="SubmitProgress(33);" />
<input type="button" value="submit2" onclick="SubmitProgress(66);" />
<input type="button" value="submit3" onclick="SubmitProgress(100);" />
</form>
<script type='text/javascript'>
function SubmitProgress(valueToSet) {
document.getElementById("progressBar1").value = valueToSet;
}
</script>
In your javascript - a typo might is what killed the script. Instead of using
;(function(){
Use this:
$(function(){