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/
Related
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.
I have the the following code:
$('#theForm').on('click', 'button', function(e){
var attrs = { };
var str =e.target.id;
var newStr = str.substring(0, str.length-1);
$("#file01b").replaceWith(function () {
attrs.text = $(this).text();
return $("<a />", attrs);
});
var field= document.getElementById(newStr);
field.value= field.defaultValue;
document.getElementById(newStr).style.display = "none";
});
All the code: http://jsfiddle.net/K9eWL/3/
and when I click on the first "Remove File" button it works fine, so I tried to make it automatically, in order it works for all the buttons:
$('#theForm').on('click', 'button', function(e){
var attrs = { };
var str =e.target.id;
var newStr = str.substring(0, str.length-1);
$("#str").replaceWith(function () {
attrs.text = $(this).text();
return $("<a />", attrs);
});
var field= document.getElementById(newStr);
field.value= field.defaultValue;
document.getElementById(newStr).style.display = "none";
});
All the code: http://jsfiddle.net/K9eWL/3/
but it doens't work, where is the error?
Thanks for the help.
How about, instead of:
$("#file01b").replaceWith(function () {
You use:
$("#"+e.target.id).replaceWith(function () {
Check your fiddle, updated.
Note: If the above is fine, then $(e.target).replaceWith(function () { will work as well.
'this.id' also works.
$("#"+this.id).replaceWith(function () {
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/
I have two click-events, that are nearly similar, but not quite. I am wondering how to refactor them best:
$('.remove_fields.dynamic').live('click', function(e) {
var $this = $(this);
var after_removal_trigger_node = $this.closest(".nested-fields").parent();
trigger_removal_callback($this);
e.preventDefault();
$this.closest(".nested-fields").remove();
trigger_after_removal_callback(after_removal_trigger_node);
});
$('.remove_fields.existing').live('click', function(e) {
var $this = $(this);
var after_removal_trigger_node = $this.closest(".nested-fields").parent();
trigger_removal_callback($this);
e.preventDefault();
$this.prev("input[type=hidden]").val("1");
$this.closest(".nested-fields").hide();
trigger_after_removal_callback(after_removal_trigger_node);
});
As you can tell there is a fair bit of overlap. I am wondering what the best/nicest way would be to refactor this code.
Do a class check in the .remove_fields click function.
$('.remove_fields').click(function(e) {
var $this = $(this);
var after_removal_trigger_node = $this.closest(".nested-fields").parent();
trigger_removal_callback($this);
e.preventDefault();
if($this.hasClass("dynamic") {
$this.closest(".nested-fields").remove();
} else if($this.hasClass("existing")) {
$this.prev("input[type=hidden]").val("1");
$this.closest(".nested-fields").hide();
}
trigger_after_removal_callback(after_removal_trigger_node);
});
Combine the selectors into $('.remove_fields.dynamic, .remove_fields.existing').
Then, test if $this has class existing. If so, run $this.prev("input[type=hidden]").val("1");.
Done.
taking cleaning a bit more:
$('.remove_fields').click(function(e) {
e.preventDefault();
var $this = $(this);
var $nestedFields = $this.closest(".nested-fields");
trigger_removal_callback($this);
if($this.hasClass("dynamic") {
$nestedFields.remove();
} else if($this.hasClass("existing")) {
$this.prev("input[type=hidden]").val("1");
$nestedFields.hide();
}
trigger_after_removal_callback($nestedFields.parent());
});
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;
});
});