DRY JS - How to Combine Identical JavaScript Functions into One? - javascript

I have a JS function that loads the same re-size function based on the button id.
JS Fidle Demo
I'm trying to simplify the code to keep it DRY and clean. Since I can have 100+ of these buttons on a single page, I need to somehow make the code more dynamic.
var a = $('.a').popover();
a.on("show.bs.popover", function(e) {
a.data()["bs.popover"].$tip.css("max-width", "630px");
});
var b = $('.b').popover();
b.on("show.bs.popover", function(e) {
b.data()["bs.popover"].$tip.css("max-width", "630px");
});
var c = $('.c').popover();
c.on("show.bs.popover", function(e) {
c.data()["bs.popover"].$tip.css("max-width", "630px");
});
var d = $('.d').popover();
d.on("show.bs.popover", function(e) {
d.data()["bs.popover"].$tip.css("max-width", "630px");
});
I tried this but it only works for the first button:
var a = $('.a, .b, .c, .d,').popover();
a.on("show.bs.popover", function (e) {
a.data()["bs.popover"].$tip.css("max-width", "630px");
});
Any ideas?
All I need is to make the bootstrap Popover window 600px.

You need to use this inside the closure so you reference the active element
$('.a, .b, .c, .d').popover().on("show.bs.popover", function (e) {
$(this).data()["bs.popover"].$tip.css("max-width", "630px");
});
also weird on how you use data and not put the key inside. Normally you would use data("key") instead of the bracket notation
$(this).data("bs.popover").$tip.css("max-width", "630px");

Try
var a = $('.a, .b, .c, .d,');
a.each(function(){
var $this = jQuery(this);
$this.popover();
$this.on("show.bs.popover", function (e) {
$this.data("bs.popover").$tip.css("max-width", "630px");
});
});

Related

Remove parent and everything inside it?

I'm trying to use jQuery to remove a div and all of its content when a child div is clicked. To explain this, here is a working FIDDLE. Basically I need to remove the pDiv when the close button is clicked. So I tried this:
$('div').on('click', '.closeDiv', function () {
$(this).prev().remove();
$(this).remove();
$(this).parent().remove();
$('#upload-file').val("");
});
However this doesn't seem to delete the pDiv.
Please test the FIDDLE above buy adding an image and then click on the Green close button and then try to add another image and you will see that the previous pDiv hasn't been removed.
Could someone please advice on this issue?
Thanks in advance
The issue is because you call $(this).remove() before you try and do further DOM traversal on the element which no longer exists. Remove that line. Note that you can also just use closest() to find the required .pDiv element, then remove it, like this:
$('#thumbnail').on('click', '.closeDiv', function() {
$(this).closest('.pDiv').remove();
});
Also note that the code in your fiddle uses an odd mix of jQuery and native JS. You should stick to one or the other. You're also doing several processes which aren't needed, such as creating a canvas element. Try this:
jQuery(function($) {
var $thumbnail = $('#thumbnail').on('click', '.closeDiv', function() {
$(this).closest('.pDiv').remove();
$('#upload-file').val('');
});
var $fileDiv = $("#upload");
var $fileInput = $("#upload-file").on('change', function(e) {
var filesVAR = this.files;
showThumbnail(filesVAR);
});
function showThumbnail(files) {
var file = files[0]
var $pDiv = $('<div class="pDiv" />').appendTo($thumbnail);
var $image = $('<img class="imgKLIK5" />').appendTo($pDiv);
var $div = $('<div class="closeDiv">X</div>').appendTo($pDiv);
var reader = new FileReader()
reader.onload = (function(aImg) {
return function(e) {
aImg.src = e.target.result;
};
}($image[0]))
var ret = reader.readAsDataURL(file);
}
});
Updated fiddle
try following and follow the comment i mentioned.
$(document).on('click', '.closeDiv', function () {
$(this).prev().remove(); // i don't know why you need this.. let us know your structure
//$(this).remove(); you don't need this line
$(this).parent().remove();
$('#upload-file').val("");
});
Please find the working Fiddle for this

How to let onclick(); listens to more than one button

