Condensing Javascript/jQuery Code - javascript

I'd like to start by thanking anyone who can help me condense this piece of Javascript/jQuery code.
jQuery(function() {
jQuery('#pitem-1').click(function(e) {
jQuery("#image-1").lightbox_me({centered: true, onLoad: function() {
jQuery("#image-1").find("input:first").focus();
}});
e.preventDefault();
});
jQuery('#pitem-2').click(function(e) {
jQuery("#image-2").lightbox_me({centered: true, onLoad: function() {
jQuery("#image-2").find("input:first").focus();
}});
e.preventDefault();
});
jQuery('#pitem-3').click(function(e) {
jQuery("#image-3").lightbox_me({centered: true, onLoad: function() {
jQuery("#image-3").find("input:first").focus();
}});
e.preventDefault();
});
jQuery('table tr:nth-child(even)').addClass('stripe');
});
Basically each #pitem-ID opens the same #image-ID in a popup.
Thanks again to anyone who can help.
Jack

Your functions all look pretty much the same, which is a clue that you should probably move that functionality out into something that can be called:
function createHandler(id) {
return function (e) {
$(id).lightbox_me({centered: true, onLoad: function() {
$(id).find("input:first").focus();
}});
e.preventDefault();
}
};
Then you can use:
$('#pitem-2').bind('click', createHandler("#image-2"));

You can:
Combine multiple objects into the selector with a common event handler
Use this to refer to the object that triggered the event
Derive the image ID from the id of the object that generated the event.
That lets you use one piece of code to handle the action for all three objects:
jQuery(function() {
jQuery("#pitem-1, #pitem-2, #pitem-3").click(function() {
var image$ = $("#" + this.id.replace("pitem", "image"));
image$.lighbox_me({centered: true, onLoad: function() {
image$.find("input:first").focus();
}});
e.preventDefault();
});
jQuery('table tr:nth-child(even)').addClass('stripe');
});

$('[id^="pitem-"]').click(function(e) {
var numb = this.id.split('-')[1];
$("#image-"+numb).lightbox_me({centered: true, onLoad: function() {
$(this).find("input:first").focus();
}
});
e.preventDefault();
});
$('table tr:nth-child(even)').addClass('stripe');

Without context it is hard to tell, but is it necessary to have a unique ID for each pitem? Why not use a CSS class instead of a ID like so:
<div class="pitem">
<div id="image1"><img ... /></img>
</div>
...
<div class="pitem">
<div id="image3"><img ... /></img>
</div>
And then use the class selector in jQuery to add the click functionality all of them at once:
$(".pitem").click(function(e) {
var currentItem = e.target;
...
e.preventDefault();
});

Related

Why my `onclick` doesn't work despite others things works?

So I'm using some parts of gentelella and there is a file custom.js. I have some problems with this file because some parts works and other don't.
The problem is with this method:
$(document).ready(function() {
console.log("custom.js inside document ready");
$('.collapse-link').on('click', function() {
console.log("clicked on a collapse-link");
var $BOX_PANEL = $(this).closest('.x_panel'),
$ICON = $(this).find('i'),
$BOX_CONTENT = $BOX_PANEL.find('.x_content');
// fix for some div with hardcoded fix class
if ($BOX_PANEL.attr('style')) {
$BOX_CONTENT.slideToggle(200, function(){
$BOX_PANEL.removeAttr('style');
});
} else {
$BOX_CONTENT.slideToggle(200);
$BOX_PANEL.css('height', 'auto');
}
$ICON.toggleClass('fa-chevron-up fa-chevron-down');
});
$('.close-link').click(function () {
console.log("close-link clicked")
var $BOX_PANEL = $(this).closest('.x_panel');
$BOX_PANEL.remove();
});
});
It write "custom.js inside document ready" but when I click nothing happened.
And if I look into the HTML I have the same classes as in the JS:
it might be that on document ready these specific elements are not found.
In general a best practice is to delegate the events to the document, like this:
$(document).ready(function() {
console.log("custom.js inside document ready");
$(document).on('click', '.collapse-link' /* <--- notice this */, function() {
console.log("clicked on a collapse-link");
var $BOX_PANEL = $(this).closest('.x_panel'),
$ICON = $(this).find('i'),
$BOX_CONTENT = $BOX_PANEL.find('.x_content');
// fix for some div with hardcoded fix class
if ($BOX_PANEL.attr('style')) {
$BOX_CONTENT.slideToggle(200, function(){
$BOX_PANEL.removeAttr('style');
});
} else {
$BOX_CONTENT.slideToggle(200);
$BOX_PANEL.css('height', 'auto');
}
$ICON.toggleClass('fa-chevron-up fa-chevron-down');
});
$(document).on('click', '.close-link' /* <--- notice this */, function () {
console.log("close-link clicked")
var $BOX_PANEL = $(this).closest('.x_panel');
$BOX_PANEL.remove();
});
});
You have written the click event on the a tag. In general functional specific tags like submit button, a tag will do their default functionality on click. So as it is anchor it will check for href which is not there so the it is not redirecting to anywhere. We can supress the default behaviour of these kinds using e.preventDefault(). Here e is the event. So change your function to
$('.collapse-link').on('click', function(e) {
e.preventDefault();
console.log("clicked on a collapse-link");
var $BOX_PANEL = $(this).closest('.x_panel'),
$ICON = $(this).find('i'),
$BOX_CONTENT = $BOX_PANEL.find('.x_content');
// fix for some div with hardcoded fix class
if ($BOX_PANEL.attr('style')) {
$BOX_CONTENT.slideToggle(200, function(){
$BOX_PANEL.removeAttr('style');
});
} else {
$BOX_CONTENT.slideToggle(200);
$BOX_PANEL.css('height', 'auto');
}
$ICON.toggleClass('fa-chevron-up fa-chevron-down');
});
And
$('.close-link').on('click', function(e) {
e.preventDefault();
console.log("close-link clicked")
var $BOX_PANEL = $(this).closest('.x_panel');
$BOX_PANEL.remove();
});

