magnific passing in array - javascript

I am trying to pass in a list of images to get magnific popup to use the images however if I pass them in as their variable it does not work. I can console.log the output of the variable and paste that in place of the variable in the magnific call and it works just fine. Any ideas why passing the variable here does not work?
Here you can edit it however you must view it here to test it.
Again, you can copy the output of the console.log and paste it in place of the variable compiledList and it works just does not work as a variable.
Below is the code...
$(function(){
var urlList = ["http://img3.wikia.nocookie.net/__cb20140125162709/cartoonfatness/images/c/c0/Futurama.jpg","http://img3.wikia.nocookie.net/__cb20140125162709/cartoonfatness/images/c/c0/Futurama.jpg","http://img3.wikia.nocookie.net/__cb20140125162709/cartoonfatness/images/c/c0/Futurama.jpg"];
var compiledList = ( '{src : \'' + urlList.join('\'}, {src : \'') + '\'}' );
$('a').on('click',function(e){
e.preventDefault();
$.magnificPopup.open({
items: [compiledList],
gallery: {
enabled: true
},
type: 'image',
callbacks: {
open: function() {
console.log(compiledList);
}
}
});
});
});

What you're doing currently is making a String which when console.loged looks like an object, but it's not. Here are 2 easy options.
Just make the urlList an array of objects by wraping each url with {src: "URL"}
Use a for loop to iterate over urlList and make an array of objects. I've added this code below.
http://jsbin.com/sokidazi/2
var urlList = ["http://img3.wikia.nocookie.net/__cb20140125162709/cartoonfatness/images/c/c0/Futurama.jpg","http://img3.wikia.nocookie.net/__cb20140125162709/cartoonfatness/images/c/c0/Futurama.jpg","http://img3.wikia.nocookie.net/__cb20140125162709/cartoonfatness/images/c/c0/Futurama.jpg"],
i = 0,
l = urlList.length,
compiledList = [];
for(;i < l;i++){
compiledList.push({src: urlList[i]});
}
$('a').on('click',function(e){
e.preventDefault();
$.magnificPopup.open({
items: compiledList,
gallery: {
enabled: true
},
type: 'image',
callbacks: {
open: function() {
console.log(compiledList);
}
}
});
});

Related

magnific popup: open by clicking on something other than the image

Client has requested that the image caption completely cover the thumbnail on hover, so I now need to be able to click the caption to open Magnific Popup instead of the <a>. So far I have been able to do:
JS/jQuery:
jQuery(".caption").on("click", function(event) {
var items = [];
jQuery(".item").each(function() {
items.push( {
src: jQuery(this).find("a").first().attr("href")
} );
});
jQuery.magnificPopup.open({
type: 'image',
gallery: {
enabled: true
},
items: items,
image: {
titleSrc: function(item) {
console.log( item.el );
// return item.el.clone();
}
}
});
});
See the fiddle for an example, and the HTML and CSS (plus alternative JS that doesn't work either).
It's giving me two blockers:
It's always the first image that pops up, instead of the image that one clicked on.
That part about return item.el.clone(); is commented out because it's producing an "item.el is undefined" error (which doesn't seem to happen when magnificPopup is instantiated via jQuery('.caption').magnificPopup() as opposed to jQuery.magnificPopup.open()). However, I need the caption HTML to show up in the popup as well.
Any help would be appreciated. Thanks.
When you use an array of items you can pass the index of the first item you want to show. So I have used var index = jQuery(this).parent().index() to get the index of the current clicked item and then passed that variable in to the magnificPopup function.
To get the caption in the popup I have added an extra property to the items object called titleSrc, which you can then retreive in the titleSrc option using item.data.titleSrc.
https://jsfiddle.net/sjp7j1zx/4/
jQuery(".caption a").on("click", function(event) {
event.stopPropagation();
});
jQuery(".caption").on("click", function(event) {
var items = [];
jQuery(".item").each(function() {
// Pass an extra titleSrc property to the item object so we can use it in the magnificPopup function
items.push( {
src: jQuery(this).find("a").first().attr("href"),
titleSrc: jQuery(this).find('.caption').html()
} );
});
// Get the index of the current selected item
var index = jQuery(this).parent().index();
jQuery.magnificPopup.open({
type: 'image',
gallery: {
enabled: true
},
items: items,
image: {
titleSrc: function(item) {
// get the titleSrc from the data property of the item object that we defined in the .each loop
return item.data.titleSrc;
}
}
// Pass the current items index here to define which item in the array to show first
}, index);
});

