// Miva Merchant // // This file and the source codes contained herein are the property of // Miva, Inc. Use of this file is restricted to the specific terms and // conditions in the License Agreement associated with this file. Distribution // of this file or portions of this file for uses not covered by the License // Agreement is not allowed without a written agreement signed by an officer of // Miva, Inc. // // Copyright 1998-2017 Miva, Inc. All rights reserved. // http://www.miva.com // // $Id: runtime.js 65308 2017-10-20 21:57:56Z rguisewite $ // /* Required elements: $unique_id = some_unique_to_DOM_value; <[HTMLElement] data-mm_searchfield_menu="Yes" data-mm_searchfield_id="$unique_id"> */ AddEvent( window, 'load', function() { MMSearchField_Initialize(); } ); var mm_searchfields = new Object(); function MMSearchField_Initialize() { var i, id, i_len, lookup, elements; lookup = new Object(); elements = document.getElementsByTagName( '*' ); for ( i = 0, i_len = elements.length; i < i_len; i++ ) { if ( id = elements[ i ].getAttribute( 'data-mm_searchfield_id' ) ) { if ( !lookup[ id ] ) { lookup[ id ] = new Object(); } if ( elements[ i ].getAttribute( 'data-mm_searchfield' ) ) lookup[ id ].element_search = elements[ i ]; else if ( elements[ i ].getAttribute( 'data-mm_searchfield_menu' ) ) lookup[ id ].element_menu = elements[ i ]; } } for ( id in lookup ) { if ( !lookup.hasOwnProperty( id ) || !lookup[ id ].element_search || !lookup[ id ].element_menu || ( lookup[ id ].element_search.nodeType !== 1 ) || ( lookup[ id ].element_menu.nodeType !== 1 ) || ( lookup[ id ].element_search.nodeName.toLowerCase() !== 'input' ) ) { continue; } mm_searchfields[ id ] = new MMSearchField( lookup[ id ].element_search, lookup[ id ].element_menu ); } } function MMSearchField( element_search, element_menu ) { var self = this; // Elements this.element_search = element_search; this.element_menu = element_menu; // Values this.current_search = ''; this.search_timeout = null; this.menu_visible = false; this.menu_items = new Array(); this.selected_item = null; this.product_count = 5; this.has_focus = false; // Events this.event_search_focus = function( event ) { return self.Event_Focus( event ? event : window.event ); }; this.event_search_keydown = function( event ) { return self.Event_Keydown( event ? event : window.event ); }; this.event_search_keyup = function( event ) { return self.Event_Keyup( event ? event : window.event ); }; this.event_search_blur = function( event ) { return self.Event_Blur( event ? event : window.event ); }; this.event_search_paste = function( event ) { setTimeout( function() { self.Search( self.element_search.value ); }, 0 ); }; this.event_search_click = function( event ) { eventStopPropagation( event ? event : window.event ); }; this.event_document_mousedown = function( event ) { return self.Event_Document_MouseDown( event ? event : window.event ); }; this.event_document_mousemove = function( event ) { return self.Event_Document_MouseMove( event ? event : window.event ); }; AddEvent( this.element_search, 'focus', this.event_search_focus ); AddEvent( this.element_search, 'keydown', this.event_search_keydown ); AddEvent( this.element_search, 'keyup', this.event_search_keyup ); AddEvent( this.element_search, 'blur', this.event_search_blur ); AddEvent( this.element_search, 'paste', this.event_search_paste ); AddEvent( this.element_search, 'click', this.event_search_click ); // Initial Setup this.Menu_Hide(); } MMSearchField.prototype.GetSearchURL = function() { return MMSearchField_Search_URL_sep; } MMSearchField.prototype.SetLoadCount = function( count ) { this.product_count = count; } MMSearchField.prototype.Menu_Empty = function() { this.menu_items = new Array(); this.element_menu.innerHTML = ''; this.Menu_Item_Select( null ); } MMSearchField.prototype.Menu_Show = function() { if ( this.menu_visible ) { return; } this.menu_visible = true; this.element_menu.style.display = 'block'; } MMSearchField.prototype.Menu_Hide = function() { this.Menu_Empty(); if ( !this.menu_visible ) { return; } this.menu_visible = false; this.element_menu.style.display = 'none'; } MMSearchField.prototype.Menu_Append_Header = function() { var item; if ( item = this.onMenuAppendHeader() ) { this.element_menu.appendChild( item ); } } MMSearchField.prototype.Menu_Append_Item = function( data ) { var self = this; var item; if ( item = this.onMenuAppendItem( data.menuitem ) ) { item.mm_data = data; item.action = data.product_link; item.onclick = function( event ) { self.Menu_Item_OnClick( event ? event : window.event, this.action ); }; item.onmousemove = function( event ) { self.Event_MenuItem_MouseMove( event ? event : window.event, item ); }; this.element_menu.appendChild( item ); this.menu_items.push( item ); } } MMSearchField.prototype.Menu_Append_StoreSearch = function() { var self = this; var item; if ( item = this.onMenuAppendStoreSearch( this.element_search.value ) ) { item.action = this.GetSearchURL() + encodeURIComponent( this.element_search.value ); item.onclick = function( event ) { self.Menu_Item_OnClick( event ? event : window.event, this.action ); }; item.onmousemove = function( event ) { self.Event_MenuItem_MouseMove( event ? event : window.event, item ); }; this.element_menu.appendChild( item ); this.menu_item_storesearch = item; this.menu_items.push( item ); } } MMSearchField.prototype.Menu_Replace_StoreSearch = function() { var self = this; var item; if ( item = this.onMenuAppendStoreSearch( this.element_search.value ) ) { item.action = this.GetSearchURL() + encodeURIComponent( this.element_search.value ); item.onclick = function( event ) { self.Menu_Item_OnClick( event ? event : window.event, this.action ); }; item.onmousemove = function( event ) { self.Event_MenuItem_MouseMove( event ? event : window.event, item ); }; this.element_menu.appendChild( item ); if ( this.menu_item_storesearch && ( ( index = this.menu_items.indexOf( this.menu_item_storesearch ) ) != -1 ) ) { this.menu_item_storesearch.parentNode.removeChild( this.menu_item_storesearch ); this.menu_items.splice( index, 1 ); } if ( this.selected_item === this.menu_item_storesearch ) { this.Menu_Item_Select( item ); } this.menu_item_storesearch = item; this.menu_items.push( item ); } } MMSearchField.prototype.Menu_Item_Select = function( item ) { this.selected_item = item; if ( item !== null ) { this.selected_item.className = classNameAdd( this.selected_item, 'mm_searchfield_menuitem_selected' ); } } MMSearchField.prototype.Menu_Item_OnClick = function( e, url ) { window.location.href = url; } MMSearchField.prototype.SetFocus = function() { this.element_search.focus(); } MMSearchField.prototype.Search = function( value ) { var self = this; if ( ( typeof value !== 'string' ) || ( value.length == 0 ) ) { return this.Menu_Hide(); } return AJAX_Call_Module( function( response ) { self.Search_Callback( response, value ); }, 'runtime', 'cmp-cssui-searchfield', 'Search', 'Search=' + encodeURIComponent( value ) + '&Count=' + this.product_count ); } MMSearchField.prototype.Search_Callback = function( response, original_search_value ) { var i, i_len, last_selected; last_selected = this.selected_item; this.Menu_Empty(); if ( !this.has_focus || this.element_search.value.length == 0 ) { return this.Menu_Hide(); } this.Menu_Show(); if ( !response.success || ( response.data.length == 0 ) || ( this.element_search.value != original_search_value ) ) { return this.Menu_Append_StoreSearch(); } this.Menu_Append_Header(); for ( i = 0, i_len = response.data.length; i < i_len; i++ ) { this.Menu_Append_Item( response.data[ i ] ); } this.Menu_Append_StoreSearch(); if ( last_selected ) { for ( i = 0, i_len = this.menu_items.length; i < i_len; i++ ) { if ( this.menu_items[ i ].action == last_selected.action ) { this.Menu_Item_Select( this.menu_items[ i ] ); break; } } } } MMSearchField.prototype.Event_Keydown = function( e ) { var keycode, modifier; keycode = e.keyCode || e.which; modifier = e.metaKey || e.ctrlKey || e.shiftKey || e.altKey; this.current_search = this.element_search.value; if ( keycode == 9 && !modifier ) return this.Menu_Hide(); else if ( keycode == 13 && !modifier ) return this.Event_Enter( e ); else if ( keycode == 27 && !modifier ) return this.Event_ESC( e ); else if ( keycode == 38 && !modifier ) return this.Event_ArrowUp( e ); else if ( keycode == 40 && !modifier ) return this.Event_ArrowDown( e ); if ( keycode == 85 && keySupportsMultiSelect( e ) ) { this.element_search.value = ''; this.current_search = ''; cursorToEnd( this.element_search ); this.Menu_Hide(); return eventPreventDefault( e ); } if ( this.element_search.value.length == 0 ) { this.Menu_Hide(); } else { this.Menu_Show(); this.Menu_Replace_StoreSearch(); } return true; } MMSearchField.prototype.Event_Keyup = function( e ) { var self = this; var keycode = e.keyCode || e.which; if ( keycode == 13 ) return; /* Enter Key */ else if ( keycode == 27 ) return; /* Esc Key */ else if ( keycode == 38 ) return; /* Up Arrow */ else if ( keycode == 40 ) return; /* Down Arrow */ if ( this.element_search.value.length == 0 ) { this.Menu_Hide(); } else { this.Menu_Show(); this.Menu_Replace_StoreSearch(); } if ( this.current_search == this.element_search.value ) { return; } if ( this.search_timeout ) { clearTimeout( this.search_timeout ); } this.search_timeout = setTimeout( function() { self.Search( self.element_search.value ); self.search_timeout = null; }, 250 ); } MMSearchField.prototype.Event_Focus = function( e ) { if ( this.has_focus ) { return; } this.has_focus = true; this.element_search.className = classNameAdd( this.element_search, 'focus' ); this.onFocus( e ); this.Search( this.element_search.value ); AddEvent( document, 'mousedown', this.event_document_mousedown ); } MMSearchField.prototype.Event_Blur = function( e ) { if ( !this.has_focus ) { return; } this.has_focus = false; this.element_search.className = classNameRemove( this.element_search, 'focus' ); this.Menu_Hide(); this.onBlur( e ); RemoveEvent( document, 'mousedown', this.event_document_mousedown ); } MMSearchField.prototype.Event_Enter = function( e ) { if ( this.selected_item && this.selected_item.action ) this.Menu_Item_OnClick( e, this.selected_item.action ); else this.Menu_Item_OnClick( e, this.GetSearchURL() + encodeURIComponent( this.element_search.value ) ); eventStopPropagation( e ); return eventPreventDefault( e ); } MMSearchField.prototype.Event_ESC = function( e ) { if ( this.menu_visible ) { this.Menu_Hide(); } else { this.element_search.value = ''; this.current_search = ''; this.Menu_Hide(); } eventStopPropagation( e ); return eventPreventDefault( e ); } MMSearchField.prototype.Event_ArrowUp = function( e ) { var i, i_len, index, next_index; if ( !this.menu_visible ) { this.Search( this.element_search.value ); return eventPreventDefault( e ); } for ( i = 0, i_len = this.menu_items.length; i < i_len; i++ ) { this.menu_items[ i ].className = classNameRemove( this.menu_items[ i ], 'mm_searchfield_menuitem_selected' ); } if ( this.menu_items.length == 0 ) { this.Menu_Item_Select( null ); } if ( ( index = this.menu_items.indexOf( this.selected_item ) ) != -1 ) { next_index = ( index - 1 < 0 ) ? ( this.menu_items.length - 1 ) : ( index - 1 ); } else { next_index = ( this.menu_items.length - 1 ); } this.Menu_Item_Select( this.menu_items[ next_index ] ); return eventPreventDefault( e ); } MMSearchField.prototype.Event_ArrowDown = function( e ) { var i, i_len, index, next_index; if ( !this.menu_visible ) { this.Search( this.element_search.value ); return eventPreventDefault( e ); } for ( i = 0, i_len = this.menu_items.length; i < i_len; i++ ) { this.menu_items[ i ].className = classNameRemove( this.menu_items[ i ], 'mm_searchfield_menuitem_selected' ); } if ( this.menu_items.length == 0 ) { this.Menu_Item_Select( null ); } if ( ( index = this.menu_items.indexOf( this.selected_item ) ) != -1 ) { next_index = ( index + 1 > this.menu_items.length - 1 ) ? 0 : ( index + 1 ); } else { next_index = 0; } this.Menu_Item_Select( this.menu_items[ next_index ] ); return eventPreventDefault( e ); } MMSearchField.prototype.Event_Document_MouseDown = function( e ) { var target = e.target || e.srcElement; if ( target === this.element_menu || containsChild( this.element_menu, target ) ) { eventStopPropagation( e ); return eventPreventDefault( e ); } } MMSearchField.prototype.Event_MenuItem_MouseMove = function( e, item ) { var i, i_len; for ( i = 0, i_len = this.menu_items.length; i < i_len; i++ ) { this.menu_items[ i ].className = classNameRemove( this.menu_items[ i ], 'mm_searchfield_menuitem_selected' ); } this.Menu_Item_Select( item ); }