Create instances of function - javascript

I have a map with a bunch of buttons that show and hide container div's. I don't want to assign the same code to each button because it's all the same.
I was thinking to create a variable when the button is clicked so it could replace a part in the DIV ID (handler?)
So I could refer to #fiche_8_1980_img_container as #fiche_VARIABLE.
Second part of my question is the animation functions I do are all looking like this:
$('#fiche_8_1980_img_container').animate({"opacity" : 1,}, 150, function() {});
Is there a way to put this in an instance or object so I could call it easier?
Here is a piece of code that I use for the button.
$('#button_8_algiers').click(function() {
$('#fiche_8_1980_img_container').css('visibility','visible');
$('#fiche_8_1980_img_container').animate({"opacity" : 1,}, 150, function() {
});
});
If anyone could point me in the right direction it would be great, I don't know where to start looking...
Thank you

would something like this help?
var ficheHandler = {
animateFiche: function(fiche) {
fiche
.css('visibility','visible');
.animate({"opacity" : 1,}, 150, function() {
});
}
}
$('#button_8_algiers').click(function() {
ficheHandler.animateFiche($('#fiche_8_1980_img_container'));
});

Try this which is basically using the help of jQuery chaining so there is no need to cache the object into local variables.
$('#button_8_algiers').click(function() {
$('#fiche_8_1980_img_container').css('visibility','visible');
.animate({"opacity" : 1,}, 150, function() {
});
});

I'm assuming you have control over the HTML. If you have that many buttons with shared functionality, give them the same CSS class, and add a unique identifier in either the rel or data attributes:
$('a.myButton').click(function(e) {
e.preventDefault();
$('#' + $(this).attr('data-target')).fadeIn(150);
});

Related

Slider Pro Slide Count

Using slider-pro, I am having trouble getting slide count for the number of slides inside the carousel. I have looked at this solution, but am having no luck. My code looks like this:
$(document).ready(function($) {
$('.slider-pro').sliderPro();
});
var slider = $( this ).data( 'sliderPro' );
$(this).append('<div class="counter"><span class="active">'+ (parseInt(slider.getSelectedSlide()) + 1) +'</span>/'+slider.getTotalSlides()+'</div>');
slider.on( 'gotoSlide', function( event ) {
$(this).find('.counter .active').text(event.index + 1);
});
But I get a console error:
TypeError: slider is undefined, can't access property "getSelectedSlide" of it
I am not much of a jquery guy, so I'm not sure why it is giving me this error when in fact the property getSelectedSlide is defined in the jquery.sliderPro.js file. Perhaps I'm not calling it correctly or need to bind the property to a class or id. I'm not sure. I've tried both, but nothing seems to work.
Thanks so much!
Unfortunately, I'm using the class selector to initialize multiple sliders on the same page with the same parameters. I don't want to use id because I will have to create a unique id for every slider instance, which I don't want and will become unmanageable. I also cannot dynamically generate an id for each slider. An example page is here:
BFMagazine
Right now, I have to hardcode the slider number/total into every slide, which isn't ideal.
The relevant Slider-Pro js used is:
$(document).ready(function($) {
$('.slider-pro').sliderPro({
width: '100%',
arrows: true,
fadeArrows: false,
buttons: false,
fade: true,
fadeDuration: 200,
thumbnailPosition: 'bottom',
thumbnailWidth: 75,
thumbnailHeight: 75,
autoplay: false,
fullScreen: false,
breakpoints: {
480: {
thumbnailWidth: 40,
thumbnailHeight: 40
}
}
});
$.each('.slider-pro', function() {
var slider = $('.slider-pro').data('sliderPro');
$('.slider-pro').append('<div class="counter"><span class="active">' + (parseInt(slider.getSelectedSlide()) + 1) +
'</span>/' + slider.getTotalSlides() + '</div>');
slider.on('gotoSlide', function(event) {
$('.slider-pro').find('.counter .active').text(event.index + 1);
});
});
});
I'm getting a console error:
TypeError: cannot use 'in' operator to search for 'length' in '.slider-pro'
I am using jquery-2.1.4.min.js
Any suggestions would be greatly appreciated.
Thanks so much!
It's a simple issue actually the code you have found is missing some other details regarding how it's being used; that code need to be used inside an object or event handler context so this will refer to the object but in your case you are trying to use it outside so there is no context for this therefore we can't use it as such.
Anyway as you have told you are new to jquery that's fine; what you need to do is instead of using this use the css selector directly if you are "outside", so you have
var slider = $('.slider-pro').data( 'sliderPro' );
// here this is not ok as it is "outside"
$('.slider-pro').append('<div class="counter"><span class="active">'+ (parseInt(slider.getSelectedSlide()) + 1)
+'</span>/'+slider.getTotalSlides()+'</div>');
slider.on('gotoSlide', function( event ) {
$(this).find('.counter .active').text(event.index + 1);
// here this is ok as it is "inside"
});
Update:
You were almost there but instead of using this each you were needed to use this each, the difference between the two is that the second one specially used for Dom nodes and you can use this magic inside to refer to each item without actually giving them any explicit property like ids
$('.slider-pro').each(function(index, element) {
//using $(element) instead of $(this) should work too
$(this).sliderPro({
//..options
});
var slider = $(this).data('sliderPro');
$(this).append('<div class="counter"><span class="active">' + (parseInt(slider.getSelectedSlide()) + 1) +
'</span>/' + slider.getTotalSlides() + '</div>');
slider.on('gotoSlide', function(event) {
$(this).find('.counter .active').text(event.index + 1);
// finds only the .counter and .active inside the current slider divsnot touching .counter and .active of other slider divs
});
});
A brief explanation would be, the $(selector).each(..) loops over all the Dom nodes that match the selector and gives you a context this that will always refer to the current item of the iteration but only within the scope of each function.For instance if matched items are a set of <div>s then you can refer to each <div> individually

