﻿/*
* jQuery local autocomplete plugin
*
* Copyright (c) 2009 Trendsales ApS (http://www.trendsales.dk)
*
* This plugin wraps the "Autocomplete - jQuery plugin 1.0.2" by
* Dylan Verheul, Dan G. Switzer, Anjesh Tuladhar, Jörn Zaefferer.
* It provides a convenient interface for autocompleting fields with
* id attributes.
*
* Note that this plugin is dependent on the autocomplete plugin.
*/

(function($) {

    $.fn.localAutocomplete = function(autoCompleteData, options) {

        var defaults = {
            autoCompleteProperty: null,               //Specify the property in the array of autoCompleteData to do the autocompletion. Defaults to this id
            entityIdInputId: null,                    //Should the autocompleter put entityId value into an ID field? Specify the ID of input field here if so.
            entityIdProperty: null,                   //Specify the Id property in the array of autoCompleteData to put in the hidden field. Defaults to value of entityIdInputId.
            autoCompleteInputDefaultValue: "Søg...",  //Used to determine how to replace input field contents, if there is a hidden ID.
            acPropertyMinWordSize: null               //Set this property only if not using Id property to handle cases where the ac result contains a word with length below this value.
        };

        $this = this;
        // Merge defaults with options.
        var options = $.extend(defaults, options);

        // If no autoCompleteProperty has been specified, we will default to the id of this field.
        if (options.autoCompleteProperty == null) {
            options.autoCompleteProperty = this.get(0).id;
        };

        // entityIdProperty defaults to entityIdInputId.
        if (options.entityIdProperty == null) {
            options.entityIdProperty = options.entityIdInputId
        };

        // Function that is typically executed when ac result is chosen by user. Strips all words from
        // the string that has less chars than minWordSize.
        function stripTooShortWords(string, minWordSize) {
            if ( minWordSize != null) {
                wordArray = $(string.split(" ")).filter(function() {
                    if (this.length >= minWordSize) {
                        return this;
                    };
                });
                var newString;
                wordArray.each(function() {
                    newString = [newString, this.toString()].join(" ");
                });
                return $.trim(newString);
            } else {
                return string;
            };
        };
        var autoCompleteInputField = this;
        var autoCompleteIdField = (options.entityIdInputId == null) ? null : $("#" + options.entityIdInputId);

        $.extend(this, {
            // Initialize the autocomplete plugin.
            initializeAutoComplete: function() {
                //Autocomplete the input field with the given autoCompleteProperty.
                autoCompleteInputField.autocomplete(autoCompleteData, {
                    autoFill: false,
                    matchContains: true,
                    formatItem: function(row) { return row[options.autoCompleteProperty]; },
                    formatMatch: function(row) { return row[options.autoCompleteProperty]; },
                    formatResult: function(row) { return stripTooShortWords(row[options.autoCompleteProperty], options.acPropertyMinWordSize); }
                }).result(function(e, item) {
                    //Put the entity ID in the hidden entityIdInputField if one is specified.
                    if (autoCompleteIdField != null) {
                        autoCompleteIdField.val(item[options.entityIdProperty]);
                    };
                });
            },

            AcPropertyFromId: function(validate) {
                hiddenBrand = $(autoCompleteData).filter(function() {
                    return (this[options.entityIdProperty] == autoCompleteIdField.val());
                })[0];
                if (validate) {
                    if ($this.val().search(hiddenBrand[options.autoCompleteProperty]) == -1) {
                        autoCompleteIdField.val("");
                    };
                };
            }
        });

        /* If there is an ID field, check if there is a value in it and no
        value in the autoCompleteField (i.e. the user has clicked the "Back" button or pushed the "Back"
        button on a search page with no results). If there is a value, find the corresponding autoCompleteProperty 
        from the autoCompleteData and put it into the autoComplete input field. 
        
        Takes into account any preexisting values in this field.
        
        Note: May be more efficient (for the client) to use another method for searching the array*/
        if (autoCompleteIdField != null) {
            if ((autoCompleteIdField.val() > 0) & (autoCompleteInputField.val().length > 0)) {
                hiddenBrand = $(autoCompleteData).filter(function() {
                    return (this[options.entityIdProperty] == autoCompleteIdField.val());
                })[0];
                var existingAcTextFieldValue = autoCompleteInputField.val()
                autoCompleteInputField.val(hiddenBrand[options.autoCompleteProperty]);

                if (existingAcTextFieldValue.search(options.autoCompleteInputDefaultValue) > -1) {
                    autoCompleteInputField.val(hiddenBrand[options.autoCompleteProperty]);
                }
                else {
                    autoCompleteInputField.val(hiddenBrand[options.autoCompleteProperty] + " " + existingAcTextFieldValue);
                }
            };
            /* When the User changes the Brand input field, check if there is any text in the field.
            If not, delete any value in the autoCompleteIdField field (so the user is not still searching
            a brand. */
            autoCompleteInputField.keyup(function() {
                if (this.value.length == 0) {
                    autoCompleteIdField.val("");
                };
                if (autoCompleteIdField.val() != 0) {
                    $this.AcPropertyFromId(true);
                };
            });
            autoCompleteInputField.blur(function() {
                if (this.value.length == 0) {
                    autoCompleteIdField.val("");
                };
                if (autoCompleteIdField.val() != 0) {
                    $this.AcPropertyFromId(true);
                };
            });
        };
        this.initializeAutoComplete();
    };
})(jQuery)
