How do such a thing to work:
function getElements(attrib) {
return document.querySelectorAll('[' + attrib + ']');
}
$(window).load(function () {
$(".b1").hover(function () {
$(this).className = 'x';
var elements = getElements('code');
for (var i = 0; i < elements.length; i++) {
if (elements[i] == 'wow') {
elements[i].className = 'blue';
} else {
elements[i].className = 'red';
}
}
}, function () {
$(this).className = 'y';
});
});
http://jsfiddle.net/rc6Pq/10/
I would like hover to "BUTTON HOVER" and then show this elements with atributes "code" in different colors for "wow" and "lol".
Regards and thanks in advance!
What about this version:
function getElements(attrib) {
return $('[' + attrib + ']');
}
$(window).load(function () {
$(".b1").hover(function () {
$(this).className = 'x';
var elements = getElements('code');
getElements('code').addClass('red').filter('[code="wow"]')
.removeClass('red').addClass('blue');
}, function () {
$(this).className = 'y';
});
});
http://jsfiddle.net/rc6Pq/11/
or even better:
var elements = getElements('code'),
wow = getElements('code').filter('[code="wow"]').addClass('blue');
elements.not(wow).addClass('red');
http://jsfiddle.net/rc6Pq/12/
Related
My problem is when I hover over something really fast, it executes the first function and then the second function when the mouse leave the text. The two functions are executed completely. I would like something like, if the mouse leave before a specific time, do something. For instance, change the text to "Fr"
$( "#nav6" ).hover(
function() {
navsix(6);
}, function() {
<!-- clearTimeout(TO) -->
nav6out(6);
}
);
function navsix(i) {
if (window.matchMedia("(min-width: 600px)").matches) {
var elem = document.getElementById("nav6");
var str = "Français";
var len = str.length + 1 - i;
var TO = setTimeout(function () {
elem.innerHTML = str.substring(0, len);
if (--i) navsix(i);
}, 50)
}
}
function nav6out(i) {
if (window.matchMedia("(min-width: 600px)").matches) {
var elem = document.getElementById("nav6");
var str = "Français";
len = i + 1
var TO = setTimeout(function () {
elem.innerHTML = str.substring(0, len);
if (--i) nav6out(i);
}, 50)
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="topnav-right"><a id="nav6" href="#Francais">Fr</a></div>
You're on the right track with clearTimeout(). I added clearTimeout() right before each of your setTimeout() functions and declared TO at the top.
var TO = "";
var hoverTimeout = "";
$("#nav6").hover(
function() {
hoverTimeout = setTimeout(function() {
navsix(6);
}, 200)
},
function() {
clearTimeout(hoverTimeout);
nav6out(6);
}
);
function navsix(i) {
if (window.matchMedia("(min-width: 600px)").matches) {
var elem = document.getElementById("nav6");
var str = "Français";
var len = str.length + 1 - i;
clearTimeout(TO);
TO = setTimeout(function() {
elem.innerHTML = str.substring(0, len);
if (--i) navsix(i);
}, 50)
}
}
function nav6out(i) {
if (window.matchMedia("(min-width: 600px)").matches) {
var elem = document.getElementById("nav6");
var str = "Français";
if (elem.innerHTML.length > 2) {
len = i + 1;
clearTimeout(TO);
TO = setTimeout(function() {
elem.innerHTML = str.substring(0, len);
if (--i) nav6out(i);
}, 50)
}
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="topnav-right"><a id="nav6" href="#Francais">Fr</a></div>
I have some JavaScrip that is meant to check if there are any media tags selected or industry tags selected--this is so the portfolio items can be sorted and displayed accordingly in the browser.
What I have almost works 100%, but I can't figure out how to make it so that if only a media tag is selected or if only an industry tag is selected, the portfolio items should still be sorted accordingly. Currently, you have to select a media tag AND an industry tag, but I'd like users to be able to search using just a media tag OR just an industry tag.
Here is what I want to accomplish: If only a media tag is selected, then get all portfolio pieces that are associated with that media tag. If only an industry tag is selected, get all portfolio items that are associated with that industry tag. If a media tag AND industry tag are selected at the same time, get all portfolio items that are associated with BOTH.
Vanilla JS isn't my strong point so forgive me if this is a dumb question, but this has had me stumped for hours now.
No jQuery answers, please, as this whole page's functionality is built using JavaScript.
Here is the function:
var update = function () {
closeDrawer();
// update ui to reflect tag changes
// get our list of items to display
var itemsToDisplay = [];
var currentMediaTag = controlsContainer.querySelector('.media.selected');
var currentIndustryTag = controlsContainer.querySelector('.industry.selected');
if (currentMediaTag != "" && currentMediaTag != null) {
selectedMediaFilter = currentMediaTag.innerHTML;
}
if (currentIndustryTag != "" && currentIndustryTag != null) {
selectedIndustryFilter = currentIndustryTag.innerHTML;
}
if (selectedMediaFilter == "" && selectedIndustryFilter == "") {
itemsToDisplay = portfolioItems.filter(function (item) {
return item.preferred;
});
} else {
itemsToDisplay = portfolioItems.filter(function (item) {
var mediaTags = item.media_tags,
industryTags = item.industry_tags;
if(industryTags.indexOf(selectedIndustryFilter) < 0){
return false;
}
else if(mediaTags.indexOf(selectedMediaFilter) < 0){
return false;
}
else{
return true;
}
});
}
renderItems(itemsToDisplay);
}
Not entirely sure it's necessary but just in case, here is the complete JS file that handles the portfolio page:
(function ($) {
document.addEventListener("DOMContentLoaded", function (event) {
// for portfolio interaction
var portfolioGrid = (function () {
var gridSize = undefined,
parentContainer = document.querySelector('.portfolio-item-container');
containers = parentContainer.querySelectorAll('.view'),
drawer = parentContainer.querySelector('.drawer'),
bannerContainer = drawer.querySelector('.banner-container'),
thumbsContainer = drawer.querySelector('.thumbs-container'),
descriptionContainer = drawer.querySelector('.client-description'),
clientNameContainer = drawer.querySelector('.client-name'),
controlsContainer = document.querySelector('.portfolio-controls-container'),
selectedMediaFilter = "", selectedIndustryFilter = "";
var setGridSize = function () {
var windowSize = window.innerWidth,
previousGridSize = gridSize;
if (windowSize > 1800) {
gridSize = 5;
} else if (windowSize > 900) {
gridSize = 4;
} else if (windowSize > 600 && windowSize <= 900) {
gridSize = 3;
} else {
gridSize = 2;
}
if (previousGridSize != gridSize) {
closeDrawer();
}
};
var attachResize = function () {
window.onresize = function () {
setGridSize();
};
};
var getRowClicked = function (boxNumber) {
return Math.ceil(boxNumber / gridSize);
};
var getLeftSibling = function (row) {
var cI = row * gridSize;
return containers[cI >= containers.length ? containers.length - 1 : cI];
};
var openDrawer = function () {
drawer.className = 'drawer';
scrollToBanner();
};
var scrollToBanner = function () {
var mainContainer = document.querySelector('#main-container'),
mainBounding = mainContainer.getBoundingClientRect(),
scrollY = (drawer.offsetTop - mainBounding.bottom) - 10,
currentTop = document.body.getBoundingClientRect().top;
animate(document.body, "scrollTop", "", document.body.scrollTop, scrollY, 200, true);
};
var animate = function (elem, style, unit, from, to, time, prop) {
if (!elem) return;
var start = new Date().getTime(),
timer = setInterval(function () {
var step = Math.min(1, (new Date().getTime() - start) / time);
if (prop) {
elem[style] = (from + step * (to - from)) + unit;
} else {
elem.style[style] = (from + step * (to - from)) + unit;
}
if (step == 1) clearInterval(timer);
}, 25);
elem.style[style] = from + unit;
}
var closeDrawer = function () {
drawer.className = 'drawer hidden';
};
var cleanDrawer = function () {
bannerContainer.innerHTML = "";
clientNameContainer.innerHTML = "";
descriptionContainer.innerHTML = "";
thumbsContainer.innerHTML = "";
};
var resetThumbs = function () {
Array.prototype.forEach.call(thumbsContainer.querySelectorAll('.thumb'), function (t) {
t.className = "thumb";
});
};
var handleBannerItem = function (item) {
bannerContainer.innerHTML = "";
if (item.youtube) {
var videoContainer = document.createElement('div'),
iframe = document.createElement('iframe');
videoContainer.className = "videowrapper";
iframe.className = "youtube-video";
iframe.src = "https://youtube.com/embed/" + item.youtube;
videoContainer.appendChild(iframe);
bannerContainer.appendChild(videoContainer);
} else if (item.soundcloud) {
var iframe = document.createElement('iframe');
iframe.src = item.soundcloud;
iframe.className = "soundcloud-embed";
bannerContainer.appendChild(iframe);
} else if (item.banner) {
var bannerImage = document.createElement('img');
bannerImage.src = item.banner;
bannerContainer.appendChild(bannerImage);
}
};
var attachClick = function () {
Array.prototype.forEach.call(containers, function (n, i) {
n.querySelector('a.info').addEventListener('click', function (e) {
e.preventDefault();
});
n.addEventListener('click', function (e) {
var boxNumber = i + 1,
row = getRowClicked(boxNumber);
var containerIndex = row * gridSize;
if (containerIndex >= containers.length) {
// we're inserting drawer at the end
parentContainer.appendChild(drawer);
} else {
// we're inserting drawer in the middle somewhere
var leftSiblingNode = getLeftSibling(row);
leftSiblingNode.parentNode.insertBefore(drawer, leftSiblingNode);
}
// 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) {
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";
}
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);
});
}
img.addEventListener('click', function (e) {
scrollToBanner();
resetThumbs();
handleBannerItem(item);
container.className = "thumb active";
});
});
}
openDrawer();
});
});
};
var preloadImages = function () {
portfolioItems.forEach(function (item) {
var childItems = item.child_items;
childItems.forEach(function (child) {
(new Image()).src = child.banner;
(new Image()).src = child.thumb;
});
});
};
//////////////////////////////////// UPDATE FUNCTION /////////////////////////////////////
var update = function () {
closeDrawer();
// update ui to reflect tag changes
// get our list of items to display
var itemsToDisplay = [];
var currentMediaTag = controlsContainer.querySelector('.media.selected');
var currentIndustryTag = controlsContainer.querySelector('.industry.selected');
if (currentMediaTag != "" && currentMediaTag != null) {
selectedMediaFilter = currentMediaTag.innerHTML;
}
if (currentIndustryTag != "" && currentIndustryTag != null) {
selectedIndustryFilter = currentIndustryTag.innerHTML;
}
if (selectedMediaFilter == "" && selectedIndustryFilter == "") {
itemsToDisplay = portfolioItems.filter(function (item) {
return item.preferred;
});
} else {
itemsToDisplay = portfolioItems.filter(function (item) {
var mediaTags = item.media_tags,
industryTags = item.industry_tags;
if (industryTags.indexOf(selectedIndustryFilter) < 0) {
return false;
}
else if (mediaTags.indexOf(selectedMediaFilter) < 0) {
return false;
}
else {
return true;
}
});
}
renderItems(itemsToDisplay);
}
//////////////////////////////////// RENDERITEMS FUNCTION /////////////////////////////////////
var renderItems = function (items) {
var children = parentContainer.querySelectorAll('.view');
Array.prototype.forEach.call(children, function (child) {
// remove all event listeners then remove child
parentContainer.removeChild(child);
});
items.forEach(function (item) {
var container = document.createElement('div'),
thumb = document.createElement('img'),
mask = document.createElement('div'),
title = document.createElement('h6'),
excerpt = document.createElement('p'),
link = document.createElement('a');
container.className = "view view-tenth";
container.setAttribute('data-portfolio-item-id', item.id);
thumb.src = item.thumb;
mask.className = "mask";
title.innerHTML = item.name;
excerpt.innerHTML = item.excerpt;
link.href = "#";
link.className = "info";
link.innerHTML = "View Work";
container.appendChild(thumb);
container.appendChild(mask);
mask.appendChild(title);
mask.appendChild(excerpt);
mask.appendChild(link);
parentContainer.insertBefore(container, drawer);
});
containers = parentContainer.querySelectorAll('.view');
attachClick();
};
var filterHandler = function (linkNode, tagType) {
var prevSelection = document.querySelector("." + tagType + '.selected');
if (prevSelection != "" && prevSelection != null) {
prevSelection.className = tagType + ' tag';
}
linkNode.className = tagType + ' tag selected';
update();
};
var clearFilters = function (nodeList, filterType) {
Array.prototype.forEach.call(nodeList, function (node) {
node.className = filterType + " tag";
console.log("Clear filters function called");
});
}
var attachFilters = function () {
var mediaFilters = controlsContainer.querySelectorAll('.tag.media'),
industryFilters = controlsContainer.querySelectorAll('.tag.industry'),
filterToggle = controlsContainer.querySelectorAll('.filter-toggle');
// resets
controlsContainer.querySelector('.media-tags .reset')
.addEventListener('click',
function (e) {
e.preventDefault();
selectedMediaFilter = "";
clearFilters(controlsContainer.querySelectorAll('.media-tags a.tag'), "media");
update();
}
);
controlsContainer.querySelector('.industry-tags .reset')
.addEventListener('click',
function (e) {
e.preventDefault();
selectedIndustryFilter = "";
clearFilters(controlsContainer.querySelectorAll('.industry-tags a.tag'), "industry");
update();
}
);
Array.prototype.forEach.call(filterToggle, function (toggle) {
toggle.addEventListener('click', function (e) {
if (controlsContainer.className.indexOf('open') < 0) {
controlsContainer.className += ' open';
} else {
controlsContainer.className = controlsContainer.className.replace('open', '');
}
});
});
//Attaches a click event to each media tag "button"
Array.prototype.forEach.call(mediaFilters, function (filter) {
filter.addEventListener('click', function (e) {
e.preventDefault();
// var selectedMediaFilter = controlsContainer.querySelector('.media.selected');
//console.log("Media tag: " +this.innerHTML); *THIS WORKS*
filterHandler(this, "media");
});
});
Array.prototype.forEach.call(industryFilters, function (filter) {
filter.addEventListener('click', function (e) {
e.preventDefault();
// var selectedIndustryFilter = this.querySelector('.industry.selected');
// console.log("Industry tag: " +this.innerHTML); *THIS WORKS*
filterHandler(this, "industry");
});
});
};
return {
init: function () {
setGridSize();
attachResize();
attachClick();
preloadImages();
// portfolio page
if (controlsContainer) {
attachFilters();
}
}
};
})();
portfolioGrid.init();
});
}());
$ = jQuery.noConflict();
if(industryTags.indexOf(selectedIndustryFilter) < 0){
return false;
}
else if(mediaTags.indexOf(selectedMediaFilter) < 0){
return false;
}
That part is giving you headaches. Whenever no industry tag or media tag is selected this will exit the function.
Change to:
if(industryTags.indexOf(selectedIndustryFilter) < 0 && mediaTags.indexOf(selectedMediaFilter) < 0){
return false;
}
Now it will test if at least one tag is selected. If so then render items.
I made a change just to experiment with an idea, and this setup works:
if((selectedIndustryFilter !="" && industryTags.indexOf(selectedIndustryFilter) < 0) || (selectedMediaFilter !="" && mediaTags.indexOf(selectedMediaFilter) < 0)){
return false;
}
return true;
Not sure if it's the best solution ever but it seems to work and I'm not going to complain.
I have the following jquery which has been created with the help of a SO member in a previous question...
var filters = [];
function filterList () {
var classes = '.' + filters.join('.');
$('.test').removeClass('main');
if (classes.length > 1) {
$(classes).addClass('main');
}
}
function removeFilter(ele) {
var len = filters.length,
idx;
for (var i = 0; i < len; i++) {
if (filters[i] === ele) {
idx = i;
break;
}
}
filters.splice(idx, 1);
}
function addFilter(ele) {
if (ele) {
filters.push(ele);
}
}
var selectIt = (function () {
var lastSelect;
return (function (ele) {
if (lastSelect) {
removeFilter(lastSelect);
}
addFilter(ele);
lastSelect = ele;
});
}());
$('.selector').on('change', function (e) {
var val = $(this).val();
selectIt(val);
filterList();
});
$('.mybuttons a').on('click', function (e) {
e.preventDefault();
var el = $(this),
col = el.data('col');
if (el.hasClass('active')) {
removeFilter(col);
} else {
addFilter(col);
}
el.toggleClass('active');
filterList();
});
http://jsfiddle.net/fprL03e5/
I am now trying to modify the code so that when an option is selected, all of the non-matching terms have reduced opacity.
When the page is initially loaded all items should have full opacity until one of the items is selected.
I have tried adding an extra class but can't work out how to have it removed when items are de-selected.
Is this what you're looking to do?
http://jsfiddle.net/fprL03e5/3/
function filterList () {
var classes = '.' + filters.join('.');
$('.test').removeClass('main');
$('.test').css('opacity', '.5');
if (classes.length > 1) {
$(classes).addClass('main').css('opacity', '1');
} else {
$('.test').css('opacity', '1');
}
}
I know this is a "classic" and I already tried to read different explanatory articles on this subject, but I still manage to do it wrong somehow. I am talking about adding event handlers and functions in a javascript loop.
Here is my code with problems (it's a suggest-box / auto complete)
function autoCompleteCB(results) {
document.getElementById('autocom').innerHTML = '';
if (results.length == 0) {
document.getElementById('autocom').style.display = 'none';
} else {
document.getElementById('autocom').style.display = 'block';
var divholders = [];
for (var i = 0; i < results.length; i++) {
divholders[i] = document.createElement('div');
divholders[i].style.width = '350px';
var divrestext = document.createElement('div');
divrestext.className = 'autocom0';
divrestext.innerHTML = results[i][0];
divholders[i].appendChild(divrestext);
var divrestype = document.createElement('div');
divrestype.className = 'autocom1' + results[i][1];
divrestype.innerHTML = results[i][1];
divholders[i].appendChild(divrestype);
divholders[i].attachEvent('onmouseover', (function(i) { return function() { divholders[i].style.backgroundColor='#266699'; }; })(i));
divholders[i].attachEvent('onmouseout', (function (i) { return function() { divholders[i].style.backgroundColor = '#F5F5F5'; }; })(i));
document.getElementById('autocom').appendChild(divholders[i]);
}
}
}
It is (of course) the attachevent lines that do not work. This part of javascript is so weird/tricky :) Can a kind expert help me fix those two lines?
This is a half-way fix (I think(:
function bindEvent(element, type, listener) {
if (element.addEventListener) {
element.addEventListener(type, listener, false);
} else if (element.attachEvent) {
element.attachEvent('on' + type, listener);
}
}
function autoCompleteCB(results) {
document.getElementById('autocom').innerHTML = '';
if (results.length == 0) {
document.getElementById('autocom').style.display = 'none';
} else {
document.getElementById('autocom').style.display = 'block';
var divholders = [];
for (var i = 0; i < results.length; i++) {
divholders[i] = document.createElement('div');
divholders[i].style.width = '350px';
var divrestext = document.createElement('div');
divrestext.className = 'autocom0';
divrestext.innerHTML = results[i][0];
divholders[i].appendChild(divrestext);
var divrestype = document.createElement('div');
divrestype.className = 'autocom1' + results[i][1];
divrestype.innerHTML = results[i][1];
// BIND THE EVENTS
divholders[i].appendChild(divrestype);
document.getElementById('autocom').appendChild(divholders[i]);
}
}
}
It looks like this now, but still no "action"
function autoComplete() {
var ss = document.getElementById('txbkeyword').value;
if (ss.length > 0) { CSearch.SearchAutoComplete(ss, 3, autoCompleteCB); }
else { document.getElementById('autocom').style.display = 'none'; }
}
function bindEvent(element, type, listener) {
if (element.addEventListener) {
element.addEventListener(type, listener, false);
} else if (element.attachEvent) {
element.attachEvent('on' + type, listener);
}
}
function autoCompleteCB(results) {
document.getElementById('autocom').innerHTML = '';
if (results.length == 0) {
document.getElementById('autocom').style.display = 'none';
} else {
document.getElementById('autocom').style.display = 'block';
var divholders = [];
for (var i = 0; i < results.length; i++) {
divholders[i] = document.createElement('div');
divholders[i].style.width = '350px';
var divrestext = document.createElement('div');
divrestext.className = 'autocom0';
divrestext.innerHTML = results[i][0];
divholders[i].appendChild(divrestext);
var divrestype = document.createElement('div');
divrestype.className = 'autocom1' + results[i][1];
divrestype.innerHTML = results[i][1];
(function (i) {
bindEvent(divholders[i], 'mouseover', function () {
divholders[i].style.backgroundColor = '#266699';
});
bindEvent(divholders[i], 'mouseout', function () {
divholders[i].style.backgroundColor = '#F5F5F5';
});
})(i);
divholders[i].appendChild(divrestype);
document.getElementById('autocom').appendChild(divholders[i]);
}
}
}
One possibility is because attachEvent is IE-specific. You'll have to use attachEventListener in many other browsers.
And, to use the "proper" method for the current browser, you'll need to feature-detect them (snippet from MDN):
if (el.addEventListener){
el.addEventListener('click', modifyText, false);
} else if (el.attachEvent){
el.attachEvent('onclick', modifyText);
}
You can also create a function to aid in this:
function bindEvent(element, type, listener) {
if (element.addEventListener) {
element.addEventListener(type, listener, false);
} else if (element.attachEvent) {
element.attachEvent('on' + type, listener);
}
}
Then, in place of these 2 lines:
divholders[i].attachEvent('onmouseover', (function(i) { return function() { divholders[i].style.backgroundColor='#266699'; }; })(i));
divholders[i].attachEvent('onmouseout', (function (i) { return function() { divholders[i].style.backgroundColor = '#F5F5F5'; }; })(i));
...use the function to bind your handlers (skipping the on in the event type argument):
(function (i) {
bindEvent(divholders[i], 'mouseover', function () {
divholders[i].style.backgroundColor = '#266699';
});
bindEvent(divholders[i], 'mouseout', function () {
divholders[i].style.backgroundColor = '#F5F5F5';
});
})(i);
You could also just enclose the <div>:
(function (div, i) {
bindEvent(div, 'mouseover', function () {
div.style.backgroundColor = '#266699';
});
bindEvent(div, 'mouseout', function () {
div.style.backgroundColor = '#F5F5F5';
});
})(divholders[i], i);
Try this:
divholders[i].attachEvent('onmouseover', this.style.backgroundColor='#266699');
Error message (Last line):
$("select").selectList is not a
function
Code:
(function( $ ){
$.fn.selectList = function(options) {
var settings = {
'buttonClass' : 'custom-select',
'buttonTextClass' : 'custom-select-status',
'buttonIconClass' : 'custom-select-button-icon',
'menuClass' : 'custom-select-menu',
'menuClassHidden' : 'custom-select-menu-hidden'
}
$('body').click(function() {
$('.' + settings.menuClass).each(function() {
$(this).addClass(settings.menuClassHidden);
})
});
return this.each(function() {
if (options) {
$.extend(settings, options);
}
var $this = $(this).hide(),
$menu = $('<ul></ul>').addClass(settings.menuClass)
.addClass(settings.menuClassHidden),
optionsTexts = new Array(),
currIdx;
$this.find('option').each(function(idx) {
var $opt = $(this);
if ($opt.is(':selected')) {
currIdx = idx;
}
optionsTexts[idx] = $opt.text();
})
for (var i = 0; i < optionsTexts.length; i++) {
var $item = $('<li></li>'),
$link = $('' + optionsTexts[i] + '');
if (i == currIdx) {
$item.addClass('selected');
}
$link.click(function() {
var linkIdx = $link.parent().parent().find('li').index($link.parent());
$this.find('option').eq(linkIdx).attr('selected', 'selected');
$menu.prev().find('.' + settings.buttonTextClass).text($link.text());
if ($menu.hasClass(settings.menuClassHidden)) {
$menu.removeClass(settings.menuClassHidden);
} else {
$menu.addClass(settings.menuClassHidden);
}
});
$item.append($link);
$menu.append($item);
}
$menu.insertBefore($this);
$('')
.html('<span class="'+ settings.buttonTextClass + '">'+ optionsTexts[currIdx] +'</span><span class="' + settings.buttonIconClass + '"></span>')
.addClass(settings.buttonClass)
.insertBefore($menu)
.click(function() {
$('.custom-select-menu').addClass(settings.menuClassHidden);
$menu.hasClass(settings.menuClassHidden)
? $menu.removeClass(settings.menuClassHidden)
: $menu.addClass(settings.menuClassHidden);
return false;
});
});
};
})(jQuery);
$(document).ready(function() {
if (! $('.section-admin').length > 0) {
$('select').selectList();
}
});
Could somebody help?
This works perfect.
See an working example here: Custom jQuery works
Please check if somewhere, somehow you're not initializing jQuery twice. See this answer: https://stackoverflow.com/a/33054683/1712145