jQuery on or live? - javascript

I recently deployed an infinite scroll to an app that I have build and found that sometimes I need to click twice for something to happen.
My app has likes, and once the dom had loaded, i need to click on the like button twice before it changes, then once i click on the other ones it's okay but I always have to click once for the app to almost "wake up"
Is there a better solution?
$(document).ready(function() {
function runUpdate(url, item) {
$.ajax({
type: "GET",
url: url,
cache: false,
success: function(data){
if (data == '200') {
removeAddColor(item);
}
}
});
}
$('.mini-like').live('click', function(){
$('.mini-like').toggle(
function() {
var item = $(this);
var href = item.attr('href');
runUpdate(href, item);
},
function() {
var item = $(this);
var rel = item.attr('rel');
runUpdate(rel, item);
}
);
});
function removeAddColorFollow(item) {
var href = $(this).attr('href');
var rel = $(this).attr('rel');
if (item.hasClass('btn-success')) {
$(item).removeClass('btn-success').attr('href', href).attr('rel', rel);
$(item).find('i').removeClass('icon-white');
} else {
$(item).addClass('btn-success').attr('href', rel).attr('rel', href);
$(item).find('i').addClass('icon-white');
};
}
});

Well unless I'm completely wrong, you only attach the toggle event to .mini-like after it has been clicked once. Try to just replace
$('.mini-like').live('click', function() {...
With
$(function() {...
To attach the toggle event handler on document ready instead of on click

The code $('.mini-like').live('click',... should be placed inside $(document).ready()
You can use .on in place of .live. As .on is a new method and .live is deprecated now you should use .on
UPDATE
The re-written version will be
$(document).ready(function(){
$('.mini-like').on('click', function(){
$('.mini-like').toggle(
function() {
var item = $(this);
var href = item.attr('href');
runUpdate(href, item);
},
function() {
var item = $(this);
var rel = item.attr('rel');
runUpdate(rel, item);
}
);
});
});
function runUpdate(url, item) {
$.ajax({
type: "GET",
url: url,
cache: false,
success: function(data){
if (data == '200') {
removeAddColor(item);
}
}
});
}
function removeAddColorFollow(item) {
var href = $(this).attr('href');
var rel = $(this).attr('rel');
if (item.hasClass('btn-success')) {
$(item).removeClass('btn-success').attr('href', href).attr('rel', rel);
$(item).find('i').removeClass('icon-white');
} else {
$(item).addClass('btn-success').attr('href', rel).attr('rel', href);
$(item).find('i').addClass('icon-white');
};
}

Related

Jquery doesn't work after loading a PHP by ajax

I try to load a php file by ajax.
This works fine by this code:
<body id="top">
<div id="loadajaxhere"></div>
<script>
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
document.getElementById("loadajaxhere").innerHTML = xmlhttp.responseText;
}
};
xmlhttp.open("GET", "myfile.php", true);
xmlhttp.send();
</script>
But in my php file are jquery plugins, which dont work after loading via ajax...
Maybe the solution is to using the ajax by jquery syntax. Is it right?
I tried it, but my Ajax didn't load the php...
It should load the php automaticlly by loading the page in a defined div.
Many thanks in advance!
use Jquery ajax in stead. for example:
$.ajax({
url: 'myfile.php',
type: 'GET',
data: {'submit':'true'}, // An object with the key 'submit' and value'true';
success: function (result) {
document.getElementById("loadajaxhere").innerHTML = result;
}
});
A small part a solved
a small script in myfile.php works now:
<script type="text/javascript">
//$('.triggermore').click(function(){ //<- This is the old line
$('body').on('click', '.triggermore', function(event){ //<- This is the new one
$(".weitere").slideDown();
$(".weitere").addClass("open");
$(".triggermore").addClass("bye");
$('html, body').animate({ scrollTop: $("#weitere").offset().top }, 1000);
});
</script>
Source of this solution: JQuery effect doesnt work for ajax content
But this huge script is stil not working:
<script type="text/javascript">
$(document).ready(function() {
//http://webdesign.tutsplus.com/tutorials/javascript-tutorials/create-a-sticky-navigation-header-using-jquery-waypoints/
var nav_container = $(".menu");
var nav = $("nav");
var top_spacing = 0;
var waypoint_offset = '40%';
var first_section = '0%';
nav_container.waypoint({
handler: function(event, direction) {
if (direction == 'down') {
nav_container.addClass("sticky")
.stop()
.css("top", -nav.outerHeight())
.animate({"top" : top_spacing});
} else {
var inputPos = $( 'input:first' ).position();
nav_container.stop().removeClass("sticky").css("top",first_section).animate({"top":first_section});
}
},
offset: function() {
return -nav.outerHeight()-waypoint_offset;
}
});
var sections = $("section");
var navigation_links = $(".menu li a");
var links = $("nav a");
sections.waypoint({
handler: function(event, direction) {
var active_section;
active_section = $(this);
if (direction === "up") active_section = active_section.prev();
var active_link = $('.menu li a[href="#' + active_section.attr("class") + '"]');
navigation_links.removeClass("selected");
if(active_section.attr("class") != "top") {
active_link.addClass("selected");
}
},
offset: waypoint_offset
})
links.click( function(event) {
$.scrollTo(
$(this).attr("href"),
{
duration: 1500,
offset: { 'left':0, 'top':0 }
}
);
});
});
</script>
**The Jquery Scripts are in my index.php not in myfile.php.
only the html markup an in the myfile.php
Okay, I found an answer by myself.
Im using this:
$.ajax({
url: 'myfile.php',
type: 'GET',
data: {'submit':'true'}, // An object with the key 'submit' and value'true';
success: function (result) {
document.getElementById("loadajaxhere").innerHTML = result;
}
});
And pasting my scripts in the succes function. But not everything is working.
I'm on it.
<script>
$.ajax({
url: "myfile.php",
success: function(result){
$("#loadajaxhere").html(result);
}
});
</script>

Adding event handler to non-existent class?

I've seen questions that relate to non-existent elements, but not non-existent classes. Here's what I want to do. When a button of class "see_answer" is clicked, I want to remove the class and replace it with "see_question". However, my click function for a button, once its class is "see_question", is not running. I have tried $(document).on("click", ".see_question", function(event ) and I have tried $(".see_question").on("click", function(event) {etc.... Thanks for the help! My code is below:
$(document).ready(function() {
// initialize variables
var lang = "javascript";
var qno = 1;
var prevText; // holds question/answer
var language = lang + ".html";
// set up tabs, and keep track of which one is clicked
$("#myTabs").tabs({
activate: function (event, ui) {
var active = $("#myTabs").tabs("option", "active");
lang = $("#myTabs ul > li a").eq(active).attr("href");
lang = lang.replace("#", "");
}
});
/* REMINDERS
actual qa part: blah_language
*/
// set up question
$.ajax({
url: language,
dataType: "html",
success: function(data) {
$("#blah_"+lang)
.text($(data).find("#1").text());
},
error: function(r) {
alert("whoops, error in initialization");
}
});
$(".next_question").on("click", function(event) {
event.preventDefault();
var id = $(this).attr("id").replace("next_question_", "");
var language = id + ".html";
var doc = "#blah_" + id;
$.ajax({
url: language,
dataType: "html",
success: function(data) {
var num = "#" + qno;
$(doc)
.text($(data).find(num).text());
qno = qno + 1;
},
error: function(r) {
alert("whoops");
}
});
prevText = "";
});
// SHOW ANSWER
$(".see_answer").on("click", function(event) {
event.preventDefault();
var id = $(this).attr("id").replace("see_answer_", "");
var prev = "#blah_" + id;
var answers = id + "_answers.html";
// Save the question
prevText = $(prev).text();
var obj = $(this);
$.ajax({
url: answers,
dataType: "html",
success: function(data) {
var num = "#" + 3;
$(prev)
.text($(data).find(num).text());
},
error: function(r) {
alert("whoops");
}
});
obj.val("See Question");
obj.removeClass("see_answer");
obj.addClass("see_question");
event.stopPropagation();
});
$(document).on("click",".see_question", function(event) {
event.preventDefault();
obj = $(this);
event.preventDefault();
var id = $(this).attr("id").replace("see_answer_", "");
var prev = "#blah_" + id;
$(prev).text(prevText);
obj.val("See Answer");
obj.removeClass("see_question");
obj.addClass("see_answer");
});
})
Click handling for .see_question elements is delegated to document. For .see_answer elements, a click handler is attached directly. Therefore, swapping the class names will have an undesirable effect.
when see_answer is in force, a click will trigger the "see_answer" handler.
when see_question is in force, a click will trigger the "see_question" handler AND the "see_answer" handler, which is still attached.
There's a number of ways to do this properly. From where you currently are, the simplest solution is to delegate click handling of .see_question and .see_answer elements to document.
$(document).on("click", ".see_answer", function(event) {
...
});
$(document).on("click", ".see_question", function(event) {
...
});
Combine the 2 handlers and figure out which version it is by hasClass() before you change the classes around
$(document).on("click", ".see_question, .see-answer", function(event ){
var $btn =$(this), isAnswer = $btn.hasClass('see_answer');
// we know which one it is so can switch classes now
$btn.toggleClass('see_answer see_question');
if(isAnswer){
/* run code for answer version */
}else{
/* run code for question version */
}
});

jQuery removes first div only once

I have a function:
function removeDiv() {
var topmost = jQuery('.xx');
var totContent = topmost.find('.zz').length;
var $target = jQuery('.xx').find('.zz').eq(0);
if(totContent > 5) {
$target.hide('slow', function(){ $target.remove(); });
}
}
I use it in my ajax call, to remove extra div then there are more than 5, hovewer it remove first div only once!
And this is how ajax call looks:
function saveClubs(array) {
for(i=0; i<array.length; i++) {
var id = array[i];
jQuery.ajax({
type: "GET",
async: true,
url: 'index.php?option=com_events&task=club.save&id=' + id,
dataType: 'json',
success: function(data) {
jQuery('.xx').append('<div class="zz">'+data+'</div>');
removeDiv();
}
});
}
}
Any ideas ?
This is Paul Roub's answer, posted as an answer rather than a comment:
The likely problem is that since you're doing a bunch of ajax calls in a loop, they tend to complete at the same time, and so you end up repeated fading out the same element (since it's still there until it's done fading).
The minimal changes fix would be to, say, add a class as you're fading it out:
function removeDiv() {
// Get the container (I take it there's only one .xx element)
var topmost = jQuery('.xx');
// Get the child elements that aren't fading
var zz = topmost.find('.zz').not('.fading');
// Too many?
if(zz.length > 5) {
// Yup, add 'fading' to the first one and fade it out
// Note that there's no need for the $target variable
zz.eq(0).addClass('fading').hide('slow', function(){ $(this).remove(); });
}
}
The problem is this:
var $target = jQuery('.xx').find('.zz').eq(0);
It's always 0 index.
function removeDiv(x) {
var topmost = jQuery('.xx');
var totContent = topmost.find('.zz').length;
var $target = jQuery('.xx').find('.zz').eq(x);
if(totContent > 5) {
$target.hide('slow', function(){ $target.remove(); });
}
}
function saveClubs(array) {
for(i=0; i<array.length; i++) {
var id = array[i];
jQuery.ajax({
type: "GET",
async: true,
url: 'index.php?option=com_events&task=club.save&id=' + id,
dataType: 'json',
success: function(data) {
jQuery('.xx').append('<div class="zz">'+data+'</div>');
removeDiv(i);
}
});
}
}
LIVE EXAMPLE HERE
NOTE
IN the Fiddle above, try to change this var $target = jQuery('.xx').find('.zz').eq(x); harcoding the value of x to 0 and it'll happen just once.

2 javascripts are conflicting

I have 2 javascripts that are conflicting with eachother, the newer one (Zeroclipboard) conflicts with the older one (delete row) and won't let the delete row one work. The moment i removed the zeroclipboard one, delete worked.
Tried adding jQuery.noConflict(); but didn't seem to work. By reading few solutions, I decided to remove $ signs, but still no.
I have a files.php file, including the header.php file. I am adding the custom.js file in header.php, which holds many functions for operations across the project, including the delete row function. Whereas, the newer script for ZerClipboard is in files.php itself.
Older one, to delete a table row on delete icon click, which won't work after I add the next:
custom.js
function deleteRow()
{
var current = window.event.srcElement;
while ( (current = current.parentElement) && current.tagName !="TR");
current.parentElement.removeChild(current);
}
$(document).ready(function()
{
$('table#delTable td a.delete').click(function()
{
if (confirm("Are you sure you want to delete?"))
{
var fid = $(this).parent().parent().attr('fid');
var str=$(this).attr('rel');
var data = 'fid=' + $(this).attr('rel') + '&uid=' + $(this).parent().attr('rel');
var deletethis = '#tr' + $(this).attr('rel');
var parent = $(this).parent().parent();
$.ajax(
{
type: "POST",
url: "delete.php",
data: data,
cache: false,
success: function(msg)
{
$(deletethis).fadeOut('slow', function() {$(this).remove();});
}
});
}
});
$('table#delTable tr:odd').css('background',' #FFFFFF');
});
ZeroClipboard's JS and SWF, along with this js to copy some text on clipboard on Share icon click:
files.php
<script type="text/javascript" src="js/ZeroClipboard.js"></script>
<script language="JavaScript">
var clip = null;
function $(id) { return document.getElementById(id); }
function init()
{
clip = new ZeroClipboard.Client();
clip.setHandCursor( true );
}
function move_swf(ee)
{
copything = document.getElementById(ee.id+"_text").value;
clip.setText(copything);
if (clip.div)
{
clip.receiveEvent('mouseout', null);
clip.reposition(ee.id); }
else{ clip.glue(ee.id); }
clip.receiveEvent('mouseover', null);
}
</script>
I used this blog post for implementing multiple zerclipboard - http://blog.aajit.com/easy-multiple-copy-to-clipboard-by-zeroclipboard/
And, here's the HTML source generated by the files.php page - http://jpst.it/tlGU
Remove the follow function definition of your second script:
function $(id) { return document.getElementById(id); }
Because this is redefining your $ object in window context, due when you use $ in your first script you're not using jquery, instead you're using your new function definition.
Hope this helps,
Here is how you should use noConflict() :
function deleteRow()
{
var current = window.event.srcElement;
while ( (current = current.parentElement) && current.tagName !="TR");
current.parentElement.removeChild(current);
}
jQuery.noConflict(); // Reinitiating $ to its previous state
jQuery(document).ready(function($) // "Protected" jQuery code : $ is referencing jQuery inside this function, but not necessarily outside
{
$('table#delTable td a.delete').click(function()
{
if (confirm("Are you sure you want to delete?"))
{
var fid = $(this).parent().parent().attr('fid');
var str=$(this).attr('rel');
var data = 'fid=' + $(this).attr('rel') + '&uid=' + $(this).parent().attr('rel');
var deletethis = '#tr' + $(this).attr('rel');
var parent = $(this).parent().parent();
$.ajax(
{
type: "POST",
url: "delete.php",
data: data,
cache: false,
success: function(msg)
{
$(deletethis).fadeOut('slow', function() {$(this).remove();});
}
});
}
});
$('table#delTable tr:odd').css('background',' #FFFFFF');
});
And in files.php:
<script src="js/ZeroClipboard.js"></script>
<script>
var clip = null;
function $(id) {
return document.getElementById(id);
}
function init() {
clip = new ZeroClipboard.Client();
clip.setHandCursor(true);
}
function move_swf(ee) {
copything = document.getElementById(ee.id + "_text").value;
clip.setText(copything);
if (clip.div) {
clip.receiveEvent('mouseout', null);
clip.reposition(ee.id);
} else {
clip.glue(ee.id);
}
clip.receiveEvent('mouseover', null);
}
</script>

How to combine two jQuery functions into one?

I've following two functions in jQuery:
$(document).on('change','.states',function(){
//on change of select
});
$(document).on('click','.date_control',function(){
//on click of input .date_control
});
How to combine the above two functions into one function so that I can use it with my AJAX function which is as below:
$(function() {
$(".add_new_rebate").on("click", function(event) {
event.preventDefault();
var manufacturer_id = $("#company_id").val();
/*if($.active > 0) { //or $.active
request_inprogress();
} else {*/
var next_rebate_no = $('.rebate_block').length + 1;
var rebate_no = $('.rebate_block').length + 1;
if ($('.rebate_block').length>0) {
rebate_no = rebate_no+1;
}
$('.add_new_rebate').attr('disabled','disabled');
//}
$.ajax({
type: "POST",
url: "add_rebate_by_product.php",
data: {'request_type':'ajax', 'op':'create_rebate', 'next_rebate_no':next_rebate_no, 'rebate_no':rebate_no, 'manufacturer_id':manufacturer_id},
beforeSend: function() {
$('.table-responsive').after("<img src='http://localhost/smart-rebate-web/web/img/ajax-loader.gif' class='load' alt='Loading...'>");
},
success: function(data) {
if(jQuery.trim(data)=="session_time_out") {
window.location.href = site_url+'admin/login.php?timeout=1';
} else {
$('.rebate_block').append(data);
$('.add_new_rebate').removeAttr('disabled');
}
$('.load').remove();
}
});
});
});
If you have any other way than combining the above two function into one then also it will be fine. My requirement is to incorporate the code of these two functions into the above AJAX function as I'm generating the two HTML controls dynamically and I want to apply the jQuery classes to them. Thanks in advance.
JS:
function do_action(){
var manufacturer_id = $("#company_id").val();
/*if($.active > 0) { //or $.active
request_inprogress();
} else {*/
var next_rebate_no = $('.rebate_block').length + 1;
var rebate_no = $('.rebate_block').length + 1;
if ($('.rebate_block').length>0) {
rebate_no = rebate_no+1;
}
$('.add_new_rebate').attr('disabled','disabled');
//}
$.ajax({
type: "POST",
url: "add_rebate_by_product.php",
data: {'request_type':'ajax', 'op':'create_rebate', 'next_rebate_no':next_rebate_no, 'rebate_no':rebate_no, 'manufacturer_id':manufacturer_id},
beforeSend: function() {
$('.table-responsive').after("<img src='http://localhost/smart-rebate-web/web/img/ajax-loader.gif' class='load' alt='Loading...'>");
},
success: function(data) {
if(jQuery.trim(data)=="session_time_out") {
window.location.href = site_url+'admin/login.php?timeout=1';
} else {
$('.rebate_block').append(data);
$('.add_new_rebate').removeAttr('disabled');
}
$('.load').remove();
}
});
}
$(document).on('change','.states',function(){
//on change of select
do_action();
return false;
});
$(document).on('click','.date_control',function(){
//on click of input .date_control
do_action();
return false;
});
I'm assuming the reason why you asked the question is to avoid using the same code inside both events, this way, it's much cleaner. No repeating.
I am not that sure if I understood the point correctly, but I you can define a function withName () {}, so you can reference that function from withing the event handlers.
Here doStuff is called either on »change« or on »click«
function doStuff (e) {
//the stuff to do
}
$(document).on('change','.states', doStuff);
$(document).on('click','.date_control',doStuff);
I hope that is what you are asking for…
Please see this link:
How to combine two jQuery functions?
And the answer can answer your question:
you simply use the same selector for both your action and your confirm
function handler(event) {
event.preventDefault();
var manufacturer_id = $("#company_id").val();
/*if($.active > 0) { //or $.active
request_inprogress();
} else {*/
var next_rebate_no = $('.rebate_block').length + 1;
var rebate_no = $('.rebate_block').length + 1;
if ($('.rebate_block').length>0) {
rebate_no = rebate_no+1;
}
$('.add_new_rebate').attr('disabled','disabled');
//}
$.ajax({
type: "POST",
url: "add_rebate_by_product.php",
data: {'request_type':'ajax', 'op':'create_rebate', 'next_rebate_no':next_rebate_no, 'rebate_no':rebate_no, 'manufacturer_id':manufacturer_id},
beforeSend: function() {
$('.table-responsive').after("<img src='http://localhost/smart-rebate-web/web/img/ajax-loader.gif' class='load' alt='Loading...'>");
},
success: function(data) {
if(jQuery.trim(data)=="session_time_out") {
window.location.href = site_url+'admin/login.php?timeout=1';
} else {
$('.rebate_block').append(data);
$('.add_new_rebate').removeAttr('disabled');
}
$('.load').remove();
}
});
}
$(document).on('change','.states', handler);
$(document).on('click','.date_control', handler);
If I understood your requirement correctly, then the following should work:
$( '.states, .date_control' ).on( 'click change', function ( event ) {
if( ( event.type == 'change' && event.target.className == 'states' )
|| ( event.type == 'click' && event.target.className == 'date_control' ) ) {
//process event here
};
} );

Categories

Resources