FullCalendar - Changing hidden days with jQuery

I'm filtering my calendar, I change the start and end date, status of my events, and other stuffs. I do that with:
$("body").on("click", "#btnFiltrar", function() {
fechaIni = $("#fechaIni").val();
fechaFin = $("#fechaFin").val();
cp = $("#txtCP").val();
var events = {
url: "./php/xxxxxxxx.php",
type: "POST",
data: {
fechaIni: fechaIni,
fechaFin: fechaFin,
cp: cp,
provincia: provincia,
...
}
}
$("#calendar").fullCalendar("removeEventSource", events);
$("#calendar").fullCalendar("addEventSource", events);
$("#calendar").fullCalendar("refetchEvents");
});
It works fine. But when I want to change the variable hiddenDays dynamically, I can't make it work!
I add to my code this:
(By default this variables are global)
var dias = ["0","1","2","3","4","5","6"];
var ocultarDias = []; // is empty because it shows all days
// inside click button
diasSeleccionados = $("#selDias").val(); // returns array eg: ["1","2","3","4","5"]
ocultarDias = $(dias).not(diasSeleccionados).get(); // compare 2 arrays and get the difference
So, with that and the call fullcalendar with the attribute:
function llenarCalendario() {
$("#calendar").fullCalendar({
lang: 'es',
firstDay: 1,
hiddenDays: ocultarDias,
...
});
}
I miss something? I want to do this without reload the page, just call again the function or, as the function on click button, refetchEvents or something like that. Is possible?
You can recreate the calendar and add the events, which you have already have, again with the following method.
function reloadCalendar(){
//Get all events in a array
var events = $("#calendar").fullCalendar( 'getEventSources' );
$("#calendar").fullCalendar( 'destroy' ); // Destroy the calendar
$("#calendar").fullCalendar({ //Recreate the calendar with the hidden days
hiddenDays: [ 2, 4 ]
});
//With JavaScript
events.forEach(function(event) { //Restore all events
$("#calendar").fullCalendar( 'addEventSource', event);
});
//With jQuery
var jEvents = $.makeArray(events);
$(jEvents).each(function( i ) {
$("#calendar").fullCalendar( 'addEventSource', events[i]);
});
}
Now you simply can call the method. I hope it was helpful.
var newhiddendays = [0, 6]; // show Mon-Fr (hide Sat/Sun)
$('#calendar').fullCalendar('option', 'hiddenDays', newhiddendays);
You have to use it with optionmethod in order to set new options for your calendar
https://fullcalendar.io/docs/utilities/dynamic_options/
function llenarCalendario() {
$("#calendar").fullCalendar('option',{
lang: 'es',
firstDay: 1,
hiddenDays: ocultarDias,
...
});
}
I finally found a way to do that without reload the page. With the help of #todes using 'options' and adding the three lines below that.
Very important: the array of hiddenDays must be an array of ints.
var dias = ["0","1","2","3","4","5","6"];
var ocultarDias = []; // is empty because it shows all days
$(document).ready(function () {
llenarCalendario();
$("body").on("click", "#btnFiltrar", function() {
fechaIni = $("#fechaIni").val();
fechaFin = $("#fechaFin").val();
cp = $("#txtCP").val();
var diasSeleccionados = $("#selDias").val(); // select multiple, returns array eg: ["1","2","3","4","5"]
ocultarDias = $(dias).not(diasSeleccionados).get(); // compare 2 arrays and get the difference
ocultarDias = ocultarDias.map(Number); // array of strings to int for fullcalendar to work
var events = {
url: "./php/xxxxxxxxxx.php",
type: "POST",
data: {
fechaIni: fechaIni,
fechaFin: fechaFin,
cp: cp
}
}
$("#calendar").fullCalendar('option', {
hiddenDays: ocultarDias
});
$("#calendar").fullCalendar("removeEventSource", events);
$("#calendar").fullCalendar("addEventSource", events);
$("#calendar").fullCalendar("refetchEvents");
});
});
function llenarCalendario() {
$("#calendar").fullCalendar({
lang: 'es',
firstDay: 1,
hiddenDays: ocultarDias,
...
});
}

