]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - jssource/src_files/include/javascript/quicksearch.js
Release 6.5.0
[Github/sugarcrm.git] / jssource / src_files / include / javascript / quicksearch.js
1 /*********************************************************************************
2  * SugarCRM Community Edition is a customer relationship management program developed by
3  * SugarCRM, Inc. Copyright (C) 2004-2012 SugarCRM Inc.
4  * 
5  * This program is free software; you can redistribute it and/or modify it under
6  * the terms of the GNU Affero General Public License version 3 as published by the
7  * Free Software Foundation with the addition of the following permission added
8  * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
9  * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
10  * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
11  * 
12  * This program is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14  * FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more
15  * details.
16  * 
17  * You should have received a copy of the GNU Affero General Public License along with
18  * this program; if not, see http://www.gnu.org/licenses or write to the Free
19  * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20  * 02110-1301 USA.
21  * 
22  * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
23  * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
24  * 
25  * The interactive user interfaces in modified source and object code versions
26  * of this program must display Appropriate Legal Notices, as required under
27  * Section 5 of the GNU Affero General Public License version 3.
28  * 
29  * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
30  * these Appropriate Legal Notices must retain the display of the "Powered by
31  * SugarCRM" logo. If the display of the logo is not reasonably feasible for
32  * technical reasons, the Appropriate Legal Notices must display the words
33  * "Powered by SugarCRM".
34  ********************************************************************************/
35
36
37
38
39 /**
40  * browse document for quickSearch fields
41  * Compatible ExtJS 1.1.1 and ExtJS 2.0
42  * parameter : noReload - if set to true, enableQS will enable only
43  *             the new sqsEnabled field on the page. If set to false
44  *             it will reload all the sqsEnabled fields.
45  */
46 function enableQS(noReload){
47         YAHOO.util.Event.onDOMReady(function(){
48         //Safety check.  If sqs_objects variable is null, we really can't do anything useful
49         if(typeof sqs_objects == 'undefined') {
50            return;
51         }
52         
53         var Dom = YAHOO.util.Dom;
54         
55         //Get all the fields where sqsEnabled is an attribue, these should be the input text fields for quicksearch
56         var qsFields = Dom.getElementsByClassName('sqsEnabled');
57         
58         //Now loop through all these fields and process them
59         for(var qsField in qsFields){
60                 
61                 //Safety checks to skip processing of invalid entries
62                 if(typeof qsFields[qsField] == 'function' || typeof qsFields[qsField].id == 'undefined') {
63                    continue;
64                 }
65                 
66                 //Create the index we are using to search for the sqs_objects Array
67                 var form_id = qsFields[qsField].form.getAttribute('id');
68                 
69                 //This is a special case where there is an element with id attribute value of "id"
70                 //In this case, we get the real_id attribute (occurs in modules/Import/tpls/step3.tpl only).
71                 if(typeof form_id == 'object' && qsFields[qsField].form.getAttribute('real_id')) {
72                         form_id = qsFields[qsField].form.getAttribute('real_id');
73                 }
74                 var qs_index_id = form_id + '_' + qsFields[qsField].name;
75
76                 //Another safety check, if the sqs_objects entry is not defined, we can't do anything useful
77                 if(typeof sqs_objects[qs_index_id] == 'undefined') {
78                         qs_index_id = qsFields[qsField].name;
79                         if(typeof sqs_objects[qs_index_id] == 'undefined') {
80                                 continue;
81                         }
82                 }
83                 //Track if this field has already been processed.  The way the enableQS function is called
84                 //is a bit problematic in that it lends itself to a lot of duplicate processing
85                 if(QSProcessedFieldsArray[qs_index_id]) {
86                 skipSTR = 'collection_0';
87                 //the 'collection_0' id is not loaded dynamically, so the first item in the collection will not have an incremental value added to the base id
88                 //only skip the additional fields so that cases where a form is closed and reopened without refreshing the screen will still work
89                 if (qs_index_id.lastIndexOf(skipSTR) != (qs_index_id.length - skipSTR.length)){
90                         continue;
91                 }
92                 }                       
93                 
94                 //Store sqs_objects entry as a reference for convenience
95                 var qs_obj = sqs_objects[qs_index_id];
96                 //The loaded variable will be used to check whether or not the quick search field should be created
97             var loaded = false;   
98
99             if (!document.forms[qs_obj.form]) {
100                         continue;
101                 }
102             //Skip quicksearch fields that are readOnly or that are disabled since you can't search on them anyway
103             if (!document.forms[qs_obj.form].elements[qsFields[qsField].id].readOnly && qs_obj['disable'] != true) {
104                 var combo_id = qs_obj.form + '_' + qsFields[qsField].id;
105                 if (Dom.get(combo_id + "_results")) {
106                         loaded = true
107                 }
108                 
109                 // if loaded == false, then we do the heavy lifting to re-create the quicksearch field
110                 if (!loaded) {
111                         QSProcessedFieldsArray[qs_index_id] = true;
112                         
113                         qsFields[qsField].form_id = form_id;
114                     
115                     var sqs = sqs_objects[qs_index_id];    
116                     
117                     //Initialize the result div
118                     var resultDiv = document.createElement('div');
119                     resultDiv.id = combo_id + "_results";
120                     Dom.insertAfter(resultDiv, qsFields[qsField]);
121                     
122                     //Add the module to the fields so we can read it from the response
123                     var fields = qs_obj.field_list.slice();
124                     fields[fields.length] = "module";
125                     
126                     //Create the DataSource for this QS
127                     var ds = new YAHOO.util.DataSource("index.php?", {
128                                         responseType: YAHOO.util.XHRDataSource.TYPE_JSON,
129                         responseSchema: {
130                                 resultsList: 'fields',
131                                     total: 'totalCount', 
132                                     fields: fields,
133                                     metaNode: "fields",
134                                     metaFields: {total: 'totalCount', fields:"fields"}
135                                         },
136                                         connMethodPost: true
137                             });
138                     
139                     // Don't force selection for search fields
140                     var forceSelect = !((qsFields[qsField].form && typeof(qsFields[qsField].form) == 'object' && qsFields[qsField].form.name == 'search_form')
141                                                         || qsFields[qsField].className.match('sqsNoAutofill') !=  null);
142                     
143                     //Finally Declare the Autocomplete
144                     var search = new YAHOO.widget.AutoComplete(qsFields[qsField], resultDiv, ds, {
145                         typeAhead: forceSelect,
146                                 forceSelection : forceSelect,
147                         fields: fields,
148                         sqs : sqs,
149                                                 animSpeed : 0.25,
150                         qs_obj: qs_obj,
151                         inputElement: qsFields[qsField],
152                         //YUI requires the data, even POST, to be URL encoded
153                         generateRequest : function(sQuery) {
154                             //preprocess values
155                             var item_id = this.inputElement.form_id + '_' + this.inputElement.name;
156                             if (QSCallbacksArray[item_id]) {
157                                 QSCallbacksArray[item_id](this.sqs);
158                             }
159                                 var out = SUGAR.util.paramsToUrl({
160                                         to_pdf: 'true',
161                                     module: 'Home',
162                                     action: 'quicksearchQuery',
163                                     data: encodeURIComponent(YAHOO.lang.JSON.stringify(this.sqs)),
164                                     query: sQuery
165                                 });
166                                 return out;
167                             },
168                             //Method to fill in form fields with the returned results. 
169                             //Should be called on select, and must be called from the AC instance scope.
170                             setFields : function (data, filter) {
171                                 this.updateFields(data, filter);        
172                             },
173                             
174                             updateFields: function(data, filter) {
175                                 for(var i in this.fields) {             
176                                         for (var key in this.qs_obj.field_list) {
177                                            //Check that the field exists and matches the filter
178                                            if (this.fields[i] == this.qs_obj.field_list[key] && 
179                                                    document.forms[this.qs_obj.form].elements[this.qs_obj.populate_list[key]] &&
180                                                    this.qs_obj.populate_list[key].match(filter)) {
181                                                    //bug: 30823 - remove the apostrophe
182                                                    var displayValue = data[i].replace(/&amp;/gi,'&').replace(/&lt;/gi,'<').replace(/&gt;/gi,'>').replace(/&#039;/gi,'\'').replace(/&quot;/gi,'"');
183                                                    document.forms[this.qs_obj.form].elements[this.qs_obj.populate_list[key]].value = displayValue;
184                                        SUGAR.util.callOnChangeListers(document.forms[this.qs_obj.form].elements[this.qs_obj.populate_list[key]]);
185                                            }
186                                        }
187                                 }
188                             SUGAR.util.callOnChangeListers(this._elTextbox);
189                             },
190                             clearFields : function() {
191                                 for (var key in this.qs_obj.field_list) {
192                                     if (document.forms[this.qs_obj.form].elements[this.qs_obj.populate_list[key]]){
193                                             document.forms[this.qs_obj.form].elements[this.qs_obj.populate_list[key]].value = "";
194                                     SUGAR.util.callOnChangeListers(document.forms[this.qs_obj.form].elements[this.qs_obj.populate_list[key]]);
195                                     }
196                                 }
197                                                         this.oldValue = "";
198                             }
199                     });
200
201                     //C.L. Bug 36575: In event of account_name quicksearch, check to see if we need to warn user
202                     //that address fields may change.  This code has similarities to code block in set_return method
203                     //of sugar_3.js when building the alert message contents.
204                     if(/^(billing_|shipping_)?account_name$/.exec(qsFields[qsField].name))
205                     {
206                       
207                        //C.L. Bug 36106 only clear the name and id fields
208                        search.clearFields = function() {
209                            for(var i in {name:0, id:1}) {
210                                         for (var key in this.qs_obj.field_list) {
211                                     //Check that the field exists
212                                            if (i == this.qs_obj.field_list[key] &&
213                                                    document.forms[this.qs_obj.form].elements[this.qs_obj.populate_list[key]])
214                                    {
215                                        document.forms[this.qs_obj.form].elements[this.qs_obj.populate_list[key]].value = "";
216                                    }
217                                 }
218                            }
219                        };
220                         
221                        search.setFields = function(data, filter) 
222                        {
223                             var label_str = '';
224                                         var label_data_str = '';
225                                         var current_label_data_str = '';                        
226                                         var label_data_hash = new Array();
227                                 
228                                 for(var i in this.fields) {
229                                         for (var key in this.qs_obj.field_list) {
230                                            //Check that the field exists and matches the filter
231                                            if (this.fields[i] == this.qs_obj.field_list[key] && 
232                                                    document.forms[this.qs_obj.form].elements[this.qs_obj.populate_list[key]] &&
233                                                    document.getElementById(this.qs_obj.populate_list[key]+'_label') &&
234                                                    this.qs_obj.populate_list[key].match(filter)) {
235                                                    
236                                                     var displayValue = data[i].replace(/&amp;/gi,'&').replace(/&lt;/gi,'<').replace(/&gt;/gi,'>').replace(/&#039;/gi,'\'').replace(/&quot;/gi,'"');
237                                         var data_label =  document.getElementById(this.qs_obj.populate_list[key]+'_label').innerHTML.replace(/\n/gi,'').replace(/<\/?[^>]+(>|$)/g, "");
238                                                                         
239                                                                         label_and_data = data_label  + ' ' + displayValue;
240                                                                         
241                                                                         //Append to current_label_data_str only if the label and data are unique
242                                                                         if(document.forms[this.qs_obj.form].elements[this.qs_obj.populate_list[key]] && !label_data_hash[data_label])
243                                                                         {
244                                                                                 label_str += data_label + ' \n';
245                                                                                 label_data_str += label_and_data + '\n';
246                                                                                 label_data_hash[data_label] = true;
247                                                                                 current_label_data_str += data_label + ' ' + document.forms[this.qs_obj.form].elements[this.qs_obj.populate_list[key]].value + '\n';
248                                                                         }                                                                       
249                                            }
250                                        }
251                                 }
252                                 
253                                             if(label_str != current_label_data_str && current_label_data_str != label_data_str) {       
254                                                 
255                                                 module_key = (typeof document.forms[form_id].elements['module'] != 'undefined') ? document.forms[form_id].elements['module'].value : 'app_strings';
256                                                 warning_label = SUGAR.language.translate(module_key, 'NTC_OVERWRITE_ADDRESS_PHONE_CONFIRM') + '\n\n' + label_data_str;                                  
257                                                                                                 
258                                                 if(!confirm(warning_label))
259                                                         {
260                                                         this.updateFields(data,/account_id/); 
261                                                         } else {
262                                                                 
263                                                                 if(Dom.get('shipping_checkbox')) 
264                                                                 {
265                                                                   if(this.inputElement.id == 'shipping_account_name')
266                                                                   {
267                                                                           //If the copy address checkbox is checked, update account and office_phone
268                                                                       filter = Dom.get('shipping_checkbox').checked ? /(account_id|office_phone)/ : filter;
269                                                                   } else if(this.inputElement.id == 'billing_account_name') {
270                                                                           //If the copy address is checked, update account, office phone and billing addresses
271                                                                           filter = Dom.get('shipping_checkbox').checked ? filter : /(account_id|office_phone|billing)/;
272                                                                   }
273                                                                 } else if(Dom.get('alt_checkbox')) {
274                                                                   filter = Dom.get('alt_checkbox').checked ? filter : /^(?!alt)/;
275                                                                 }
276                                                         
277                                                                 this.updateFields(data,filter);
278                                                         }
279                                             } else {
280                                         this.updateFields(data,filter);                                                 
281                                             }
282                        };
283                     }
284                     
285                     
286                     if ( typeof(SUGAR.config.quicksearch_querydelay) != 'undefined' ) {
287                         search.queryDelay = SUGAR.config.quicksearch_querydelay;
288                     }
289                     
290                     //fill in the data fields on selection
291                     search.itemSelectEvent.subscribe(function(e, args){
292                         var data = args[2];
293                         var fields = this.fields;
294                         this.setFields(data, /\S/);
295                         
296                         //Handle special case where post_onblur_function is set    
297                         if (typeof(this.qs_obj['post_onblur_function']) != 'undefined') {
298                             collection_extended = new Array();
299                             for (var i in fields) {
300                                 for (var key in this.qs_obj.field_list) {
301                                     if (fields[i] == this.qs_obj.field_list[key]) {
302                                         collection_extended[this.qs_obj.field_list[key]] = data[i];
303                                     }
304                                 }
305                             }
306                             eval(this.qs_obj['post_onblur_function'] + '(collection_extended, this.qs_obj.id)');
307                         }
308                     });
309                                         
310                                         // We will get the old value firstly when the field lose focus.
311                     search.textboxFocusEvent.subscribe(function(){
312                         this.oldValue = this.getInputEl().value;
313                     });
314                     
315                     //If there is no change for this qucik search field , the value of it will not be cleared.
316                     search.selectionEnforceEvent.subscribe(function(e, args){
317                             if (this.oldValue != args[1]) {
318                                         this.clearFields();
319                             } else {
320                                 this.getInputEl().value = this.oldValue;
321                             }
322                     });
323                                         
324                                         search.dataReturnEvent.subscribe(function(e, args){
325                         //Selected the first returned value if a tab was done before results were returned
326                                                 if (this.getInputEl().value.length == 0 && args[2].length > 0) {
327                                                         var data = [];
328                                                         for(var key in this.qs_obj.field_list) {
329                                                                 data[data.length] = args[2][0][this.qs_obj.field_list[key]];
330                                                         }
331                                                         this.getInputEl().value = data[this.key];
332                                                         this.itemSelectEvent.fire(this, "", data);
333                                                 }
334                     });
335
336                                         search.typeAheadEvent.subscribe(function (e, args) {
337                                                 this.getInputEl().value = this.getInputEl().value.replace(/&amp;/gi,'&').replace(/&lt;/gi,'<').replace(/&gt;/gi,'>').replace(/&#039;/gi,'\'').replace(/&quot;/gi,'"');                  
338                                         });                                     
339                                         
340                     
341                     if (typeof QSFieldsArray[combo_id] == 'undefined' && qsFields[qsField].id) {
342                         QSFieldsArray[combo_id] = search;
343                     }
344                 }
345             }
346         }
347         });        
348 }
349
350 function registerSingleSmartInputListener(input) {
351     if ((c = input.className) && (c.indexOf("sqsEnabled") != -1)) {
352         enableQS(true);
353     }
354 }
355
356 if(typeof QSFieldsArray == 'undefined') {
357    QSFieldsArray = new Array();
358    QSProcessedFieldsArray = new Array();
359    QSCallbacksArray = new Array();
360 }