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

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);
});

Related

Getting the selected value on autocomplete in Jquery

I added an Autocomplete feature to a form on a HTML template, i would like to perform some actions when an hint is selected, is there any way to do it? I'm using Jquery-Typeahead. Here is my actual code:
$(document).ready(function(){
// Defining the local dataset
$.getJSON('http://127.0.0.1:8000/myapi', function(data) {
console.log(data)
var dt = data
$(() => {
$('#myform').typeahead({
source: {
data: dt.results.map(record => record.item)
},
callback: {
onInit: function($el) {
console.log(`Typeahead initiated on: ${$el.prop('tagName')}#${$el.attr('id')}`);
},
onClick: function() {
console.log(); //How can i console.log() the selected value here, for example?
}
}
});
});
});
});
Try defining an onClickAfter callback, it's called right after user clicks on an item. Something like this:
onClickAfter: function(node, a, item, event) {
// item will be the item you selected
console.log(item);
}
You can also define the onClickBefore callback the same way, and it will be called immediately before "normal" typeahead behaviour kicks in

JQuery click function order

I would like to know how can I change the background-image of another div element, when I click on it. I would like to see images one after another in order but what I get is the last one. Here is some code:
$(document).ready(function () {
// console.log('ready!');
$('.right').click(function () {
$('.zur-gda-img').css('background','url(images/sail-boat.jpg)');
}).click(function() {
$('.zur-gda-img').css('background','url(images/sad_ostateczny.jpg)');
}) }).click(function() {
$('.zur-gda-img').css('background','url(images/twierdza_wisloujscie.jpg)');
});
Instead of adding multiple event handler use single. Inside handler change images from the array with help of a counter variable.
$(document).ready(function() {
// store images in an array
var images = ['url(images/sail-boat.jpg)', 'url(images/sad_ostateczny.jpg)', 'url(images/twierdza_wisloujscie.jpg)'],
// variable to store index
i = 0;
$('.right').click(function() {
// update index based on array length
i = i % images.length;
// update background from array using the index value
$('.zur-gda-img').css('background', images[i++]);
})
});
You don't need three event handlers for this (they will just fire one after another and you'll only see the last image). If you want to see images changing, try the following:
$(document).ready(function () {
// document has loaded
$('.right').click(function () {
// 1st image:
$('.zur-gda-img').css('background','url(images/sail-boat.jpg)');
// 2nd image, appears in a second:
setTimeout(function() {
$('.zur-gda-img').css('background','url(images/sad_ostateczny.jpg)');
// 3rd image, appears in another second:
setTimeout(function() {
$('.zur-gda-img').css('background','url(images/twierdza_wisloujscie.jpg)');
},
1000);
},
1000);
});
});

jQuery always prevents the action of the first click

I have several "Purchase Now" buttons of different articles. When the button has the class "sold-out" it shouldn't do anything otherwise it should open a jQuery Magnific Popup. So far that works. My problem is, that when I click for the first time I visit the homepage the purchaseable "Purchase Now" button, it isn't doing anything. When I click for the second time on it, it opens the jQuery window. But why it doesn't work for the first time already ??
My HTML:
Purchase Now
My JQuery:
$('.open-popup-link').magnificPopup({
type:'inline',
midClick: true,
mainClass: 'mfp-fade'
});
$('.ajax-popup').click(function(e){
e.preventDefault();
if($(this).hasClass("sold-out")) {
return false;
}
var region = $(this).data('region');
var quantity = $(this).data('quantity');
if(typeof quantity == 'undefined') quantity = $(this).parent().find('select').val();
var packageid = $(this).data('packageid');
$(this).magnificPopup({
type: 'ajax',
ajax: {
settings: {
data : {
region : region,
quantity : quantity,
packageid : packageid,
}
}
},
closeOnContentClick: false,
closeOnBgClick: false
});
});
It might be because you are declaring the popup definition within the click function. Can you try declaring the function outside the click function?
It doesn't open on first click cause this is the time you BIND it to the element.
Hovewer, we see in documentation that we can instantly open MagnificPopup.
// Open popup immediately. If popup is already opened - it'll just overwite the content (but old options will be kept).
// - first parameter: options object
// - second parameter (optional): index of item to open
$.magnificPopup.open({
items: {
src: 'someimage.jpg'
},
type: 'image'
// You may add options here, they're exactly the same as for $.fn.magnificPopup call
// Note that some settings that rely on click event (like disableOn or midClick) will not work here
}, 0);
http://dimsemenov.com/plugins/magnific-popup/documentation.html#options

magnific passing in array

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);
}
}
});
});

