PageSourceSearch

https://www.paxinasgalegas.es/agencia-marketing-online/js/selectFx.js

js paxinasgalegas.es collected 2026-09-24 09:36:56 UTC 9,143 bytes, 338 lines download raw bytes

1/**
2 * selectFx.js v1.0.0
3 * http://www.codrops.com
4 *
5 * Licensed under the MIT license.
6 * http://www.opensource.org/licenses/mit-license.php
7 * 
8 * Copyright 2014, Codrops
9 * http://www.codrops.com
10 */
11;( function( window ) {
12	
13	'use strict';
14
15	/**
16	 * based on from https://github.com/inuyaksa/jquery.nicescroll/blob/master/jquery.nicescroll.js
17	 */
18	function hasParent( e, p ) {
19		if (!e) return false;
20		var el = e.target||e.srcElement||e||false;
21		while (el && el != p) {
22			el = el.parentNode||false;
23		}
24		return (el!==false);
25	};
26	
27	/**
28	 * extend obj function
29	 */
30	function extend( a, b ) {
31		for( var key in b ) { 
32			if( b.hasOwnProperty( key ) ) {
33				a[key] = b[key];
34			}
35		}
36		return a;
37	}
38
39	/**
40	 * SelectFx function
41	 */
42	function SelectFx( el, options ) {	
43		this.el = el;
44		this.options = extend( {}, this.options );
45		extend( this.options, options );
46		this._init();
47	}
48
49	/**
50	 * SelectFx options
51	 */
52	SelectFx.prototype.options = {
53		// if true all the links will open in a new tab.
54		// if we want to be redirected when we click an option, we need to define a data-link attr on the option of the native select element
55		newTab : false,
56		// when opening the select element, the default placeholder (if any) is shown
57		stickyPlaceholder : true,
58		// callback when changing the value
59		onChange : function( val ) { 
60		
61		$(this).prop("selectedIndex", $(this).data("index"));
62		
63		}
64	}
65
66	/**
67	 * init function
68	 * initialize and cache some vars
69	 */
70	SelectFx.prototype._init = function() {
71		// check if we are using a placeholder for the native select box
72		// we assume the placeholder is disabled and selected by default
73		var selectedOpt = this.el.querySelector( 'option[selected]' );
74		this.hasDefaultPlaceholder = selectedOpt && selectedOpt.disabled;
75
76		// get selected option (either the first option with attr selected or just the first option)
77		this.selectedOpt = selectedOpt || this.el.querySelector( 'option' );
78
79		// create structure
80		this._createSelectEl();
81
82		// all options
83		this.selOpts = [].slice.call( this.selEl.querySelectorAll( 'li[data-option]' ) );
84		
85		// total options
86		this.selOptsCount = this.selOpts.length;
87		
88		// current index
89		this.current = this.selOpts.indexOf( this.selEl.querySelector( 'li.cs-selected' ) ) || -1;
90		
91		// placeholder elem
92		this.selPlaceholder = this.selEl.querySelector( 'span.cs-placeholder' );
93
94		// init events
95		this._initEvents();
96	}
97
98	/**
99	 * creates the structure for the select element
100	 */
101	SelectFx.prototype._createSelectEl = function() {
102		var self = this, options = '', createOptionHTML = function(el) {
103			var optclass = '', classes = '', link = '';
104
105			if( el.selectedOpt && !this.foundSelected && !this.hasDefaultPlaceholder ) {
106				classes += 'cs-selected ';
107				this.foundSelected = true;
108			}
109			// extra classes
110			if( el.getAttribute( 'data-class' ) ) {
111				classes += el.getAttribute( 'data-class' );
112			}
113			// link options
114			if( el.getAttribute( 'data-link' ) ) {
115				link = 'data-link=' + el.getAttribute( 'data-link' );
116			}
117
118			if( classes !== '' ) {
119				optclass = 'class="' + classes + '" ';
120			}
121
122			return '<li ' + optclass + link + ' data-option data-value="' + el.value + '"><span>' + el.textContent + '</span></li>';
123		};
124
125		[].slice.call( this.el.children ).forEach( function(el) {
126			if( el.disabled ) { return; }
127
128			var tag = el.tagName.toLowerCase();
129
130			if( tag === 'option' ) {
131				options += createOptionHTML(el);
132			}
133			else if( tag === 'optgroup' ) {
134				options += '<li class="cs-optgroup"><span>' + el.label + '</span><ul>';
135				[].slice.call( el.children ).forEach( function(opt) {
136					options += createOptionHTML(opt);
137				} );
138				options += '</ul></li>';
139			}
140		} );
141
142		var opts_el = '<div class="cs-options"><ul>' + options + '</ul></div>';
143		this.selEl = document.createElement( 'div' );
144		this.selEl.className = this.el.className;
145		this.selEl.tabIndex = this.el.tabIndex;
146		this.selEl.innerHTML = '<span class="cs-placeholder">' + this.selectedOpt.textContent + '</span>' + opts_el;
147		this.el.parentNode.appendChild( this.selEl );
148		this.selEl.appendChild( this.el );
149	}
150
151	/**
152	 * initialize the events
153	 */
154	SelectFx.prototype._initEvents = function() {
155		var self = this;
156
157		// open/close select
158		this.selPlaceholder.addEventListener( 'click', function() {
159			self._toggleSelect();
160		} );
161
162		// clicking the options
163		this.selOpts.forEach( function(opt, idx) {
164			opt.addEventListener( 'click', function() {
165				self.current = idx;
166				self._changeOption();
167				// close select elem
168				self._toggleSelect();
169			} );
170		} );
171
172		// close the select element if the target it´s not the select element or one of its descendants..
173		document.addEventListener( 'click', function(ev) {
174			var target = ev.target;
175			if( self._isOpen() && target !== self.selEl && !hasParent( target, self.selEl ) ) {
176				self._toggleSelect();
177			}
178		} );
179
180		// keyboard navigation events
181		this.selEl.addEventListener( 'keydown', function( ev ) {
182			var keyCode = ev.keyCode || ev.which;
183
184			switch (keyCode) {
185				// up key
186				case 38:
187					ev.preventDefault();
188					self._navigateOpts('prev');
189					break;
190				// down key
191				case 40:
192					ev.preventDefault();
193					self._navigateOpts('next');
194					break;
195				// space key
196				case 32:
197					ev.preventDefault();
198					if( self._isOpen() && typeof self.preSelCurrent != 'undefined' && self.preSelCurrent !== -1 ) {
199						self._changeOption();
200					}
201					self._toggleSelect();
202					break;
203				// enter key
204				case 13:
205					ev.preventDefault();
206					if( self._isOpen() && typeof self.preSelCurrent != 'undefined' && self.preSelCurrent !== -1 ) {
207						self._changeOption();
208						self._toggleSelect();
209					}
210					break;
211				// esc key
212				case 27:
213					ev.preventDefault();
214					if( self._isOpen() ) {
215						self._toggleSelect();
216					}
217					break;
218			}
219		} );
220	}
221
222	/**
223	 * navigate with up/dpwn keys
224	 */
225	SelectFx.prototype._navigateOpts = function(dir) {
226		if( !this._isOpen() ) {
227			this._toggleSelect();
228		}
229
230		var tmpcurrent = typeof this.preSelCurrent != 'undefined' && this.preSelCurrent !== -1 ? this.preSelCurrent : this.current;
231		
232		if( dir === 'prev' && tmpcurrent > 0 || dir === 'next' && tmpcurrent < this.selOptsCount - 1 ) {
233			// save pre selected current - if we click on option, or press enter, or press space this is going to be the index of the current option
234			this.preSelCurrent = dir === 'next' ? tmpcurrent + 1 : tmpcurrent - 1;
235			// remove focus class if any..
236			this._removeFocus();
237			// add class focus - track which option we are navigating
238			classie.add( this.selOpts[this.preSelCurrent], 'cs-focus' );
239		}
240	}
241
242	/**
243	 * open/close select
244	 * when opened show the default placeholder if any
245	 */
246	SelectFx.prototype._toggleSelect = function() {
247		// remove focus class if any..
248		this._removeFocus();
249		
250		if( this._isOpen() ) {
251			if( this.current !== -1 ) {
252				// update placeholder text
253				this.selPlaceholder.textContent = this.selOpts[ this.current ].textContent;
254			}
255			classie.remove(this.selEl, 'cs-active');
256			document.body.classList.remove("-selectFx");
257			
258		}
259		else {
260			if( this.hasDefaultPlaceholder && this.options.stickyPlaceholder ) {
261				// everytime we open we wanna see the default placeholder text
262				this.selPlaceholder.textContent = this.selectedOpt.textContent;
263			}
264			classie.add(this.selEl, 'cs-active');
265			document.body.classList.add("-selectFx");
266		}
267	}
268
269	/**
270	 * change option - the new value is set
271	 */
272	SelectFx.prototype._changeOption = function() {
273		// if pre selected current (if we navigate with the keyboard)...
274		if( typeof this.preSelCurrent != 'undefined' && this.preSelCurrent !== -1 ) {
275			this.current = this.preSelCurrent;
276			this.preSelCurrent = -1;
277		}
278
279		// current option
280		var opt = this.selOpts[ this.current ];
281
282		// update current selected value
283		this.selPlaceholder.textContent = opt.textContent;
284		
285		// change native select element´s value
286		this.el.value = opt.getAttribute( 'data-value' );
287
288		// remove class cs-selected from old selected option and add it to current selected option
289		var oldOpt = this.selEl.querySelector( 'li.cs-selected' );
290		if( oldOpt ) {
291			classie.remove( oldOpt, 'cs-selected' );
292		}
293		classie.add( opt, 'cs-selected' );
294
295		// if there´s a link defined
296		if( opt.getAttribute( 'data-link' ) ) {
297	
298			if( opt.getAttribute( 'data-link' ) == '#' ){
299				$('.modal.construccion').toggleClass('active');	
300				return;
301			}
302	
303			// open in new tab?
304			if( this.options.newTab ) {
305				window.open( opt.getAttribute( 'data-link' ), '_blank' );
306			}
307			else {
308				window.location = opt.getAttribute( 'data-link' );
309			}
310		}
311
312		// callback
313		this.options.onChange( this.el.value );
314	}
315
316	/**
317	 * returns true if select element is opened
318	 */
319	SelectFx.prototype._isOpen = function(opt) {
320		return classie.has( this.selEl, 'cs-active' );
321	}
322
323	/**
324	 * removes the focus class from the option
325	 */
326	SelectFx.prototype._removeFocus = function(opt) {
327		var focusEl = this.selEl.querySelector( 'li.cs-focus' )
328		if( focusEl ) {
329			classie.remove( focusEl, 'cs-focus' );
330		}
331	}
332
333	/**
334	 * add to global namespace
335	 */
336	window.SelectFx = SelectFx;
337
338} )( window );

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.