Javascript looping nested click event - javascript

I have a nested click event listeners and I have a problem, that when I trigger the event listeners multiple times they get looped and send a request x2 times than it should. Where is the mistake in my code? It's probably a beginner's mistake, so I'm very sorry if that's the case. I'm still learning JavaScript and jQuery.
Code:
$('body').on('click', '.color-pick-btn', function() {
id = $(this).data("highlight");
unique = $(this).data("unique");
$(".color-picker").show();
//show the menu directly over the placeholder
$(".color-picker").position({
my: "right top",
at: "right bottom",
of: this,
collision: "fit"
});
$('body').on('click', '.color-picker-item', function() {
color = $(this).data("color");
$.ajax({
type: "POST",
url: '/echo/json',
//data: "highlight=" + id + '&color=' + color + "&unique=" + unique,
data: {
json:'{"highlight":"id","color":"color","unique": "unique"}'
},
dataType: 'json',
}).done(function(data) {
console.log('test');
});
$(".color-picker").hide();
return false;
});
$(document).click(function(event) {
if (!(($(event.target).hasClass('color-pick-btn')) || ($(event.target).hasClass('color-picker-item')))) {
$(".color-picker").hide();
}
return false;
});
return false;
});
JSFiddle here: https://jsfiddle.net/o0r4z6g3/
Check out the console output "test".
Cheers!

You added event listeners every time your event listener was called. I haven't taken a look at the intention of your code, and you haven't explained it in your answer, but this may fix your problem.
$('body').on('click', '.color-pick-btn', function() {
// .position() uses position relative to the offset parent,
// so it supports position: relative parent elements
pos = $(this).offset();
id = $(this).data("highlight");
unique = $(this).data("unique");
// .outerWidth() takes into account border and padding.
width = $(this).outerWidth();
$(".color-picker").show();
//show the menu directly over the placeholder
$(".color-picker").position({
my: "right top",
at: "right bottom",
of: this,
collision: "fit"
});
return false;
});
$('body').on('click', '.color-picker-item', function() {
color = $(this).data("color");
$.ajax({
type: "POST",
url: '/echo/json',
//data: "highlight=" + id + '&color=' + color + "&unique=" + unique,
data: {
json: '{"highlight":"id","color":"color","unique": "unique"}'
},
dataType: 'json',
}).done(function(data) {
console.log('test');
});
$(".color-picker").hide();
return false;
});
$(document).click(function(event) {
if (!(($(event.target).hasClass('color-pick-btn')) || ($(event.target).hasClass('color-picker-item')))) {
$(".color-picker").hide();
}
return false;
});

Related

Jquery Ajax simple application: missing ) after argument list