On/off click event on alternating tabs

$('#filter').on('click', function(){
$('#sort').off('click');
console.log($(this));
});
$('#sort').on('click', function(){
$('#filter').off('click');
console.log($(this))
});
$('.close').on('click', function () {
console.log($(this));
$('#sort').on('click');
$('#filter').on('click');
});
Why doesnt the div .close give back the on method to the divs above if they have the same selector id?
EDIT: For clarity, I'm wanting to temporarily remove the on event on whichever of the two elements wasn't clicked (#filter or #sort). Then clicking '.close' will return the said element back to having the on method again.
The off() does not work the way you think. It actually removes the event handlers (callback functions), not just hides them, so you cannot restore them with a simple on(), they are not stored any longer by the element after the off(), you have to add them again. It is not easy to track whether an event handler is added, so I suggest another approach.
var sort = true;
var filter = true;
$('#filter').on('click', function(){
if (!filter)
return;
sort = false;
console.log($(this));
});
$('#sort').on('click', function(){
if (!sort)
return;
filter = false;
console.log($(this))
});
$('.close').on('click', function () {
console.log($(this));
sort = true;
filter = true;
});
Another approach to use toggle() and combine it with the on() and off() functions. Hmm I found that jquery toggle() is not loosely coupled to dom elements, so you cannot do this with that. You have to create your own implementation, for example something like this:
function toggle(options) {
var currentValue = !!options.value;
return function (value){
if (value === undefined)
value = !currentValue;
if (value != currentValue)
if (value) {
currentValue = true;
options.on();
}
else {
currentValue = false;
options.off();
}
};
}
With this toggle implementation your code will be the following:
var switches = {
sort: toggle({
on: function (){
$('#sort').on('click', function(){
switches.filter(false);
console.log($(this))
});
},
off: function (){
$('#sort').off('click');
}
}),
filter: toggle({
on: function (){
$('#filter').on('click', function(){
switches.sort(false);
console.log($(this));
});
},
off: function (){
$('#filter').off('click');
}
})
};
$('.close').on('click', function () {
console.log($(this));
switches.sort(true);
switches.filter(true);
});
switches.sort(true);
switches.filter(true);
You can try with:
$('#filter:not(.off)').on('click', function(){
$('#sort').addClass('off');
console.log($(this));
});
$('#sort:not(.off)').on('click', function(){
$('#filter').addClass('off');
console.log($(this))
});
$('.close').on('click', function(){
$('#sort').removeClass('off');
$('#filter').removeClass('off');
console.log($(this));
});
I'm assuming that in your block of code…
$('.close').on('click', function () {
console.log($(this));
$('#sort').on('click');
$('#filter').on('click');
});
You want to click #sort and #filter. To do such, you'll need to do the following:
$('.close').on('click', function () {
console.log($(this));
$('#sort').click();
$('#filter').click();
});
Even so, it would probably be better to wrap the other event handlers in a function and call them like such:
$('.close').on('click', function () {
console.log($(this));
sortClickFunction();
filterClickFunction();
});
This will do anything: $('#sort').on('click');
You need to call: $('#sort').trigger('click');

Onclick function on td element Kendo Scheduler

I have a table that is generated by a Kendo Scheduler.
I have to add a click function on each td on document load.
For now, I have tried this:
$(document).ready(function () {
$('td.k-nonwork-hour').click(function () {
alert("Hello");
});
});
For adding a onclick function. I have also tried with onclick
$(document).ready(function () {
$('td.k-nonwork-hour').onclick =function () {
alert("Hello");
};
});
But none of them works. Anyone knows a solution? :)
Better use delegated event instead of attaching event handler to each cell.
e.g.
scheduler.wrapper.on("click", "td.k-nonwork-hour", function() {
alert("Non working day!")
});
Here is live example.
scheduler.wrapper.on("mouseup touchend", ".k-scheduler-table td, .k-event", function(e) {
var target = $(e.currentTarget);
if (target.hasClass("k-event")) {
var event = scheduler.occurrenceByUid(target.data("uid"));
scheduler.editEvent(event);
} else {
var slot = scheduler.slotByElement(target[0]);
scheduler.addEvent({
start: slot.startDate,
end: slot.endDate
});
}
});

