First click is not working in jquery - javascript

I am trying to make a seatchart. All seats are elements. I click first seat and after that i click the other one. Second one changed its colour but first one is not working. Why?
function seatObject(id, label, status, token){
this.id = id;
this.label = label;
this.status = status;
this.token = token;
}
var seats = [];
var currentSeat;
function initAll() {
$(".seatObj").each(function() {
var id = $(this).attr("id");
var temp = new seatObject("#" + id, "label" + id, "available", "");
seats[id] = temp;
$("#" + id).click(function () {
currentSeat = $(this).attr("id");
if (seats[currentSeat].status == "selected")
{
dequeueSeat();
}
else
{
enqueueSeat();
//alert($(this).attr("inkscape:label"));
}
});
});
}

No problem with your code dude...
You need little changes...
Ordinary Click does not attach an event handler functions for one or more events. So use on method - Attach an event handler function for one or more events to the selected elements.
$(".seatObj").on('click',"#" + id, function () {
currentSeat = $(this).attr("id");
if (seats[currentSeat].status == "selected")
{
dequeueSeat();
}
else
{
enqueueSeat();
//alert($(this).attr("inkscape:label"));
}
});
You can use class instead of id in on method.

Try wrapping the function in $( document ).ready(function() {}
works for me.

Related

TypeError: Object.defineProperty called on non-object JQUERY

I have this error in Jquery when I try to each an array of HTML elements and handle onclick of that element.
Object.keys(collapsibles).forEach(function (key){
$(collapsibles[key]).on('click' , function( e ) {
e.preventDefault();
const id = $(this).data("id");
if (id !== _that.currentId) {
_that.closeCurrentOpen();
$(`[data-target="${$(this).data("id")}"]`).slideDown().addClass('open');
$(`[data-img="${$(this).data("id")}"]`).slideDown().addClass('arrowOpened');
return _that.currentId = id;
} else {
return _that.closeCurrentOpen();
}
});
});
The error is appear in this line
$(collapsibles[key]).on('click' , function( e ) {
Collapsibles value
var collapsibles = $('[data-behavior="collapsible"]');
Code below has makes error because $(collapsibles[key]) is not a jQuery object:
$(collapsibles[key]).on('click' , function( e ) {//...});
Please see this fiddle. I simulated your code in that. You can see collapsibles in console that seems you didn't think it's a array that it's not suitable for you.
You can use this code instead (jsFiddle):
$.each(collapsibles, function() {
$(this).on('click', function() {
// ...
});
});
Uh, var collapsibles = $('[data-behavior="collapsible"]'); is not an array but rather a jQuery collection object. And you should not iterate array-like objects like that, neither with for … in nor with Object.keys(…).forEach.
For jQuery collections, just use .each, or don't use it at all but just call the .on method on it directly which will install the listener on all of the selected elements.
var collapsibles = $('[data-behavior="collapsible"]');
collapsibles.each(function() {
$(this).on('click', function(e) {
e.preventDefault();
const id = $(this).data("id");
if (id !== _that.currentId) {
_that.closeCurrentOpen();
$(`[data-target="${$(this).data("id")}"]`).slideDown().addClass('open');
$(`[data-img="${$(this).data("id")}"]`).slideDown().addClass('arrowOpened');
return _that.currentId = id;
} else {
return _that.closeCurrentOpen();
}
});
});
var collapsibles = $('[data-behavior="collapsible"]');
collapsibles.on('click', function(e) {
e.preventDefault();
const id = $(this).data("id");
if (id !== _that.currentId) {
_that.closeCurrentOpen();
$(`[data-target="${$(this).data("id")}"]`).slideDown().addClass('open');
$(`[data-img="${$(this).data("id")}"]`).slideDown().addClass('arrowOpened');
return _that.currentId = id;
} else {
return _that.closeCurrentOpen();
}
});

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 */
}
});

Click event object tracking woes

So I am working on this but of jQuery that gets the element id through a click event. This then triggers a function that acts like the deprecated .toggle()- it slides an element down on the fist click and slides that element up on the second click. However, there is a bug that causes the element to slide up and down the amount of times that it has been clicked on. For instance, if this is the second time I use the .clickToggle function, the element (table) slides up and down twice before settling, and so on. I suspect it has something to do with the event object, e, tracking the number of clicks-- i.e. I probably shouldn't set id = e.target.id-- but I'm not sure how to fix while still getting the relevant element id that I need.
Here is the relevant clickToggle plug in (courtesy of an answer here on stackoverflow).
(function($) {
$.fn.clickToggle = function(func1, func2) {
var funcs = [func1, func2];
this.data('toggleclicked', 0);
this.click(function() {
var data = $(this).data();
var tc = data.toggleclicked;
$.proxy(funcs[tc], this)();
data.toggleclicked = (tc + 1) % 2;
});
return this;
};
}(jQuery));
Here is the buggy code that fits the above description.
$(document).click(function(e) {
//get the mouse info, and parse out the relevant generated div num
var id = e.target.id;
var strId = id.match(/\d$/);
//clickToggle the individual table
$('#showTable' + strId).clickToggle(function () {
$('#table' + strId).slideDown();
$('#table' + strId).load('files.php');
},
function () {
$('#table' + strId).slideUp();
});
});//close mousemove function
Any help would be much appreciated. Thanks.
The problem is that you're registering a new click handler for the element each time you invoke clickToggle:
this.click(function() {...
On each subsequent click, you add another handler, as well as invoking all previous handlers. Bleagh.
Better to be straightforward: (DEMO)
var showTable = function($table) {
$table.slideDown();
$table.load('files.php');
$table.removeClass('hidden');
};
var hideTable = function($table) {
$table.slideUp();
$table.addClass('hidden');
};
$(document).click(function (e) {
//get the mouse info, and parse out the relevant generated div num
var id = e.target.id;
var strId = id.match(/\d$/)[0];
var $table = $('#table' + strId);
if ($table.hasClass('hidden')) {
showTable($table);
} else {
hideTable($table);
}
});

How to loop through ids with same prefix

I have this section of code that saves a list item on click to localStorage based on the list item's id number. On a different page I am then able to load whatever list items were saved.
var save1075 = $('#store-1075').get(0);
$('#store-1075').on('click', function () {
var storeStorageKey1075 = $(this).attr('id');
localStorage.setItem('storeStorageKey1075', $(this).attr('id'));
localStorage.setItem('storeStorageKey1075', this.innerHTML);
});
if ( localStorage.getItem('storeStorageKey1075') ) {
save1075.innerHTML = localStorage.getItem('storeStorageKey1075');
}
var storeStorageKey1075 = $(this).attr('id');
if ( localStorage.getItem('storeStorageKey1075') ) {
storeStorageKey1075 = localStorage.getItem('storeStorageKey1075');
}
Right now I have to repeat that chunk of code for every individual id number and I'm trying to instead make the id number a variable that loops through all possible id numbers when clicked but only saves the id of that specific one. Maybe something along the lines of this:
var id = //some sort of loop or array of possible ids.
var save = $('#store-'+id).get(0);
$('#store-'+id).on('click', function () {
var storeStorageKey = $(this).attr('id');
localStorage.setItem('storeStorageKey', $(this).attr('id'));
localStorage.setItem('storeStorageKey', this.innerHTML);
});
if ( localStorage.getItem('storeStorageKey') ) {
save.innerHTML = localStorage.getItem('storeStorageKey');
}
var storeStorageKey = $(this).attr('id');
if ( localStorage.getItem('storeStorageKey') ) {
storeStorageKey = localStorage.getItem('storeStorageKey');
}
Each of the list items has the same prefix of "store-" and the numbers are in no specific order but randomly generated each time a new store location is created.
The obvious thing to do is to add a class but you could also:
var elems = $( "[id^='store']")
elems.on( "click", function() {//Save html on click
localStorage.setItem( this.id, this.innerHTML );
});
//Retrieve html
elems.each( function() {
var html = localStorage.getItem( this.id );
if( html ) {
$(this).html( html );
}
});
This loops over all keys that begin with storeStorageKey:
for (var i=0; i<localStorage.length; i++) {
var key = localStorage.key(i);
if (/^storeStorageKey/.test(key)) {
var item = localStorage.getItem(key);
// do something with item
}
}
Instead of using a prefix in the id I'd suggest adding a class to indicate that an item is storable:
<div class="storable" id="store-1234">...</div>
then you can use the class to select all the storable things in one go:
$('.storable').on('click', function () {
var storeStorageKey = $(this).attr('id');
...
});

trying to remove and store and object with detach()

I am trying to remove an object and store it (in case a user wants to retrieve it later). I have tried storing the object in a variable like it says in the thread below:
How to I undo .detach()?
But the detach() does not remove the element from the DOM or store it. I am also not getting any error messages. Here is the code I am using to detach the element:
function MMtoggle(IDnum) {
var rowID = "row" + IDnum;
var jRow = '#' + rowID;
thisMMbtn = $(jRow).find(".addMMbtn");
var light = false;
var that = this;
if (light == false) {
thisMMbtn.bind("click",
function() {
var thisRow = $(this).closest(".txtContentRow");
var thisTxt = thisRow.find(".txtContent");
var cellStr = '<div class = "mmCell prep"></div>';
$(cellStr).appendTo(thisTxt);
$(this).unbind("click");
light = true;
}
);
}
else {
thisMMbtn.bind("click",
function() {
var thisRow = $(this).closest(".txtContentRow");
thisMM = thisRow.find(".mmCell");
SC[rowID].rcbin = thisMM.detach(); //here is where I detach the div and store it in an object
$(this).unbind("click");
light = false;
}
);
}
}
MMtoggle(g.num);
A fiddle of the problem is here: http://jsfiddle.net/pScJc/
(the button that detaches is the '+' button on the right. It is supposed to add a div and then detach it when clicked again.)
Looking at your code I don't think so you need detach for what you are trying to achieve.
Instead try this code.
thisMMbtn.bind("click",
function() {
var thisRow = $(this).closest(".txtContentRow");
var thisTxt = thisRow.find(".txtContent");
var $mmCell = thisTxt.find('.mmCell');
if($mmCell.length == 0){
$mmCell = $('<div class = "mmCell prep"></div>')
.appendTo(thisTxt).hide();
}
$mmCell.toggle();
//$(this).unbind("click");
}
);
Demo

Categories

Resources