livequery doesn't bind after a DOM insertion - javascript

I don't understand why livequery doesn't bind the event, but I have to use .click.
This is just an example, which might also use the .click(), but in the real code I'm forced to use livequery.
Does anyone know why livequery isn't working?
function bind_remove(comment){
var id = comment.attr('comment_id');
comment.find(".remove").livequery("click", function(e){
$.post("/deleteComment", {id: id}, function(response){
comment.remove();
comments = comments_container.find('.comment');
});
});
}
$(document).ready(function(){
var comments_container = $('#comments_container');
var comments = comments_container.find('.comment');
comments.each(function(){
bind_remove($(this));
});
$(".submit_button").livequery("click", function(e){
$.post("/newComment", {text: textarea.val()}, function(response){
comments_container.last().append($(response).fadeIn('slow',function(){
comments = comments_container.find('.comment');
bind_remove(comments.last());
}));
});
});
});

Try replacing
comment.find(".remove").livequery("click", function(e){
with this
comment.find(".remove").live("click", function(e){

I added a random id to the last comment, then I selected it with $('#myid'), not using 'last()'. Then I bind it and started to work

Related

jQuery Eventhandler for an dynamically added object

I got an problem with dynamically added DOM objects in jQuery. First of all I use this:
var $input = $('#search-input');
var $usersList = $('#ulist');
$input.on('input', function () {
$.ajax({
type: 'get',
url: '/userlist',
data: {query: $input.val()},
success: function (response) {
var json = JSON.parse(response);
$usersList.empty();
$.each(json, function (index, val) {
$usersList.append("<div id=\"listelem\">" + val + "</div>");
});
}
});
});
<div id="ulist"></div>
<input id="search-input" type="text">
to insert divs into usersList. This works well, but now I want to get val from this div when I click on it to process it further. I wrote this piece of code:
$usersList.on('click','#listelem', function(){
alert("clicked");
});
When I click on div I got proper alert, but now I have no idea how could I took data from inside of this element.
I don't know the proper engineering but I have dealt with similar issue while I was developing some requirements. basically as I understood you want to find out the target of the event and drag a value from there? if so you can do something like this:
jQuery(document).on('click', '#listelem', function(event){
var x = event.target.val();// event.target.value; depending on your situation and availability of the method.
});
Hope this helps.
try this
$(document).on('click','#listelem', function(event) {
alert($(event.target).text());
});
jsfiddle
Thanks you for help. for me proper option was to call
var mem =event.target.innerText;
you can do that with the regular javascript, you don't need Jquery.
document.addEventListener("click", function(e) {
if(e.target) {
console.log("item clicked ", e.target.textContent);
}
});
This should do the job to get the value of current target.

Simplifying a jQuery functions

I was wondering the method of simplifying this script, because somehow I am repeating myself all over again...
$('.userprofile').click(function(){
card_profile.load(url_settings).dialog('open');
});
$('.cust-profile').click(function(){
card_profile.load(url_customer).dialog('open');
});
$('.my-profile').click(function(){
card_profile.load(url_my).dialog('open');
});
var obj = {
'.userprofile' : url_settings,
'.cust-profile': url_customer,
'.my-profile' : url_my
};
$.each(obj, function(sel, url) {
$(sel).click(function(){
card_profile.load(url).dialog('open');
});
});
or
$(".userprofile,.cust-profile,.my-profile").click(function() {
var url = $(this).hasClass("userprofile") ? url_settings :
$(this).hasClass("cust-profile") ? url_customer :
url_my;
card_profile.load(url).dialog("open");
});
This is somewhat better, but you can't get significant gain I guess:
$('.userprofile').data('url',url_settings);
$('.cust-profile').data('url',url_customer);
$('.my-profile').data('url',url_my);
$('.userprofile, .cust-profile, .my-profile').click(function(){
card_profile.load($(this).data('url')).dialog('open');
});
If you assign URL to every button, then you don't have to repeat the classes:
$('button').click(function(){
card_profile.load($(this).data('url')).dialog('open');
});
One way to do this would be to iterate over an array (or two) of strings.
Edit: declared i outside of for loop to address comment from #crazytrain
arr = ['user', 'cust', 'my'];
url_arr = [urlA, urlB, urlC];
var i;
for (i in arr){
$('.' + arr[i] + '-profile').click(function(){
card_profile.load(url_arr[i]).dialog('open');
});
}
$(document).on('click', function(e){
if($(e.target).hasClass('userprofile')){
card_profile.load(url_settings).dialog('open');
}
if($(e.target).hasClass('cust-profile')){
card_profile.load(url_costumer).dialog('open');
}
if($(e.target).hasClass('myprofile')){
card_profile.load(url_my).dialog('open');
}
It's a little better with a function:
$('.userprofile').click(function(){
loadDiag(url_settings);
});
$('.cust-profile').click(function(){
loadDiag(url_customer);
});
$('.my-profile').click(function(){
loadDiag(url_my);
});
function loadDiag(url){
card_profile.load(url).dialog('open');
}
You could also switch through the parameter and do multiple things per click
$('.my-profile, .userprofile, .cust-profile').click(function(){
card_profile.load(url).dialog('open');
});
Edit: on second thoughts - do what Eltier says.
Assign a url attribute to each element. Then you can retrieve that value and use in your code in this way.
$('.userprofile').attr('url',url_settings);
$('.cust-profile').attr('url',url_customer);
$('.my-profile').attr('url',url_my);
$('.my-profile, .userprofile, .cust-profile').click(function(){
var url = $(this).attr('url');
card_profile.load(url).dialog('open');
});
You could use the html data attribute and have it simple like this
$('.userprofile, .cust-profile, .my-profile').click(function(){
var url = $(this).attr('data-url');
card_profile.load( url ).dialog('open');
});
<div class="userprofile" data-url="settings.php">Settings</div>
And to make it even better you could add a class to all load items like this
$('.load-box').click(function(){
var url = $(this).attr('data-url');
card_profile.load( url ).dialog('open');
});
<div class="userprofile load-box" data-url="settings.php">Settings</div>
Throwing another hat in the ring here...
var links = [{profile: '.userprofile', url: url_settings, clickDialog: 'open'},
{profile: '.cust-profile', url: url_customer, clickDialog: 'open'},
{profile: '.my-profile', url: url_my, clickDialog: 'open'}];
function clickOpen(url,value) {
card_profile.load(url).dialog(value);
}
links.forEach(function(element) { $(element.profile).click(
clickOpen(element.url,element.clickDialog) });
You can save a parameter in de caller object and then do something like this:
$('.userprofile, .cust-profile, .my-profile').on('click',function(){
var parameter = $(this).data( 'parameter' );
card_profile.load( parameter ).dialog( 'open' );
});
You can find more information about storing data here, is very easy.

How can I trigger on URL change in jQuery?

How can I trigger a function when the URL changes? I try something like:
$(windows.location).change(function(){
//execute code
});
So my URL is something like http://www.mysite.com/index.html#/page/1. How can I execute jQuery or JavaScript code when the URL becomes something like http://www.mysite.com/index.html#/page/2?
That would be a hashchange event, so I'd suggest:
$(window).on('hashchange', function(e){
// do something...
});
JS Fiddle demo.
References:
on().
Try the hashchange event, which is built exactly for this - http://benalman.com/projects/jquery-hashchange-plugin/
var current_href = location.href;
setInterval(function(){
if(current_href !== location.href){
// if changed Do ...
current_href = location.href;
}else{
// Do ...
}
},500);
This worked for me ^^
$(window).on('hashchange') // not firing
You could also try using http://www.asual.com/jquery/address/
$(function(){
$.address.strict(false);
$.address.internalChange(function(e) {
// do something here
});
});
To Detect URL change only for pop use
window.onpopstate = function (event) {
//enter code here
}

How to reduce my repeated jQuery code

first post here at this great website!
I would like to reduce the amount of code for the following, espacially as there are more parts I need to add in the future - I'm sure there must be an easy way but I'm just not seeing it. Thanks for your help!
$(document).ready(function(){
$(function(){
$('#iqdrive').click(
function(){
$('#iqdrive-cont').show();
});
});
$(function(){
$('#optiwave').click(
function(){
$('#optiwave-cont').show();
});
});
$(function(){
$('#vario').click(
function(){
$('#vario-cont').show();
});
});
$(function(){
$('#autostain').click(
function(){
$('#autostain-cont').show();
});
});
$(function(){
$('#autoload').click(
function(){
$('#autoload-cont').show();
});
});
});
Firstly, you don't need to nest document.ready functions (all the $(function() { are redundant as it is equivalent to document.ready). And to simplify your code:
$(function() {
$('#iqdrive, #optiwave, #vario, #autostain, #autoload').click(function() {
$('#' + this.id + '-cont').show();
});
});
All of the internal $(function()) calls are unnecessary, since $(function()) is an alias for $(document).ready(function()). Your example shows a lot of repetition of the same sort of task; that's very easy to consolidate.
$(document).ready(function(){
$('#iqdrive, #optiwave, #vario, #autostain, #autoload').click(function(){
$($(this).attr("id") + "-cont").show();
});
});
What that does is register for clicks on elements with any of those IDs, and on click, gets the ID of the clicked element, appends -cont, and uses that as a selector to get a set of elements to show.

Javascript Jquery doesn't work. $(this)

$(document).ready(function() {
$(".delete_user_button").click(function(){
var username_to_delete = $(this).attr('rel');
$.ajax({
type:"POST",
url:"/delete/",
data:{'username_to_delete':username_to_delete},
beforeSend:function() {
$(this).val("Removing...");
},
success:function(html){
$("div.delete_div[rel=" + username_to_delete + "]").remove();
}
});
return false;
});
});
Why doesn't $(this).val() work?
I'm trying to change the text of the button when the user clicks remove.
In your event handler (beforeSend), this refers to the XMLHttpRequest object used for the ajax call, not your original this of the click event handler. You should "capture" it in a variable first:
$(document).ready(function() {
$(".delete_user_button").click(function(){
var element = $(this);
var username_to_delete = element.attr('rel');
$.ajax({
type:"POST",
url:"/delete/",
data:{'username_to_delete':username_to_delete},
beforeSend:function() {
element.val("Removing...");
},
success:function(html){
$("div.delete_div[rel=" + username_to_delete + "]").remove();
}
});
return false;
});
});
This mechanism is called "closures". For an interesting explanation of this, check this link:
http://www.bennadel.com/blog/1482-A-Graphical-Explanation-Of-Javascript-Closures-In-A-jQuery-Context.htm
Without more knowledge about the context or analysing the script itself: Keep in mind that, in certain environments, it might be possible that $ itself does not work and needs to be replaced with jQuery - I've seen this in Liferay.
I guess this is not your problem here, but it might come in handy for others looking for this problem from another context.

Categories

Resources