How to make pop up using colorbox.js on anchor click?

I have a hierarchy module which creates a table of which on anchor tag click i want to make a pop with the value related to that field.but in my code it doesn't step inside .click in jquery. In my view
As you can see the hierarchy is dynamically created but on click in employee or 8 it does not step inside my function.
My code:
sb.Append("<div class='sfGridwrapper'>");
sb.Append("<table class='positiontable'>");
sb.Append("<thead><th>position name</th><th>poscount</th></thead>");
sb.Append("<tbody>");
foreach (var item in a)
{
string[] words = item.Split('_');
sb.Append("<tr>");
foreach (string word in words)
{
sb.Append("<td>");
sb.Append("<a href='Javascript:void(0);' class='Popup'>")
sb.Append("<span data-departname="+ word + " class='popupmembers'>");
sb.Append(word);
sb.Append("</span></a></td>");
}
sb.Append("</tr>");
}
sb.Append("</tbody></table></div>");
In my jquery:
$('.positiontable').on('click', '.popupmembers', function () {
alert('hello');
var getPositionName = $(this).closest('td').siblings().eq(0);
var getDepartmentName = $(this).parents('a').find('span').eq(0).text();
Hierarchy.GetEmployeeValues(getPositionName, getDepartmentName);
$(this).colorbox({
inline: true,
href: '#employeeValue',
closeButton: true,
onClosed: function () { $('#employeeValue').hide(); }
});
});
The div that needs to be pop up is
StringBuilder stb = new StringBuilder();
stb.Append("<div id='employeeValue'></div>");
LiteralControl literal = new LiteralControl(stb.ToString());
PlaceHolderEmployee.Controls.Add(li);
I need help to step into my function in jquery. Can anyone point out where i am doing mistake.
$('Body').on('click', '.popupmembers', function () {
alert('hello');
var getPositionName =$(this).closest('td').find('td:eq(0)').Text();
var getDepartmentName = $(this).parents('a').find('span').eq(0).text();
Hierarchy.GetEmployeeValues(getPositionName, getDepartmentName);
$.colorbox({
inline: true,
href: '#employeeValue',
closeButton: true,
onClosed: function () { $('#employeeValue').hide(); }
});
});
I have made a new Js file and initialize with all the required parameter then placing the code in new js just worked for me as well as the colorbox just made popup of my data.

jQuery use variable outside function