I'm pulling my hair out here. I keep getting "missing ) after argument list" on my final line of code. I'm thinking it has something to do with my concatenation but I can't figure it out. It's jQuery with jQuery UI: a simple slider. User increases the amount on the slider and the available flights at that amount are displayed. Clicking on the available flight shows the duration:
$(document.ready(function(){
$.ajax({
url: 'http://localhost:8888/all_work_july_6/javascript_start_here/flights.php',
dataType: "json",
success: function(data){
var counter = 0;
$.each(data, function(key, value){
$("#flightList").append('<li ' + 'id="flight' + counter + '"' + ' class="flightLi">' + value['trip'] + '<span class="hiddenPrice">' + value['price'] + '</span></li>');
counter++;
});
}
});
$("#priceSlider").slider({
orientation: "vertical",
min: 200,
max: 1650,
step: 200,
value: 1650,
slide: function(event, uiElement){
$("#flightDetails").html("<p>Flight Details</p>").addClass("hidden");
var numRegex = /(\d+)(\d{3})/;
var inputNum = uiElement.value;
var strNum = inputNum.toString();
strNum = strNum.replace(numRegex, '$1' + ',' + '$2');
$("#spanPrice").text(strNum);
$("#inputPrice").val(uiElement.value);
$(".hiddenPrice").each(function(){
if($(this).text() > inputNum){
$(this).parent().addClass("hidden");
}
else if($(this).text() < inputNum){
$(this).parent().removeClass("hidden");
}
});
}
});
$(".flightLi").on('click', function(){
$("#flightDetails").html("<p>Flight Details</p>").addClass("hidden");
var myId = $(this).attr("id");
$.ajax({
url: 'http://localhost:8888/all_work_july_6/javascript_start_here/details.php',
dataType: "json",
data: { "flightID": myId },
type: "POST",
success: function(data) {
$("#flightDetails").removeClass("hidden").append('<ul>' + '<li class="detailsLi">Trip Duration: ' + data['duration'] + '</li>' + '</ul>');
}
});
});
});
The problem was in the first line, Missing ) in $(document
//$(document.ready(function(){ You had this. ) is missing
$(document).ready(function(){
 Missing )in $(document
Replace $(document to $(document)
Here is a live demo
$(document).ready(function() {
// mocked response from flights.php
var data = {
json: $.toJSON({0: {trip: "Hawaii", price: "1000"} }),
delay: 3
}
// AJAX post to "fllights.php" and process the response
$.ajax({
url:"/echo/json/", // JSfiddle Echo API - http://doc.jsfiddle.net/use/echo.html
data:data,
type:"POST",
success:function(data){
var counter = 0;
$.each(data, function(key, value){
var li = "<li id='flight"+counter+"'"+" class='flightLi'>"+value['trip']+"<span class='hiddenPrice'>"+value['price']+"</span></li>";
$('#flightList').append(li);
addListener(); // add the onClick listener to the newly created <li> item.
counter++; // You could also pass in the id attribute to this method
});
}
});
// Slider
$("#priceSlider").slider({
orientation: "vertical",
min: 200,
max: 1650,
step: 200,
value: 1650,
slide: function(event, uiElement){
$("#flightDetails").html("<p>Flight Details</p>").addClass("hidden");
var numRegex = /(\d+)(\d{3})/;
var inputNum = uiElement.value;
var strNum = inputNum.toString();
strNum = strNum.replace(numRegex, '$1' + ',' + '$2');
$("#spanPrice").text(strNum);
$("#inputPrice").val(uiElement.value);
$(".hiddenPrice").each(function(){
if($(this).text() > inputNum){
$(this).parent().addClass("hidden");
}
else if($(this).text() < inputNum){
$(this).parent().removeClass("hidden");
}
});
}
});
// moked response from details.php for "flightID": myId
data = {
json: $.toJSON({duration: '1000 hrs'}),
delay: 1
}
// wraper method to only add the onClick listner after the new <li> is inserted to the DOM
function addListener(){
// List item onClick AJAX
$(".flightLi").one( "click", function() { // Using the .one method to only add the onClick event listener once
$("#flightDetails").html("<p>Flight Details</p>").addClass("hidden");
console.log("Flight id: "+$(this).attr("id"));
$.ajax({
url:"/echo/json/",
dataType: "json",
data: data,
type: "POST",
success: function(data) {
var li = "<ul><li class='detailsLi'>Trip Duration: "+data['duration']+"</li></ul>";
$("#flightDetails").removeClass("hidden").append(li);
}
});
});
}
// Origional code
// This doesn't work due to the fact that the <li> item
// in the flightList list is inserted to the the DOM after the intital load
// you can also bind the event at the document level see this post http://bit.ly/1S0H2q0
// $(".flightLi").on('click', function(){
// $("#flightDetails").html("<p>Flight Details</p>").addClass("hidden");
// console.log("Flight id: "+$(this).attr("id"));
// $.ajax({
// url:"/echo/json/",
// dataType: "json",
// data: data,
// type: "POST",
// success: function(data) {
// var li = "<ul><li class='detailsLi'>Trip Duration: "+data['duration']+"</li></ul>";
// $("#flightDetails").removeClass("hidden").append(li);
// }
// });
// });
});
A few things I noticed while going through your code:
The $("#flightDetails").html("<p>Flight Details</p>").addClass("hidden"); line is actually removing the Trip Duration: content because it completely replaces the html inside of the #flightDetails element. - This might be intentional
Adding the onClick event listener to the newly created <li> elements must be done at the document level, or from inside of the call back that actually injects them into the DOM. I chose to implement the call back method. See this post for adding the listener at the document level
Adding the event listener from inside of the call back method opens up the issue of possibly adding the event listener to the same element multiple times. This can result in an onClick event firing multiple times per one trigger. Again you must either add the event at the document level, or use the one method to only add the event once. See the JQuery.one documentation

jQuery event binding with dynamically loaded elements when scroll down at the end of window

<script type="text/javascript">
$(document).ready(function() {
var page = 0;
$(window).scroll(function () {
if ($(document).height()-$(document).height()*0.2 <= $(window).scrollTop() + $(window).height()) {
$.ajax({
type: "POST",
url: "/",
dataType: "json",
data: { 'page' : page, 'csrfmiddlewaretoken': '{{csrf_token}}'},
success: function(data) {
obj1 = JSON.parse(data.fulldata);
var newHTML = '<a href = "" >somecode</a>';
$(".newdata").append(newHTML);
},
error: function(data) {
// alert("error")
}
});
}
}
});
</script>
i have readed this link for dynamically added elements, that we must bind the function to one of it's parents
...but no success
i am not pasting the entire code here. suppose code is correct and working fine. only when i am clicking the loaded element its not working..
Thanks in advance
full code

JQuery with ajax keeps posting multiple results

I have many images on a page that show the status of the machine. If you click on the image then modal window opens and you can select new status. Status gets send via ajax to the DB. If I try to change another machines status the previous machines status gets changed also. Every status that I have touched gets resend every time as the last status that I selected.
It somehow creates an array of the machines I have changed and with every change posts all of them. Refresh of the page empties the array.
I think I need to use something similar to unset in php or move the inner click function outside of the first click function.
$(function() {
$('#mach_status_dialog').hide();
$('.mach_status').click(function(){
var mach = $(this).attr('id');
$('#mach_status_dialog').dialog({
modal: true,
draggable: false,
resizable: false,
width: 500,
title: 'Mach ' + mach + ' status'
});
$('.statuses').click(function(){
var user = user;
var class = $(this).attr('class');
class = class.substring(10);
var status = $(this).first().find('p').parent().text();
var data_string = 'mach=' + mach + '&status=' + status + '&user=' + user;
$.ajax({
url: 'ajax_op_mach_status.php',
type:'POST',
data: data_string,
dataType: 'json',
cache: false,
success: function(response){
var newSrc = 'images/Circle2_'+class+'_25.png';
console.log($('#'+mach+'.mach_status').attr('src', newSrc));
$('#'+mach+'.mach_status').attr('src', newSrc);
$('#'+mach+'.mach_status').attr('title', status);
$( "#mach_status_dialog" ).dialog('close');
}
});
});
});
});
$(function() {
$('#mach_status_dialog').hide();
$('.mach_status').click(function(){
var mach = $(this).attr('id');
$('#mach_status_dialog').dialog({
modal: true,
draggable: false,
resizable: false,
width: 500,
title: 'Mach ' + mach + ' status'
});
});
$(document).on('click', '.statuses', function(){
var user = user;
var class = $(this).attr('class');
class = class.substring(10);
var status = $(this).first().find('p').parent().text();
var data_string = 'mach=' + mach + '&status=' + status + '&user=' + user;
$.ajax({
url: 'ajax_op_mach_status.php',
type:'POST',
data: data_string,
dataType: 'json',
cache: false,
success: function(response){
var newSrc = 'images/Circle2_'+class+'_25.png';
console.log($('#'+mach+'.mach_status').attr('src', newSrc));
$('#'+mach+'.mach_status').attr('src', newSrc);
$('#'+mach+'.mach_status').attr('title', status);
$( "#mach_status_dialog" ).dialog('close');
}
});
});
});
As you say, just move the .click event into the DOM ready callback. As it stands, every time you click on a mach_status, you are assigning a new click event handler. So if I click on mach_status 10 times, then click on a statuses link once, you'll get 10 AJAX requests.
If you only want to bind onto a statuses click when the user clicks on mach_status, add a class onto the element to tell it when it's ready:
$(function() {
$('#mach_status_dialog').hide();
$('.mach_status').click(function(){
$(".statuses").addClass("ready");
var mach = $(this).attr('id');
$('#mach_status_dialog').dialog({
modal: true,
draggable: false,
resizable: false,
width: 500,
title: 'Mach ' + mach + ' status'
});
});
$('.statuses.ready').click(function(){
// Do AJAX
});
});
The problem is here...
$('.statuses').click(function(){
Every time you click on *.mach_status* element, it adds the event listener for all the statuses. You can changes this to
$(this).find('.statuses').click(function abc(){
.
.
.
this.removeEventListner('click', abc);
});
Notice How I am using the named functions and removing them from event queue once they are fired.

Jquery applying class and removing class

The code which changes the active class to the currently clicked pagination class. Removing it works but adding the new class doesn't work.
http://jsfiddle.net/spadez/qKyNL/35/
$('a').click(function(event){
event.preventDefault();
var number = $(this).attr('href');
$.ajax({
url: "/ajax_json_echo/",
type: "GET",
dataType: "json",
timeout: 5000,
beforeSend: function () {
$('#content').fadeTo(500, 0.5);
},
success: function (data, textStatus) {
// TO DO: Load in new content
$('html, body').animate({
scrollTop: '0px'
}, 300);
// TO DO: Change URL
$('#pagination li.active').removeClass("active");
$(this).parent().addClass("active");
},
error: function (x, t, m) {
if (t === "timeout") {
alert("Request timeout");
} else {
alert('Request error');
}
},
complete: function () {
$('#content').fadeTo(500, 1);
}
});
});
Can anyone please tell me where I am going wrong?
The problem is that this in the success callback isn't your element.
You may do this :
$('a').click(function(event){
var element = this; // <= save the clicked element in a variable
event.preventDefault();
var number = $(this).attr('href');
$.ajax({
...
success: function (data, textStatus) {
...
$('#pagination li.active').removeClass("active");
$(element).parent().addClass("active"); // <= use it
},
...
});
});
This this in ajax callback isn't what you expect it to be. Add this to your ajax parameters:
context: this,
No need to build custom object saving system and making code more messy, as jQuery already has this functionality.
Edit: In this case it should look like:
$('a').click(function(event){
event.preventDefault();
var number = $(this).attr('href');
$.ajax({
context: this,
url: "/ajax_json_echo/",
...

Div moves out of window when resized

Whenever i resize the browser, the div moves out of window. I use jquery scroll to plugin for navigating through divs. But when i resize the #home div it works fine, but when i resize other divs, it gets out of window.
Please help me out, here is the link to the website.
Here is the code i used,
$(document).ready(function()
{
$("#bg-home").backstretch("images/Bg-home3.jpg");
var images = ['1.jpg', '2.jpg','3.jpg'];
$("#container").backstretch('images/' + images[Math.floor(Math.random() * images.length)]);
$( "#draggable" ).draggable({
drag: function() {
$(".scrolldown span").css("color","lightgreen").html("Drop");
},
stop: function() {
$(".scrolldown span").css("color","white").html("Drag");
},axis: "x",containment:"#menu",scroll: false//,grid: [ 159,0 ]
});
$(".content,.content1").droppable({drop: function() {
var $url = $(this);
document.title = $url.attr('alt');
$('html, body').scrollTo($url.attr('id'),500,"easeInOutExpo");
//event.preventDefault();
}});
$("#welcome").effect("slide",3000);
$("#welcome").click(function()
{
$("#welcome").animate({left: "-1000px"},"easeInOutBounce");
$(".about_w").animate({left: "100px"},"easeInOutBounce");
$(".about_w").delay(4000).animate({left: "-800px"});
$("#welcome").delay(4500).animate({left: "100px"});
});
$('#menu a').bind('click',function(event){
var $url = $(this);
document.title = $url.attr('alt');
$('html, body').scrollTo($url.attr('href'),500,"easeInOutExpo");
event.preventDefault();
});
$("#about .text p").vertiscroll({ width:6, color:'#f07','cover': 200,'areacursor': 'pointer' });
$('.side_container').slimScroll({
height:"88%",
color: '#fff',
start: $('.side_container'),
alwaysVisible: false
});
$('#container_wrap_metro').slimScroll({
height:"400px",
color: '#fff',
railVisible: false,
alwaysVisible: false
});
$(".menu nav").click(function(){
$url = $(this);
$(".text p").load($url.attr('id'));
});
function loading_show()
{
$('#loading').html("<p style='color:white;'>Loading</p><br><img src='images/loading.gif'/>").fadeIn('fast');
}
function loading_hide()
{
$('#loading').fadeOut();
}
//Status
function loadData(page)
{
loading_show();
$("#container_wrap_metro").html("");
$.ajax({
url: "load_data.php",
type: "post",
data: "page="+page,
success: function(data){
loading_hide();
$("#container_wrap_metro").html(data);
},
error:function(){
alert("failure");
$("#container_wrap_metro").html('Unable to process request!');
}
});
}
function loads(page)
{
$.ajax({
url: "load_10.php",
type: "post",
data: "page="+page,
success: function(data){
$(".side_container").html(data);
},
error:function(){
alert("failure");
$(".side_container").html('Unable to process request!');
}
});
}
loads(1);
//Search
$("#result").keyup(function(){
$(".side_container").html('<center><i>Fetching...</i></center>')
var q = $(this).val();
$.get("results.php?q="+q, function(data){
if(q){
$(".side_container").html(data);
}
else {
loads(1);
}
});
});
});
Try editing the following lines:
$("#welcome").animate({left: "-1000px"},"easeInOutBounce");
$(".about_w").animate({left: "100px"},"easeInOutBounce");
$(".about_w").delay(4000).animate({left: "-800px"});
$("#welcome").delay(4500).animate({left: "100px"});
And:
height:"400px",
The earlier response is right. When it comes to responsive web design, use em or % when setting the sizes. You can use 100% instead or 40 em. You can change the values until you get the desired output.
For this you need responsive designs and for that you need to give widths as in "%" everywhere But in your script you are using left:..px like that....Its creating the problem.So First thing better to give them responsively or second thing replace it with the responsive one..
Try this LINK

Categories

Resources