I've made this little plugin to show Twitter style alerts:
jQuery.fn.myAlert = function (options) {
var defaults = {
message: false,
class: 'normal',
timer: 500,
delay: 3000,
};
var options = $.extend(defaults, options);
if (!options.message || options.message == '') {
return false;
}
$('body').append('<div id="alert_notification" class="'+options.class+'"><div id="alert_message">' + options.message + '</div></div>')
$('#alert_notification').slideToggle(options.timer).delay(options.delay).slideToggle(options.timer);
return;
}
The problem is: first time it works great, but when I call again in the same page, the values are set from previous call.
Any ideas how to make it work?
My guess is that the slideToggle() isn't showing the <div> you are intending it to show because jQuery isn't appending new <div>s that don't have unique IDs. You should probably remove the originally appended <div>s from the page before appending the new ones. Or, make jQuery replace the existing ones.
$('#alert_notification').remove();
$('body').append(...);
In addition, class is a reserved word in JavaScript. I would change your defaults to:
var defaults = {
message: false,
'class': 'normal',
timer: 500,
delay: 3000,
};
And then access it with options['class'] instead of options.class, or pick a different name for the class property.
Related
I am attempting to use javascript to show or hide a collapsable element but not both.
(that is to say i dont want toggle to be enabled)
according to the documentation
https://getbootstrap.com/docs/5.0/components/collapse/#via-javascript
i can do something like this to trigger toggling between shown and hidden
var myCollapse = document.getElementById('myCollapse')
var bsCollapse = new bootstrap.Collapse(myCollapse, {
toggle: true
})
of course if i change toggle to false it stops it from doing anything - as expected.
however it also says i can use the show and hide properties on an object passed as the second array to enable/disable these behaviors
like so
var myCollapse = document.getElementById('myCollapse')
var bsCollapse = new bootstrap.Collapse(myCollapse, {
toggle: false,
show: true,
hide: false
})
but if i try to use these options only toggle works
I looked at the BS js and found that it does check the status of toggle
if (_this._config.toggle) {
_this.toggle();
}
however there is no equivalent for show and hide which suggests to me that the show and hide options of the bootstrap.Collapse() object do nothing.
Am I correct in my belief that the show and hide options dont work when using bootstrap.Collapse()?
If no what am i doing wrong.
toggle is both a config option, and a method .toggle()
show() and hide() are methods, not config options.
Therefore, using show and hide and as config options does nothing...
var bsCollapse = new bootstrap.Collapse(myCollapse, {
toggle: false,
show: true, //useless
hide: false //useless
})
However, show and hide work as methods...
bsCollapse.show()
or
bsCollapse.hide()
Demo
If you want to toggle the collaspe :
new bootstrap.Collapse(myCollapse, {
toggle: true
});
- toggle option must be true.
=> Toggles the collapsible element on invocation of the instance constructor.
- no nead to point a variable to the collapse instance.
if you want to show or hide the collapse :
var bsCollapse = new bootstrap.Collapse(myCollapse, {
toggle: false
})
bsCollapse.show();
or
bsCollapse.hide();
- toggle option must be false.
So I have these:
var containerId = 'anim1'
var animation = bodymovin.loadAnimation({
container: document.getElementById(containerId),
renderer: 'svg',
loop: false,
autoplay: false,
path: "https://assets10.lottiefiles.com/packages/lf20_rd4wrn81.json"
});
function playanim() {
animation.goToAndPlay(0);
}
$('div').on('click', function() {
containerId = $(this).attr('id');
$('#text').text(containerId + ' was just clicked');
playanim();
})
The global variable containerId is being updated on click events, however the updated value is not being passed to the same containerId within the variable animation. Not sure if it's a bodymovin specific issue- how can I get this to work?
In the line that begins var animation = ..., you are creating an object, setting its container property to document.getElementById(containerId) (using whatever value containerId has at that time, i.e. 'anim1') and then passing that object to bodymovin.loadAnimation (presumably as a configuration - I'm unfamiliar w/that library)
When the div is clicked, the value of containerId is being updated, but this is not changing the value of the container property in the config object you created earlier; that's still equal to anim1. And even if it did change, it might not make any difference unless bodymovin is monitoring that config object. It's quite possible that bodymovin.loadAnimation just checks the value of container when it's initialized, and then never checks it again.
It might achieve what you want if you rebuild the animation every time the div is clicked, e.g. something like this (you might want to stop the animation in the old div as well?)
var animation // just declare it for now, assign below
// The following function will load the animation to the specified container
function setAnimation (containerId) {
console.log ("Loading animation into " + containerId)
animation = bodymovin.loadAnimation({
container: document.getElementById(containerId),
renderer: 'svg',
loop: false,
autoplay: false,
path: "https://assets10.lottiefiles.com/packages/lf20_rd4wrn81.json"
});
}
// Load it in 'anim1' first
setAnimation ('anim1')
function playanim() {
animation.goToAndPlay(0);
}
$('div').on('click', function() {
var id = $(this).attr('id')
console.log(id + ' was just clicked');
$('#text').text(id + ' was just clicked');
setAnimation (id); // re-initialize the animation
animation.addEventListener('data_ready',playanim);
})
Without knowing more about bodymovin (sorry), I can't tell if this is a wildly inefficient way to do it. Maybe bodymovin has a more lightweight way of changing the container for an animation that's already loaded, in which case you could just do that in your click handler.
I am using YUI Paginator API for pagination and I need to show Total number of pages on screen. I saw that there is a function getTotalPages() in API but I am unsure about how to use it, there isn't enough documentation. Also after looking at some other documentation I tried using {totalPages} but didn't work.
Can somebody help me out in this issue? Thanks in advance!!
Below is the code snippet I am using. Please refer to template object from config:
config = {
rowsPerPage: 100,
template :
'<p class="klass">' +
'<label>Total pages: {totalPages}</label>'+
'<label>Page size: {RowsPerPageDropdown}</label>'+
'</p>',
rowsPerPageDropdownClass : "yui-pg-rpp-options",
rowsPerPageOptions : [
{ value : 100 , text : "100" },
{ value : 250 , text : "250" },
{ value : 500 , text : "500" },
{ value : 1000 , text : "1000" },
{ value : tstMap[tabName].length , text : "All" }
],
};
var myPaginator = new YAHOO.widget.Paginator(config);
The Paginator utility allows you to display an item or a group of items depending on the number of items you wish to display at one time.
Paginator's primary functionality is contained in paginator-core and is mixed into paginator to allow paginator to have extra functionality added to it while leaving the core functionality untouched. This allows paginator-core to remain available for use later on or used in isolation if it is the only piece you need.
Due to the vast number of interfaces a paginator could possibly consist of, Paginator does not contain any ready to use UIs. However, Paginator is ready to be used in any Based-based, module such as a Widget, by extending your desired class and mixing in Paginator. This is displayed in the following example:
YUI().use('paginator-url', 'widget', function (Y){
var MyPaginator = Y.Base.create('my-paginator', Y.Widget, [Y.Paginator], {
renderUI: function () {
var numbers = '',
i, numberOfPages = this.get('totalPages');
for (i = 1; i <= numberOfPages; i++) {
// use paginator-url's formatUrl method
numbers += '' + i + '';
}
this.get('boundingBox').append(numbers);
},
bindUI: function () {
this.get('boundingBox').delegate('click', function (e) {
// let's not go to the page, just update internally
e.preventDefault();
this.set('page', parseInt(e.currentTarget.getContent(), 10));
}, 'a', this);
this.after('pageChange', function (e) {
// mark the link selected when it's the page being displayed
var bb = this.get('boundingBox'),
activeClass = 'selected';
bb.all('a').removeClass(activeClass).item(e.newVal).addClass(activeClass);
});
}
});
var myPg = new MyPaginator({
totalItems: 100,
pageUrl: '?pg={page}'
});
myPg.render();
});
Ok I have a JQVMAP that I have on my site to select states for a search box. Everything worked great until I added my Clear function.
I also had to incorporate the patch from member HardCode Link to the patch
Found the solution, change line 466 in jqvmap.js file to:
regionClickEvent = $.Event('regionClick.jqvmap');
jQuery(params.container).trigger(regionClickEvent, [code, mapData.pathes[code].name]);
This is how I initialize it:
// with this Code it will select states and change the color of selected states plus save the codes of selected states into a hidden field
$('#omap').vectorMap(
{
map: 'usa_en',
backgroundColor: '#fff',
borderColor: '#000',
borderWidth: 4,
color: '#f4f3f0',
enableZoom: false,
hoverColor: '#fece2f',
hoverOpacity: null,
normalizeFunction: 'linear',
scaleColors: ['#b6d6ff', '#005ace'],
selectedColor: '#db9b15',
selectedRegion: null,
showTooltip: true,
multiSelectRegion: true,
onRegionClick: function(element, code, region) {
if(highlight[code]!=='#db9b15'){
highlight[code]='#db9b15';
origin = $('#search_origin_states');
states = origin.val();
if (states == ""){
origin.val(code);
} else {
origin.val(states + "," + code);
}
} else {
highlight[code]='#f4f3f0';
states = origin.val();
if (states.indexOf(","+code) >= 0) {
states = states.replace(","+code,"");
origin.val(states);
} else if (states.indexOf(code+",") >= 0){
states = states.replace(code+",","");
origin.val(states);
} else {
states = states.replace(code,"");
origin.val(states);
}
}
$('#omap').vectorMap('set', 'colors', highlight);
}
});
I use to have to click each state to clear it. But I wrote a script to clear all in one click.
function search_map_clear(field, map) {
var states = $('#search_' + field + '_states');
var sel_states = states.val();
var highlight2 = [];
$.each(sel_states.split(','), function (i, code) {
highlight2[code] = '#f4f3f0';
$('#' + map).vectorMap('set', 'colors', highlight2);
});
states.val("");
}
This will change all colors back to the original color, but apparently it does not clear the selectedRegions because after clearing if I select any other state all the states that I changed back to original color show back up.
My Question is:
How can I clear the selected states so were I can select different ones without clicking on every state that was selected prior
UPDATE
I have been able to run this command from the console and I can select and deselect states... But it will not deselect a state that was clicked on to select.
$('#omap').vectorMap('select', 'ar');
$('#omap').vectorMap('deselect', 'ar');
I need to clear out the states that have been clicked on...
Here is my jsFiddle that will show you what is happening:
JSFIDDLE DEMO
You store information in the variable highlight, and you clean the map with highlight2. It will not change the information in highlight so that when you trigger onRegionClick() it will change back to what you select.
Use global variable to let the scope of highlight to cross two script, then replace highlight2 by highlight and remove highlight2 declation.
See jsfiddle here, I think this is what you want.
I just added this function to library
setSelectedRegions: function(keys){
for (var key in this.countries) {
this.deselect(key, undefined);
}
var array = keys.split(",");
for (i=0;i<array.length;i++) {
//alert(array[i])
this.select(array[i], undefined);
}
},
and used it later as
jQuery('#vmap').vectorMap('set', 'selectedRegions', 'gb,us');
I'm trying to create my own lightbox script where I can pass the variables (title, description, itemtype, itemid, etc.) in clean formatting like this (inspired by fancybox):
myFunction({
title: "My title",
description: "My description"
});
Clicking on a certain element prepends some HTML to a div with jQuery.
I have adapted a piece of code I found on Stackoverflow and "kind of" understand the code. The top function has not been changed and worked before I edited the bottom code, to that I added click(function() { } because in the example the code was executed on pageload.
However, when I click my H1 element the firebug console tells me ReferenceError: popup is not defined
This is my Javascript:
$(document).ready(function() {
(function ($) {
$.fn.popup = function (options) {
var settings = $.extend({
title: function (someData) {
return someData;
},
description: function (someData) {
return someData;
},
}, options);
$("#content").prepend(
"<div style=\"position:fixed;top:0;left:0;width:100%;height:100%;background:#FFFFFF;\">\
<h1>"+ settings.title +"</h1>\
<p>" + settings.description +"</p>\
</div>"
);
};
}(jQuery));
$(".openbox1").click(function() {
popup({
title: "Title 1",
description: "Description 1"
});
}));
$(".openbox2").click(function() {
popup({
title: "Title 2",
description: "Description 2"
});
}));
});
This is my HTML
<div id="content">
<h1 class="openbox1">open box 1</h1>
<h1 class="openbox2">open box 2</h1>
</div>
A. Wolff commented that I need to execute the function like this:
$(".openbox1").click(function() {
$(this).popup({
...
});
});
This fixed it, thanks!
First off, what you did, and I hope this helps:
// This, of course is same as "document.onload"
// Don't confuse it with "window.onload"
// wich will wait till WHOLE dom is loaded to run any script
$(document).ready(function() {
(function ($) {
// This is, in essence, the start of a jQuery plugin
// This is often referred to as the "quick and dirty setup"
// as it's a direct call to add a method to jQuery's
// element object. Meaning it can be recalled as
// $(element).popup().
// This should not be confused with $.popup = function
// which would just add a method to jQuery's core object
$.fn.popup = function (options) {
var settings = $.extend({
...
}(jQuery));
$(".openbox1").click(function() {
// here is where your issue comes in
// as previously noted, you did not create a
// method named "popup".
// you added a method to jQuery's Element Object
// called "popup".
// This is why `$(this).popup` works and
// plain `popup` does not.
// You're inside an "event" asigned to any element
// having class name `openbox1`. Thus, any call
// in here to `this`, will reference that element
popup({
Secondly, a different example of how to write it. I won't say better because, even if I say my way is better, it wouldn't make your "corrected" way wrong. In Javascript, as the old saying goes, There's more than one way to skin a cat.
My Example:
// Notice I'm adding this plugin BEFORE the document load.
// This means, you could easily add this to a file and load it
// in script tags like any other Javascript,
// as long as it's loaded AFTER jquery.
(function($) {
// this ensures that your plugin name is available and not previously added to jQuery library
if (!$.popup) {
// this also provides us "variable scope" within to work in
// here begin adding the plugin to jQuery
// I started with $.extend, so it can be added to the jQuery library and used in traditional format
// $.popup('element selector', { options })
// as well as the element.action format we'll add later
// $.(element selector).popup({ options })
// This should help give you a good idea of the whole of what all is going on
$.extend({
popup: function() {
var ele = arguments[0], // this is our jQuery element
args = Array.prototype.slice.call(arguments, 1); // this gets the rest of the arguments
// this next step is useful if you make the traditional call `$.popup(this, { options })`
if (!(ele instanceof jQuery)) ele = $(ele);
// now we have total control! Bwahahha!
// Fun aside, here is where it's good to check if you've already asigned this plugin
// if not, then make some "marker", so you can recall the element plugin and comment an
// action instead of reinitializing it
if (!ele.data('popup')) $.popup.init(ele, args);
else {
// at this point, you would know the element already has this plugin initialized
// so here you could change an initial options
// like how with jQueryUI, you might would call:
// $(element).popup('option', 'optionName', value)
}
return ele;
}
});
// here is where we add the $(element selector).popup method
// this simply adds the method to the element object
// If you don't fully understand what's going on inside (as I explain below),
// just know that it's some "fancy footwork" to pass the method onto our initial
// method creation, $.popup
$.fn.extend({
popup: function(/*no need for parameter names here as arguments are evaluated inside and passed on to initial method*/) {
// set this element as first argument to fit with initial plugin method
var args = [$(this)];
// if there are arguments/params/options/commands too be set, add them
if (arguments.length) for (x in arguments) args.push(arguments[x]);
// pass through jquery and our arguments, end result provides same arguments as if the call was:
// $.popup($(element), options)
return $.popup.apply($, args);
}
});
// This next part is not seen in many plugins but useful depending on what you're creating
$.popup.init = function(ele, opt) {
// here is where we'll handle the "heavy work" of establishing a plugin on this element
// Start with setting the options for this plugin.
// This means extending the default options to use any passed in options
// In the most simple of cases, options are passed in as an Oject.
// However, that's not always the case, thus the reason for this being
// a continued array of our arguments from earlier.
// We'll stick with the simplest case for now, your case, that the only options are an
// Object that was passed in.
// using the extend method, with true, with a blank object,
// allows us to added the new options "on top" of the default ones, without changing the default ones
// oh and the "true" part just tells extend to "dig deep" basically (multideminsional)
if (opt && typeof opt[0] == 'object') opt = $.extend(true, {}, $.popup.defaults, opt[0]);
var par = opt.parent instanceof jQuery ? opt.parent : $('body'),
tit = opt.title,
des = opt.description,
// this last one will be the wrapper element we put everything in
// you have this in yours, but it's written in a very long way
// this is jQuery simplified
wrap = $('<div />', { style: 'position:fixed;top:0;left:0;width:100%;height:100%;background:#FFFFFF;' }),
// much like the previous element, cept this is where our title goes
head = $('<h1 />', { text: tit }).appendTo(wrap),
content = $('<p />', { text: des }).appendTo(wrap);
$(par).append(wrap);
// finally, add our marker i mentioned earlier
ele.data('popup', opt);
// just adding the following cause i noticed there is no close
// fyi, i would change this plugin a little and make an actial "open" command, but that's another tutorial
var closer = $('<span />', { text: '[x]', style: 'cursor:pointer;position:absolute;bottom:1em;right:1em;' });
wrap.append(closer);
closer.click(function(e) { ele.data('popup', false); wrap.remove(); });
};
$.popup.defaults = { // establish base properties here that can be over-written via .props, but their values should never truly change
'parent': undefined, // added this to keep it dynamic, instead of always looking for an element ID'd as content
title: '',
description: ''
};
}
})(jQuery);
// the following is basically jQuery shorthand for document.ready
$(function() {
// i think you get the rest
$(".openbox1").on('click', function(e) {
$(this).popup({
title: "Title 1",
description: "Description 1",
parent: $("#content")
});
})
$(".openbox2").on('click', function(e) {
$(this).popup({
title: "Title 2",
description: "Description 2",
parent: $("#content")
});
})
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div id="content">
<h1 class="openbox1">open box 1</h1>
<h1 class="openbox2">open box 2</h1>
</div>