PageSourceSearch

https://steel-toe-shoes.com/mm5/clientside.mvc?T=5d122bff&Module_C…=cmp-cssui-searchfield&Filename=runtime.js

js steel-toe-shoes.com collected 2026-10-08 11:05:00 UTC 14,719 bytes, 579 lines download raw bytes

1// Miva Merchant
2//
3// This file and the source codes contained herein are the property of
4// Miva, Inc.  Use of this file is restricted to the specific terms and
5// conditions in the License Agreement associated with this file.  Distribution
6// of this file or portions of this file for uses not covered by the License
7// Agreement is not allowed without a written agreement signed by an officer of
8// Miva, Inc.
9//
10// Copyright 1998-2019 Miva, Inc.  All rights reserved.
11// http://www.miva.com
12//
13// $Id: runtime.js 74489 2019-04-08 15:49:50Z rguisewite $
14//
15
16/*
17	Required elements:
18		$unique_id = some_unique_to_DOM_value;
19
20		<input type="[any text supported input]" class="any" data-mm_searchfield="Yes" data-mm_searchfield_id="$unique_id" value="&mvte:global:Search;" />
21		<[HTMLElement] data-mm_searchfield_menu="Yes" data-mm_searchfield_id="$unique_id"></[HTMLElement]>
22*/
23
24(function( obj, eventType, fn )
25{
26	if ( obj.addEventListener )
27	{
28		obj.addEventListener( eventType, fn, false );
29	}
30	else if ( obj.attachEvent )
31	{
32		obj.attachEvent( 'on' + eventType, fn );
33	}
34})( window, 'load', function() { MMSearchField_Initialize(); } );
35
36var mm_searchfields = new Object();
37
38function MMSearchField_Initialize()
39{
40	var e, i, id, i_len, lookup, elements;
41
42	FireEvent( window, 'mmsearchfield_override' );
43
44	lookup			= new Object();
45	elements		= document.getElementsByTagName( '*' );
46
47	for ( i = 0, i_len = elements.length; i < i_len; i++ )
48	{
49		if ( id = elements[ i ].getAttribute( 'data-mm_searchfield_id' ) )
50		{
51			if ( !lookup[ id ] )
52			{
53				lookup[ id ] = new Object();
54			}
55
56			if ( elements[ i ].getAttribute( 'data-mm_searchfield' ) )				lookup[ id ].element_search	= elements[ i ];
57			else if ( elements[ i ].getAttribute( 'data-mm_searchfield_menu' ) )	lookup[ id ].element_menu	= elements[ i ];
58		}
59	}
60
61	for ( id in lookup )
62	{
63		if ( !lookup.hasOwnProperty( id )						||
64			 !lookup[ id ].element_search						||
65			 !lookup[ id ].element_menu							||
66			 ( lookup[ id ].element_search.nodeType !== 1 )		||
67			 ( lookup[ id ].element_menu.nodeType !== 1 )		||
68			 ( lookup[ id ].element_search.nodeName.toLowerCase() !== 'input' ) )
69		{
70			continue;
71		}
72
73		mm_searchfields[ id ] = new MMSearchField( lookup[ id ].element_search, lookup[ id ].element_menu );
74	}
75
76	FireEvent( window, 'mmsearchfield_initialized' );
77}
78
79function MMSearchField( element_search, element_menu )
80{
81	var self = this;
82
83	// Elements
84	this.element_search					= element_search;
85	this.element_menu					= element_menu;
86
87	// Values
88	this.current_search					= '';
89	this.search_timeout					= null;
90	this.search_delay					= 400;
91	this.menu_visible					= false;
92	this.menu_items						= new Array();
93	this.selected_item					= null;
94	this.product_count					= 5;
95	this.has_focus						= false;
96	this.delegator						= new AJAX_ThreadPool( 1 );
97	this.last_displayed_search_value	= null;
98
99	// Events
100	this.event_search_focus				= function( event ) { return self.Event_Focus( event ? event : window.event ); };
101	this.event_search_keydown			= function( event ) { return self.Event_Keydown( event ? event : window.event ); };
102	this.event_search_keyup				= function( event ) { return self.Event_Keyup( event ? event : window.event ); };
103	this.event_search_blur				= function( event ) { return self.Event_Blur( event ? event : window.event ); };
104	this.event_search_paste				= function( event ) { setTimeout( function() { self.Search( self.element_search.value ); }, 0 ); };
105	this.event_search_click				= function( event ) { eventStopPropagation( event ? event : window.event ); };
106	this.event_document_mousedown		= function( event ) { return self.Event_Document_MouseDown( event ? event : window.event ); };
107	this.event_document_mousemove		= function( event ) { return self.Event_Document_MouseMove( event ? event : window.event ); };
108
109	AddEvent( this.element_search, 'focus',		this.event_search_focus );
110	AddEvent( this.element_search, 'keydown',	this.event_search_keydown );
111	AddEvent( this.element_search, 'keyup',		this.event_search_keyup );
112	AddEvent( this.element_search, 'blur',		this.event_search_blur );
113	AddEvent( this.element_search, 'paste',		this.event_search_paste );
114	AddEvent( this.element_search, 'click',		this.event_search_click );
115
116	// Initial Setup
117
118	this.Menu_Empty();
119	this.Menu_Hide();
120}
121
122MMSearchField.prototype.GetSearchURL = function()
123{
124	return MMSearchField_Search_URL_sep;
125}
126
127MMSearchField.prototype.SetLoadCount = function( count )
128{
129	this.product_count = count;
130}
131
132MMSearchField.prototype.SetSearchDelay = function( delay )
133{
134	this.search_delay = delay;
135}
136
137MMSearchField.prototype.Menu_Empty = function()
138{
139	this.menu_items						= new Array();
140	this.element_menu.innerHTML 		= '';
141	this.last_displayed_search_value	= null;
142
143	this.Menu_Item_Select( null );
144}
145
146MMSearchField.prototype.Menu_Show = function()
147{
148	if ( this.menu_visible )
149	{
150		return;
151	}
152
153	this.menu_visible = true;
154	this.element_menu.style.display = 'block';
155}
156
157MMSearchField.prototype.Menu_Hide = function()
158{
159	if ( !this.menu_visible )
160	{
161		return;
162	}
163
164	this.menu_visible = false;
165	this.element_menu.style.display = 'none';
166}
167
168MMSearchField.prototype.Menu_Append_Header = function()
169{
170	var item;
171
172	if ( item = this.onMenuAppendHeader() )
173	{
174		this.element_menu.appendChild( item );
175	}
176}
177
178MMSearchField.prototype.Menu_Append_Item = function( data )
179{
180	var self = this;
181	var item;
182
183	if ( item = this.onMenuAppendItem( data.menuitem ) )
184	{
185		item.mm_data		= data;
186		item.action			= data.product_link;
187		item.onclick		= function( event ) { self.Menu_Item_OnClick( event ? event : window.event, this.action ); };
188		item.onmousemove	= function( event ) { self.Event_MenuItem_MouseMove( event ? event : window.event, item ); };
189		this.element_menu.appendChild( item );
190		this.menu_items.push( item );
191	}
192}
193
194MMSearchField.prototype.Menu_Append_StoreSearch = function()
195{
196	var self = this;
197	var item;
198
199	if ( item = this.onMenuAppendStoreSearch( this.element_search.value ) )
200	{
201		item.action					= this.GetSearchURL() + encodeURIComponent( this.element_search.value );
202		item.onclick				= function( event ) { self.Menu_Item_OnClick( event ? event : window.event, this.action ); };
203		item.onmousemove			= function( event ) { self.Event_MenuItem_MouseMove( event ? event : window.event, item ); };
204
205		this.element_menu.appendChild( item );
206
207		this.menu_item_storesearch	= item;
208		this.menu_items.push( item );
209	}
210}
211
212MMSearchField.prototype.Menu_Replace_StoreSearch = function()
213{
214	var self = this;
215	var item;
216
217	if ( item = this.onMenuAppendStoreSearch( this.element_search.value ) )
218	{
219		item.action			= this.GetSearchURL() + encodeURIComponent( this.element_search.value );
220		item.onclick		= function( event ) { self.Menu_Item_OnClick( event ? event : window.event, this.action ); };
221		item.onmousemove	= function( event ) { self.Event_MenuItem_MouseMove( event ? event : window.event, item ); };
222
223		this.element_menu.appendChild( item );
224
225		if ( this.menu_item_storesearch && ( ( index = this.menu_items.indexOf( this.menu_item_storesearch ) ) != -1 ) )
226		{
227			this.menu_item_storesearch.parentNode.removeChild( this.menu_item_storesearch );
228			this.menu_items.splice( index, 1 );
229		}
230
231		if ( this.selected_item === this.menu_item_storesearch )
232		{
233			this.Menu_Item_Select( item );
234		}
235
236		this.menu_item_storesearch = item;
237		this.menu_items.push( item );
238	}
239}
240
241MMSearchField.prototype.Menu_Item_Select = function( item )
242{
243	this.selected_item = item;
244
245	if ( item !== null )
246	{
247		this.selected_item.className = classNameAdd( this.selected_item, 'mm_searchfield_menuitem_selected' );
248	}
249}
250
251MMSearchField.prototype.Menu_Item_OnClick = function( e, url )
252{
253	window.location.href = url;
254}
255
256MMSearchField.prototype.SetFocus = function()
257{
258	this.element_search.focus();
259}
260
261MMSearchField.prototype.Search = function( value )
262{
263	var self = this;
264
265	if ( ( typeof value !== 'string' ) || ( value.length == 0 ) )
266	{
267		this.Menu_Empty();
268		this.Menu_Hide();
269
270		return;
271	}
272	else if ( value.length < 3 )
273	{
274		this.Menu_Empty();
275		this.Menu_Show();
276		this.Menu_Replace_StoreSearch();
277
278		return;
279	}
280
281	AJAX_Call_Module( function( response ) { self.Search_Callback( response, value ); }, 'runtime',
282					  'cmp-cssui-searchfield',
283					  'Search',
284					  'Search=' + encodeURIComponent( value ) +
285					  '&Count=' + this.product_count,
286					  this.delegator );
287
288	this.delegator.LimitQueueToCount( 1 );
289	this.delegator.Run();
290}
291
292MMSearchField.prototype.Search_Callback = function( response, original_search_value )
293{
294	var i, i_len, last_selected;
295
296	last_selected			= this.selected_item;
297
298	this.Menu_Empty();
299
300	if ( !this.has_focus || this.element_search.value.length == 0 )
301	{
302		this.Menu_Empty();
303		this.Menu_Hide();
304
305		return;
306	}
307
308	this.Menu_Show();
309
310	if ( !response.success || ( response.data.length == 0 ) || ( this.element_search.value != original_search_value ) )
311	{
312		return this.Menu_Append_StoreSearch();
313	}
314
315	this.last_displayed_search_value = this.element_search.value;
316
317	this.Menu_Append_Header();
318
319	for ( i = 0, i_len = response.data.length; i < i_len; i++ )
320	{
321		this.Menu_Append_Item( response.data[ i ] );
322	}
323
324	this.Menu_Append_StoreSearch();
325
326	if ( last_selected )
327	{
328		for ( i = 0, i_len = this.menu_items.length; i < i_len; i++ )
329		{
330			if ( this.menu_items[ i ].action == last_selected.action )
331			{
332				this.Menu_Item_Select( this.menu_items[ i ] );
333				break;
334			}
335		}
336	}
337}
338
339MMSearchField.prototype.Event_Keydown = function( e )
340{
341	var keycode, modifier;
342
343	keycode				= e.keyCode || e.which;
344	modifier			= e.metaKey || e.ctrlKey || e.shiftKey || e.altKey;
345	this.current_search = this.element_search.value;
346
347	if ( keycode == 9 && !modifier )			return this.Menu_Hide();
348	else if ( keycode == 13 && !modifier )		return this.Event_Enter( e );
349	else if ( keycode == 27 && !modifier )		return this.Event_ESC( e );
350	else if ( keycode == 38 && !modifier )		return this.Event_ArrowUp( e );
351	else if ( keycode == 40 && !modifier )		return this.Event_ArrowDown( e );
352
353	if ( keycode == 85 && keySupportsMultiSelect( e ) )
354	{
355		this.element_search.value	= '';
356		this.current_search			= '';
357
358		cursorToEnd( this.element_search );
359		this.Menu_Empty();
360		this.Menu_Hide();
361
362		return eventPreventDefault( e );
363	}
364
365	if ( this.element_search.value.length == 0 )
366	{
367		this.Menu_Empty();
368		this.Menu_Hide();
369	}
370	else
371	{
372		this.Menu_Show();
373		this.Menu_Replace_StoreSearch();
374	}
375
376	return true;
377}
378
379MMSearchField.prototype.Event_Keyup = function( e )
380{
381	var self = this;
382	var keycode = e.keyCode || e.which;
383
384	if ( keycode == 13 )		return;	/* Enter Key */
385	else if ( keycode == 27 )	return; /* Esc Key */
386	else if ( keycode == 38 )	return;	/* Up Arrow */
387	else if ( keycode == 40 )	return;	/* Down Arrow */
388
389	if ( this.element_search.value.length == 0 )
390	{
391		this.Menu_Empty();
392		this.Menu_Hide();
393	}
394	else
395	{
396		this.Menu_Show();
397		this.Menu_Replace_StoreSearch();
398	}
399
400	if ( this.current_search == this.element_search.value )
401	{
402		return;
403	}
404
405	if ( this.search_timeout )
406	{
407		clearTimeout( this.search_timeout );
408	}
409
410	this.search_timeout = setTimeout( function()
411	{
412		self.Search( self.element_search.value );
413		self.search_timeout = null;
414	}, this.search_delay );
415}
416
417MMSearchField.prototype.Event_Focus = function( e )
418{
419	if ( this.has_focus )
420	{
421		return;
422	}
423
424	this.has_focus					= true;
425	this.element_search.className	= classNameAdd( this.element_search, 'focu
425s' );
426
427	this.onFocus( e );
428
429	if ( this.element_search.value === this.last_displayed_search_value )
430	{
431		this.Menu_Show();
432	}
433	else if ( this.element_search.value.length )
434	{
435		this.Menu_Empty();
436		this.Menu_Show();
437		this.Menu_Replace_StoreSearch();
438		this.Search( this.element_search.value );
439	}
440
441	AddEvent( document, 'mousedown', this.event_document_mousedown );
442}
443
444MMSearchField.prototype.Event_Blur = function( e )
445{
446	if ( !this.has_focus )
447	{
448		return;
449	}
450
451	this.has_focus					= false;
452	this.element_search.className	= classNameRemove( this.element_search, 'focus' );
453
454	this.Menu_Hide();
455	this.onBlur( e );
456
457	RemoveEvent( document, 'mousedown', this.event_document_mousedown );
458}
459
460MMSearchField.prototype.Event_Enter = function( e )
461{
462	if ( this.selected_item && this.selected_item.action )	this.Menu_Item_OnClick( e, this.selected_item.action );
463	else													this.Menu_Item_OnClick( e, this.GetSearchURL() + encodeURIComponent( this.element_search.value ) );
464
465	eventStopPropagation( e );
466	return eventPreventDefault( e );
467}
468
469MMSearchField.prototype.Event_ESC = function( e )
470{
471	if ( this.menu_visible )
472	{
473		this.Menu_Hide();
474	}
475	else
476	{
477		this.element_search.value	= '';
478		this.current_search			= '';
479
480		this.Menu_Empty();
481		this.Menu_Hide();
482	}
483
484	eventStopPropagation( e );
485	return eventPreventDefault( e );
486}
487
488MMSearchField.prototype.Event_ArrowUp = function( e )
489{
490	var i, i_len, index, next_index;
491
492	if ( !this.menu_visible )
493	{
494		this.Search( this.element_search.value );
495
496		return eventPreventDefault( e );
497	}
498
499	for ( i = 0, i_len = this.menu_items.length; i < i_len; i++ )
500	{
501		this.menu_items[ i ].className = classNameRemove( this.menu_items[ i ], 'mm_searchfield_menuitem_selected' );
502	}
503
504	if ( this.menu_items.length == 0 )
505	{
506		this.Menu_Item_Select( null );
507	}
508
509	if ( ( index = this.menu_items.indexOf( this.selected_item ) ) != -1 )
510	{
511		next_index = ( index - 1 < 0 ) ? ( this.menu_items.length - 1 ) : ( index - 1 );
512	}
513	else
514	{
515		next_index = ( this.menu_items.length - 1 );
516	}
517
518	this.Menu_Item_Select( this.menu_items[ next_index ] );
519
520	return eventPreventDefault( e );
521}
522
523MMSearchField.prototype.Event_ArrowDown = function( e )
524{
525	var i, i_len, index, next_index;
526
527	if ( !this.menu_visible )
528	{
529		this.Search( this.element_search.value );
530
531		return eventPreventDefault( e );
532	}
533
534	for ( i = 0, i_len = this.menu_items.length; i < i_len; i++ )
535	{
536		this.menu_items[ i ].className = classNameRemove( this.menu_items[ i ], 'mm_searchfield_menuitem_selected' );
537	}
538
539	if ( this.menu_items.length == 0 )
540	{
541		this.Menu_Item_Select( null );
542	}
543
544	if ( ( index = this.menu_items.indexOf( this.selected_item ) ) != -1 )
545	{
546		next_index = ( index + 1 > this.menu_items.length - 1 ) ? 0 : ( index + 1 );
547	}
548	else
549	{
550		next_index = 0;
551	}
552
553	this.Menu_Item_Select( this.menu_items[ next_index ] );
554
555	return eventPreventDefault( e );
556}
557
558MMSearchField.prototype.Event_Document_MouseDown = function( e )
559{
560	var target = e.target || e.srcElement;
561
562	if ( target === this.element_menu || containsChild( this.element_menu, target ) )
563	{
564		eventStopPropagation( e );
565		return eventPreventDefault( e );
566	}
567}
568
569MMSearchField.prototype.Event_MenuItem_MouseMove = function( e, item )
570{
571	var i, i_len;
572
573	for ( i = 0, i_len = this.menu_items.length; i < i_len; i++ )
574	{
575		this.menu_items[ i ].className	= classNameRemove( this.menu_items[ i ], 'mm_searchfield_menuitem_selected' );
576	}
577
578	this.Menu_Item_Select( item );
579}

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.