jquery .on(click) not working

i have a link on html
Veja aqui »</p>
and i'm using .on() to do a transition and load content from a external file
$(document).on("click", '#instalacoesbutton', function(){
$("#maincontent").slideUp(1000, function () {
$("#maincontent").load("instalacoes.html #instalacoes");
}).delay(500).slideDown(1000);
});
any idea why this doesn't work?
if i do:
$("#instalacoesbutton").on("click", function(){
$("#maincontent").slideUp(1000, function () {
$("#maincontent").load("instalacoes.html #instalacoes");
}).delay(500).slideDown(1000);
});
it works, for the 1st click, but doesn't after the page has been generated dinamically
Here you go:
jQuery:
$(document).ready(function() {
$("#instalacoesbutton").on("click", function() {
$("#maincontent").slideUp(1000, function () {
$("#maincontent").load("instalacoes.html #instalacoes");
}).delay(500).slideDown(1000);
});
});
Try it yourself on jsFiddle
If you want the action to fire on all future elements which match that selector, you can set up a click on the document and look for a clicks on that item. This would look something like:
$(document).click(function (e) {
if ($(e.target).is(".testSelector")) {
// do stuff to $(e.target)
}
});

Is it possible to bind multiple functions to multiple delegation targets in one place?

As it is possible to define multiple event handlers in one single function in jQuery like this:
$(document).on({
'event1': function() {
//do stuff on event1
},
'event2': function() {
//do stuff on event2
},
'event3': function() {
//do stuff on event3
},
//...
});
Then again we can do this:
$(document).on('click', '.clickedElement', function() {
//do stuff when $('.clickedElement') is clicked
});
I was wondering if it is also possible to do something like this (the following code does not work, it's just for illustration):
$(document).on('click', {
'.clickedElement1', function() {
//do stuff when $('.clickedElement1') is clicked
},
'.clickedElement2', function() {
//do stuff when $('.clickedElement2') is clicked
},
//... and so on
});
This code gives me an error complaining about the "," after '.clickedElementX'. I also tried it like this:
$(document).on('click', {
'.clickedElement1': function() {
//do stuff when $('.clickedElement1') is clicked
},
//... and so on
});
Then I don't have the error but also the function is not executed. Is there a way to collect all the click handlers in one place like this or would I have to always do it like this:
$(document).on('click', '.clickedElement1', function() {
//do stuff when $('.clickedElement1') is clicked
});
$(document).on('click', '.clickedElement2', function() {
//do stuff when $('.clickedElement2') is clicked
});
//... and so on
You can chain :
$(document).on({
click: function() {
//click on #test1
},
blur: function() {
//blur for #test1
}
}, '#test1').on({
click: function() {
//click for #test2
}
}, '#test2');
FIDDLE
Short answer: no, you have to bind them all separately.
Long answer: You can create an "infrastructure" for your site and have all events in one place. e.g.
var App = function(){
// business logic
return {
Settings: { ... },
Events: {
'event1': function(){
},
'event2': function(){
},
'event3': function(){
}
}
}
}();
Then wiring it up involves:
$(document).on(App.Events);
Then internally you can add then new bindings to your App object but still remains wired up in only one place (as far as jQuery is concerned). You could then make some kind of subscriber model within App (e.g. App.Subscribe('click', function(){ ... })) and each new subscription still is only wired through the single .on() binding.
but, IMHO, this is a lot of overhead with very little pay-off.
$(document).on('click' , function(e){
if($(e.target).hasClass("some-class")){
//do stuff when .some-class is clicked
}
if($(e.target).hasClass("some-other-class")){
//do stuff when .some-other-class is clicked
}
});
you can choose any some-class you want
It can be easily done, really:
$(document).ready(function()
{
$(this).on('click', '.one, .two',function()
{
if ($(this).hasClass('one'))
{//code for handler on .one selector
console.log('one');
}
else
{//code for handler on .two selector
console.log('two');
}
console.log(this);//code for both
});
});
If multiple events is what you're after:
$(document).ready(function()
{
$(this).on('click focus', '.one, .two',function()
{
if (event.which === 'click')
{
if ($(this).hasClass('one'))
{
console.log('one');
}
else
{
console.log('two');
}
}
else
{
console.log('focus event fired');
}
console.log(this);
});
});
Play around with this: here's a fiddle
documentation on event
jQuery's on, which is used here as though it were delegate
you can use a helper function:
function oneplace(all){
for (var query in all){
$(query).on('click', all[query]);
}
}
and then call:
oneplace(
{'#ele1':function(){
alert('first function');
},
'#ele2':function(){
alert('second function');
}});
jsfiddle here: http://jsfiddle.net/5zwkf/

Categories

Resources