I'm using jquery.feeds.js to aggregate rss feeds and preprocessing the data received with jsonp.js. The problem is I can't use the variable summarize I've set within the preprocess function outside of it. I did set it as a universal variable though so I don't know what I could be doing wrong. Could it be a problem that I'm running multiple JSON requests?
My code:
$('#feed').feeds({
feeds: {
reuters: 'http://feeds.reuters.com/reuters/businessNews'
},
max: 2,
preprocess: function ( feed ) {
var articleLink = (this.link);
var summarize = '';
$.getJSON({
url: 'https://jsonp.nodejitsu.com/?url=http://clipped.me/algorithm/clippedapi.php?url='+articleLink+'&callback=?',
corsSupport: true,
jsonpSupport: true,
success: function(data){
var summarize = data.summary
}
});
alert(summarize);
this.contentSnippet = summarize
},
entryTemplate: '<h3><!=title!></h3><p><!=contentSnippet!></p><i><!=link!></i>'
});
And a JSFIDDLE
You have a series of errors that are not addressed in the other posts..
the preprocess callback allows for changes in the current object (feed) right before it gets displayed.
Since the getJSON is an ajax call it will get the results too late. And changing the contentSnippet even in the success callback will not fix this.
You use the $.getJSON method as if it was $.ajax. So you pass it wrong arguments. Just use $.ajax for your syntax
finally to fix the first issue, you need to alter your template a bit so you can find the relevant parts later on (when the ajax requests complete) and use the onComplete callback instead (of the feeds plugin)
All changes together give
$('#feed').feeds({
feeds: {
reuters: 'http://feeds.reuters.com/reuters/businessNews'
},
max: 2,
onComplete: function(entries){ // use onComplete which runs after the normal feed is displayed
var $this = $(this);
entries.forEach(function(entry){
var $self = $this.find('.entry[data-link="'+entry.link+'"]');
$.ajax({
url:'https://jsonp.nodejitsu.com/?url=http://clipped.me/algorithm/clippedapi.php?url='+entry.link,
corsSupport: true,
jsonpSupport: true,
success: function(data){
// add the results to the rendered page
$self.find('.snippet').html( data.summary );
}
});
});
}, // change the template for easier access through jquery
entryTemplate: '<div class="entry" data-link="<!=link!>"><h3><!=title!></h3><p class="snippet"><!=contentSnippet!></p><i><!=link!></i></div>'
});
Demo at http://jsfiddle.net/gaby/pc7s2bmr/1/
I think you mean this
$('#feed').feeds({
feeds: {
reuters: 'http://feeds.reuters.com/reuters/businessNews'
},
max: 2,
preprocess: function ( feed ) {
var articleLink = (this.link);
var summarize = '';
var that = this;
$.getJSON({
url: 'https://jsonp.nodejitsu.com/?url=http://clipped.me/algorithm/clippedapi.php?url='+articleLink+'&callback=?',
corsSupport: true,
jsonpSupport: true,
success: function(data){
that.contentSnippet = data.summary
}
});
},
entryTemplate: '<h3><!=title!></h3><p><!=contentSnippet!></p><i><!=link!></i>'
});
Mathletics is correct. Do this...
$('#feed').feeds({
feeds: {
reuters: 'http://feeds.reuters.com/reuters/businessNews'
},
max: 2,
preprocess: function ( feed ) {
var articleLink = (this.link);
var summarize = '';
var _this = this;
$.getJSON({
url: 'https://jsonp.nodejitsu.com/?url=http://clipped.me/algorithm/clippedapi.php?url='+articleLink+'&callback=?',
corsSupport: true,
jsonpSupport: true,
success: function(data){
_this.contentSnippet = data.summary
}
});
alert(summarize);
},
entryTemplate: '<h3><!=title!></h3><p><!=contentSnippet!></p><i><!=link!></i>'
});

How to change a Javascript singleton to something that can be used multiple times?

