Prototype hasclassname issue - javascript

I have a ul list :
<ul id="menubar">
<li onclick="ajx=new Ajax.Updater('container','schedule.php',{evalScripts:true,onComplete:oncom(this)})">one</li>
<li onclick="ajx=new Ajax.Updater('container','schedule.php',{evalScripts:true,onComplete:oncom(this)})">two</li>
</ul>
Here is the function callback:
function oncom(element){
//$(element).addClassName('current');
$$('#menubar li').invoke('observe', 'click', (function(element) {
//removes classname from all the li elements
//
var list_item = Event.element(element);
//Gets the li you clicked on
//adds the classname
if(!(list_item.hasClassName('current'))){
list_item.addClassName('current');
}else{
$$('#menubar li').invoke('removeClassName', 'current');
}
}).bindAsEventListener(this));
}
But its not making the current link having affect of that class, but when I click on next link its takes affect. How to solve this?

The options you are passing to the updater are {evalScripts:true,onComplete:oncom(this)}. You are not assigning the function oncom to onComplete but calling oncom(this) straight away then assigning it's result to onComplete - and the result is null.
If container contains the menubar list then it will also be replaced (probably why you are recreating click handlers). Consider using Event.on once so that newly inserted elements behave correctly.
Event.on('container', 'click', '#menubar li', function(event, element) {
// manipulate class names here
});
Also consider that if all you're doing is manipulating class names you can do that on the server when AJAX is used, that will avoid race problems.

The reason its not working until you click the first item is because the oncom function contains the observe for the li elements, and you're not running that code until you click on one. You need to get rid of the onClick stuff in the html if possible. Just run this code when the page load, and it will observe the li's straight away:
$$('#menubar li').invoke('observe', 'click', (function(e) {
//Removes current class from all the li's
$$('#menubar li').invoke('removeClassName', 'current');
//Add current class to the li clicked on
Event.element(e).addClassName('current');
//Does whatever this does, without being in the onClick
new Ajax.Updater('container','schedule.php',{
evalScripts:true
});
}).bindAsEventListener(this));

Related

What does the keyword this refer to in this context?

I am using jQuery and semantic UI for a project, and I got stuck with what the second this is referring to. what would the second this be referring to? I am new with jQuery by the way. I want the second this to refer to #sideBar a but every time I try to add classes it doesn't work,
I want to remove all classes, then add item to all of them, then get the text content of the anchor tag and set that anchor tag's attribute with a class with the textContent as it's name.
$('#sideBar a').on('click', function(){
$('#sideBar a').removeClass().addClass("item");
var addC = ($(this).text());
$(this).addClass(addC);
});
Could anyone tell me how to do this, I have some knowledge of apply call and bind in javascript by the way
this inside and event listener with a non-arrow function will be your event target:
$('#sideBar a').on('click', function (event) {
// next line removes all classes from all anchor elements that are children of #sideBar then adds the class item to each of them
$('#sideBar a').removeClass().addClass("item");
// sets addC to whatever the event target's text is
var addC = ($(this).text());
// adds the text stored in addC as a class to the event target
$(this).addClass(addC);
console.log(this === event.target); // logs true
});
edit: I just realized I didn't answer your question:
$(this).parents('#sideBar').first().addClass(addC); instead of $(this).addClass(addC); should do the trick.

Jquery only click once

