All Downloads are FREE. Search and download functionalities are using the official Maven repository.

SLING-INF.content.dev.lib.jquery.plugins.jquery.autoSuggest.js Maven / Gradle / Ivy

/*
 * AutoSuggest
 * Copyright 2009-2010 Drew Wilson
 * www.drewwilson.com
 * code.drewwilson.com/entry/autosuggest-jquery-plugin
 *
 * Forked by Wu Yuntao
 * github.com/wuyuntao/jquery-autosuggest
 *
 * Version 1.6.2
 *
 * This Plug-In will auto-complete or auto-suggest completed search queries
 * for you as you type. You can add multiple selections and remove them on
 * the fly. It supports keybord navigation (UP + DOWN + RETURN), as well
 * as multiple AutoSuggest fields on the same page.
 *
 * Inspired by the Autocomplete plugin by: Joern Zaefferer
 * and the Facelist plugin by: Ian Tearle (iantearle.com)
 *
 * This AutoSuggest jQuery plug-in is dual licensed under the MIT and GPL licenses:
 *   http://www.opensource.org/licenses/mit-license.php
 *   http://www.gnu.org/licenses/gpl.html
 */

// Note: This version of the code is from Chris's repo at https://github.com/croby/jquery-autosuggest

require([ 'jquery' ], function(jQuery) {

(function( $ ) {
    var methods = {

        init: function( data, options ) {
            var defaults = {
                asHtmlID: false,
                startText: "Enter Name Here",
                usePlaceholder: false,
                emptyText: "No Results Found",
                preFill: {},
                limitText: "No More Selections Are Allowed",
                selectedItemProp: "value", //name of object property
                selectedValuesProp: "value", //name of object property
                searchObjProps: "value", //comma separated list of object property names
                queryParam: "q",
                retrieveLimit: false, //number for 'limit' param on ajax request
                extraParams: "",
                matchCase: false,
                minChars: 1,
                keyDelay: 400,
                resultsHighlight: true,
                neverSubmit: false,
                selectionLimit: false,
                showResultList: true,
                showResultListWhenNoMatch: false,
                canGenerateNewSelections: true,
                scroll: false,
                scrollHeight: 200,
                start: function(){},
                selectionClick: function( elem ){},
                selectionAdded: function( elem ){},
                selectionRemoved: function( elem ) {
                    elem.remove();
                },
                formatList: false, //callback function
                processNewSelection: function( string ) {
                    return string;
                },
                beforeRetrieve: function( string ) {
                    return string;
                },
                retrieveComplete: function( data ) {
                    return data;
                },
                resultClick: function( data ){},
                resultsComplete: function(){}
            };
            var opts = $.extend( defaults, options );

            return this.each(function( x ) {
                var d_fetcher = false;
                var input = $( this );
                input.data( "opts", opts );
                input.data( "num_count", 0 );
                input.data( "selections", [] );
                var countValidItems = function( data ) {
                    var n = 0;
                    $.each( data, function() {
                        n++;
                    });
                    return n;
                };

                if ( $.isFunction( data ) ) {
                    d_fetcher = data;
                } else if ( typeof data === "string" ) {
                    d_fetcher = function( query, next ) {
                        var limit = "";
                        if ( input.data( "opts" ).retrieveLimit ) {
                            limit = "&limit=" + encodeURIComponent( input.data( "opts" ).retrieveLimit );
                        }
                        $.getJSON( data + "?" + input.data( "opts" ).queryParam + "=" + encodeURIComponent( query ) + limit + input.data( "opts" ).extraParams, function( data ) {
                            var new_data = input.data( "opts" ).retrieveComplete.call( this, data );
                            next( new_data, query );
                        });
                    };
                } else if ( typeof data === "object" && countValidItems( data ) > 0 ) {
                    d_fetcher = function( query, next ) {
                        next( data, query );
                    };
                }

                if ( d_fetcher ) {
                    input.data( "results_ul", $( "
    " ) ); var setup = function() { if ( !input.data( "opts" ).asHtmlID ) { x = x + "" + Math.floor( Math.random() * 100 ); //this ensures there will be unique IDs on the page if autoSuggest() is called multiple times input.data( "x_id", "as-input-" + x); } else { x = input.data( "opts" ).asHtmlID; input.data( "x_id", x); } input.data( "opts" ).start.call( this, { add: function( data ) { input.autoSuggest( "add_selected_item", data, "u" + $( "li", input.data( "selections_holder" ) ).length ).addClass( "blur" ); }, remove: function( value ) { input.data( "values_input" ).val( input.data( "values_input" ).val().replace( "," + value + ",", "," ) ); input.data( "selections_holder" ).find( "li[ data-value = '" + value + "' ]" ).remove(); } }); input.attr( "autocomplete", "off" ).addClass( "as-input" ).attr( "id", input.data( "x_id" ) ); if ( input.data( "opts" ).usePlaceholder ) { input.attr( "placeholder", input.data( "opts" ).startText ); } else { input.val( input.data( "opts" ).startText ); } // Setup basic elements and render them to the DOM input.wrap( "
      " ).wrap( "
    • " ); input.data( "selections_holder", $( "#as-selections-" + x ) ); input.data( "org_li", $( "#as-original-" + x ) ); input.data( "results_holder", $( "
      " ).hide() ); input.data( "values_input", $( "" ) ); if ( typeof input.data( "opts" ).preFill === "string" ) { var vals = input.data( "opts" ).preFill.split( "," ); for (var i = 0; i < vals.length; i++ ) { var v_data = {}; v_data[ input.data( "opts" ).selectedValuesProp ] = vals[ i ]; if ( vals[ i ] !== "" ) { input.autoSuggest( "add_selected_item", v_data, "000" + i ); } } input.data( "prefill_value", input.data( "opts" ).preFill ); } else { input.data( "prefill_value", "" ); var prefill_count = 0; $.each( input.data( "opts" ).preFill, function() { prefill_count++; }); if (prefill_count > 0) { for ( var j = 0; j < prefill_count; j++ ) { var new_v = input.data( "opts" ).preFill[ j ][ input.data( "opts" ).selectedValuesProp ]; if ( new_v === undefined ) { new_v = ""; } input.data( "prefill_value", input.data( "prefill_value" ) + new_v + "," ); if ( new_v !== "" ) { input.autoSuggest( "add_selected_item", input.data( "opts" ).preFill[ j ], "000" + j ); } } } } if ( input.data( "prefill_value") !== "" ) { input.val( "" ); var lastChar = input.data( "prefill_value" ).substring( input.data( "prefill_value" ).length - 1 ); if ( lastChar !== "," ) { input.data( "prefill_value", input.data( "prefill_value") + "," ); } input.data( "values_input" ).val( "," + input.data( "prefill_value" ) ); $( "li.as-selection-item", input.data( "selections_holder" ) ).addClass( "blur" ).removeClass( "selected" ); } input.after( input.data( "values_input" ) ); input.data( "selections_holder" ).click(function() { input.data( "input_focus", true ); input.focus(); }).mousedown(function() { input.data( "input_focus", false ); }).after(input.data( "results_holder" )); // Handle input (functionfield events input.focus(function(){ if ( !input.data( "opts" ).usePlaceholder && $( this ).val() === input.data( "opts" ).startText && input.data( "values_input" ).val() === "" ) { $( this ).val( "" ); } else if ( input.data( "input_focus" ) ) { $( "li.as-selection-item", input.data( "selections_holder" ) ).removeClass( "blur" ); if ( $( this ).val() !== "" ) { input.data( "results_ul" ).css( "width", input.data( "selections_holder" ).outerWidth() ); input.data( "results_holder" ).show(); } } if ( input.data( "interval" ) ) { clearInterval( input.data( "interval" ) ); } input.data( "interval", setInterval(function() { if ( input.data( "opts" ).showResultList ) { if ( input.data( "opts" ).selectionLimit && $( "li.as-selection-item", input.data( "selections_holder" ) ).length >= input.data( "opts" ).selectionLimit ) { input.data( "results_ul" ).html( "
    • " + input.data( "opts" ).limitText + "
    • " ); input.data( "results_holder" ).show(); } else { keyChange(); } } }, input.data( "opts" ).keyDelay)); input.data( "input_focus", true ); if (input.data( "opts" ).minChars === 0 ) { processRequest( $( this ).val() ); } return true; }).blur(function( e ) { if ( !input.data( "opts" ).usePlaceholder && $( this ).val() === "" && input.data( "values_input" ).val() === "" && input.data( "prefill_value" ) === "" && input.data( "opts" ).minChars > 0 ) { $( this ).val( input.data( "opts" ).startText ); } else if ( input.data( "input_focus" ) ) { $( "li.as-selection-item", input.data( "selections_holder" ) ).addClass( "blur" ).removeClass( "selected" ); input.data( "results_holder" ).hide(); } if ( input.data("interval") ) { clearInterval( input.data("interval") ); } }).keydown(function( e ) { first_focus = false; var active = false; switch( e.keyCode ) { case 38: // up e.preventDefault(); moveSelection( "up" ); break; case 40: // down e.preventDefault(); moveSelection( "down" ); break; case 8: // delete if ( input.val() === "" ) { var last = input.data( "values_input" ).val().split( "," ); last = last[ last.length - 2 ]; input.data( "selections_holder" ).children().not( input.data( "org_li" ).prev() ).removeClass( "selected" ); if ( input.data( "org_li" ).prev().hasClass( "selected" ) ) { input.autoSuggest( "remove_item", last, input.data( "org_li" ).prev(), $( input.data( "org_li" ).prev() ).data( "data" )); } else { input.data( "opts").selectionClick.call( this, input.data( "org_li" ).prev() ); input.data( "org_li" ).prev().addClass( "selected" ); } } if ( input.val().length === 1 ) { input.data( "results_holder" ).hide(); input.data( "prev", ""); } if ( $( ":visible", input.data( "results_holder" ) ).length > 0 ) { if ( input.data( "timeout" ) ) { clearTimeout( input.data( "timeout" ) ); } input.data( "timeout", setTimeout(function() { keyChange(); }, input.data( "opts" ).keyDelay)); } break; case 9: case 188: // tab or comm if ( input.data( "opts" ).canGenerateNewSelections ) { processSelection( e ); } break; case 13: // return active = $( "li.active:first", input.data( "results_holder" ) ); if ( active.length === 0 && input.data( "opts" ).canGenerateNewSelections ) { processSelection( e ); } else { input.data( "tab_press", false ); if ( active.length > 0 ) { active.click(); input.data( "results_holder" ).hide(); } if ( input.data( "opts" ).neverSubmit || active.length > 0 ) { e.preventDefault(); } } break; // ignore if the following keys are pressed: [escape] [shift] [capslock] case 27: // escape case 16: // shift case 20: // capslock input.data( "results_holder" ).hide(); break; } }); }; var processSelection = function( e ) { input.data( "tab_press", true ); var i_input = input.val().replace( /(,)/g, "" ); active = $( "li.active:first", input.data( "results_holder" ) ); i_input = input.data( "opts" ).processNewSelection.call( this, i_input ); // need to escape regex characters before doing a search using them // RegExp from http://80.68.89.23/2006/Jan/20/escape/ var searchVal = i_input.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"); // Generate a new bubble with text when no suggestion selected if ( i_input !== "" && input.data( "values_input" ).val().search( ","+searchVal+"," ) < 0 && i_input.length >= input.data( "opts" ).minChars && active.length === 0 ) { e.preventDefault(); var n_data = {}; n_data[ input.data( "opts" ).selectedItemProp ] = i_input; n_data[ input.data( "opts" ).selectedValuesProp ] = i_input; var lis = $( "li", input.data( "selections_holder" )).length; input.autoSuggest( "add_selected_item", n_data, "00" + ( lis + 1 ) ); input.val( "" ); } }; var keyChange = function() { // Since most IME does not trigger any key events, if we press [del] // and type some chinese character, `lastKeyPressCode` will still be [del]. // This might cause problem so we move the line to key events section; // ignore if the following keys are pressed: [del] [shift] [capslock] // if ( lastKeyPressCode === 46 || (lastKeyPressCode > 8 && lastKeyPressCode < 32) ){ return results_holder.hide(); } var string = input.val().replace( /[\\]+|[\/]+/g,"" ); if (string === input.data( "prev" )) { return; } input.data( "prev" , string ); if ( string.length >= input.data( "opts" ).minChars ) { processRequest(string); } else if ( input.data( "selections_holder" ) && input.data( "results_holder" ) ) { input.data( "selections_holder" ).removeClass( "loading" ); input.data( "results_holder" ).hide(); } }; var processRequest = function( string ) { if ( input.data( "opts" ).beforeRetrieve ) { string = input.data( "opts" ).beforeRetrieve.call( this, string ); } if ( string ) { if ( input.data( "selections_holder" ) ) { input.data( "selections_holder" ).addClass( "loading" ); } d_fetcher( string, processData ); } }; var processData = function( data, query ) { if ( !input.data( "opts" ).matchCase ) { query = query.toLowerCase(); } query = query.replace("(", "\\(", "g").replace(")", "\\)", "g"); var matchCount = 0; input.data( "results_holder" ).html( input.data( "results_ul" ).html( "" ) ).hide(); var d_count = countValidItems( data ); for ( var i = 0; i < d_count; i++ ) { var num = i; input.data( "num_count", input.data( "num_count" ) + 1 ); var forward = false; var str = ""; if ( input.data( "opts" ).searchObjProps === "value" ) { str = data[ num ].value; } else { var names = input.data( "opts" ).searchObjProps.split( "," ); for ( var y = 0; y < names.length; y++ ) { var name = $.trim( names[ y ] ); str = str + data[ num ][ name ] + " "; } } if ( str ) { if ( !input.data( "opts" ).matchCase ) { str = str.toLowerCase(); } if ( str.search(query) != -1 && input.data( "values_input" ).val().search( "," + data[ num ][ input.data( "opts" ).selectedValuesProp ] + "," ) === -1 ) { forward = true; } } if ( forward ) { var formatted = $( "
    • " ).click(function() { var raw_data = $( this ).data( "data" ); var number = raw_data.num; if ( $( "#as-selection-" + number, input.data( "selections_holder" ) ).length <= 0 && !input.data( "tab_press" ) ) { var data = raw_data.attributes; input.val( "" ).focus(); input.data( "prev", ""); input.autoSuggest( "add_selected_item", data, number ); input.data( "opts" ).resultClick.call( this, raw_data ); input.data( "results_holder" ).hide(); } input.data( "tab_press", false ); }).mousedown(function() { input.data( "input_focus", false ); }).mouseover(function() { $( "li", input.data( "results_ul" )).removeClass( "active" ); $( this ).addClass( "active" ); }).data( "data", { attributes: data[ num ], num: input.data( "num_count" ) }); var this_data = $.extend( {}, data[ num ] ); var regx = new RegExp( "(?![^&;]+;)(?!<[^<>]*)(" + query + ")(?![^<>]*>)(?![^&;]+;)", "g" ); if ( !input.data( "opts" ).matchCase ) { regx = new RegExp( "(?![^&;]+;)(?!<[^<>]*)(" + query + ")(?![^<>]*>)(?![^&;]+;)", "gi" ); } if ( input.data( "opts" ).resultsHighlight && query.length > 0 ) { this_data[ input.data( "opts" ).selectedItemProp ] = this_data[ input.data( "opts" ).selectedItemProp ].replace( regx,"$1" ); } if ( !input.data( "opts" ).formatList ) { formatted = formatted.html( this_data[ input.data( "opts" ).selectedItemProp ] ); } else { formatted = input.data( "opts" ).formatList.call( this, this_data, formatted ); } input.data( "results_ul" ).append( formatted ); delete this_data; matchCount++; if ( input.data( "opts" ).retrieveLimit && input.data( "opts" ).retrieveLimit === matchCount ) { break; } } } input.data( "selections_holder" ).removeClass( "loading" ); if ( matchCount <= 0 ) { input.data( "results_ul" ).html( "
    • " + input.data( "opts" ).emptyText + "
    • " ); } input.data( "results_ul" ).css( "width", input.data( "selections_holder" ).outerWidth() ); if ( input.data( "opts" ).scroll ) { input.data( "results_ul" ).css({ "max-height": input.data( "opts" ).scrollHeight, "overflow-y": "scroll" }); } if ( matchCount > 0 || input.data( "opts" ).showResultListWhenNoMatch ) { input.data( "results_holder" ).show(); } else if ( !input.data( "opts" ).showResultListWhenNoMatch ) { input.data( "results_holder" ).hide(); } input.data( "opts" ).resultsComplete.call( this ); }; var moveSelection = function( direction ) { if ( $( ":visible", input.data( "results_holder" ) ).length > 0 ) { var lis = $( "li", input.data( "results_holder" ) ); var start = lis.filter( ":last" ); if ( direction === "down" ) { start = lis.eq( 0 ); } var active = $( "li.active:first", input.data( "results_holder" ) ); if ( active.length > 0 ) { if ( direction === "down" ) { start = active.next(); } else { start = active.prev(); } } lis.removeClass( "active" ); start.addClass( "active" ); start.focus(); // Handle scrolling if ( input.data( "opts" ).scroll && start.length && ( start.position().top + start.height() > input.data( "results_ul" ).height() || start.position().top < 0 ) ) { input.data( "results_ul" ).scrollTop( input.data( "results_ul" ).scrollTop() + ( start.position().top ) ); } } }; setup(); } }); }, add_selected_item: function( data, num ) { return this.each(function( x ) { var input = $( this ); if ( !num ) { num = "00" + ($( "li", input.data( "selections_holder" )).length + 1); } input.data( "values_input" ).val( ( input.data( "values_input" ).val() || "," ) + data[ input.data( "opts" ).selectedValuesProp ] + "," ); input.removeAttr( "placeholder" ); var item = $( "
    • " ).click(function() { input.data( "opts" ).selectionClick.call( this, $( this ) ); input.data( "selections_holder" ).children().removeClass( "selected" ); $( this ).addClass( "selected" ); }).mousedown(function() { input.data( "input_focus", false ); }).data( "data", data ); var close = $( "×" ).click(function() { input.autoSuggest( "remove_item", data[ input.data( "opts" ).selectedValuesProp ], item, data ); input.data( "input_focus", true ); input.focus(); return false; }); input.data( "org_li" ).before( item.html( data[ input.data( "opts" ).selectedItemProp ] ).prepend( close ) ); input.data( "selections" ).push( data ); input.data( "opts" ).selectionAdded.call( this, input.data( "org_li" ).prev(), data[ input.data( "opts" ).selectedValuesProp ] ); return input.data( "org_li" ).prev(); }); }, remove_item: function( text, elt, data ) { return this.each(function( x ) { var input = $( this ); input.data( "values_input" ).val( input.data( "values_input" ).val().replace( "," + text + ",", "," ) ); input.data( "opts" ).selectionRemoved.call( this, $( elt ) ); if ( input.data( "org_li" ).prev().length === 0 && input.data( "opts" ).usePlaceholder ) { input.attr( "placeholder", input.data( "opts" ).startText); } var selections = input.data( "selections" ); selections = $.grep( selections, function( sel, i ) { return sel[ input.data( "opts" ).selectedValuesProp ] !== data[ input.data( "opts" ).selectedValuesProp ]; }); input.data( "selections", selections ); }); }, get_selections: function() { return $( this ).data( "selections" ) || []; } }; $.fn.autoSuggest = function( method ) { if (methods[method]) { return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 )); } else { return methods.init.apply( this, arguments ); } }; })(jQuery); });




      © 2015 - 2025 Weber Informatics LLC | Privacy Policy