javascript - avoid repetable code

I have a page with a button that calls a menu modal. The modal contains two more buttons that call two submenus - one for each button. Watch the pen:
https://codepen.io/t411tocreate/pen/yoxJGO
It actually works. But the current problem is that I re-write a repeatable code to call each submenu:
$('.show-submenu-1').on('click', function () {
$('.submenu-1.offcanvas').addClass('offcanvas--active');
})
$('.show-submenu-2').on('click', function () {
$('.submenu-2.offcanvas').addClass('offcanvas--active');
})
This approach seems to be pretty dumb. I need a solution with less repetition, something like forEach function for arrays:
var menus = [
'.show-submenu-1',
'.show-submenu-2'
];
menus.forEach(function(menu){
$(menu).on('click', function () {
$(`${menu}.offcanvas`).addClass('offcanvas--active');
})
});
Of course, this scenario won't work. How can I make my code DRY?
Use markup:
<div class="submenu" data-index="1">
<div class="submenu" data-index="2">
<button class="show-submenu-button" data-submenu-index="1">
<button class="show-submenu-button" data-submenu-index="2">
Then:
$('.show-submenu-button').on('click', function () {
var index = $(this).attr('data-submenu-index');
$('.submenu[data-index="' + index + '"]').addClass('offcanvas--active');
})
There is little value to using classnames that are so specific that they identify every element on the page individually. Classnames should define a class of elements that behave the same way.
Hi I hope I got the question right but you could use data-attributes for something like this. Just set a general class for .show-submenu and mark their connection to the menus with a number in a data-submenu=x attribute. Where x would be the number in .submenu-x.
And then you do something like this:
Notice that i changed .show-submenu-1 to .show-submenu. Make sure every trigger has this class. Also add a data-submenu=x for every submenu you want to use.
$('.show-submenu').on('click', function () {
var number = $(this).attr("data-submenu");
var selector = '.submenu-' + number + '.offcanvas'
$(selector).addClass('offcanvas--active');
})
So the data-submenu is used to pair the trigger and the modal. This way you can stick to an easy to read html code and a short bit of jquery.
Try this:
var menus = [1, 2];
menus.forEach(index => {
$(`.show-submenu-${index}`).on('click', () => {
$(`.submenu-${index}.offcanvas`).addClass('offcanvas--active');
});
});
You can use this as well.
$('.show-submenu-1, .show-submenu-2').on('click', function (event) {
$(event.target).hasClass('show-submenu-1'){
$('.submenu-1.offcanvas').addClass('offcanvas--active');
}else{
$('.submenu-2.offcanvas').addClass('offcanvas--active');
}
})
it would be better to have your show-submenu-1(as showmenu) and submenu-1(as submenu) in same parent element that allows you to use closest() method and make life easy
for eg:
$('.show-submenu').on('click', function (event) {
$(event.target).closest('.submenu').addClass('offcanvas--active');
})