I'm trying to disable a li click event after it has clicked the first time. Essentially to stop the array data being doubled. The click is working fine for each time. My current method doesn't appear to be working. I also need to disable the other li's from being clicked once the first one has :)
Thanks
JS code is:
$('#eventType ul li').click(function(e) {
e.preventDefault();
var value = $(this).attr('value');
answers.push(value);
// Below isn't working
$(this).click(function() {
return false;
});
console.log(answers);
});
you need to use one:
$('#eventType ul li').one('click',function(){
//your code here
});
this event will be fired only once
UPDATE
you can do that using $.off()
$('#eventType ul li').one('click',function(){
//your code here
$('#eventType ul li').off('click');
});
jQuery is just JavaScript so you can easily add behaviors that you want
// basic jQuery plugin boilerplate
$.fn.once = function once(eventType, f) {
// this = the selected elements
return this.each(idx, elem) {
// create reference to jQuery-wrapped elem
var $elem = $(elem);
// add event listener for eventType
$elem.on(eventType, function(event) {
// call the event handler
return f(event);
// remove the event handler
$elem.off(eventType, f);
});
});
};
Usage would look like this
$('#eventType ul li').once('click', function(event) {
console.log("you will only see this once");
});
However, this is obviously a common need so it exists in jQuery already. It's called $.one. As APIs grow, you may not know about the existence of such procedures. This answer exists to show you that you can use your brain to program the things that you want or that might be missing from a particular library. This lessens your dependence on the creator's of the lib to introduce the functionality you need.
EDIT
In a comment, you ask if the event handler can be disabled for all other LI elements after the first LI is clicked. The trouble here is that jQuery uses implicit iteration, which means that when you call $('li').on('click', ...), jQuery will bind an onclick event handler for each LI.
A better solution to this problem would be to use jQuery's event delegation
// only fire event handler for the first LI clicked
$('ul').one('click', 'li', function(event) {
console.log($(this).text());
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li>one</li>
<li>two</li>
<li>three</li>
</ul>
This will delegate the event listener to the children LI, but once one of the LI is clicked, the event handler will be removed (because we delegated using the $.one procedure).
Try clicking one LI, you will see a message in the console. When you click the second LI, nothing will happen because the event handler was removed.
var used = false;
$('#eventType ul li').click(function(e) {
if (used == false) {
used = true;
e.preventDefault();
var value = $(this).attr('value');
answers.push(value);
console.log(answers);
}
});
the way you did it was just adding another on click handler, not removing or overriding the old ond.
You can use CSS classes; add the class 'disabled' to elements you don't need, and avoid adding elements that have the classe 'disabled'.
https://plnkr.co/edit/6aloNPETHGxfiP5oYZ9f?p=preview
$('ul li').click(function(e) {
if(!$(this).hasClass('disabled')) {
var value = $(this).text();
answers.push(value);
$('li').addClass('disabled');
}
console.log(answers);
});

My jquery menu focus function is not working

I'm sorry but I just started to learn jquery and Im struggling with a most basic thing
jsfiddle : http://jsfiddle.net/ufvakggn/
Here is my function :
var active = $('nav ul li');
active.focus(function() {
$(this).children('ul').toggleClass('active');
})
basically I want to navigate with tab through my menu. I thought the best way to do this is to use a toggleclass on children element when a parent element has focus. But I can't make this work
update : actually I made some progress with
var active = $('.has-sub a');
active.focus(function() {
$('nav ul ul').toggleClass('active');
})
still trying to find a way to tab through every element and not activating all submenus when I focus something
You want to target the specific <ul> that is a sibling of the target <a>
$('.has-sub a').on('focus blur', function() {
$(this).siblings('ul').toggleClass('active');
});
Within an event handler this is the element within the selector that the event occurred on. From that element you can use whatever traverses you need to target other specific elements
DEMO

click function call with $(this) from another function in javascript/jquery

I have a click function which is given below
$('.page-nav li').click(function(event){
console.log("clickedTab-page-nav-first-before set ="+Session.get('clickedTab'));
Session.set('clickedTab',event.target.id);
//var sel = event.prevUntil("[class*=active]").andSelf();
var sel = $(this).prevUntil("[class*=active]").andSelf(); //find all previous li
//of li which have
//class=active
sel = sel.add(sel.eq(0).prev()); // include the that li also(Now all li elements).
sel.removeClass('active'); //Remove the active.
//sel = event.nextUntil("[class*=active]").andSelf(); //Also for top to bottom
//(Viceversa)
sel = $(this).nextUntil("[class*=active]").andSelf();
sel = sel.add(sel.eq(-1).next());
sel.removeClass('active');
//event.addClass('active');
$(this).addClass('active'); //Now add class active for the clicked li
var rightcontent="";
console.log("clickedTab-page-nav-second-after set = "+Session.get('clickedTab'));
switch($(this).attr('id')){
case 'rfq':
.......
.....
}
});
Then next is I want to call this click function from another place
$(document).ready(function() {
console.log("clickedTab-page load = "+Session.get('clickedTab'));
if(Session.get('clickedTab')!=null||Session.get('clickedTab')!= undefined){
alert("Got It");
//$('.page-nav li').click(event);
$('.page-nav li').click(); //this is not working
}
});
Now the problem is page click function in if condition is not working. However I got the alert. Any help is highly appreciated. Thanks in advance...
you are not really using the event parameter in your function and you state you wish to call it outside of an event chain so you could change it to be a regular function
var setupClicktab = function(id){
console.log("clickedTab-page-nav-first-before set ="+Session.get('clickedTab'));
Session.set('clickedTab',id);
...
}
the you'd use it like:
$('.page-nav li').click(function(event){return setupClicktab(event.target.id);});
and in document ready
setupClicktab.Call($('.page-nav li'),Session.get('clickedTab'));
The latter call class it in the context of the selection (that is this inside the function will refer to the selection(1). It also passes the value stored in the session variable in as the id.
a side note. Your test
if(Session.get('clickedTab')!=null||Session.get('clickedTab')!= undefined)
could simply be
if(Session.get('clickedTab'))
Unless you might store either an empty string, zero or the boolean value false in that variable. But seeing how it's used that's unlikely since they are all invalid values for the id attribute
(1)This is slightly different than in the click event where it refers to the DOM element)
You need to put $('.page-nav li').click(function(event){ inside document.ready and before your $('.page-nav li').click();. Because if you call .click when the DOM is not ready, there are chances that there is no event handler attached
If you don't put $('.page-nav li').click(function(event){ inside document.ready OR you're dealing with dynamically created elements. You need delegated event $(document).on("click",".page-nav li",function(event){
From $.on

Removing elements of list using parent/child

I'm looking to dynamically remove li elements from several connected ul lists. Right now I am assigning 'dblclick' event behaviors by using $("#sortable1").children().on('dblclick',function() {...})
The items in #sortable1 will be moved to other lists (#sortable2, #sortable3, etc) by the user.
When a list item is double clicked, a dialog box pops up asking if the user would like to delete it. If the user says yes, I want the list item to be removed from whatever list it is in. I am trying to do it using something like:
$($(this).parent().childNodes[$(this).index()]).remove()
But that doesn't work.
Advice?
Something like this should work.
var showPopup = function( elem ){
//show your popup with a function like this, as i assume it already does...
$( '#delete_toggle' ).one( 'click', function(){
elem.remove();
});
};
$("#sortable1").children().on('dblclick',function(){
showPopup( $(this) );
});
To remove the element that was clicked on, you just use this in the event handler:
$(this).remove();
or if you've saved the element reference to a variable elem, it would be this:
$(elem).remove();
You are trying to make it way more complicated than need be. The jQuery .remove() method looks at who its current parent is and takes care of all that for you.

Categories