I have a bit of a problem, i have just inherited a colleague script and while i maintain his code, i am rewriting his, so that being said my problem is with the check boxes i can change the checks but after that i want to send the box that has been changed the element
so here is the on when i do the change
$(":checkbox[value=" + valu + "]").prop("checked","true");
and then i want to send it to his function: add2this(this, type);
var arrTmp // global array
function test( valu ){
$(":checkbox[value=" + valu + "]").prop("checked","true");
add2this(this, 'List');
}
function add2this(ths, type){
switch (type) {
case "List":
if (ths.checked) {
arrTmp.push(vl);
}
break;
default:
break;
}
}
hopefully the code will help to understand better
thanks
Your function is not passing the checkbox itself. You are using keyword "this" in a place where it does not mean what you think it means. You need to use jquery .each() .
function test( valu ){
$(":checkbox[value=" + valu + "]")
.prop("checked","true")
.each(function(){ add2this(this, 'List'); });
}
Related
I've got the following bit of code (using JQuery) that I've written for a project. The idea is to have a function that you can attach to an element within an "item" div and it will return the id of that div. In this case, the div id would be item-[some item primary key value]. This function works probably 9/10 times, but every once in a while it will get to the else else case and return false. I've verified through the console that the input for selector is the exact same JQuery $() item in both the success and fail cases.
I'm relatively new to JavaScript, so there may be something obvious I'm missing, but this is some really unusual behavior.
var recursionCounter = 0;
function getElementID(selector, recursionDepth, searchString){
console.log(selector);
var elementID = selector.attr("id");
if(elementID === undefined){
elementID = "";
}
if(elementID.indexOf(searchString) !== -1){
elementID = elementID.split("-")[1];
return elementID;
} else {
if(recursionCounter < recursionDepth){
recursionCounter++;
return getElementID(selector.parent(), recursionDepth, searchString);
} else {
recursionCounter = 0;
alert("The element clicked does not have an associated key.");
return false;
}
}
}
Here is an example of code that calls this function, for some context.
$(document).on("click", ".edit-pencil-item", function(event) {
//Use helper function to get the id of the surrounding div then pass it to the function
var itemID = getElementID($(this), 10, "item-");
jsEditItem(itemID);
return false;
});
Thanks in advance for any help!
If you want to get the encapsulating element of your clicked element, and you know it should have an id starting with "item-" you should be able to do something along the lines of
$(this).closest('[id^="item-"]').attr('id')
Which says find this elements closest parent that has an id starting with "item-" and tell me its id.
I feel silly asking this question. I have a javascript problem that I have been trying to solve since spring break.
I dynamically create divs to contain ratings for a product. But when I click on one of them, it always returns the last one.
for(var i=0; i < 5; i++) {
// Create Class called divReview
var divReview = document.createElement("div");
divReview.className = "divReview";
counter_ratings++;
var s = counter_ratings.toString();
divReview.id = "ratings" + s;
divReview.innerHTML = divReview.id;
$( divReview ).click(function() {
alert("You clicked " + divReview.innerHTML);
});
mainContainer.appendChild(divReview);
}
Here's the fiddle:
http://jsfiddle.net/alvasay/a9GZq/4/
I am pretty sure this is a simple problem, but I just can't see where I'm doing wrong. Thanks!
As mglison said, late binding. Alternative solution though is to use this in place of divReview in your click handler to reference the element being clicked.
$( divReview ).click(function() {
alert("You clicked " + this.innerHTML);
});
http://jsfiddle.net/a9HAH/
You're experiencing late binding. At the time the function is called, the value of divReview is the last value it had in the loop. I've solved it by creating a function which wraps the actual function to return so that you get the correct value from the closure:
Essentially, the code is something like:
for (...) {
...
var funcMaker = function(divRev) {
return function() {
alert("you clicked " + divRev.innerHTML);
};
};
$( divReview ).click(funcMaker(divReview));
}
http://jsfiddle.net/a9GZq/9/
Apart from the problem mentioned by mgilson, you have an odd mix of plain JS and jQuery. Here's a shorter version
for (var i = 1; i < 6; i++) {
var divReview = $('<div id="ratings' + i + '" class="divReview">ratings' + i + '</div>');
$('#gameContainer').append(divReview);
divReview.click(function() {
alert("You clicked " + this.innerHTML);
});
}
I have two very similar function that are called on different events i.e. 1st on 'onmousedown' and 2nd on 'onmouseup' . I am thinking to merge them into one to improve maintainability of my code. My problem is how could I find the current event inside switch statement ?
function update_button_to_idle(id){
var img = 'images/';
switch(id){
case 'abc1':
img += 'enter1.png';
break;
case 'abc2':
case 'abc3':
img += 'play1.png';
break;
}
$('#' + id + ' img').attr('src', img);
}
function update_button_to_active(id){
var img = 'images/';
switch(id){
case 'abc1':
img += 'enter2.png';
break;
case 'abc2':
case 'abc3':
img += 'play2.png';
break;
}
$('#' + id + ' img').attr('src', img);
}
Instead of using onXXX attributes, bind your handlers using jQuery:
$("selector").on("mousedown mouseup", function(event) {
update_button(this.id, event.type);
}
Then combine your functions into one update_button() function that takes two arguments.
Depending on how the event is registered - if you pass in the event to the function you can identify it by calling the event.type. For example:
function (event) {
if (event.type == "mousedown") {
}
}
Without knowing more about how the event is triggered, its hard to give you a complete answer.
That's not that great of a title for the question, so if anyone else has a better way to word it after reading it, that'd be appreciated.
Disclosure out of the way, this is homework. The assignment for this week is to refactor our already existing plain JS code to use JQM and I'm having an issue with a conversion I can't quite figure out, here's the code:
function populateItemLinks(key, listItem)
{
var ecLink = $('<a class="padRightRed"></a>');
ecLink.attr("href", "#");
ecLink.attr("key", key);
ecLink.html("Edit Character");
ecLink.on("click", editCharacter);
ecLink.appendTo(listItem);
console.log(ecLink.attr("key"));
ecLink = $('<a class="padLeftRed"></a>');
ecLink.attr("href", "#");
ecLink.attr("key", key);
ecLink.html("Delete Character");
ecLink.on("click", deleteCharacter);
ecLink.appendTo(listItem);
console.log(ecLink.attr("key"));
};
function deleteCharacter()
{
var toDelete = confirm("Do you wish to delete this character?");
if (toDelete)
{
console.log(this.key);
alert("Character was deleted.");
localStorage.removeItem(this.key);
$.mobile.changePage("#home");
}
else
{
alert("Character was not deleted.");
}
}
The issue is the using of the .key attribute as an itentified for the links in the populateItemLinks functions. When it was strait javascript, I could just do linkname.key = key; and then get the key back in the deleteCharacter function with "this.key". Well, now it's always returning undefined and I can't think of any way that wouldn't be convoluted to get the same functionality as the non-JQM version, so any help would be appreciated.
The reason your code is returning undefined is that you're trying to read a property of the DOM element, but you've set an attribute of the DOM element.
The top answers for this question explain the different between the two: .prop() vs .attr()
If you were to set the property of your newly created DOM element like this:
ecLink.prop('key', 12355);
And continued to directly access the DOM element (not via jQuery):
this.key; // 123455
All would of been well. Here is a JSFiddle example showing this in further detail.
Anyway, I've adjusted your code to work with the attribute you're setting:
function deleteCharacter()
{
var toDelete = confirm("Do you wish to delete this character?");
if (toDelete)
{
var key = $(this).attr('key');
alert("Character was deleted.");
localStorage.removeItem(key);
$.mobile.changePage("#home");
}
else
{
alert("Character was not deleted.");
}
}
Having said all this, Data attributes are better suited for storing arbitrary data against a DOM element:
ecLink.data('key', myKey); // set
ecLink.data('key'); // get
What I would do is pass the clicked ecLink as an argument to deleteCharacter() like this:
ecLink.on("click",function() { deleteCharacter($(this)); });
Then you can modify deleteCharacter():
function deleteCharacter(el)
{
var toDelete = confirm("Do you wish to delete this character?");
if (toDelete)
{
var key = el.attr('key'); //get the key attribute
console.log(key);
alert("Character was deleted.");
localStorage.removeItem(key);
$.mobile.changePage("#home");
}
else
{
alert("Character was not deleted.");
}
}
i need help on this one....i want to trigger the alert() e.g some code to execute after the change event on both input boxes....here is my code..
Millimeter: <input type="text" id="millimeter" class="filter"/>
Inch: <input type="text" id="inch" class="filter"/>
<script type="text/javascript">
$(document).ready(function(){
$(".filter").change(function(){
var value = this.value;
var id = this.id;
var convert = "";
switch(id)
{
case "millimeter":
convert = (value / 25.4).toFixed(2); //converts the value of input(mm) to inch;
$("#inch").val(convert).change();
break;
case "inch":
convert = (value * 25.4).toFixed(2); //converts the value of input(inch) to mm;
$("#millimeter").val(convert).change();
break;
default:
alert('no input has been changed');
}
alert(id+" triggered the change() event");
//some code here....
});
});
</script>
what i want is to trigger the alert() 2 twice...the result would be look like this..."Millimeter triggered the change() event"...and then when the other input box changes its value...."Inch triggered the change() event"....vice versa...i'm new to javascript and jquery...any help would be much appreciated..
The problem with your code is that in the change event of the first textbox you are triggering the change event of the second and thus entering in an endless loop. You should only use the following:
$("#inch").val(convert);
and:
$("#millimeter").val(convert);
in order to set the value of the other field but do not trigger change again.
Running your script on jsFiddle got me a "Maximum call stack size exceeded" error. This is because you're calling your .change() function inside of itself. I removed it, and it works fine.
Fiddle: http://jsfiddle.net/EwdLs/
$(".filter").change(function() {
var value = this.value;
var id = this.id;
var convert = "";
switch (id) {
case "millimeter":
convert = (value / 25.4).toFixed(2); //converts the value of input(mm) to inch;
$("#inch").val(convert);
break;
case "inch":
convert = (value * 25.4).toFixed(2); //converts the value of input(inch) to mm;
$("#millimeter").val(convert);
break;
default:
alert('no input has been changed');
}
alert(id + " triggered the change() event");
//some code here....
});
If you want each input's change to also trigger the other input's change, but don't want to get in an endless loop, try some variation on the following:
$(document).ready(function(){
function applyChange(el, changeOther) {
var value = el.value;
var id = el.id;
var convert,
other = "";
if (changeOther) {
switch(id) {
case "millimeter":
convert = (value / 25.4).toFixed(2);
other = "#inch";
break;
case "inch":
convert = (value * 25.4).toFixed(2);
other = "#millimeter";
break;
default:
alert('no input has been changed');
break;
}
if (other != "") {
$(other).val(convert);
applyChange($(other)[0], false);
}
}
alert(id+" triggered the change() event");
//some code here....
}
$(".filter").change(function(){
applyChange(this, true);
});
});
In case it's not obvious, I basically took your existing change handler and put it in a new function, applyChange, which has a parameter to tell it whether or not to recurse. The code as is is clunky, but it should give you the general idea of one way to do what you seem to be asking.
P.S. Be sure to add in some validation that what the user entered is really a number.