jQuery click inside each loop - javascript

I want to loop my click events, to make the code shorter. I might have 30 of these values later on.
My working code
$(document).ready(function () {
var last_click = '';
$("#title").click(function() { last_click = 'title'; });
$("#subtitle").click(function() { last_click = 'subtitle'; });
$("#test").click(function() { last_click = 'test'; });
});
This is how I want it (not working)
My guess is that the each-loop runs on dom ready and then never again and that way the click-event can never be triggered?
$(document).ready(function () {
var last_click = '';
var contents = new Array();
contents = ['title', 'subtitle', 'test'];
$.each(contents , function(index, value){
$("#" + value).click(function() { last_click = value; });
});
});
If there is not solved like I would, I would be thankful for a nice workaround.

I would rather add a class to all elements you want to bind this to, eg class="last-click"
and define the binding once as:
$(".last-click").on('click', function() {
last_click = this.id;
}

If you really wanted to make it shorter, give them all a similar class.
$(document).ready(function () {
var last_click = '';
$(".theclass").click(function() {
last_click = this.id;
});
});

if you have value attribute for your buttons or elements, you can do it:
$(document).ready(function() {
var last_click = '';
$("input").click(function() {
last_click = $(this).attr('value');
alert(last_click);
});
});​
I assumed that you are using "input type="button". Also here is the demo you can see it in action: http://jsfiddle.net/rS2Gb/5/

Related

How would I loop this?

I am trying to loop functionality for buttons I've made. I have 3 video collections. and they all need the same script for next and previous.
What I want is that I only have to make one next button and one prev button.
This is what it should do:
$("#next-1").click(function(){
var $this = $(".video-album-1");
callback = function() {
$this.insertBefore($this.siblings(':eq(2)'));
}
$this.fadeOut(200, callback).fadeIn(400);
});
$("#prev-1").click(function(){
var $this = $(".video-album-1");
callback = function() {
$this.insertAfter($this.siblings(':eq(3)'));
}
$this.fadeOut(200, callback).fadeIn(400);
});
$("#next-2").click(function(){
var $this = $(".video-album-2");
callback = function() {
$this.insertBefore($this.siblings(':eq(2)'));
}
$this.fadeOut(200, callback).fadeIn(400);
});
$("#prev-2").click(function(){
var $this = $(".video-album-2");
callback = function() {
$this.insertAfter($this.siblings(':eq(3)'));
}
$this.fadeOut(200, callback).fadeIn(400);
});
I've already tried to loop it, but this doesn't work:
for (i = 0; i < 3; i++) {
$("#next-"+i).click(function(){
var $this = $(".video-album-"+i);
callback = function() {
$this.insertBefore($this.siblings(':eq(2)'));
}
$this.fadeOut(200, callback).fadeIn(400);
});
$("#prev-"+i).click(function(){
var $this = $(".video-album-"+i);
callback = function() {
$this.insertAfter($this.siblings(':eq(3)'));
}
$this.fadeOut(200, callback).fadeIn(400);
});
}
Is there anyone that could tell me a solution? I do not want to repeatedly create #next-3 #next-4 ids etc..
Thanks in advance.
Can you take a look at below approach:
$("[id^=next-]").click(function(){
var current_id = $(this).attr("id");
var number = current_id.replace("next-","");
var $this = $(".video-album-"+number);
callback = function() {
$this.insertBefore($this.siblings(':eq(2)'));
}
$this.fadeOut(200, callback).fadeIn(400);
});
$("[id^=prev-]").click(function(){
var current_id = $(this).attr("id");
var number = current_id.replace("prev-","");
var $this = $(".video-album-"+number);
callback = function() {
$this.insertAfter($this.siblings(':eq(3)'));
}
$this.fadeOut(200, callback).fadeIn(400);
});
Here we are using jQuery's starts with selector to attach the event to required DOM elements and within event handler we are grabbing the associated number for further process.
Use a class with next(),prev(),find() to get the video album class based on the next/prev elements or use this hack
$('[id^="next-"]').click(function(){
var i = $(this).attr('id').split('-')[1];
var $this = $(".video-album-"+i);
callback = function() {
$this.insertBefore($this.siblings(':eq(2)'));
}
$this.fadeOut(200, callback).fadeIn(400);
});
$('[id^="prev-"]').click(function(){
var i = $(this).attr('id').split('-')[1];
var $this = $(".video-album-"+i);
callback = function() {
$this.insertAfter($this.siblings(':eq(3)'));
}
$this.fadeOut(200, callback).fadeIn(400);
I'll emphasize now this is just one way, there might be better ones
Assuming these are your buttons
<button class="next" data-videocollectionname="video1">next</button>
<button class="next" data-videocollectionname="video2">next</button>
<button class="next" data-videocollectionname="video3">next</button>
<button class="previous" data-videocollectionname="video1">previous</button>
<button class="previous" data-videocollectionname="video2">previous</button>
<button class="previous" data-videocollectionname="video3">previous</button>
I've given each button a data attribute to say which collection the button is relevant too.
Forgive me if I've miss understood the question
$(".next").click(function(){
var videoCollectionName = $(this).data("videocollectionname");
var videoElement = $("#"+videoCollectionName);
//do whatever code you want for the videocollection
});
$(".previous").click(function(){
var videoCollectionName = $(this).data("videocollectionname");
var videoElement = $("#"+videoCollectionName);
//do whatever code you want for the videocollection
});
This question and its answers explain why your attempt didn't work correctly.
Based on your attempted for loop, this will work:
$("[id^=next-]").click(function() {
var i = this.id.substring(5);
var album = $(".video-album-" + i);
callback = function() {
album.insertBefore(album.siblings(':eq(2)'));
};
album.fadeOut(200, callback).fadeIn(400);
});
$("[id^=prev-]").click(function() {
var i = this.id.substring(5);
var album = $(".video-album-" + i);
callback = function() {
album.insertAfter(album.siblings(':eq(3)'));
};
album.fadeOut(200, callback).fadeIn(400);
});
That works by using an attribute starts with selector to match all of your next- (and prev-) buttons, then figures out the index from the id of the button actually clicked.
But there's probably a better answer we could give you if you quote your HTML.

Javascript Dynamically invoke shortcut keys combination function to shortcutjs plugin

Am getting key Combination from the server. Based on that am assigning key Combination to function dynamically. The below code is working for last iteration in loop. how below code is work for all iterations.
In my page i have two buttons save and cancel the below code is working for last iteration in for loop, It means btnCanel button triggers if i press key for save function.Any suggestions. hope understand my question.
$(document).ready(function fn() {
var keyCombination = new Object();
keyCombination['btnAdd'] = "Alt+S";
keyCombination['btnCancel'] = "Alt+C";
for (var k in keyCombination) {
if (keyCombination.hasOwnProperty(k)) {
shortcut.add(String(keyCombination[k]), function () {
var btnAdd = document.getElementById(String(k));
btnAdd.focus();
btnAdd.click();
});
}
}
});
if i give like this means it is working
shortcut.add("Alt+S", function () {
var btnAdd = document.getElementById('btnAdd ');
btnAdd .focus();
btnAdd .click();
});
shortcut.add("Alt+C", function () {
var btnCancel = document.getElementById('btnCancel');
btnCancel.focus();
btnCancel.click();
});
but if i try to add dynamically its overriding help me this issue.
Thanks in Advance.
I created a separate function outside the document.ready function like this now its working fine.
$(document).ready(function fn() {
var keyCombination = new Object();
keyCombination['btnAdd'] = "Alt+S";
keyCombination['btnCancel'] = "Alt+C";
for (var k in keyCombination) {
if (keyCombination.hasOwnProperty(k)) {
Set_KeyCombinations(k, keyCombination);
}
}
});
function Set_KeyCombinations(k, keyCombination) {
shortcut.add(String(keyCombination[k]), function () {
var eleId = document.getElementById(String(k));
if (eleId) {
if ($('#' + String(k).trim()).css('display') !== 'none' && eleId.getAttribute("disabled") !== "disabled") {
eleId.click();
eleId.focus();
}
}
});
}
Try this:
var keyCombinations = [ "Ctrl+Shift+X" , "Ctrl+Shift+Y" ];
for(var i=0; i<keyCombinations.length; i++){
(function(shorcutCombination){
shortcut.add(shorcutCombination,function() {
alert("i am " + shorcutCombination);
});
})(keyCombinations[i]);
}
The idea is that you need to preserve the value of keyCombinations[i]
as i increases in the loop. Tested this here: Openjs

Making bootstrap-tags responsive, jquery events lost

I am trying to change this demo:
http://maxwells.github.io/bootstrap-tags.html
into a responsive version in which I can set it to readOnly and remove it from readOnly as I like. This code:
var alltags = ["new tag", "testtag", "tets", "wawa", "wtf", "wtf2"];
$(document).ready(function() {
var tagbox = $('#my-tag-list').tags({
suggestions: alltags
});
var tagenable = true;
$('#my-tag-list').focusout(function() {
if (tagenable) {
tagbox.readOnly = true;
$('#my-tag-list').empty();
tagbox.init();
tagenable = false;
}
});
$('#my-tag-list').click(function() {
if(!tagenable) {
tagbox.readOnly = false;
$('#my-tag-list').empty();
tagbox.init();
tagenable = true;
}
});
});
seems to work fairly well, it makes everything readonly after focusout and editable when I click it. However, the editing does not work since I cannot insert new tags nor delete them (seems to be like event handling was lost or something like that).
I am guessing that emptying the #my-tag-list div is causing this, but I cannot yet find a way to use for instance "detach" instead that removes everything inside (not the element itself) and putting it back in again.
I tried to make a JS Fiddle, but it isn't really working so well yet:
http://jsfiddle.net/tomzooi/cLxz0L06/
The thing that does work is a save of the entire website, which is here:
https://www.dropbox.com/sh/ldbfqjol3pppu2k/AABhuJA4A6j9XTxUKBEzoH6za?dl=0
this link has the unminimized JS of the bootstrap-tags stuff I am using:
https://github.com/maxwells/bootstrap-tags/blob/master/dist/js/bootstrap-tags.js
So far I managed to do this with some modifications of the bootstrap javascript code. I use two different tagbox which I hide and unhide with some click events.
var tagbox = $('#my-tag-list').tags({
suggestions: alltags,
tagData: tmp_tags,
afterAddingTag: function(tag) { tagboxro.addTag(tag); },
afterDeletingTag: function(tag) {tagboxro.removeTag(tag); }
});
var tagboxro = $('#my-tag-listro').tags({
suggestions: alltags,
tagData: tmp_tags,
readOnly: 'true',
tagSize: 'sm',
tagClass: 'btn-info pull-right'
});
$(document).mouseup(function (e) {
var container = $("#my-tag-list");
if (!container.is(e.target) // if the target of the click isn't the container...
&& container.has(e.target).length === 0) { // ... nor a descendant of the container
if (tagsave) {
$("#my-tag-listro").show();
$("#my-tag-list").hide();
var tags = tagbox.getTags();
$.post("%basedir%/save.php", {
editorID:"new_tags",
tags:tags
}, function(data,status){
//alert("Data: " + data + "\nStatus: " + status);
});
tagsave = false;
}
}
});
$('#my-tag-listro').click(function() {
tagsave = true;
//$(".tag-list").toggle();
$("#my-tag-list").show();
$("#my-tag-listro").hide();
});
I had to modify the code of bootstrap-tags.js to allow for this since it normally deletes all of the usefull functions when it is considered readonly in the init function:
if (this.readOnly) {
this.renderReadOnly();
this.removeTag = function(tag) {
if (_this.tagsArray.indexOf(tag) > -1) {
_this.tagsArray.splice(_this.tagsArray.indexOf(tag), 1);
_this.renderReadOnly();
}
return _this;
};
this.removeTagClicked = function() {};
this.removeLastTag = function() {};
this.addTag = function(tag) {
_this.tagsArray.push(tag);
_this.renderReadOnly();
return _this;
};
this.addTagWithContent = function() {};
this.renameTag = function() {};
return this.setPopover = function() {};
}
would be awesome if this feature was incorporated in a somewhat less hacky way though :)

Creating a re-usable function in JavaScript

I'm extracting a part of the current button ID and want it to re-use this in several other functions.
How could I make the following section common,
var idRec = $(this).attr("id"),
inp = idRec.substr(4,this.id.length);
So that it could be used in multiple .on('click',) events. Please see the following code and advise,
$(function() {
function studentsRecords(e) {
//do_somehting
}
$(document).on('click', '.studentID', function(e) {
var idRec = $(this).attr("id"),
inp = idRec.substr(2, this.id.length);
//do_something_using_inp
}).on('click', '.admissionID', function(e) {
//do_something_else_using_inp
});
});
$(function() {
function studentsRecords(e) {
//do_somehting
}
function get_id(that){
var idRec = that.id;
var inp = idRec.substr(2,that.id.length);
return inp
}
$(document)
.on('click', '.studentID', function(e) {
var inp = get_id(this);
//do_something_using_inp
})
.on('click', '.admissionID', function(e) {
var inp = get_id(this);
//do_something_else_using_inp
})
})
You can declare inp before click function. http://fiddle.jshell.net/x3xo25vz/

Toggling two events on one button

I'm trying to add some functionality to be able to edit comments inline. So far it's pretty close, but I'm experiencing issues trying to trigger a second event. It works the first time, but after that, fails.
$(function() {
var $editBtn = $('.js-edit-comment-btn');
var clicked = false;
$editBtn.on('click', $editBtn, function() {
clicked = true;
var $that = $(this);
var $form = $that.closest('.js-edit-comment');
var $commentTextBody = $that.closest('div').find('.js-comment-body');
var commentText = $commentTextBody.text();
var $editableText = $('<textarea />');
if ($that.text() === 'Save Edits') {
$that.text('Saving...').attr('disabled', true);
} else {
$that.text('Save Edits').attr('alt', 'Save your edits');
}
// Replace div with textarea, and populate it with the comment text
var makeDivTextarea = function($editableText, commentText, $commentTextBody) {
$editableText.val(commentText);
$commentTextBody.replaceWith($editableText);
$editableText.addClass('gray_textarea js-edited-comment').width('100%').css('padding', '4px').focus();
};
makeDivTextarea($editableText, commentText, $commentTextBody);
var saveEdits = function($that, $editableText) {
$that.on('click', $that, function() {
if (clicked) {
var comment = $that.closest('div').find('.js-edited-comment').val();
$editableText.wrap('<div class="js-comment-body" />').replaceWith(comment);
$that.text('Edit').attr('alt', 'Edit Your Comment').attr('disabled', false);
$('#output').append('saved');
clicked = false;
return false;
}
});
};
saveEdits($that, $editableText);
return false;
});
});​
jsfiddle demo here
Hiya demo for your working solution: http://jsfiddle.net/8P6uz/
clicked=true was the issue :)) I have rectified another small thing. i.e. $('#output') is set to empty before appending another saved hence text **saved** will only appear once.
small note: If I may suggest use Id of the button or if there are many edit buttons try using this which you already i reckon; I will see if I can write this more cleaner but that will be sometime latter-ish but this should fix your issue. :) enjoy!
Jquery Code
$(function() {
var $editBtn = $('.js-edit-comment-btn');
var clicked = false;
$editBtn.on('click', $editBtn, function() {
clicked = true;
var $that = $(this);
var $form = $that.closest('.js-edit-comment');
var $commentTextBody = $that.closest('div').find('.js-comment-body');
var commentText = $commentTextBody.text();
var $editableText = $('<textarea />');
if ($that.text() === 'Save Edits') {
$that.text('Saving...').attr('disabled', true);
} else {
$that.text('Save Edits').attr('alt', 'Save your edits');
}
// Replace div with textarea, and populate it with the comment text
var makeDivTextarea = function($editableText, commentText, $commentTextBody) {
$editableText.val(commentText);
$commentTextBody.replaceWith($editableText);
$editableText.addClass('gray_textarea js-edited-comment').width('100%').css('padding', '4px').focus();
};
makeDivTextarea($editableText, commentText, $commentTextBody);
var saveEdits = function($that, $editableText) {
$that.on('click', $that, function() {
if (clicked) {
var comment = $that.closest('div').find('.js-edited-comment').val();
$editableText.wrap('<div class="js-comment-body" />').replaceWith(comment);
$that.text('Edit').attr('alt', 'Edit Your Comment').attr('disabled', false);
$('#output').text("");
$('#output').append('saved');
clicked = true;
return false;
}
});
};
saveEdits($that, $editableText);
return false;
});
});​

Categories