A bit of an architectural question...
I originally created a Javascript singleton to house methods needed to operate a photo gallery module in a template file for a CMS system. The original specification only called for one instance of this photo gallery module on a page. (The code below is a gross simplification of what I actually wrote.)
Shortly after releasing the code, it dawned on me that even though the specification called for one instance of this module, this code would fall apart if a page had two instances of the module (i.e. the user adds two photo galleries to a page via the CMS). Now, the HTML markup is safe, because I used class names, but how would I go about restructuring my Javascript and jQuery event listeners to be able to handle multiple modules? You may assume that each photo gallery has its own JSON-P file (or you may assume a single JSON-P file if you think it can be handled more elegantly with one JSON-P file).
I think my original jQuery event listeners might have to be converted to $.delegate(), but I have no clue what to do after that and what to do about converting my singleton. Any leads would be appreciated. If you offer code, I prefer readability over optimization.
I'm not asking this question, because I have an immediate need to solve the problem for work. I am asking this question to be forward-thinking and to be a better Javascript developer, because I am expecting to run into this problem in the future and want to be prepared.
Thank you for reading.
HTML
<div class="photoGalleryMod">
<div class="photoGalleryImgBox"><img src="http://www.test.org/i/intro.jpg" alt="Intro Photo" /></div>
<div class="photoGalleryImgCap"><p>Caption</p></div>
</div>
The Javascript is an external static file and makes a call to a JSON-P file via $.getSCript(), created by the CMS.
Javascript/jQuery
(function($) {
photoGalleryModule = {
json: '',
numSlidesInJson: '',
currentSlide: '',
updateSlide: function (arg_slidNum) {
/* Update the slide here */
},
init: function (arg_jsonObj) {
this.json = arg_jsonObj;
this.numSlidesInJson = this.json.photoGallerySlides.length;
this.currentSlide = 0;
}
};
$(document).ready(function() {
$.getScript('./photogallery.json');
$('.photoGalleryPrevImgLnk').live('click', function(event) {
photoGalleryModule.currentSlide = photoGalleryModule.currentSlide - 1;
photoGalleryModule.updateSlide(photoGalleryModule.currentSlide);
event.preventDefault();
});
$('.photoGalleryNextImgLnk').live('click', function(event) {
photoGalleryModule.currentSlide = photoGalleryModule.currentSlide + 1;
photoGalleryModule.updateSlide(photoGalleryModule.currentSlide);
event.preventDefault();
});
});
})(jQuery);
Contents of photo-gallery.json
photoGalleryModule.init(
{
photoGallerySlides:
[
{
type: 'intro',
pageTitle: 'Intro Photo',
imgUrl: 'http://www.test.org/i/intro.jpg',
imgAltAttr: 'Intro photo',
captionText: 'The intro photo',
},
{
type: 'normal',
pageTitle: 'First Photo',
imgUrl: 'http://www.test.org/i/img1.jpg',
imgAltAttr: 'First photo',
captionText: 'the first photo',
},
{
type: 'normal',
pageTitle: 'Second Photo',
imgUrl: 'http://www.test.org/i/img2.jpg',
imgAltAttr: 'Second photo',
captionText: 'the second photo',
}
]
});
I think the easiest way is to just turn your code into a plugin. So for the following HTML:
<div id="photoGallery1">
<div class="photoGalleryImgBox"></div>
<div class="photoGalleryImgCap"></div>
</div>
<div id="photoGallery2">
...
</div>
<div id="photoGallery3">
...
</div>
You would create the plugin with $.fn.photoGallery where you pass in an index as a parameter:
$.fn.photoGallery = function (index) {
var $this = this,
module = {
json: '',
numSlidesInJson: '',
currentSlide: '',
updateSlide: function (arg_slidNum) {
/* Update the slide here */
},
init: function (arg_jsonObj) {
module.json = arg_jsonObj;
module.numSlidesInJson = module.json.photoGallerySlides.length;
module.currentSlide = 0;
}
},
events = {
prev: function(e) {
module.currentSlide = module.currentSlide - 1;
module.updateSlide(module.currentSlide);
e.preventDefault();
},
next: function(e) {
module.currentSlide = module.currentSlide + 1;
module.updateSlide(module.currentSlide);
e.preventDefault();
}
};
$.getScript('./photogallery' + index + '.json');
$this.find('.photoGalleryPrevImgLnk').live('click', events.prev);
$this.find('.photoGalleryNextImgLnk').live('click', events.next);
};
And then initiate each gallery like so:
$(document).ready(function(){
$('#photoGallery1').photoGallery(1);
$('#photoGallery2').photoGallery(2);
$('#photoGallery3').photoGallery(3);
});
Where you have the files photogallery1.json, photogallery2.json and photogallery3.json that each invoke module.init({ ... }); with the necessary object data.
Something like this should do the trick: (untested)
// jquery plugin: jquery.photogallery.js
$.fn.photoGallery = (function($){
var PhotoGalleryModule = function(el, opts){
$.extend(this, opts);
this.el = $(el);
// if there are multiple on the page do not re-bind or re-init
if(!!this.el.data('photoGallery')) return el;
this.numSlidesInJson = this.json.photoGallerySlides.length;
this.bind();
};
PhotoGalleryModule.prototype = {
updateSlide: function (arg_slidNum) {
/* Update the slide here */
},
bind: function(){
var self = this;
this.el.find('.photoGalleryPrevImgLnk')
.live('click', function(event) {
self.currentSlide = self.currentSlide - 1;
self.updateSlide(self.currentSlide);
event.preventDefault();
});
this.el.find('.photoGalleryNextImgLnk')
.live('click', function(event) {
self.currentSlide = self.currentSlide + 1;
self.updateSlide(self.currentSlide);
event.preventDefault();
});
}
};
return function (opts) {
return this.each(function () {
$(this).data('photoGallery',
new PhotoGalleryModule(this, opts));
});
};
})(jQuery);
// activate
$(function(){
var ready = function(){
$('div.photoGalleryMod').photoGallery({
// similar technique as below to load json
json: { photoGallerySlides: { /*...*/} },
currentSlide: 0
});
};
// load script dynamically when needed
('photoGallery' in $.fn) ? ready() :
$.getScript('/scripts/jquery.photogallery.js', ready);
});

Categories

Resources