I have a problem with the jQuery's live() function.
I'm creating the shopping basket with PHP and make a json call to the php script to add specific item to the basket. Rather than re-binding the click to the button ( tag) I've decided to use live(), however it doesn't seem to like it.
Here's my call:
if ($('.add_to_basket').length > 0) {
$('.add_to_basket').live('click', function() {
var button = $(this);
var id = $(this).attr("rel");
$.getJSON("/basket/action/add/id/" + id, function(data) {
if (!data.error) {
$('.basket_no_of_items').text(data.no_of_items);
$('.basket_items_total').text(data.total);
button.text('Remove from the basket');
}
});
return false;
});
}
Any idea what I might be doing wrong?
I've checked with firebug and it seem to post the request to only /basket/action/add - without id bit.
The whole idea of using live() is to register a function on the occurrence of an event (eg. click) on a set of elements whether they exist or not at the time of creation of the function.
Adding ($('.add_to_basket').length > 0) will check whether this particular set of elements exist or not. This is counter productive as per my description above. So, either:
Remove ($('.add_to_basket').length > 0) and this should work for all .add_to_basket elements
Change $('.add_to_basket').live('click', function() {...}); to $('.add_to_basket').click(function() {...}); and wrap it around with a $(document).ready() to ensure that all DOM elements have loaded when the function is registered to the click.
Hope this makes sense.
Sumit
Try removing the "length" check, I bet it's interfering with the .live() function.
change $.getJSON("/basket/action/add/id/" + id, function(data) {})
to $.getJSON("/basket/action/add/id/" ,{ pid : id}, function(data) {})
Related
I have two different IDs. One auto increment (using jquery) from an ID called id="H+currentRow+"(+currentRow+ is the current row). And another that does an ajax request to PHP that appends the form with an id="Z#"(# will be depending on the ID in the database).
Ive done this:
$(document).ready(function(){
$("input").change(function(){
var sum=0;
$("[id^=H]").each(function(){
sum=sum+(+parseInt(this.value));
});
var sum2=0;
$("[id^=Z]").each(function(){
sum2=sum2+(+parseInt(this.value));
});
var total = sum + sum2;
if(isNaN(total)) {
var total = 0;
}
$("#total").text(total);
});
});
But thats not working. It works for the first fields but it work for anything else thats being appended. Anyone know whats going on and why its not working?
when you bind an event direct to an element, new elements appended to page will not trigger the event. you have to bind a parent element where inputs are appended to.
Try this bind:
$('body').on('change', 'input', function () {
// your code remain the same here...
});
you can be more specifc than body, binding the event to parent elements of input.
Unable to use id or class of the label, which one is fetching from php...
My Code is:
$.ajax({
type:'POST',
url:"<?php echo base_url(); ?>main/user_list",
data:"",
async:false,
success: function(rest)
{
$('#list').html(rest);
}
})
PHP Code is:
function user_list()
{
$dir="chat_files/";
$files1 = scandir($dir);
$files1=array_reverse($files1);
$count=count($files1);
for($i=0;$i<=$count-1;$i++)
{
$file_nm=explode(".",$files1[$i]);
echo "<label id=$files1[$i] class='user'>".$file_nm[0]."</label><br>";
}
}
This is not working:
$('.user').click(function(ace)
{
alert('Work');
});
I am using codeigniter ajax send data to controller function and then show html results but in that result i am unable to use label id or class for further action... please help..
Since your elements have been added dynamically to the DOM through the AJAX call, the click event will not be available to these elements until you attach it. In this case, you can use event delegation:
Event delegation allows us to attach a single event listener, to a
parent element, that will fire for all children matching a selector,
whether those children exist now or are added in the future.
$('#list').on('click','.user', function() {
alert('Work');
});
use delegation using .on for dynamically created element:
$(document).on('click','.user',function(ace)
{
alert('Work');
});
I thought the easiest way would be to explain it with an image of what I have.
Summary -
I have a form to submit posts (pretty much like what you would find in twitter). Within each post there is an <ol> where comments to that post will reside.
Problem -
When I submit the first comment (button submit 2 in the picture), it doesn't call the ajax and just goes to a page where it presents me the php output of the comment. It seems it is not reloading or aplying DOM events to that portion of code. If I go back, the comment is presented (because it refreshs the page) and when adding the 2nd comment, everything goes normal, as expected. The problem is just the first comment.
Flow -
1) insert new post
2) click the textarea, put some text and press submit
3) Jumps to a page where php output for comment is presented
3a) no ajax call is done. It never enters the code
Could you please help me out understand what is going on? Thanks in advance.
In case you need more of the code just tell me.
JS (post_comment.js - associated with submit 2 in picture. I use ajaxForm - jquery form plugin - though I also tried with the standard .ajax call and the result is the same)
$(function () {
var options = {
success: function (html) {
var arrHTML = html.split(',');
var postId = $.trim(arrHTML[0]);
var html_code = arrHTML[1];
$('ol#post_comment_list' + postId).load(html_code);
//$('ol#post_comment_list'+postId 'li:first').slideDown('slow');
$('.footer-post').hide();
$('.comments-feed').delay(2000).slideUp({
duration: 1000,
queue: true
});
$('.small-textarea-main-feed').removeClass('set-large');
resetForm($('.footer-comment'));
},
error: function () {
alert('ERROR: unable to upload files');
},
complete: function () {
},
};
$(".footer-comment").ajaxForm(options);
function ShowRequest(formData, jqForm, options) {
var queryString = $.param(formData);
alert('BeforeSend method: \n\nAbout to submit: \n\n' + queryString);
return true;
}
function resetForm($form) {
$form.find('input:text, input:password, input:file, select, textarea').val('');
$form.find('input:radio, input:checkbox')
.removeAttr('checked').removeAttr('selected');
}
});
I am working on a site right now and have discovered that the jquery/javascript that I have implemented for the Search applies the same effect to all search boxes on the page when I click in the input field. By default, it removes the "Search" text and clears it out so that you can type your search term. I only want it to perform this function on the search box that is clicked within, not all search boxes on the page. However, if you look at this example, you'll notice that when you click into the search field at the top of the page, it clears the text out of both. I think I could fix it with .parent() or something, but am a jQuery novice. Any help would be appreciated.
Also don't know quite why the border is showing up around my icon, but I'll fix that.
Here's the search function jQuery:
$(document).ready(function(){
$('.search-box').textdefault({'text':'Search'});
});
(function($){
$.fn.textdefault = function(settings){
var Elements = this;
var settings = $.extend({}, $.fn.textdefault.defaults, settings);
return Elements.each(function(){
if($(Elements).is("input")){ TextDefault( $(Elements) ); }
});
function TextDefault(Input){
if (Input.val().length==0) Input.val(settings.text);
Input.focus(function () {
if (Input.val()==settings.text) Input.val('');
});
Input.blur(function () {
if (Input.val().length==0) Input.val(settings.text);
});
}
};
$.fn.textdefault.defaults = {
text: 'Search'
};
})(jQuery);
Thanks!
Taylor
plugin example
here is the correction.
Elements contains all the elements that are 'passed' to this plugin.
var Elements = this;
By using $(Elements) instead of $(this) in the each function, you
used all inputs as one
return Elements.each(function() {
if ($(this).is("input")) {
TextDefault($(this));
}
});
This line of code should be called to initialize the plugin. So it should be put somewhere outside of the plugin, in a $(document).ready() {} code block for example, since you need the plugin initialized for the inputs on the load of the page.
$('.search-box').textdefault({
'text': 'Search'
});
Use a different selector. Instead of all inputs with a class of "search-box" try giving it a unique ID or class.
$("#search_default").textdefault({'text':'Search'});
or
$(".search-box.defaulttext").textdefault({'text':'Search'});
The HTML would then be
<input type="text" class="search-box defaulttext" ...
or
<input type="text" id="search_default" ...
This is the method that I use, which could also be helpful for you. It won't fire for both objects since it uses $(this) to control just the object being focused/blurred.
$(".search-box").live("focus", function(){
if ( $(this).val() == $(this).attr("rel") ){
$(this).val('');
}
}).live("blur", function(){
if ( $(this).val() == '' ) {
$(this).val( $(this).attr("rel") );
}
}).each( function(){
$(this).attr("rel", $(this).val() );
});
I would try to use a more "jQuery" way to do this. jsFiddle
$('input').focus(function(){
$(this).data('text', $(this).val()).val('');
});
$('input').blur(function(){
if( $(this).val() === "" ) $(this).val( $(this).data('text') );
});
How can I hide and show a div (and change the width of another div) using the same link,for example I can show A div and change its widht. How can I make it so that if the user clicks again, the width goes back to 600px and the right div is hidden.
$("a").click(function(event){
$('#main-content').width(800);
$('#right').show('slow').slideDown('slow');
event.preventDefault();
});
EDIT:
From All your replies, I've done this:
$(document).ready(function(){
$('#right').hide();
$('#main-content').width(600);
$('#show-stats').toggle(function() {
$('#main-content').width(800);
$(this).text($(this).text() == 'Show' ? 'Hide' : 'Show');
$('#right').show('slow').slideDown('slow').fadeIn('slow');
event.preventDefault();
}, function() {
$('#main-content').width(600);
$(this).text($(this).text() == 'Hide' ? 'Show' : 'Hide');
$('#right').hide('slow').slideUp('slow').fadeOut('slow'); // change the text
event.preventDefault();
});
});
Will this break the internet? Is there a more elegant way or is this fine?
You can use .toggle()
A small example :
$("a").toggle(
function() {
$('#main-content').width(800);
$('#right').show('slow').slidedown('slow');
},
function() {
$('#main-content').width(600);
$('#right').hide();
}
);
You need to use the toggle pseudo-event handler. This accepts multiple function definitions as its arguments and calls them in turn, so, given two arguments, the first call will call the first function, the second call the second function, the third call the first function, etc...
$('a').toggle(function(event){
$('#main-content').width(800);
$('#right').show('slow').slideDown('slow');
event.preventDefault();
}, function(event) {
$('#main-content').width(600);
$('#right').slideUp('slow').hide('slow');
event.preventDefault();
});