jQuery - calling function with parameters inside method - javascript

I'm wondering how is possible to call a function with parameters inside a method.
I have 2 functions and i'd like to call function deleteCode() when clicked on list element which is created by addCode() function.
I'm sure the solution is really simple, but i just can't see it right now.
Many thanks!
function addCode(code) {
$('#codeList').append('<li class="codeList" onClick="deleteCode(code);">' + code + '</li>');
}
function deleteCode(code) {
$('#'+code).remove();
}

Do it unobtrusive and you're fine.
function addCode(code) {
$('#codeList').append($('<li>', {
'class': 'codeList',
'text': code,
'click': function(e) {
deleteCode(code);
}
}));
}
Ref.: $()

Create the <li> element via code rather than appending raw HTML.
function addCode(code) {
// Create the <li>
var newEl = document.createElement("li");
newEl.className = "codeList";
// Assign the click function via jquery's event helper.
$(newEl).click(function(code) {
// Call your deleteCode function and pass in the given parameter.
deleteCode(code);
});
// Append the new element to the codeList node.
$(#codeList).append(newEl);
}

You can try:
function addCode(code) {
$('#codeList').append('<li class="codeList" onClick="deleteCode(' + code + ');">'+code+'</li>');
}

You can do that like this:
function addCode(code) {
$('<li class="codeList">' + code + '</li>').click(function() {
deleteCode(code);
}).appendTo('#codeList');
}
function deleteCode(code) {
$('#'+code).remove();
}
...or more simply:
function addCode(code) {
$('<li class="codeList">' + code + '</li>').click(function() {
$('#'+code).remove();
}).appendTo('#codeList');
}
When using a library like jQuery (or even when not, frankly), there's virtually never any reason to use the old-style onclick attributes for setting up handlers. In the above, I've replaced it with the click function, which sets up a handler when the user clicks the element.
Note: Lazarus notes that your code is removing an element by id using the code value:
$('#' + code).remove();
...but that the code doesn't produce an element with that ID. I assume you've added that element with some other code elsewhere, and that the goal isn't to remove the li you've added with this code.
If you did want to remove that same li on click, no need for an ID at all:
function addCode(code) {
$('<li class="codeList">' + code + '</li>').click(function() {
$(this).remove(); // <== Changed here
}).appendTo('#codeList');
}

Related

Grab URL parameter onclick of url.. Jquery, Javascript

I am having some trouble trying to store the url parameters of some dynamic links that I created with an ajax post response. The ajax post is working correctly and the name and subgenre vars are being properly filled from the ajax response. Now what I would like to happen is that a user clicks on one of the generated urls, the parameters inside of the urls, i.e. subgenre="blah", are going to be sent to a database and stored. The problem I am having is that a standard event click function will not work inside or outside of the document ready function.
$(document).ready(function() {
$.each(data, function() {
$('#artist-suggestions').append('<li>' + this.name + this.new + '</li>');
});
});
I then created an onclick function, as below, but I can not use the "this" query because it is outside of the document scope. I had to put the onclick function outside of the document ready function or else it would not work.
function artistGen(){
alert('dfdsf');
};
What am I missing here or what am I doing wrong?
You can pass these in the onclick function when you make each element.
$(document).ready(function() {
$.each(data, function() {
artist = this.name;
$('#artist-suggestions').append('<li>' + this.name + this.new + '</li>');
});
})
;
function artistGen(Blah1, Blah2){
saveData(Blah1, Blah2);
alert('dfdsf');
};
In jQuery for dynamic elements you can use the click event in this way
$('#artist-suggestions li').on('click', 'a', function() {
// do something
});
or you can continue with the way you did, by using a function but just add a parameter to that function
like
function artistGen(Artist){
// do something
};
You need to remove the artistGen() function from the scope of the .load()
$(window).load(function(){
$('#artist-suggestions').append('<li>jim new</li>');
});
function artistGen(){
alert('dfdsf');
}
JSFIDDLE DEMO
That's just how it is a function called in those event attributes have to be defined globally(or defined right there) not in any wrapper function. A better solution would be to attach event handlers.
$(document).ready(function() {
function artistGen(){
alert(this.href);
};
$.each(data, function() {
var $li = $('<li>' + this.name + this.new + '</li>');
$li.find('a').on('click', artistGen);
$('#artist-suggestions').append($li)
});
});

.each() bind hover events and pass a variable to handler functions

I'm trying to bind a hover event to some elements, walking through them with $.each, with the peculiarity that I want to pass a css classname as a parameter of the hover's handler functions, but it seems that the scope is not the one I'm expecting. I've tried to
$(document).ready(function () {
var $madewithLabels = $("#made-with .label");
// Binding
$madewithLabels.each(function (index) {
// get bootstrap css classname for the current element in the loop
var bsClass = getHoverClass($(this));
console.info("css class is: " + bsClass + " - " + typeof(bsClass));
$(this).hover(
function (bsClass) {
console.info(bsClass);
$(this).addClass(bsClass);
},
function (bsClass) {
console.info(bsClass);
$(this).removeClass(bsClass);
}
);
});
});
1st console.info: getHover() gets the right css class name (string) when the events are bound (on document ready)
2nd/3rd console.info: when hover's handler functions are executed bsClass is an object (I guess it's a jQuery one)
I've solved it this way:
$(document).ready(function () {
var $madewithLabels = $("#made-with .label");
// Binding
$madewithLabels.each(function (index) {
$(this).hover(
function () {
$(this).addClass(getHoverClass($(this)));
},
function () {
$(this).removeClass(getHoverClass($(this)));
}
);
});
});
But my questions are...
Is using $(this) the right solution?
Why when I pass a string variable to the handler functions I get an object when the function is called? is it because some type casting? is it because closure scope?
Thanks to the jQuery gurus answering!
What you're getting in the hover callback is an Event object, as mentioned by the docs:
handlerIn
Type: Function( Event eventObject )
A function to execute when the mouse pointer enters the element.
So in your first example change:
function (bsClass) {
To this:
function () {
So you keep using the original bsClass that you calculated before.

Combine two jQuery-json functions. Right way

I'm totally newbie in jQuery and i wonder if it is possible to combine these two functions.
As you can see, the first function is used to load json data to trigger a click.
The second function is used to toggle view for the list items.
Could you help me, and show me the good way to combine these functions!?
When the json file is loaded, it will be create the list elements (li), and the toggle will be able to toggle these list elements (li).
IMPORTANT: actually, my code don't work (the toggle function not work fine).
Here is the code of 1st functions :
$(document).ready(function() {
// ----------------------
// JSON INFOS
// ----------------------
$(".color-list.one li:first-child").on('click', function() {
$.getJSON("result.json", function(data) {
//Handle my response
$('ul.elements-list').html(
'<li class="elements-item"><span class="tog">' + data.name + '</span><div class="togcont hidden">' + data.info + data.size + '</div></li>');
//alert(data);
});
});
});
The code of 2nd function :
$(document).ready(function() {
// ----------------------
// TOGGLE BULLZ
// ----------------------
$(".tog").click(function(){
var obj = $(this).next();
if($(obj).hasClass("hidden")){
$(obj).removeClass("hidden").slideDown();
$(this).addClass("bounce");
} else {
$(obj).addClass("hidden").slideUp();
$(this).removeClass("bounce");
}
});
});
When you use $(".tog").click() it only binds to whatever elements match the ".tog" selector at that moment so won't work on elements that you add dynamically later. You can instead use the delegated syntax of .on() like this:
$('ul.elements-list').on("click", ".tog", function(){ ...
...which will bind the click handler to your list, but only execute your function if the click occurred on an element in that list that matches the ".tog" selector in the second parameter at the time of the click. And within the handler this will be set to the ".tog" element that was clicked.
Also you can put all your code in a single document ready handler assuming all the code is in the same file.
Also your obj variable is a jQuery object, so you can call jQuery methods on it directly like obj.hasClass() rather than wrapping it in $() again as $(obj).hasClass().
So try this instead:
$(document).ready(function() {
$(".color-list.one li:first-child").on('click', function() {
$.getJSON("result.json", function(data) {
//Handle my response
$('ul.elements-list').html(
'<li class="elements-item"><span class="tog">' + data.name + '</span><div class="togcont hidden">' + data.info + data.size + '</div></li>');
});
});
$('ul.elements-list').on("click", ".tog", function(){
var obj = $(this).next();
if(obj.hasClass("hidden")){
obj.removeClass("hidden").slideDown();
$(this).addClass("bounce");
} else {
obj.addClass("hidden").slideUp();
$(this).removeClass("bounce");
}
});
});

How to write jquery selectors for dynamically generated html elements?

I'm currently writing an object oriented module which assigns callback to dynamically generated elements.
function Instant(containerID) {
this.var1 = 0;
this.var2 = 0;
this.containerID = containerID;
// and more variables...
};
And here containerID is the id of a DIV which is dynamically generated. I populate this DIV via Ajax Request which reads a file like the following:
<!-- content.html -->
<div class="general_container">
<div class="top_container">
<!-- plenty of divs, spans etc -->
</div>
<div class="tweet_section">
<!-- plenty of divs, spans etc -->
</div>
</div>
Now the important part is, I assign all callbacks like the following:
Instant.prototype.addCallbacks = function() {
$(this.containerID + " bar").click(function() {
$(this.containerID + " bar").foo();
});
$(this.containerID + " bar").click(function() {
$(this.containerID + " bar").foo();
});
$(this.containerID+ " bar").click(function(e) {
$(this.containerID + "bar, " + this.containerID+ " bar").foo();
});
});
As you see, I always have to put this.containerID before each selector to assign events. (Therefore, I make sure I'm selecting only one element) Now, my code is full of clutter as I have plenty of this.containerIDs. I don't know if there is a smarter method to make my code easy. Any help will be appreciated.
Here is a sample JSFiddle.
Note that this is not my real module, I just made it up to make it clear!
Then you shouldn't be using IDs. You should be using classes instead.
It would take long to edit your code, but here's a hint: Add a handler to the parent. Use event delegation, like .on(). Then have it listen for all children, now or future.
Create a separate java script file and put your add callbacks function in there and just pass the containerID. That way, you can re-use it later. However, looks like you cannot get rid of containterID since you will be needing that to do your add, subtract, save etc..
in your current file shown as above,
Instant.prototype.addCallbacks = createAddCallbacks(this.ContainerID);
create addCallbacks.js
function createAddCallbacks(containerId)
{
Instant.prototype.addCallbacks = function() {
$(containerId + " bar").click(function() {
$(containerId + " bar").foo();
});
$(containerId + " bar").click(function() {
$(containerId + " bar").foo();
});
$(containerId+ " bar").click(function(e) {
$(containerId + "bar, " + containerIdD+ " bar").foo();
});
});
}
Like #JosephTheDreamer said, use Event Delegation. (Jquery.fn.on)
Using event delegation you set one handler to multiple targets. It means just one handler in memory and dynamic event handlers set.
I made a demonstration modifying your code, take a look...
Instant.prototype.addCallbacks = function () {
var selfContainer = null, // DOMElement container
me = this; // Object reference
$('body').on("click", ".selection_container .btn-add", function () { //Using event delegation
selfContainer = $(this).parents(".general_container"); //set DOMElement
selfContainer.find("input[name=currentValue]").val(++me.instantValue);
});
$('body').on("click", ".selection_container .btn-subtract", function () {
selfContainer.find("input[name=currentValue]").val(--me.instantValue);
});
$('body').on("click", ".selection_container .btn-reset", function () {
me.instantValue = 0;
selfContainer.find('input[name=currentValue]').val(0);
});
$('body').on("click", ".selection_container .btn-save", function () {
me.savedValue = me.instantValue;
});
$('body').on("click", ".selection_container .btn-load", function () {
me.instantValue = me.savedValue;
selfContainer.find('input[name=currentValue]').val(me.savedValue);
});
};
Hope it helps...
So, I think I find a better method according to this post
I wanted to limit the scope of my selector.
Firstly, I'll create a jQuery instance variable
function Instant(containerID) {
this.var1 = 0;
this.var2 = 0;
this.container= $('#'+containerID);
// and more variables...
};
and adding a new prototype like this
Instant.prototype.$ = function(selector){
return this.container.find(selector);
};
I'll only use this.$(selector) function which is better.

Only last item has bound click/hover events?

I'm a newbie to Javascript & HTML5. I'm iterating through a set of objects called requests and creating divs for them. I'm trying to have it so that if any of the items are hovered over the style class changes, and if they are clicked on that I will later invoke a function but for now just want an alert. Only the last item gets it.
I've looked at what seemed like similar issues other people have had, but I can't see where I am going wrong.
for (i= 0; i<reqs.length; i++) {
var requestID = "request"+i;
// Build the DIV for each request
element.innerHTML += "<div id="+requestID+" class=request><img class=requestImage src=images/"
+reqs[i].image+" alt=Face /> "+reqs[i].name+"</div>";
var requestElement = $('#'+requestID);
requestElement.hover(
function() {
$(this).removeClass().addClass("requestHover");
},
function() {
$(this).removeClass().addClass("request");
}
);
requestElement.click(
// if the request is clicked, then alert me - testing
function() {
alert('Handler for .click() called.');
}
);
}// end for
From my understanding the $('#request1') should reference the first div item, and $('#request2') the second, etc. It behaves like each .hover and .click assignment overwrites the previous one.
I'd write it this way
for (i= 0; i<reqs.length; i++) {
var requestID = "request"+i;
// Build the DIV for each request
element.innerHTML += "<div id="+requestID+" class=request><img class=requestImage src=images/"
+reqs[i].image+" alt=Face /> "+reqs[i].name+"</div>";
}// end for
var requestElement = $(".request");
requestElement.hover(
function() {
$(this).removeClass().addClass("requestHover");
},
function() {
$(this).removeClass().addClass("request");
}
);
requestElement.click(
// if the request is clicked, then alert me - testing
function() {
alert('Handler for .click() called.');
}
);
Edit to answer to your comment:
No, it's a matter of closure. At the end of the loop, requestID is always the same, so $("#"+requestID); is always the same. It's has if there is only one bind.
To overcome such a thing, you have some option:
using $.each to loop (see http://forum.jquery.com/topic/binding-event-to-element-dynamically , http://forum.jquery.com/topic/binding-click-event-in-a-loop, http://api.jquery.com/jQuery.each/ )
using the live() method (see http://api.jquery.com/live/, http://jsfiddle.net/VrzUb/1/ (used for the click))
assigning the events thanks to a selector common to each object (e.g. using classes, as above)
You can assign the event listener after the for loop, maybe that solves your problem:
for (...) {
}
$('div.request').hover( ... );

Categories

Resources