]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - jssource/src_files/include/javascript/quicksearch.js
Release 6.2.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-2011 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(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                 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                 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                    continue;
87                 }                       
88                 
89                 //Store sqs_objects entry as a reference for convenience
90                 var qs_obj = sqs_objects[qs_index_id];
91                 //The loaded variable will be used to check whether or not the quick search field should be created
92             var loaded = false;   
93
94             if (!document.forms[qs_obj.form]) {
95                         continue;
96                 }
97             //Skip quicksearch fields that are readOnly or that are disabled since you can't search on them anyway
98             if (!document.forms[qs_obj.form].elements[qsFields[qsField].id].readOnly && qs_obj['disable'] != true) {
99                 combo_id = qs_obj.form + '_' + qsFields[qsField].id;
100                 if (Dom.get(combo_id + "_results")) {
101                         loaded = true
102                 }
103                 
104                 // if loaded == false, then we do the heavy lifting to re-create the quicksearch field
105                 if (!loaded) {
106                         QSProcessedFieldsArray[qs_index_id] = true;
107                         
108                         qsFields[qsField].form_id = form_id;
109                     
110                     var sqs = sqs_objects[qs_index_id];    
111                     
112                     //Initialize the result div
113                     var resultDiv = document.createElement('div');
114                     resultDiv.id = combo_id + "_results";
115                     Dom.insertAfter(resultDiv, qsFields[qsField]);
116                     
117                     //Add the module to the fields so we can read it from the response
118                     var fields = qs_obj.field_list.slice();
119                     fields[fields.length] = "module";
120                     
121                     //Create the DataSource for this QS
122                     var ds = new YAHOO.util.DataSource("index.php?", {
123                                         responseType: YAHOO.util.XHRDataSource.TYPE_JSON,
124                         responseSchema: {
125                                 resultsList: 'fields',
126                                     total: 'totalCount', 
127                                     fields: fields,
128                                     metaNode: "fields",
129                                     metaFields: {total: 'totalCount', fields:"fields"}
130                                         },
131                                         connMethodPost: true
132                             });
133                     
134                     // Don't force selection for search fields
135                     var forceSelect = !((qsFields[qsField].form && typeof(qsFields[qsField].form) == 'object' && qsFields[qsField].form.name == 'search_form')
136                                                         || qsFields[qsField].className.match('sqsNoAutofill') !=  null);
137                     
138                     //Finally Declare the Autocomplete
139                     var search = new YAHOO.widget.AutoComplete(qsFields[qsField], resultDiv, ds, {
140                         typeAhead: forceSelect,
141                                 forceSelection : forceSelect,
142                         fields: fields,
143                         sqs : sqs,
144                                                 animSpeed : 0.25,
145                         qs_obj: qs_obj,
146                         inputElement: qsFields[qsField],
147                         //YUI requires the data, even POST, to be URL encoded
148                         generateRequest : function(sQuery) {
149                                 var out = SUGAR.util.paramsToUrl({
150                                         to_pdf: 'true',
151                                     module: 'Home',
152                                     action: 'quicksearchQuery',
153                                     data: encodeURIComponent(YAHOO.lang.JSON.stringify(this.sqs)),
154                                     query: sQuery
155                                 });
156                                 return out;
157                             },
158                             //Method to fill in form fields with the returned results. 
159                             //Should be called on select, and must be called from the AC instance scope.
160                             setFields : function (data, filter) {
161                                 this.updateFields(data, filter);        
162                             },
163                             
164                             updateFields: function(data, filter) {
165                                 for(var i in this.fields) {             
166                                         for (var key in this.qs_obj.field_list) {
167                                            //Check that the field exists and matches the filter
168                                            if (this.fields[i] == this.qs_obj.field_list[key] && 
169                                                    document.forms[this.qs_obj.form].elements[this.qs_obj.populate_list[key]] &&
170                                                    this.qs_obj.populate_list[key].match(filter)) {
171                                                    //bug: 30823 - remove the apostrophe
172                                                    var displayValue = data[i].replace(/&amp;/gi,'&').replace(/&lt;/gi,'<').replace(/&gt;/gi,'>').replace(/&#039;/gi,'\'').replace(/&quot;/gi,'"');
173                                                    document.forms[this.qs_obj.form].elements[this.qs_obj.populate_list[key]].value = displayValue;
174                                            }
175                                        }
176                                 }                                       
177                             },
178                             clearFields : function() {
179                                 for (var key in this.qs_obj.field_list) {
180                                     if (document.forms[this.qs_obj.form].elements[this.qs_obj.populate_list[key]]){
181                                             document.forms[this.qs_obj.form].elements[this.qs_obj.populate_list[key]].value = "";
182                                     }
183                                 }
184                                                         this.oldValue = "";
185                             }
186                     });
187
188                     //C.L. Bug 36575: In event of account_name quicksearch, check to see if we need to warn user
189                     //that address fields may change.  This code has similarities to code block in set_return method
190                     //of sugar_3.js when building the alert message contents.
191                     if(/^(billing_|shipping_)?account_name$/.exec(qsFields[qsField].name))
192                     {
193                       
194                        //C.L. Bug 36106 no-op function for clearFields (do not clear out values)
195                        search.clearFields = function() {};
196                         
197                        search.setFields = function(data, filter) 
198                        {
199                             var label_str = '';
200                                         var label_data_str = '';
201                                         var current_label_data_str = '';                        
202                                         var label_data_hash = new Array();
203                                 
204                                 for(var i in this.fields) {
205                                         for (var key in this.qs_obj.field_list) {
206                                            //Check that the field exists and matches the filter
207                                            if (this.fields[i] == this.qs_obj.field_list[key] && 
208                                                    document.forms[this.qs_obj.form].elements[this.qs_obj.populate_list[key]] &&
209                                                    document.getElementById(this.qs_obj.populate_list[key]+'_label') &&
210                                                    this.qs_obj.populate_list[key].match(filter)) {
211                                                    
212                                                     var displayValue = data[i].replace(/&amp;/gi,'&').replace(/&lt;/gi,'<').replace(/&gt;/gi,'>').replace(/&#039;/gi,'\'').replace(/&quot;/gi,'"');
213                                                                         var data_label =  document.getElementById(this.qs_obj.populate_list[key]+'_label').innerHTML.replace(/\n/gi,'');
214                                                                         
215                                                                         label_and_data = data_label  + ' ' + displayValue;
216                                                                         
217                                                                         //Append to current_label_data_str only if the label and data are unique
218                                                                         if(document.forms[this.qs_obj.form].elements[this.qs_obj.populate_list[key]] && !label_data_hash[data_label])
219                                                                         {
220                                                                                 label_str += data_label + ' \n';
221                                                                                 label_data_str += label_and_data + '\n';
222                                                                                 label_data_hash[data_label] = true;
223                                                                                 current_label_data_str += data_label + ' ' + document.forms[this.qs_obj.form].elements[this.qs_obj.populate_list[key]].value + '\n';
224                                                                         }                                                                       
225                                            }
226                                        }
227                                 }
228                                 
229                                             if(label_str != current_label_data_str && current_label_data_str != label_data_str) {       
230                                                 
231                                                 module_key = (typeof document.forms[form_id].elements['module'] != 'undefined') ? document.forms[form_id].elements['module'].value : 'app_strings';
232                                                 warning_label = SUGAR.language.translate(module_key, 'NTC_OVERWRITE_ADDRESS_PHONE_CONFIRM') + '\n\n' + label_data_str;                                  
233                                                                                                 
234                                                 if(!confirm(warning_label))
235                                                         {
236                                                         this.updateFields(data,/account_id/); 
237                                                         } else {
238                                                                 
239                                                                 if(Dom.get('shipping_checkbox')) 
240                                                                 {
241                                                                   if(this.inputElement.id == 'shipping_account_name')
242                                                                   {
243                                                                           //If the copy address checkbox is checked, update account and office_phone
244                                                                       filter = Dom.get('shipping_checkbox').checked ? /(account_id|office_phone)/ : filter;
245                                                                   } else if(this.inputElement.id == 'billing_account_name') {
246                                                                           //If the copy address is checked, update account, office phone and billing addresses
247                                                                           filter = Dom.get('shipping_checkbox').checked ? filter : /(account_id|office_phone|billing)/;
248                                                                   }
249                                                                 } else if(Dom.get('alt_checkbox')) {
250                                                                   filter = Dom.get('alt_checkbox').checked ? filter : /^(?!alt)/;
251                                                                 }
252                                                         
253                                                                 this.updateFields(data,filter);
254                                                         }
255                                             } else {
256                                         this.updateFields(data,filter);                                                 
257                                             }
258                        };
259                     }
260                     
261                     
262                     if ( typeof(SUGAR.config.quicksearch_querydelay) != 'undefined' ) {
263                         search.queryDelay = SUGAR.config.quicksearch_querydelay;
264                     }
265                     
266                     //fill in the data fields on selection
267                     search.itemSelectEvent.subscribe(function(e, args){
268                         var data = args[2];
269                         var fields = this.fields;
270                         this.setFields(data, /\S/);
271                         
272                         //Handle special case where post_onblur_function is set    
273                         if (typeof(this.qs_obj['post_onblur_function']) != 'undefined') {
274                             collection_extended = new Array();
275                             for (var i in fields) {
276                                 for (var key in this.qs_obj.field_list) {
277                                     if (fields[i] == this.qs_obj.field_list[key]) {
278                                         collection_extended[this.qs_obj.field_list[key]] = data[i];
279                                     }
280                                 }
281                             }
282                             eval(this.qs_obj['post_onblur_function'] + '(collection_extended, this.qs_obj.id)');
283                         }
284                     });
285                                         
286                                         // We will get the old value firstly when the field lose focus.
287                     search.textboxFocusEvent.subscribe(function(){
288                         this.oldValue = this.getInputEl().value;
289                     });
290                     
291                     //If there is no change for this qucik search field , the value of it will not be cleared.
292                     search.selectionEnforceEvent.subscribe(function(e, args){
293                             if (this.oldValue != args[1]) {
294                                         this.clearFields();
295                             } else {
296                                 this.getInputEl().value = this.oldValue;
297                             }
298                     });
299                                         
300                                         search.dataReturnEvent.subscribe(function(e, args){
301                         //Selected the first returned value if a tab was done before results were returned
302                                                 if (this.getInputEl().value.length == 0 && args[2].length > 0) {
303                                                         var data = [];
304                                                         for(var key in this.qs_obj.field_list) {
305                                                                 data[data.length] = args[2][0][this.qs_obj.field_list[key]];
306                                                         }
307                                                         this.getInputEl().value = data[this.key];
308                                                         this.itemSelectEvent.fire(this, "", data);
309                                                 }
310                     });
311
312                                         search.typeAheadEvent.subscribe(function (e, args) {
313                                                 this.getInputEl().value = this.getInputEl().value.replace(/&amp;/gi,'&').replace(/&lt;/gi,'<').replace(/&gt;/gi,'>').replace(/&#039;/gi,'\'').replace(/&quot;/gi,'"');                  
314                                         });                                     
315                                         
316                     
317                     if (typeof QSFieldsArray[combo_id] == 'undefined' && qsFields[qsField].id) {
318                         QSFieldsArray[combo_id] = search;
319                     }
320                 }
321             }
322         }
323         });        
324 }
325
326 function registerSingleSmartInputListener(input) {
327     if ((c = input.className) && (c.indexOf("sqsEnabled") != -1)) {
328         enableQS(true);
329     }
330 }
331
332 if(typeof QSFieldsArray == 'undefined') {
333    QSFieldsArray = new Array();
334    QSProcessedFieldsArray = new Array();
335 }