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);
});
});
Related
I am trying to create a product builder and I have found a template on codyhouse that looks like it will do the job. The only issue is that the button to select just stays on loading and doesn't progress.
This is the link to the website. https://codyhouse.co/demo/product-builder/index.html
Once the radio button is selected, it keeps loading. Any help would be greatly appreciated as I am out of my depth. I suspect this is an issue with JS but I am not sure.
jQuery(document).ready(function($){
function ProductBuilder( element ) {
this.element = element;
this.stepsWrapper = this.element.children('.cd-builder-steps');
this.steps = this.element.find('.builder-step');
//store some specific bulider steps
this.models = this.element.find('[data-selection="models"]');
this.summary;
this.optionsLists = this.element.find('.options-list');
//bottom summary
this.fixedSummary = this.element.find('.cd-builder-footer');
this.modelPreview = this.element.find('.selected-product').find('img');
this.totPriceWrapper = this.element.find('.tot-price').find('b');
//builder navigations
this.mainNavigation = this.element.find('.cd-builder-main-nav');
this.secondaryNavigation = this.element.find('.cd-builder-secondary-nav');
//used to check if the builder content has been loaded properly
this.loaded = true;
// bind builder events
this.bindEvents();
}
ProductBuilder.prototype.bindEvents = function() {
var self = this;
//detect click on the left navigation
this.mainNavigation.on('click', 'li:not(.active)', function(event){
event.preventDefault();
self.loaded && self.newContentSelected($(this).index());
});
//detect click on bottom fixed navigation
this.secondaryNavigation.on('click', '.nav-item li:not(.buy)', function(event){
event.preventDefault();
var stepNumber = ( $(this).parents('.next').length > 0 ) ? $(this).index() + 1 : $(this).index() - 1;
self.loaded && self.newContentSelected(stepNumber);
});
//detect click on one element in an options list (e.g, models, accessories)
this.optionsLists.on('click', '.js-option', function(event){
self.updateListOptions($(this));
});
//detect clicks on customizer controls (e.g., colors ...)
this.stepsWrapper.on('click', '.cd-product-customizer a', function(event){
event.preventDefault();
self.customizeModel($(this));
});
};
ProductBuilder.prototype.newContentSelected = function(nextStep) {
//first - check if a model has been selected - user can navigate through the builder
if( this.fixedSummary.hasClass('disabled') ) {
//no model has been selected - show alert
this.fixedSummary.addClass('show-alert');
} else {
//model has been selected so show new content
//first check if the color step has been completed - in this case update the product bottom preview
if( this.steps.filter('.active').is('[data-selection="colors"]') ) {
//in this case, color has been changed - update the preview image
var imageSelected = this.steps.filter('.active').find('.cd-product-previews').children('.selected').children('img').attr('src');
this.modelPreview.attr('src', imageSelected);
}
//if Summary is the selected step (new step to be revealed) -> update summary content
if( nextStep + 1 >= this.steps.length ) {
this.createSummary();
}
this.showNewContent(nextStep);
this.updatePrimaryNav(nextStep);
this.updateSecondaryNav(nextStep);
}
}
ProductBuilder.prototype.showNewContent = function(nextStep) {
var actualStep = this.steps.filter('.active').index() + 1;
if( actualStep < nextStep + 1 ) {
//go to next section
this.steps.eq(actualStep-1).removeClass('active back').addClass('move-left');
this.steps.eq(nextStep).addClass('active').removeClass('move-left back');
} else {
//go to previous section
this.steps.eq(actualStep-1).removeClass('active back move-left');
this.steps.eq(nextStep).addClass('active back').removeClass('move-left');
}
}
ProductBuilder.prototype.updatePrimaryNav = function(nextStep) {
this.mainNavigation.find('li').eq(nextStep).addClass('active').siblings('.active').removeClass('active');
}
ProductBuilder.prototype.updateSecondaryNav = function(nextStep) {
( nextStep == 0 ) ? this.fixedSummary.addClass('step-1') : this.fixedSummary.removeClass('step-1');
this.secondaryNavigation.find('.nav-item.next').find('li').eq(nextStep).addClass('visible').removeClass('visited').prevAll().removeClass('visited').addClass('visited').end().nextAll().removeClass('visible visited');
this.secondaryNavigation.find('.nav-item.prev').find('li').eq(nextStep).addClass('visible').removeClass('visited').prevAll().removeClass('visited').addClass('visited').end().nextAll().removeClass('visible visited');
}
ProductBuilder.prototype.createSummary = function() {
var self = this;
this.steps.each(function(){
//this function may need to be updated according to your builder steps and summary
var step = $(this);
if( $(this).data('selection') == 'colors' ) {
//create the Color summary
var colorSelected = $(this).find('.cd-product-customizer').find('.selected'),
color = colorSelected.children('a').data('color'),
colorName = colorSelected.data('content'),
imageSelected = $(this).find('.cd-product-previews').find('.selected img').attr('src');
self.summary.find('.summary-color').find('.color-label').text(colorName).siblings('.color-swatch').attr('data-color', color);
self.summary.find('.product-preview').attr('src', imageSelected);
} else if( $(this).data('selection') == 'accessories' ) {
var selectedOptions = $(this).find('.js-option.selected'),
optionsContent = '';
if( selectedOptions.length == 0 ) {
optionsContent = '<li><p>No Accessories selected;</p></li>';
} else {
selectedOptions.each(function(){
optionsContent +='<li><p>'+$(this).find('p').text()+'</p></li>';
});
}
self.summary.find('.summary-accessories').children('li').remove().end().append($(optionsContent));
}
});
}
ProductBuilder.prototype.updateListOptions = function(listItem) {
var self = this;
if( listItem.hasClass('js-radio') ) {
//this means only one option can be selected (e.g., models) - so check if there's another option selected and deselect it
var alreadySelectedOption = listItem.siblings('.selected'),
price = (alreadySelectedOption.length > 0 ) ? -Number(alreadySelectedOption.data('price')) : 0;
//if the option was already selected and you are deselecting it - price is the price of the option just clicked
( listItem.hasClass('selected') )
? price = -Number(listItem.data('price'))
: price = Number(listItem.data('price')) + price;
//now deselect all the other options
alreadySelectedOption.removeClass('selected');
//toggle the option just selected
listItem.toggleClass('selected');
//update totalPrice - only if the step is not the Models step
(listItem.parents('[data-selection="models"]').length == 0) && self.updatePrice(price);
} else {
//more than one options can be selected - just need to add/remove the one just clicked
var price = ( listItem.hasClass('selected') ) ? -Number(listItem.data('price')) : Number(listItem.data('price'));
//toggle the option just selected
listItem.toggleClass('selected');
//update totalPrice
self.updatePrice(price);
}
if( listItem.parents('[data-selection="models"]').length > 0 ) {
//since a model has been selected/deselected, you need to update the builder content
self.updateModelContent(listItem);
}
};
ProductBuilder.prototype.updateModelContent = function(model) {
var self = this;
if( model.hasClass('selected') ) {
var modelType = model.data('model'),
modelImage = model.find('img').attr('src');
//need to update the product image in the bottom fixed navigation
this.modelPreview.attr('src', modelImage);
//need to update the content of the builder according to the selected product
//first - remove the contet which refers to a different model
this.models.siblings('li').remove();
//second - load the new content
$.ajax({
type : "GET",
dataType : "html",
url : modelType+".html",
beforeSend : function(){
self.loaded = false;
model.siblings().removeClass('loaded');
},
success : function(data){
self.models.after(data);
self.loaded = true;
model.addClass('loaded');
//activate top and bottom navigations
self.fixedSummary.add(self.mainNavigation).removeClass('disabled show-alert');
//update properties of the object
self.steps = self.element.find('.builder-step');
self.summary = self.element.find('[data-selection="summary"]');
//detect click on one element in an options list
self.optionsLists.off('click', '.js-option');
self.optionsLists = self.element.find('.options-list');
self.optionsLists.on('click', '.js-option', function(event){
self.updateListOptions($(this));
});
//this is used not to load the animation the first time new content is loaded
self.element.find('.first-load').removeClass('first-load');
},
error : function(jqXHR, textStatus, errorThrown) {
//you may want to show an error message here
}
});
//update price (no adding/removing)
this.totPriceWrapper.text(model.data('price'));
} else {
//no model has been selected
this.fixedSummary.add(this.mainNavigation).addClass('disabled');
//update price
this.totPriceWrapper.text('0');
this.models.find('.loaded').removeClass('loaded');
}
};
ProductBuilder.prototype.customizeModel = function(target) {
var parent = target.parent('li')
index = parent.index();
//update final price
var price = ( parent.hasClass('selected') )
? 0
: Number(parent.data('price')) - parent.siblings('.selected').data('price');
this.updatePrice(price);
target.parent('li').addClass('selected').siblings().removeClass('selected').parents('.cd-product-customizer').siblings('.cd-product-previews').children('.selected').removeClass('selected').end().children('li').eq(index).addClass('selected');
};
ProductBuilder.prototype.updatePrice = function(price) {
var actualPrice = Number(this.totPriceWrapper.text()) + price;
this.totPriceWrapper.text(actualPrice);
};
if( $('.cd-product-builder').length > 0 ) {
$('.cd-product-builder').each(function(){
//create a productBuilder object for each .cd-product-builder
new ProductBuilder($(this));
});
}
});
Changing the JS/Css, but no luck.
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 have a open function that once triggered, simply plays video in a dedicated panel.
This function can be triggered in two ways - one with a click and another one with a page load (window load) with url that contains a valid anchor tag.
They all work fine but some codes of the window load handler are repetitive and I'm not too sure how I can keep this DRY.
Please take a look and point me in some directions on how I can write this better.
I commented in open function which is for which.
$.videoWatch.prototype = {
init: function() {
this.$openLinks = this.$element.find(".open");
this.$closeLinks = this.$element.find(".close");
this.open();
this.close();
},
_getContent: function(element) {
var $parent = element.parent(),
id = element.attr('href').substring(1),
title = $parent.data('title'),
desc = $parent.data('desc');
return {
title: title,
desc: desc,
id: id
}
},
open: function() {
var self = this;
//open theatre with window load with #hash id
window.onload = function() {
var hash = location.hash;
var $a = $('a[href="' + hash + '"]'),
content = self._getContent($a),
$li = $a.parents("li"),
$theatreVideo = $(".playing"),
$theatreTitle = $(".theatre-title"),
$theatreText = $(".theatre-text");
$(".theatre").attr('id', content.id);
$theatreTitle.text(content.title);
$theatreText.text(content.desc);
if ($theatreText.text().length >= 90) {
$(".theatre-text").css({
'overflow': 'hidden',
'max-height': '90px',
});
$moreButton.insertAfter($theatreText);
}
$a.parent().addClass("active");
$(".theatre").insertAfter($li);
$(".theatre").slideDown('fast', scrollToTheatre);
oldIndex = $li.index();
}
//open theatre with click event
self.$openLinks.on("click", function(e) {
// e.preventDefault();
if (curID == $(this).parent().attr("id")) {
$("figure").removeClass("active");
$("button.more").remove();
$(".theatre").slideUp('fast');
$('.playing').attr("src", "");
removeHash();
oldIndex = -1;
curID = "";
return false
} else {
curID = $(this).parent().attr("id");
}
var $a = $(this),
content = self._getContent($a),
$li = $a.parents("li"),
$theatreVideo = $(".playing"),
$theatreTitle = $(".theatre-title"),
$theatreText = $(".theatre-text");
$(".theatre").attr('id', content.id);
$theatreTitle.text(content.title);
$theatreText.text(content.desc);
if ($theatreText.text().length >= 90) {
$(".theatre-text").css({
'overflow': 'hidden',
'max-height': '90px',
});
$moreButton.insertAfter($theatreText);
}
if (!($li.index() == oldIndex)) {
$("figure").removeClass("active");
$(".theatre").hide(function(){
$a.parent().addClass("active");
$(".theatre").insertAfter($li);
$(".theatre").slideDown('fast', scrollToTheatre);
oldIndex = $li.index();
});
} else {
$(".theatre").insertAfter($li);
scrollToTheatre();
$("figure").removeClass("active");
$a.parent().addClass("active");
}
});
},
...
Simplified and refactored open method:
open: function() {
var self = this;
var serviceObj = {
theatreVideo : $(".playing"),
theatre: $(".theatre"),
theatreTitle : $(".theatre-title"),
theatreText : $(".theatre-text"),
setTheatreContent: function(content){
this.theatre.attr('id', content.id);
this.theatreTitle.text(content.title);
this.theatreText.text(content.desc);
if (this.theatreText.text().length >= 90) {
this.theatreText.css({
'overflow': 'hidden',
'max-height': '90px',
});
$moreButton.insertAfter(this.theatreText);
}
},
activateTeatre: function(a, li){
a.parent().addClass("active");
this.theatre.insertAfter(li);
this.theatre.slideDown('fast', scrollToTheatre);
oldIndex = li.index();
}
};
//open theatre with window load with #hash id
window.onload = function() {
var hash = location.hash;
var $a = $('a[href="' + hash + '"]'),
content = self._getContent($a),
$li = $a.parents("li");
serviceObj.setTheatreContent(content);
serviceObj.activateTeatre($a, $li);
}
//open theatre with click event
self.$openLinks.on("click", function(e) {
// e.preventDefault();
if (curID == $(this).parent().attr("id")) {
$("figure").removeClass("active");
$("button.more").remove();
$(".theatre").slideUp('fast');
$('.playing').attr("src", "");
removeHash();
oldIndex = -1;
curID = "";
return false
} else {
curID = $(this).parent().attr("id");
}
var $a = $(this),
content = self._getContent($a),
$li = $a.parents("li");
serviceObj.setTheatreContent(content);
if (!($li.index() == oldIndex)) {
$("figure").removeClass("active");
$(".theatre").hide(function(){
serviceObj.activateTeatre($a, $li);
});
} else {
$(".theatre").insertAfter($li);
scrollToTheatre();
$("figure").removeClass("active");
$a.parent().addClass("active");
}
});
},
1st of all there are variables that don't depend on the input, you could pull them to the class (I'll show just one example, as you asked for directions):
init: function() {
this.$theatreVideo = $(".playing");
All the variables that do depend on the input, like $li could be moved to a function:
var $a = $(this),
$dependsOnA = self.dependsOnA($a);
self.actionDependsOnA($dependsOnA); // see below
function dependsOnA($a) {
return {
a: $a,
li: $a.parents("li"),
content: self._getContent($a)
}
}
Also the code that "repeats" can be moved to a function:
function actionDependsOnA($dependsOnA)
$(".theatre").attr('id', $dependsOnA.content.id);
$theatreTitle.text($dependsOnA.content.title);
$theatreText.text($dependsOnA.content.desc);
}
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.
This is a script that is generated by CodeCharge (code generator) as part of my app (well, also by Artisteer designs, apparently). I have very little knowledge of web development, zero knowledge of JS and I have to use this code generator. The script keeps coming up with this error: "Line: 139, Char: 13, Error: Unable to get property 'parent' of undefined or null reference, Code:0, URL: ). Like I was saying, I have no control upon generation of this script, but I can go and modify it, to hopefully fix this. Below is the full script. Line 139 is:
var s = c.parent().children('.art-layout-cell:not(.art-content)');
This is full script:
/* begin Page */
/* Created by Artisteer v3.1.0.55575 */
// css helper
(function($) {
var data = [
{str:navigator.userAgent,sub:'Chrome',ver:'Chrome',name:'chrome'},
{str:navigator.vendor,sub:'Apple',ver:'Version',name:'safari'},
{prop:window.opera,ver:'Opera',name:'opera'},
{str:navigator.userAgent,sub:'Firefox',ver:'Firefox',name:'firefox'},
{str:navigator.userAgent,sub:'MSIE',ver:'MSIE',name:'ie'}];
for (var n=0;n<data.length;n++) {
if ((data[n].str && (data[n].str.indexOf(data[n].sub) != -1)) || data[n].prop) {
var v = function(s){var i=s.indexOf(data[n].ver);return (i!=-1)? parseInt(s.substring(i+data[n].ver.length+1)):'';};
$('html').addClass(data[n].name+' '+data[n].name+v(navigator.userAgent) || v(navigator.appVersion)); break;
}
}
})(jQuery);
/* end Page */
/* begin Menu */
jQuery(function () {
if (!jQuery.browser.msie || parseInt(jQuery.browser.version) > 7) return;
jQuery('ul.art-hmenu>li:not(:first-child)').each(function () { jQuery(this).prepend('<span class="art-hmenu-separator"> </span>'); });
if (!jQuery.browser.msie || parseInt(jQuery.browser.version) > 6) return;
jQuery('ul.art-hmenu li').each(function () {
this.j = jQuery(this);
this.UL = this.j.children('ul:first');
if (this.UL.length == 0) return;
this.A = this.j.children('a:first');
this.onmouseenter = function () {
this.j.addClass('art-hmenuhover');
this.UL.addClass('art-hmenuhoverUL');
this.A.addClass('art-hmenuhoverA');
};
this.onmouseleave = function() {
this.j.removeClass('art-hmenuhover');
this.UL.removeClass('art-hmenuhoverUL');
this.A.removeClass('art-hmenuhoverA');
};
});
});
jQuery(function() { setHMenuOpenDirection({container: "div.art-sheet-body", defaultContainer: "#art-main", menuClass: "art-hmenu", leftToRightClass: "art-hmenu-left-to-right", rightToLeftClass: "art-hmenu-right-to-left"}); });
function setHMenuOpenDirection(menuInfo) {
var defaultContainer = jQuery(menuInfo.defaultContainer);
defaultContainer = defaultContainer.length > 0 ? defaultContainer = jQuery(defaultContainer[0]) : null;
jQuery("ul." + menuInfo.menuClass + ">li>ul").each(function () {
var submenu = jQuery(this);
var submenuWidth = submenu.outerWidth();
var submenuLeft = submenu.offset().left;
var mainContainer = submenu.parents(menuInfo.container);
mainContainer = mainContainer.length > 0 ? mainContainer = jQuery(mainContainer[0]) : null;
var container = mainContainer || defaultContainer;
if (container != null) {
var containerLeft = container.offset().left;
var containerWidth = container.outerWidth();
if (submenuLeft + submenuWidth >=
containerLeft + containerWidth)
/* right to left */
submenu.addClass(menuInfo.rightToLeftClass).find("ul").addClass (menuInfo.rightToLeftClass);
if (submenuLeft <= containerLeft)
/* left to right */
submenu.addClass(menuInfo.leftToRightClass).find("ul").addClass (menuInfo.leftToRightClass);
}
});
}
jQuery(function ($) {
$("ul.art-hmenu a:not([href])").attr('href', '#').click(function (e) { e.preventDefault(); });
});
/* end Menu */
/* begin MenuSubItem */
jQuery(function () {
jQuery("ul.art-hmenu ul li").hover(function () { jQuery(this).prev().children("a").addClass("art-hmenu-before-hovered"); },
function () { jQuery(this).prev().children("a").removeClass("art-hmenu-before-hovered"); });
});
jQuery(function () {
if (!jQuery.browser.msie) return;
var ieVersion = parseInt(jQuery.browser.version);
if (ieVersion > 7) return;
/* Fix width of submenu items.
* The width of submenu item calculated incorrectly in IE6-7. IE6 has wider items, IE7 display items like stairs.
*/
jQuery.each(jQuery("ul.art-hmenu ul"), function () {
var maxSubitemWidth = 0;
var submenu = jQuery(this);
var subitem = null;
jQuery.each(submenu.children("li").children("a"), function () {
subitem = jQuery(this);
var subitemWidth = subitem.outerWidth();
if (maxSubitemWidth < subitemWidth)
maxSubitemWidth = subitemWidth;
});
if (subitem != null) {
var subitemBorderLeft = parseInt(subitem.css("border-left-width"), 10) || 0;
var subitemBorderRight = parseInt(subitem.css("border-right-width"), 10) || 0;
var subitemPaddingLeft = parseInt(subitem.css("padding-left"), 10) || 0;
var subitemPaddingRight = parseInt(subitem.css("padding-right"), 10) || 0;
maxSubitemWidth -= subitemBorderLeft + subitemBorderRight + subitemPaddingLeft + subitemPaddingRight;
submenu.children("li").children("a").css("width", maxSubitemWidth + "px");
}
});
if (ieVersion > 6) return;
jQuery("ul.art-hmenu ul>li:first-child>a").css("border-top-width", "1px");
});
/* end MenuSubItem */
/* begin Layout */
jQuery(function () {
jQuery(window).bind('resize', function () {
var bh = jQuery('body').height();
var mh = 0;
jQuery('#art-main').children().each(function() {
if (jQuery(this).css('position') != 'absolute')
mh += jQuery(this).outerHeight(true);
});
if (mh < bh)
{
var r = bh - mh;
var c = jQuery('div.art-content');
c.css('height', (c.outerHeight(true) + r) + 'px');
}
});
if (jQuery.browser.msie && parseInt(jQuery.browser.version) < 8) {
jQuery(window).bind('resize', function() {
var c = $('div.art-content');
var s = c.parent().children('.art-layout-cell:not(.art-content)');
var w = 0;
c.hide();
s.each(function() { w += this.clientWidth; });
c.w = c.parent().width(); c.css('width', c.w - w + 'px');
c.show();
});
}
jQuery(window).trigger('resize');
});
/* end Layout */
/* begin Button */
function artButtonSetup(className) {
jQuery.each(jQuery("a." + className + ", button." + className + ", input." + className), function (i, val) {
var b = jQuery(val);
if (!b.parent().hasClass('art-button-wrapper')) {
if (b.is('input')) b.val(b.val().replace(/^\s*/, '')).css('zoom', '1');
if (!b.hasClass('art-button')) b.addClass('art-button');
jQuery("<span class='art-button-wrapper'><span class='art-button-l'> </span><span class='art-button-r'> </span></span>").insertBefore(b).append(b);
if (b.hasClass('active')) b.parent().addClass('active');
}
b.mouseover(function () { jQuery(this).parent().addClass("hover"); });
b.mouseout(function () { var b = jQuery(this); b.parent().removeClass("hover"); if (!b.hasClass('active')) b.parent().removeClass('active'); });
b.mousedown(function () { var b = jQuery(this); b.parent().removeClass("hover"); if (!b.hasClass('active')) b.parent().addClass('active'); });
b.mouseup(function () { var b = jQuery(this); if (!b.hasClass('active')) b.parent().removeClass('active'); });
});
}
jQuery(function() { artButtonSetup("art-button"); });
/* end Button */
// adds spans to apply css styles for buttons with class "Button"
jQuery(function() { artButtonSetup("Button"); });
jQuery(function() {
// events for CCS AjaxPanel can be set with help of AjaxPanelEvents
if (typeof window.AjaxPanelEvents == "undefined") window.AjaxPanelEvents = [];
// when CCS AjaxPanel is updated the buttons should be decorated with spans again
window.AjaxPanelEvents.push({
eventName: "afterUpdate",
func: function(updatePanel) {
// adds spans to apply css styles for buttons with class "Button"
artButtonSetup("Button", updatePanel);
// adds spans to apply css styles for buttons with class "art-button"
artButtonSetup("art-button", updatePanel);
}
});
});
Can anybody help? Thanks!
It seems that c is not instantiated, something like c = new anything.
It looks like you might have used jQuery.noConflit() in your project, so $ is not jQuery object.
So change
var c = $('div.art-content');
to
var c = jQuery('div.art-content');