I have running script which moves the tr elements from one container to another on double click. But i have below mentioned issues:
1) If we do are very quick double-click on elements than it moves but its values doesn't come, it shows empty tags.
2) I want to change the background color on double click and it color should remove when we click outside or another elements.
<script>
$(function () {
function initTabelMgmt() {
selectInvitees();
moveSelectedInvitees();
deleteInvitees();
//scrollOpen();
}
var tmContainer = $("div.cv-tm-body");
var toggleAssignBtn = tmContainer.find('.cv-move-items button');
/*
function scrollOpen() {
var position = $('div.cv-item li.open').first().position();
var offsetTop = $('div.cv-tm-col-r .cv-helper-grid-overflow').scrollTop();
var unitHeight = $('div.cv-item li.open').first().height();
var containerHeight = $('div.cv-tm-col-r .cv-helper-grid-overflow').height();
var scrollAmount = offsetTop + position.top;
if ((offsetTop - position.top) <= 0 && (offsetTop - position.top) >= (-containerHeight + unitHeight)) {
//do nothing
} else {
$('div.cv-tm-col-r .cv-helper-grid-overflow').animate({
scrollTop: scrollAmount
});
}
};
*/
// scrollOpen end
function selectInvitees() {
//select items from invitee list
var startIndex, endIndex;
var dbclick = false;
tmContainer.find("table.cv-invitees").on('click', 'tr', function (e) {
var row = $(this);
setTimeout(function () {
//singleclick functionality start.
if (dbclick == false) {
if (!row.is('.assigned')) {
toggleAssignBtn.removeClass('is-disabled');
if (e.shiftKey) {
row.parents('.cv-invitees').find('tr').removeClass('selected');
endIndex = row.parents('.cv-invitees').find('tr').index(this);
var range = row.closest('table').find('tr').slice(Math.min(startIndex, endIndex), Math.max(startIndex, endIndex) + 1).not('.assigned');
range.addClass('selected');
} else if (e.ctrlKey) {
startIndex = row.parents('.cv-invitees').find('tr').index(this);
row.toggleClass('selected');
} else {
startIndex = row.parents('.cv-invitees').find('tr').index(this);
row.parents('.cv-invitees').find('tr').not(this).removeClass('selected');
row.toggleClass('selected');
}
}
}
}, 200)
})
.dblclick(function () {
dbclick = true
//doubleclick functionality start.
toggleAssignBtn.addClass('is-disabled');
function moveSelectedInviteesDBClick() {
var row = tmContainer.find("table.cv-invitees tr.selected");
if (!row.is('.assigned')) {
var allOpenSeat = $('.cv-item .open');
var numberOpen = allOpenSeat.length;
var name = row.find("td").eq(0).text();;
var company = row.find("td").eq(1).text();
var addedInvitees = [];
allOpenSeat.each(function (index) {
if (index < 1) {
var openSeat = $(this);
openSeat.find('.name').text(name);
if (company != '') {
openSeat.find('.company').addClass('show').text(company);
}
var seatAssignment = new Object();
seatAssignment.company = "";
addedInvitees.push(seatAssignment);
openSeat.removeClass('open');
}
row.remove();
});
}
} // moveSelectedInviteesDBClick
moveSelectedInviteesDBClick();
setTimeout(function () {
dbclick = false
}, 300)
});
} // selectInvitees end
function moveSelectedInvitees() {
//move invitees from left to right
tmContainer.find('button.cvf-moveright').click(function () {
var selectedItem = $('.cv-invitees .selected');
var allOpenSeat = $('.cv-item .open');
var numberSelected = selectedItem.length;
var numberOpen = allOpenSeat.length;
var errorMsg = tmContainer.prev('.cv-alert-error');
if (numberSelected > numberOpen) {
errorMsg.removeClass('is-hidden');
} else {
var name;
var company;
var invitee = [];
var selectedInvitees = [];
var count = 0;
selectedItem.each(function () {
var $this = $(this);
name = $this.find("td").eq(0).text();
company = $this.find("td").eq(1).text();
invitee = [name, company];
selectedInvitees.push(invitee);
count = count + 1;
i = 0;
$this.remove();
});
var addedInvitees = [];
var items = $('div.cv-item li');
var seatItems = $('div.cv-order li');
allOpenSeat.each(function (index) {
if (index < count) {
var openSeat = $(this);
openSeat.find('.name').text(selectedInvitees[index][0]);
if (selectedInvitees[index][1] != '') {
openSeat.find('.company').addClass('show').text(selectedInvitees[index][1]);
}
var seatAssignment = new Object();
seatAssignment.company = "";
addedInvitees.push(seatAssignment);
//selectedInvitees.shift();
openSeat.removeClass('open');
}
});
selectedInvitees = [];
}
toggleAssignBtn.addClass('is-disabled');
});
} // moveSelectedInvitees end
function deleteInvitees() {
//move invitees from left to right
tmContainer.find('div.cv-tm-col-r .cv-icon-remove').click(function () {
//delete seat assignment
var icon = $(this);
var idx = $('.ui-sortable li').index(icon.parent());
icon.parent().fadeTo(0, 0).addClass('open').find('.name').text('Open').end().fadeTo(750, 1);
icon.parent().find('.company').removeClass('show').text('');
// icon.parent().find('.entitystub').text('00000000-0000-0000-0000-000000000000');
// icon.parent().find('.entitytype').text('0');
// icon.parent().find('.pipe').remove();
// icon.hide();
// var testSeat = $('.seat-numbers li').get(idx);
//var seatStub = j$.trim(j$(testSeat).find('.seatstub').text());
//var input = { 'seatStub': seatStub };
//AssignSeats(input, "/Subscribers/WS/SeatAssignmentService.asmx/DeleteRegistrant");
});
}
initTabelMgmt();
}); // document.ready end
</script>
Your code looks pretty nice. You should also use in order to register from jQuery a single click event the native method .click(...). So please change the following line
tmContainer.find("table.cv-invitees").on('click', 'tr', function (e) {
To:
tmContainer.find("table.cv-invitees").click(function (e) {
and everything should work fine. For some strange reasons the function
$("#someelement").on("click", ...);
does not work always, only sometimes. JQuery officially recommends you to use the native functions for predefined events (such as onclick, onkeyup, onchange etc.) because of this strange behavior.
Edit:
If dblick does not work now, then make 2 lines please, like this:
tmContainer.find("table.cv-invitees").click(function (e) {
// [...]
;
tmContainer.find("table.cv-invitees").dbclick(function (e) {
// [...]
Edit2:
If it does not work, too, then please remove the single click event listener when you are in the .click() closure. Because if this happens, jQuery´s behavior is to treat it always as a single click. So, in other words dblick() will never be triggered, because .click() will always happens before. And then jQuery won´t count up to 2 fast clicks. Expect the unexpected^^
Edit3: This is the full code, which should hopefully work now as it is:
$(function ()
{
function initTabelMgmt()
{
selectInvitees();
moveSelectedInvitees();
deleteInvitees();
//scrollOpen();
}
var tmContainer = $("div.cv-tm-body");
var toggleAssignBtn = tmContainer.find('.cv-move-items button');
var iClickCounter = 0;
var dtFirstClick, dtSecondClick;
/*
function scrollOpen() {
var position = $('div.cv-item li.open').first().position();
var offsetTop = $('div.cv-tm-col-r .cv-helper-grid-overflow').scrollTop();
var unitHeight = $('div.cv-item li.open').first().height();
var containerHeight = $('div.cv-tm-col-r .cv-helper-grid-overflow').height();
var scrollAmount = offsetTop + position.top;
if ((offsetTop - position.top) <= 0 && (offsetTop - position.top) >= (-containerHeight + unitHeight)) {
//do nothing
} else {
$('div.cv-tm-col-r .cv-helper-grid-overflow').animate({
scrollTop: scrollAmount
});
}
};
*/
// scrollOpen end
function selectInvitees()
{
//select items from invitee list
var startIndex, endIndex;
var dbclick = false;
tmContainer.find("table.cv-invitees").click(function(e)
{
iClickCounter++;
if (iClickCounter === 1)
{
dtFirstClick = new Date();
var row = $(this);
window.setTimeout(function ()
{
//singleclick functionality start.
if (dbclick == false)
{
if (!row.is('.assigned'))
{
toggleAssignBtn.removeClass('is-disabled');
if (e.shiftKey)
{
row.parents('.cv-invitees').find('tr').removeClass('selected');
endIndex = row.parents('.cv-invitees').find('tr').index(this);
var range = row.closest('table').find('tr').slice(Math.min(startIndex, endIndex), Math.max(startIndex, endIndex) + 1).not('.assigned');
range.addClass('selected');
}
else if (e.ctrlKey)
{
startIndex = row.parents('.cv-invitees').find('tr').index(this);
row.toggleClass('selected');
}
else
{
startIndex = row.parents('.cv-invitees').find('tr').index(this);
row.parents('.cv-invitees').find('tr').not(this).removeClass('selected');
row.toggleClass('selected');
}
}
}
},
200);
}
else if (iClickCounter === 2)
{
dtSecondClick = new Date();
}
else if (iClickCounter === 3)
{
if (dtSecondClick.getTime() - dtFirstClick.getTime() < 1000)
{
return;
}
iClickCounter = 0;
dbclick = true
//doubleclick functionality start.
toggleAssignBtn.addClass('is-disabled');
function moveSelectedInviteesDBClick()
{
var row = tmContainer.find("table.cv-invitees tr.selected");
if (!row.is('.assigned'))
{
var allOpenSeat = $('.cv-item .open');
var numberOpen = allOpenSeat.length;
var name = row.find("td").eq(0).text();;
var company = row.find("td").eq(1).text();
var addedInvitees = [];
allOpenSeat.each(function (index)
{
if (index < 1)
{
var openSeat = $(this);
openSeat.find('.name').text(name);
if (company != '') {
openSeat.find('.company').addClass('show').text(company);
}
var seatAssignment = new Object();
seatAssignment.company = "";
addedInvitees.push(seatAssignment);
openSeat.removeClass('open');
}
row.remove();
}
);
}
}
// moveSelectedInviteesDBClick
moveSelectedInviteesDBClick();
window.setTimeout(function ()
{
dbclick = false
}, 300);
}
}
);
} // selectInvitees end
function moveSelectedInvitees()
{
//move invitees from left to right
tmContainer.find('button.cvf-moveright').click(function ()
{
var selectedItem = $('.cv-invitees .selected');
var allOpenSeat = $('.cv-item .open');
var numberSelected = selectedItem.length;
var numberOpen = allOpenSeat.length;
var errorMsg = tmContainer.prev('.cv-alert-error');
if (numberSelected > numberOpen) {
errorMsg.removeClass('is-hidden');
}
else
{
var name;
var company;
var invitee = [];
var selectedInvitees = [];
var count = 0;
selectedItem.each(function () {
var $this = $(this);
name = $this.find("td").eq(0).text();
company = $this.find("td").eq(1).text();
invitee = [name, company];
selectedInvitees.push(invitee);
count = count + 1;
i = 0;
$this.remove();
});
var addedInvitees = [];
var items = $('div.cv-item li');
var seatItems = $('div.cv-order li');
allOpenSeat.each(function (index)
{
if (index < count)
{
var openSeat = $(this);
openSeat.find('.name').text(selectedInvitees[index][0]);
if (selectedInvitees[index][1] != '')
{
openSeat.find('.company').addClass('show').text(selectedInvitees[index][1]);
}
var seatAssignment = new Object();
seatAssignment.company = "";
addedInvitees.push(seatAssignment);
//selectedInvitees.shift();
openSeat.removeClass('open');
}
}
);
selectedInvitees = [];
}
toggleAssignBtn.addClass('is-disabled');
}
);
} // moveSelectedInvitees end
function deleteInvitees()
{
//move invitees from left to right
tmContainer.find('div.cv-tm-col-r .cv-icon-remove').click(function ()
{
//delete seat assignment
var icon = $(this);
var idx = $('.ui-sortable li').index(icon.parent());
icon.parent().fadeTo(0, 0).addClass('open').find('.name').text('Open').end().fadeTo(750, 1);
icon.parent().find('.company').removeClass('show').text('');
// icon.parent().find('.entitystub').text('00000000-0000-0000-0000-000000000000');
// icon.parent().find('.entitytype').text('0');
// icon.parent().find('.pipe').remove();
// icon.hide();
// var testSeat = $('.seat-numbers li').get(idx);
//var seatStub = j$.trim(j$(testSeat).find('.seatstub').text());
//var input = { 'seatStub': seatStub };
//AssignSeats(input, "/Subscribers/WS/SeatAssignmentService.asmx/DeleteRegistrant");
}
);
}
initTabelMgmt();
}
); // document.ready end
I guess that you interpret in your special case a double click as 3 times clicked at the same table entry. And if a user do so and if the time difference between first and second click is longer than one second, a double click will be fired. I think should be the solution to deal with this special case.
Edit 4: Please test, if it is possible to click on 3 different table column and get also double click fired. I think this is an disadvantage on how my code handles the double click. So, you need to know from which table column you have already 1 to 3 clicks set. How can we do this? Basically, there are 3 possibilities to do this:
(HTML5 only:) Make data attribute on each tr and the value for this data attribute
should be the clicks already clicke on this tr.
Define a global object key/value pair object, which holds the
event-ID (but I don´t know how to get this back by jQuery driven
events) as the key and the amount of clicks already done as the
value. And then if you are on the next click, you can decide what is
to do now for this tr. This is my favorite alternative!
Last but not least: Only register the click event on every tr and
make for each click-registering an own global area, so that we just
avoid the actual problem. You can do this e. g. by making an JS
Object which hold a member variable as the iclickCounter and you
make a new object of this class, each time a new click event is
registered. But this alternative need a lot more code and is main-memory-hungry.
All of thes possible options need a wrap around your click event, e. g. a loop, that iterates over all tr elements in the given table. You did this already partially by calling the jQuery-function .find(..). This executes the closure on every found html element. So, in your case on all tr elements in the searched table. But what you need to do is to make the workaround of one of my options given above.
Related
I'm using an existing code, written not by me and I have a very limited experience in Java. The code creates a filtered gallery with 15 pics per page using isotope.pkgd.min. Each pic can be opened in a popup, magnific popup.
The problem: I have a filter item e.g. nature with 30-40 pics. The code creates two pages with 15 items per page. However also the popup shows only 15 items and not 30-40. What do I need to do, in order to show 30-40 items in popup but keep 15 items per page in the gallery? Many thanks in advance for your help
$(document).ready(function () {
/*************** Gallery ******************/
var itemSelector = ".tm-gallery-item";
var responsiveIsotope = [ [480, 4], [720, 6] ];
var itemsPerPageDefault = 15;
var itemsPerPage = defineItemsPerPage();
var currentNumberPages = 1;
var currentPage = 1;
var currentFilter = '*';
var filterValue = "";
var pageAttribute = 'data-page';
var pagerClass = 'isotope-pager';
var $container = $('.tm-gallery-container').isotope({
itemSelector: itemSelector
});
function adjustGalleryLayout(currentPopup) {
if(currentPopup == 'gallery') {
// layout Isotope after each image loads
$container.imagesLoaded().progress( function() {
$container.isotope('layout');
});
}
}
/************** Popup *****************/
$('#inline-popups').magnificPopup({
delegate: 'a',
removalDelay: 500, //delay removal by X to allow out-animation
callbacks: {
beforeOpen: function() {
this.st.mainClass = this.st.el.attr('data-effect');
},
open: function() {
adjustGalleryLayout($.magnificPopup.instance.content.attr('id'));
}
},
midClick: true, // allow opening popup on middle mouse click. Always set it to true if you don't provide alternative source.
showCloseBtn: false
});
$('.tm-close-popup').on( "click", function() {
$.magnificPopup.close();
});
var popupInstance = $.magnificPopup.instance;
$('.tm-btn-next').on("click", function(e) {
popupInstance.next();
adjustGalleryLayout(popupInstance.content.attr('id'));
});
$('.tm-btn-contact').on("click", function(e) {
popupInstance.goTo(4);
})
// update items based on current filters
function changeFilter(selector) { $container.isotope({ filter: selector });
$(selector).magnificPopup({
delegate: 'a',
type:'image',
gallery:{
enabled:true
}
})
}
// grab all checked filters and goto page on fresh isotope output
function goToPage(n) {
currentPage = n;
var selector = itemSelector;
var exclusives = [];
if(currentFilter != '*') {
exclusives.push(selector + '.' + currentFilter);
}
// smash all values back together for 'and' filtering
filterValue = exclusives.length ? exclusives.join('') : '*';
a=exclusives;
// add page number to the string of filters
var wordPage = currentPage.toString();
filterValue += ('.'+wordPage);
changeFilter(filterValue);
}
// determine page breaks based on window width and preset values
function defineItemsPerPage() {
var pages = itemsPerPageDefault;
for( var i = 0; i < responsiveIsotope.length; i++ ) {
if( $(window).width() <= responsiveIsotope[i][0] ) {
pages = responsiveIsotope[i][1];
break;
}
}
return pages;
}
function setPagination() {
var SettingsPagesOnItems = function(){
var itemsLength = $container.children(itemSelector).length;
var pages = Math.ceil(itemsLength / itemsPerPage);
var item = 1;
var page = 1;
var selector = itemSelector;
var exclusives = [];
if(currentFilter != '*') {
exclusives.push(selector + '.' + currentFilter);
}
// smash all values back together for 'and' filtering
filterValue = exclusives.length ? exclusives.join('') : '*';
// find each child element with current filter values
$container.children(filterValue).each(function(){
// increment page if a new one is needed
if( item > itemsPerPage ) {
page++;
item = 1;
}
// add page number to element as a class
wordPage = page.toString();
var classes = $(this).attr('class').split(' ');
var lastClass = classes[classes.length-1];
// last class shorter than 4 will be a page number, if so, grab and replace
if(lastClass.length < 4){
$(this).removeClass();
classes.pop();
classes.push(wordPage);
classes = classes.join(' ');
$(this).addClass(classes);
} else {
// if there was no page number, add it
$(this).addClass(wordPage);
}
item++;
});
currentNumberPages = page;
}();
// create page number navigation
var CreatePagers = function() {
var $isotopePager = ( $('.'+pagerClass).length == 0 ) ? $('<div class="'+pagerClass+' tm-paging"></div>') : $('.'+pagerClass);
$isotopePager.html('');
if(currentNumberPages > 1){
for( var i = 0; i < currentNumberPages; i++ ) {
var $pager = '';
if(currentPage == i+1) {
$pager = $('');
} else {
$pager = $('');
}
$pager.html(i+1);
$pager.click(function(){
$('.tm-paging-link').removeClass('active');
$(this).addClass('active');
var page = $(this).eq(0).attr(pageAttribute);
goToPage(page);
});
$pager.appendTo($isotopePager);
}
}
$container.after($isotopePager);
}();
}
setPagination();
goToPage(1);
//event handlers
$('.tm-gallery-link').click(function(e) {
var filter = $(this).data('filter');
currentFilter = filter;
setPagination();
goToPage(1);
$('.tm-gallery-link').removeClass('active');
$(e.target).addClass('active');
})
//Handle window resize
$(window).resize(function(){
itemsPerPage = defineItemsPerPage();
setPagination();
goToPage(1);
});
});
I would like to add the condition, that the function is only triggered if both
addEventListener('change', SwitchG) Events are True (=both have changed).
The code which I use currently activates the function already when one of the two has changed.
var hallo = document.getElementById("S131_01");
var hallo1 = document.getElementById("S130_01");
hallo.addEventListener('change', SwitchG);
hallo1.addEventListener('change', SwitchG);
function SwitchG () {
var test1 = document.getElementById("submit");
test1.classList.add("css");
}
You need another variable, which checks if both have been changed and only executes the handler function if both changes already happened:
var hallo = document.getElementById("S131_01");
var hallo1 = document.getElementById("S130_01");
var countChanges = 0; // <-- this tracks changes
hallo.addEventListener('change', SwitchG);
hallo1.addEventListener('change', SwitchG);
function SwitchG () {
countChanges += 1; // <-- count up
if (countChanges >= 2) {
countChanges = 0; // <-- reset (if needed)
var test1 = document.getElementById("submit");
test1.classList.add("css");
}
}
A more robust implementation however, also tracks the elements which changed and ensures a repeating change event from a single element won't succeed to run the handler.
For example with this utility:
function ChangedCounter (minChanges) {
var elements = new Set();
return {
changed(element) {
elements.add(element);
},
clear() {
elements.clear();
},
isReady() {
return elements.size >= minChanges;
}
};
}
You'd write it like this:
var hallo = document.getElementById("S131_01");
var hallo1 = document.getElementById("S130_01");
var countChanges = ChangedCounter(2);
hallo.addEventListener('change', SwitchG);
hallo1.addEventListener('change', SwitchG);
function SwitchG (e) {
countChanges.changed(e.target);
if (countChanges.isReady()) {
countChanges.clear();
var test1 = document.getElementById("submit");
test1.classList.add("css");
}
}
You could create a "state" to store when the both has changed. I've created two variables, halloState and hallo1State. The snippet below shows how it could be done:
var hallo = document.getElementById("S131_01");
var hallo1 = document.getElementById("S130_01");
var halloState = false;
var hallo1State = false;
hallo.addEventListener('change', SwitchG);
hallo1.addEventListener('change', SwitchG);
function SwitchG (e) {
if(e.target.id === "S131_01") halloState = true;
else if(e.target.id === "S130_01") hallo1State = true;
if(halloState && hallo1State){
var test1 = document.getElementById("submit");
test1.classList.add("css");
}
}
.css {
background-color:red;
}
<input id="S131_01" type="text"/>
<input id="S130_01" type="text"/>
<button id="submit">Submit</button>
I'm stuck as to why I can't get an AddEventListener click event to work on a set of images that appear in a modal. I had them working before before the modal aspect was involve, but I'm not sure that the modal broke the image click event either.
Here is the function in question, which is called within a massive document.addEventListener("DOMContentLoaded", function (event) function:
var attachClick = function () {
Array.prototype.forEach.call(containers, function (n, i) {
n.addEventListener('click', function (e) {
// populate
cleanDrawer();
var mediaFilterSelected = document.querySelector('.media-tags .tag-container .selected');
var selectedFilters = "";
if (mediaFilterSelected != "" && mediaFilterSelected != null) {
selectedFilters = mediaFilterSelected.innerHTML;
}
var portfolioItemName = '';
var selectedID = this.getAttribute('data-portfolio-item-id');
var data = portfolioItems.filter(function (item) {
portfolioItemName = item.name;
return item.id === selectedID;
})[0];
clientNameContainer.innerHTML = data.name;
descriptionContainer.innerHTML = data.description;
var childItems = data.child_items;
//We will group the child items by media tag and target the unique instance from each group to get the right main banner
Array.prototype.groupBy = function (prop) {
return this.reduce(function (groups, item) {
var val = item[prop];
groups[val] = groups[val] || [];
groups[val].push(item);
return groups;
}, {});
}
var byTag = childItems.groupBy('media_tags');
if (childItems.length > 0) {
handleBannerItem(childItems[0]);
var byTagValues = Object.values(byTag);
byTagValues.forEach(function (tagValue) {
for (var t = 0; t < tagValue.length; t++) {
if (tagValue[t].media_tags == selectedFilters) {
handleBannerItem(tagValue[0]);
}
}
});
childItems.forEach(function (item, i) {
// console.log("childItems.forEach"); we get into here
var img = document.createElement('img'),
container = document.createElement('div'),
label = document.createElement('p');
container.appendChild(img);
var mediaTags = item.media_tags;
container.className = "thumb";
label.className = "childLabelInactive thumbLbl";
thumbsContainer.appendChild(container);
if (selectedFilters.length > 0 && mediaTags.length > 0) {
for (var x = 0; x < mediaTags.length; x++) {
if (mediaTags[x] == selectedFilters) {
container.className = "thumb active";
label.className = "childLabel thumbLbl";
}
}
}
else {
container.className = i == 0 ? "thumb active" : "thumb";
// console.log("no tags selected"); we get to here
}
img.src = item.thumb;
if (item.media_tags != 0 && item.media_tags != null) {
childMediaTags = item.media_tags;
childMediaTags.forEach(function (cMTag) {
varLabelTxt = document.createTextNode(cMTag);
container.appendChild(label);
label.appendChild(varLabelTxt);
});
}
//console.log("before adding click to images"); we get here
console.log(img.src);
img.addEventListener("click", function () {
console.log("thumbnail clicked"); //this is never reached
resetThumbs();
handleBannerItem(item);
container.className = "thumb active";
});
});
}
attachClick();
//open a modal to show off the portfolio pieces for the selected client
var tingleModal = document.querySelector('.tingle-modal');
drawer.className = 'drawer';
var portfolioModal = new tingle.modal({
onOpen: function() {
if(tingleModal){
tingleModal.remove();
}
console.log('modal open');
},
onClose: function() {
console.log('modal closed');
//tingleModal.remove();
}
});
e.preventDefault();
portfolioModal.open();
portfolioModal.setContent(document.querySelector('.drawer-content').innerHTML);
});
});
};
And the specific bit that I'm having trouble with:
console.log(img.src);
img.addEventListener("click", function () {
console.log("thumbnail clicked"); //this is never reached
resetThumbs();
handleBannerItem(item);
container.className = "thumb active";
});
I tried removing the e.PreventDefault() bit but that didn't solve the issue. I know the images are being created, so the img variable isn't empty. I feel like the addEventListener is setup correctly. I also tried moving that bit up just under the img.src = item.thumb line, but no luck. For Some reason, the click event just will not trigger for the images.
So if I understand correctly, you have a modal that lies above the images (it has a higher z-index)? Well in this case the clicks are not reaching the images as they will hit the modal. You can pass clicks through elements that lie above by applying the css property pointer-events: none; to the modal, but thats somehow controversial to what a modal is intended to do.
Are the images present in the modal on DOMContentLoaded? You may be able to try delegating the handling of clicks to a parent element if that's the case.
You can try the delegation approach shown here: Vanilla JavaScript Event Delegation
I am trying to implement a fancy slider from codepen in wordpress. I have correctly added the script using the enqueue script method. I know I did it coorectly because it worked for a very small experiment I tried. Now the pen is: http://codepen.io/suez/pen/wMMgXp .
(function() {
var $$ = function(selector, context) {
var context = context || document;
var elements = context.querySelectorAll(selector);
return [].slice.call(elements);
};
function _fncSliderInit($slider, options) {
var prefix = ".fnc-";
var $slider = $slider;
var $slidesCont = $slider.querySelector(prefix + "slider__slides");
var $slides = $$(prefix + "slide", $slider);
var $controls = $$(prefix + "nav__control", $slider);
var $controlsBgs = $$(prefix + "nav__bg", $slider);
var $progressAS = $$(prefix + "nav__control-progress", $slider);
var numOfSlides = $slides.length;
var curSlide = 1;
var sliding = false;
var slidingAT = +parseFloat(getComputedStyle($slidesCont)["transition-duration"]) * 1000;
var slidingDelay = +parseFloat(getComputedStyle($slidesCont)["transition-delay"]) * 1000;
var autoSlidingActive = false;
var autoSlidingTO;
var autoSlidingDelay = 5000; // default autosliding delay value
var autoSlidingBlocked = false;
var $activeSlide;
var $activeControlsBg;
var $prevControl;
function setIDs() {
$slides.forEach(function($slide, index) {
$slide.classList.add("fnc-slide-" + (index + 1));
});
$controls.forEach(function($control, index) {
$control.setAttribute("data-slide", index + 1);
$control.classList.add("fnc-nav__control-" + (index + 1));
});
$controlsBgs.forEach(function($bg, index) {
$bg.classList.add("fnc-nav__bg-" + (index + 1));
});
};
setIDs();
function afterSlidingHandler() {
$slider.querySelector(".m--previous-slide").classList.remove("m--active-slide", "m--previous-slide");
$slider.querySelector(".m--previous-nav-bg").classList.remove("m--active-nav-bg", "m--previous-nav-bg");
$activeSlide.classList.remove("m--before-sliding");
$activeControlsBg.classList.remove("m--nav-bg-before");
$prevControl.classList.remove("m--prev-control");
$prevControl.classList.add("m--reset-progress");
var triggerLayout = $prevControl.offsetTop;
$prevControl.classList.remove("m--reset-progress");
sliding = false;
var layoutTrigger = $slider.offsetTop;
if (autoSlidingActive && !autoSlidingBlocked) {
setAutoslidingTO();
}
};
function performSliding(slideID) {
if (sliding) return;
sliding = true;
window.clearTimeout(autoSlidingTO);
curSlide = slideID;
$prevControl = $slider.querySelector(".m--active-control");
$prevControl.classList.remove("m--active-control");
$prevControl.classList.add("m--prev-control");
$slider.querySelector(prefix + "nav__control-" + slideID).classList.add("m--active-control");
$activeSlide = $slider.querySelector(prefix + "slide-" + slideID);
$activeControlsBg = $slider.querySelector(prefix + "nav__bg-" + slideID);
$slider.querySelector(".m--active-slide").classList.add("m--previous-slide");
$slider.querySelector(".m--active-nav-bg").classList.add("m--previous-nav-bg");
$activeSlide.classList.add("m--before-sliding");
$activeControlsBg.classList.add("m--nav-bg-before");
var layoutTrigger = $activeSlide.offsetTop;
$activeSlide.classList.add("m--active-slide");
$activeControlsBg.classList.add("m--active-nav-bg");
setTimeout(afterSlidingHandler, slidingAT + slidingDelay);
};
function controlClickHandler() {
if (sliding) return;
if (this.classList.contains("m--active-control")) return;
if (options.blockASafterClick) {
autoSlidingBlocked = true;
$slider.classList.add("m--autosliding-blocked");
}
var slideID = +this.getAttribute("data-slide");
performSliding(slideID);
};
$controls.forEach(function($control) {
$control.addEventListener("click", controlClickHandler);
});
function setAutoslidingTO() {
window.clearTimeout(autoSlidingTO);
var delay = +options.autoSlidingDelay || autoSlidingDelay;
curSlide++;
if (curSlide > numOfSlides) curSlide = 1;
autoSlidingTO = setTimeout(function() {
performSliding(curSlide);
}, delay);
};
if (options.autoSliding || +options.autoSlidingDelay > 0) {
if (options.autoSliding === false) return;
autoSlidingActive = true;
setAutoslidingTO();
$slider.classList.add("m--with-autosliding");
var triggerLayout = $slider.offsetTop;
var delay = +options.autoSlidingDelay || autoSlidingDelay;
delay += slidingDelay + slidingAT;
$progressAS.forEach(function($progress) {
$progress.style.transition = "transform " + (delay / 1000) + "s";
});
}
$slider.querySelector(".fnc-nav__control:first-child").classList.add("m--active-control");
};
var fncSlider = function(sliderSelector, options) {
var $sliders = $$(sliderSelector);
$sliders.forEach(function($slider) {
_fncSliderInit($slider, options);
});
};
window.fncSlider = fncSlider;
}());
/* not part of the slider scripts */
/* Slider initialization
options:
autoSliding - boolean
autoSlidingDelay - delay in ms. If audoSliding is on and no value provided, default value is 5000
blockASafterClick - boolean. If user clicked any sliding control, autosliding won't start again
*/
fncSlider(".example-slider", {autoSlidingDelay: 4000});
var $demoCont = document.querySelector(".demo-cont");
[].slice.call(document.querySelectorAll(".fnc-slide__action-btn")).forEach(function($btn) {
$btn.addEventListener("click", function() {
$demoCont.classList.toggle("credits-active");
});
});
document.querySelector(".demo-cont__credits-close").addEventListener("click", function() {
$demoCont.classList.remove("credits-active");
});
document.querySelector(".js-activate-global-blending").addEventListener("click", function() {
document.querySelector(".example-slider").classList.toggle("m--global-blending-active");
});
The javascript code can e found above and in the mentioned link.I know that in wordpress we have to use jQuery in place of $ but I still can't seem to figure out how to do it in this case. And one more thing, the css is in scass form but I have taken the compiled css form but I don't think that is causing any problem (rignt?) Everything I have tried till this point has failed. Any help will be appreciated
You can use $ instead of jQuery in WordPress so long as you wrap all your code inside the following:
(function($) {
// Your code goes here
})( jQuery );
If the code is in the header (before the document is ready) then instead use:
jQuery(document).ready(function( $ ) {
// Your code goes here
});
If your code is still having problems, then please include both the enqueue code in your theme and the error messages
I am trying to create collapsible DIVs that react to links being clicked. I found how to do this using "next" but I wanted to put the links in a separate area. I came up with this which works...
JSFiddle - Works
function navLink(classs) {
this.classs = classs;
}
var homeLink = new navLink(".content-home");
var aboutLink = new navLink(".content-about");
var contactLink = new navLink(".content-contact");
var lastOpen = null;
$('.home').click(function() {
if(lastOpen !== null) {
if(lastOpen === homeLink) {
return; } else {
$(lastOpen.classs).slideToggle('fast');
}
}
$('.content-home').slideToggle('slow');
lastOpen = homeLink;
}
);
$('.about').click(function() {
if(lastOpen !== null) {
if(lastOpen === aboutLink) {
return; } else {
$(lastOpen.classs).slideToggle('fast');
}
}
$('.content-about').slideToggle('slow');
lastOpen = aboutLink;
}
);
$('.contact').click(function() {
if(lastOpen !== null) {
if(lastOpen === contactLink) {
return; } else {
$(lastOpen.classs).slideToggle('fast');
}
}
$('.content-contact').slideToggle('slow');
lastOpen = contactLink;
}
);
I am now trying to create the same result but with a single function instead of one for each link. This is what I came up with....
function navLink(contentClass, linkClass, linkId) {
this.contentClass = contentClass;
this.linkClass = linkClass;
this.linkId = linkId;
}
var navs = [];
navs[0] = new navLink(".content-home", "nav", "home");
navs[1] = new navLink(".content-about", "nav", "about");
navs[2] = new navLink(".content-contact", "nav", "contact");
var lastOpen = null;
$('.nav').click(function(event) {
//loop through link objects
var i;
for (i = 0; i < (navsLength + 1); i++) {
//find link object that matches link clicked
if (event.target.id === navs[i].linkId) {
//if there is a window opened, close it
if (lastOpen !== null) {
//unless it is the link that was clicked
if (lastOpen === navs[i]) {
return;
} else {
//close it
$(lastOpen.contentClass).slideToggle('fast');
}
}
//open the content that correlates to the link clicked
$(navs[i].contentClass).slideToggle('slow');
navs[i] = lastOpen;
}
}
});
JSFiddle - Doesn't Work
No errors so I assume that I am just doing this completely wrong. I've been working with Javascript for only about a week now. I've taken what I've learned about arrays and JQuery events and tried to apply them here. I assume I'm way off. Thoughts? Thanks
You just forgot to define navsLength:
var navsLength=navs.length;
Of course you could also replace it with a $().each loop as you're using jQuery.
[Update] Two other errors I corrected:
lastOpen=navs[i];
for(i=0; i < navsLength ; i++)
Demo: http://jsfiddle.net/jMzPJ/4/
Try:
var current, show = function(){
var id = this.id,
doShow = function() {
current = id;
$(".content-" + id).slideToggle('slow');
},
toHide = current && ".content-" + current;
if(current === id){ //Same link.
return;
}
toHide ? $(toHide).slideToggle('fast', doShow): doShow();;
};
$("#nav").on("click", ".nav", show);
http://jsfiddle.net/tarabyte/jMzPJ/5/