How to call a function inside a Javascript class (jQuery, jSuggest)

I'm using the code found in this jsbin: http://jsbin.com/asahe5/10/edit
There is a function within that class called addItem, which adds an auto-suggested item to the page. However, there is no API built in to add something by clicking on a button for example.
I have tried the following, but it doesn't work (Uncaught TypeError: Object [object Object] has no method 'addItem'):
var test = $("#test").jSuggest({
source: 'http://example.com/page.php',
minChars: 1,
keyDelay: 200,
selectedItemProp: 'name',
seekVal: 'name',
startText: 'Enter a country',
newItem: false,
newText: 'Please select a country from the list.',
selectionAdded: function(elem, data){ add_country(data.value); },
selectionRemoved: function(elem, data){ elem.fadeTo("fast", 0, function(){ elem.remove(); rem_country(data.value); }); }
});
function add_item(object, id) {
test.addItem(object, id);
}
The most relevant part of the plugin:
(function($){
$.fn.jSuggest = function(options) {
var defaults = {
source: {}, // Object or URL where jSuggest gets the suggestions from.
uniqID: false,
startText: 'Enter a Value', // Text to display when the jSuggest input field is empty.
emptyText: 'No Results Found', // Text to display when their are no search results.
preFill: {}, // Object from which you automatically add items when the page is first loaded.
limitText: 'No More Values Are Allowed', // Text to display when the number of selections has reached it's limit.
newItem: false, // If set to false, the user will not be able to add new items by any other way than by selecting from the suggestions list.
newText: 'Adding New Values Is Not Allowed', // Text to display when the user tries to enter a new item by typing.
selectedItemProp: 'value', // Value displayed on the added item
selectProp: 'value', // Name of object property added to the hidden input.
seekVal: 'value', // Comma separated list of object property names.
queryParam: 'q', // The name of the param that will hold the search string value in the AJAX request.
queryLimit: false, // Number for 'limit' param on ajax request.
extraParams: '', // This will be added onto the end of the AJAX request URL. Make sure you add an '&' before each param.
matchCase: false, // Make the search case sensitive when set to true.
minChars: 1, // Minimum number of characters that must be entered before the search begins.
keyDelay: 400, // The delay after a keydown on the jSuggest input field and before search is started.
resultsHighlight: true, // Option to choose whether or not to highlight the matched text in each result item.
selectionLimit: false, // Limits the number of selections that are allowed.
showResultList: true, // If set to false, the Results Dropdown List will never be shown at any time.
selectionClick: function(elem){}, // Custom function that is run when a previously chosen item is clicked.
selectionAdded: function(elem, data){}, // Custom function that is run when an item is added to the items holder.
selectionRemoved: function(elem, data){ elem.remove(); }, // Custom function that is run when an item is removed from the items holder.
spotFirst: true, // Option that spots the first suggestions on the results list if true.
formatList: false, // Custom function that is run after all the data has been retrieved and before the results are put into the suggestion results list.
beforeRetrieve: function(string){ return string; }, // Custom function that is run before the AJAX request is made, or the local objected is searched.
retrieveComplete: function(data){ return data; },
resultClick: function(data){}, // Custom function that is run when a search result item is clicked.
resultsComplete: function(){} // Custom function that is run when the suggestion results dropdown list is made visible.
};
// Merge the options passed with the defaults.
var opts = $.extend(defaults, options);
// Get the data type of the source.
var dType = typeof opts.source;
.....................................
function addItem(data, num) {
// Add to the hidden input the seleced values property from the passed data.
hiddenInput.val(hiddenInput.val()+data[opts.selectProp]+',');
// If a selected item is clicked, add the selected class and call the custom selectionClick function.
var item = $('<li class="as-selection-item" id="as-selection-'+num+'"></li>').click(function() {
opts.selectionClick.call(this, $(this));
itemsHolder.children().removeClass('selected');
$(this).addClass('selected');
});
// If the close cross is clicked,
var close = $('<a class="as-close">x</a>').click(function() {
// Remove the item from the hidden input.
hiddenInput.val(hiddenInput.val().replace(data[opts.selectProp]+',',''));
// Call the custom selectionRemoved function.
opts.selectionRemoved.call(this, item, data);
input.focus();
return false;
});
// Insert the item with the selectedItemProp as text and the close cross.
orgLI.before(item.html(data[opts.selectedItemProp]).prepend(close));
// Call the custom selectionAdded function with the recently added item as elem and its associated data.
opts.selectionAdded.call(this, orgLI.prev(), data);
}
.....................................
});
}
};
})(jQuery);
You can't call that function without changing the plugin to expose the function as a visible API.

Categories

Resources