My javascript script for changing css don't seem to be working

function normToggle(){
document.getElementById('normToggle').onclick = function(){
if(document.getElementById('normToggle').checked){
document.getElementsByTagName('add').style.verticalAlign= 'baseline';
}else{
document.getElementsByTagName('add').style.verticalAlign= 'super';
}
};
document.getElementsByTagName('add').style.verticalAlign= 'super';
document.getElementById('normToggle').checked = false;
}
So I try to use a checkbox to change the style of the 'add' tags. Their vertical align are super first, then i wnat them to change normal, but they didnt respond. Another javascript from the smae file working just fine.
getElementsByTagName returns a HTML Collection - you'll need to iterate through the collection to change the style of each element in the collection
something like this:
function normToggle() {
var setAlign = function (align) {
[].forEach.call(document.getElementsByTagName('add'), function(tag) {
tag.style.verticalAlign = align;
});
}
document.getElementById('normToggle').addEventListener('click', function() {
setAlign(this.checked ? 'baseline' : 'super');
});
setAlign('super');
document.getElementById('normToggle').checked = false;
}
Looking at the code now, you're unlikely to have elements called <add> !!! Is that some sort of mistake in your HTML?

Countable.js get in Object

I'm new to JavaScript and jQuery, I found this plugin which allows me to count the amount of words in a textbox. I was able to implement this into my form. However, what I would like to do is if the user adds more than 25 words it will give me an error.
I am using jquery validation in my form to validate.
The code I have in my Javascript is;
jQuery(document).ready(function($){
$('#textarea').simplyCountable({
counter: '#words',
countType: 'words',
maxCount: 25,
overClass: 'over',
countDirection: 'up'
});
var area = document.getElementById('textarea')
Countable.live(area, function (counter) {
console.log(counter)
})
});
When I view this on my page, I see the following;
My question is how can I get to Object > words?
Thanks in advance
Countable.live($('#textarea'), function (counter) {
var totalWOrdsCount = counter.words;
})

How to create simple jQuery plugin?

This test plugin, is supposed to work like this: When an element is clicked, it moves down. Simple as that.
jQuery.fn.moveDown = function(howMuch){
$(this).css("border", "1px solid black");
$(this).click(function(){
$(this).css("position", "relative");
$(this).animate({top: '+='+howMuch});
});
}
The problem is, when an element is clicked, it not only moves the clicked element but also ALL the other elements which the plugin was applied to.
What is the solution for this?
For plugin authoring try this way, much more solid:
Edit:
Here is working jsFiddle example.
PLUGIN:
(function($){
$.fn.extend({
YourPluginName: function(options) {
var defaults = {
howMuch:'600',
animation: '',//users can set/change these values
speed: 444,
etc: ''
}
};
options = $.extend(defaults, options);
return this.each(function() {
var $this = $(this);
var button = $('a', $this);// this represents all the 'a' selectors;
// inside user's plugin definition.
button.click(function() {
$this.animate({'top':options.howMuch});//calls options howMuch value
});
});
})(jQuery);
USER'S DOCUMENT:
$(function() {
$('#plugin').YourPluginName({
howMuch:'1000' //you can give chance users to set their options for plugins
});
});
<div id="plugin">
<a>1</a>
<a>2</a>
<a>3</a>
</div>
Here i want to suggest steps to create simple plugin with arguments.
JS
(function($) {
$.fn.myFirstPlugin = function( options ) {
// Default params
var params = $.extend({
text : 'Default Title',
fontsize : 10,
}, options);
return $(this).text(params.text);
}
}(jQuery));
Here, we have added default object called params and set default values of options using extend function. Hence, If we pass blank argument then it will set default values instead otherwise it will set.
HTML
$('.cls-title').myFirstPlugin({ text : 'Argument Title' });
Read more: How to Create JQuery plugin
Original answer Here i want to suggest steps to create simple plugin with arguments
If you have Node.js installed you can use create-jquery-plugin CLI utility. Just run
npx create-jquery-plugin
Or, you can clone the jquery-plugin-boilerplate
to get started.

Categories