I am trying to let Jq listen to three buttons at the same onclick method
then trigger a function and call the clicked button by $(this);
here is a sample :
$("body").on('click', 'a.home:visible', 'a.mobile:visible', 'a.phone:visible', function () {
var attr = $(this).attr('attr');
$(this).parents('.dropdown-menu').prev().prev().text(attr);
});
You did it basically correct. Your approach is fine. But you have to combine it in one string, not as single parameters. And you don't need :visible, because you can't click on invisible elements. ;)
$("body").on('click', 'a.home, a.mobile, a.phone', function() {
var attr = $(this).attr('attr');
$(this).parents('.dropdown-menu').prev().prev().text(attr);
});
If the elements are static you should even use a normal event listener instead of a delegation.
$('a.home, a.mobile, a.phone').click(function() {
var attr = $(this).attr('attr');
$(this).parents('.dropdown-menu').prev().prev().text(attr);
});
Put them in one quotes
$("body").on('click', 'a.home:visible,a.mobile:visible,a.phone:visible', function() {
alert('Clicked')
});
JSFIDDLE

hide two elements on click on anywhere on the page

I am trying to hide two elements with classes notify-me and write-review, on click on anywhere on the page but not on those two elements.
How to do this using prototype?
Right now if I click on even the overlays, they are being closed.
PS: I am attaching the click event to body.
Try this :
$(document).on('click', function (e) {
var re = /(^|\s)(notify-me|write-preview)(\s|$)/;
if (re.test($(e.target).classNames())) return false;
$$('.notify-me', '.write-preview').invoke('hide');
});
Here is an improved version which bubbles up through the target element's ancestors :
$(document).on('click', function (e) {
var re, els, iterator;
re = /(^|\s)(notify-me|write-preview)(\s|$)/;
els = [$(e.target)].concat($(e.target).ancestors());
iterator = function (el) { return re.test(el.classNames()); };
if (els.find(iterator)) return false;
$$('.notify-me', '.write-preview').invoke('hide');
});
Here is a demo : http://jsfiddle.net/wared/U7E2a/.

jQuery Bind each() and also click() on the same function

So I have the following fragment:
$(".server").each(function() {
var element = $(this);
//bunch of javascript here with element
});
I also want to bind a single click event for an id to do the same work as the above, how is this possible, without copying and pasting the entire block and doing:
$("#my-id").click(function() {
var element = $(this);
//bunch of javascript here with element
});
I think the following should work:
var eventHandler = function() {
var element = $(this);
//bunch of javascript here with element
};
$(".server").each(eventHandler);
$("#my-id").click(eventHandler);

Adding two click events to the same button only works once

Basically I'm trying to make a button be able to handle editing of an element. I want it so that when I click on the Edit button, it changes the text to Save Changes and adds a class which will then bind the button to another click event so that when they click Save Changes, it'll alert "Saved!" and change the text back to Edit. It does this perfectly once. If you continue to try to do it, it simply won't add the class or change the text anymore.
Here is a demo on jsfiddle
The code:
$(function() {
$button = $('button[name="edit"]');
$button.on('click', $button, function() {
var $that = $(this);
$that.text('Save Changes');
$that.addClass('js-editing');
if ($that.hasClass('js-editing')) {
$that.off('click').on('click', $that, function() {
alert('Saved!');
$that.text('Edit');
$that.removeClass('js-editing');
});
}
});
});​
Try this http://jsfiddle.net/bpD8B/4/
$(function() {
$button = $('button[name="edit"]');
$button.on('click', $button, function() {
var $that = $(this);
if($that.text()=='Edit'){
$that.text('Save Changes');
$that.addClass('js-editing');
}
else{
alert('Saved!');
$that.text('Edit');
$that.removeClass('js-editing');
}
});
});
You never add back the original handler after calling off(), which removes it.
That being said, it might be easier to have two buttons, with appropriate click handlers, and then use hide() and show() to alternate which one is available. To the end user it should look and act exactly the same, and to you it will be a lot less of a headache to code.
Example: http://jsfiddle.net/VgsLA/
I think in the end, this code is more robust and manageable.
This is just a logic problem. And with $that.off('click').on('click', $that, function() { you are delegating to itself, which is not how you should do it.
Here is a solution using your code:
$(function() {
$button = $('button[name="edit"]');
$button.on('click', $button, function() {
var $that = $(this);
if ($that.hasClass('js-editing')) {
alert('Saved!');
$that.text('Edit');
$that.removeClass('js-editing');
} else {
$that.text('Save Changes');
$that.addClass('js-editing');
}
});
});​
Demo

Categories