]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - jssource/src_files/include/SugarFields/Fields/Collection/SugarFieldCollection.js
Release 6.5.0
[Github/sugarcrm.git] / jssource / src_files / include / SugarFields / Fields / Collection / SugarFieldCollection.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 if(typeof(SUGAR.collection) == "undefined") {
38     SUGAR.collection = function(form_name, field_name, module, popupData){
39
40         /*
41          * boolean variable to handle expand/collapse views
42          * false if the collection field is collapsed and true if the rows are expanded.
43          */
44         this.more_status = false;
45         
46         /*
47          * Store the form name containing this field.  Example: EditView
48          */
49         this.form = form_name;
50         
51         /*
52          * Store the name of the collection field. Example: account_name 
53          */
54         this.field = field_name;
55         
56         
57         /*
58          * Store the unique form + field name that uses the combination of form and field
59          */
60         this.field_element_name = this.form + '_' + this.field;
61         
62         /*
63          * Store the name of the module from where come the field. Example: Accounts 
64          */
65         this.module = module;
66         
67         /*
68          * Number of secondaries linked records (total of linked records - 1). 
69          */
70         this.fields_count = 0;
71         
72         /*
73          * Number of extra fields. 
74          */
75         this.extra_fields_count = 0;
76         
77         /*
78          * Set to true if it is the initialization. 
79          */
80         this.first = true;
81         
82         /*
83          * Name of the primary field. Example: "accounts_collection_0" 
84          */
85         this.primary_field = "";
86         
87         /*
88          * Store the row cloned in key "0" and the context cloned in key "1". 
89          */
90         this.cloneField = new Array();
91         
92         /*
93          * Store the sqs_objects for the cloned row encoded in JSON. 
94          */
95         this.sqs_clone = "";
96         
97         /*
98          * Store the name and the id of all the secondaries linked records. this is used to create the secondary rows. 
99          */
100         this.secondaries_values = new Array();
101         
102         /*
103          * Store all the extra fields which has been updated in the collection field to save on save of the main record. 
104          */
105         this.update_fields = new Object();
106         
107         /*
108          * boolean variable indicating whether or not to show the expand/collapse arrow
109          */
110         this.show_more_image = true;
111
112     };
113     
114     SUGAR.collection.prototype = {
115         /*
116          * Remove the row designated by the passed 'id' or clear the row if there is only one row. 
117          */
118         remove: function(num){
119             // if there is only one record, clear it instead of removing it
120             // this is determined by the visibility of the drop down arrow element
121             var radio_els = this.get_radios();
122             var div_el;
123             if(radio_els.length == 1) {
124                 div_el = document.getElementById(this.field_element_name + '_input_div_' + num);
125                 var input_els = div_el.getElementsByTagName('input');
126                 //Clear text field
127                 input_els[0].value = '';
128                 
129                 //Clear hidden field
130                 input_els[1].value = '';
131                 
132                 if(this.primary_field) {
133                    div_el = document.getElementById(this.field_element_name + '_radio_div_' + num);
134                    radio_els = div_el.getElementsByTagName('input');
135                    //Clear the radio field
136                    radio_els[0].checked = false;
137                 }
138             } else {    
139                 div_el = document.getElementById(this.field_element_name + '_input_div_' + num);
140                 if (!div_el)
141                     div_el = document.getElementById(this.field_element_name + '_radio_div_' + num);
142                 var tr_to_remove = document.getElementById('lineFields_' + this.field_element_name + '_' + num);
143                 div_el.parentNode.parentNode.parentNode.removeChild(tr_to_remove);
144                 
145                 var div_id = 'lineFields_' + this.field_element_name + '_' + num;
146                 if (typeof sqs_objects[div_id.replace("_field_", "_")] != 'undefined') {
147                     delete (sqs_objects[div_id.replace("_field_", "_")]);
148                 }
149                 var checked=false;
150                 for(var k=0; k< radio_els.length; k++){
151                     if(radio_els[k].checked){
152                         checked=true;
153                     }
154                 }
155                 // If we remove an entry marked as the primary, set another record as the primary 
156                 var primary_checked = document.forms[this.form].elements[this.field+"_allowed_to_check"];
157                 var allowed_to_check = true;
158                 if(primary_checked && primary_checked.value == 'false'){
159                         allowed_to_check = false;
160                 }
161                 if(/EditView/.test(this.form) && !checked && typeof radio_els[0] != 'undefined' && allowed_to_check) {
162                     radio_els[0].checked = true;
163                     this.changePrimary(true);
164                     this.js_more();
165                     this.js_more();
166                 }
167                 // if there is now only one record, hide the "more..." link
168                 if(radio_els.length == 1){
169                     this.more_status = false;
170                                         if (document.getElementById('more_'+this.field_element_name) && document.getElementById('more_'+this.field_element_name).style.display != 'none') {
171                             document.getElementById('more_'+this.field_element_name).style.display='none';                      
172                                         }
173
174                     this.show_arrow_label(false);
175                     this.js_more();
176                 }else{
177                         this.js_more();
178                     this.js_more();
179                 }
180             }
181         },
182         
183         get_radios: function() {
184                 return YAHOO.util.Selector.query('input[name^=primary]', document.getElementById(this.field_element_name+'_table'));
185         },
186         
187         /*
188          * Add a new empty row.
189          */
190         add: function(values){
191             this.fields_count++;
192             var Field0 = this.init_clone(values);
193             this.cloneField[1].appendChild(Field0);
194             //Enable quicksearch for this field
195             enableQS(true);
196             this.changePrimary(false);
197                       
198             //If the arrow field and label are collapsed, un-collapse it
199             if(document.getElementById('more_'+this.field_element_name) && document.getElementById('more_'+this.field_element_name).style.display == 'none'){
200                document.getElementById('more_'+this.field_element_name).style.display='';
201             }
202             
203             if(!this.is_expanded()) {
204                this.js_more();
205                this.show_arrow_label(true);
206             }
207         },
208         
209         /*
210          * Add the secondaries rows on load of the page.
211          */
212         add_secondaries: function(){
213             var clone_id = this.form + '_' + this.field + '_collection_0';
214             YAHOO.util.Event.onContentReady(clone_id, function(c){
215                 c.create_clone();
216                 enableQS();
217                 c.changePrimary(true);
218                 for(key in c.secondaries_values){
219                     if (isInteger(key)) {
220                         c.add(c.secondaries_values[key]);
221                     }
222                 }
223                 c.js_more();
224                 // Update the "hash" of the unchanged form, because this is just adding data, not actually changing anything
225                 initEditView(document.forms[c.form]);
226             }, this);
227         },
228         /*
229          * Create the new row from a cloned row. 
230          */
231         init_clone: function(values){
232                 
233                 //Safety check, this means that the clone field was not created yet
234                 if(typeof this.cloneField[0] == 'undefined') {
235                    return;
236                 }
237                 
238             if (typeof values == "undefined") {
239                 values = new Array();
240                 values['name'] = "";
241                 values['id'] = "";
242             }
243             
244             var count = this.fields_count;
245             
246             //Clone the table element containing the fields for each row, use safe_clone uder IE to prevent events from being cloned
247             var Field0 = SUGAR.isIE ? 
248                 SUGAR.collection.safe_clone(this.cloneField[0], true) : 
249                 this.cloneField[0].cloneNode(true);
250
251             Field0.id = "lineFields_"+this.field_element_name+"_"+count;
252                         
253             for ( var ii = 0; ii < Field0.childNodes.length; ii++ ){
254                 if(typeof(Field0.childNodes[ii].tagName) != 'undefined' && Field0.childNodes[ii].tagName == "TD") {             
255                     for (var jj = 0; jj < Field0.childNodes[ii].childNodes.length; jj++) {
256                         currentNode = Field0.childNodes[ii].childNodes[jj];
257                         this.process_node(Field0.childNodes[ii], currentNode, values);
258                     } //for
259                 } //if
260             } //for
261             return Field0;
262         },
263         /**
264          * process_node
265          * 
266          * method to process cloning of nodes, moved out of init_clone so that
267          * this may be recursively called
268          */
269         process_node: function(parentNode, currentNode, values) {
270             if(parentNode.className == 'td_extra_field'){
271                 // If this is an extra field
272                 if(parentNode.id){
273                     parentNode.id='';
274                 }
275                 var toreplace = this.field + "_collection_extra_0";
276                 var re = new RegExp(toreplace, 'g');
277                 parentNode.innerHTML = parentNode.innerHTML.replace(re, this.field + "_collection_extra_" + this.fields_count);
278             } else if (currentNode.tagName && currentNode.tagName == 'SPAN') { 
279                 //If it is our div element, recursively find all input elements to process
280                 currentNode.id = /_input/.test(currentNode.id) ? this.field_element_name + '_input_div_' + this.fields_count :  this.field_element_name + '_radio_div_' + this.fields_count;            
281                                 if (/_input/.test(currentNode.id)) {
282                                         currentNode.name = 'teamset_div';
283                                 }
284                 
285                 var input_els = currentNode.getElementsByTagName('input');
286                 for ( var x = 0; x < input_els.length; x++ ){
287
288                     //if the input tag id is blank (IE bug), then set it equal to that of the parent span id
289                     if(typeof(input_els[x].id) == 'undefined' || input_els[x].id == '') {
290                         input_els[x].id = currentNode.id;
291                     }
292
293                         if(input_els[x].tagName && input_els[x].tagName == 'INPUT') {
294                            this.process_node(parentNode, input_els[x], values);
295                         }
296                 }
297             } else if (currentNode.name) {
298                 // If this is a standard field
299                 var toreplace = this.field + "_collection_0";
300                 var re = new RegExp(toreplace, 'g');
301                 var name = currentNode.name;                
302                 var new_name = name.replace(re, this.field + "_collection_" + this.fields_count);
303                 var new_id = currentNode.id.replace(re, this.field + "_collection_" + this.fields_count);
304
305                 switch (name) {
306                     case toreplace:
307                         var sqs_id = this.form + '_' + new_name;
308                         if (typeof this.sqs_clone != 'undefined') {
309                                 var sqs_clone = YAHOO.lang.JSON.stringify(this.sqs_clone);
310                             eval('sqs_objects[sqs_id]=' + sqs_clone);
311                             
312                             for (var pop_field in sqs_objects[sqs_id]['populate_list']) {
313                                 if (typeof sqs_objects[sqs_id]['populate_list'][pop_field] == 'string') {
314                                     sqs_objects[sqs_id]['populate_list'][pop_field] = sqs_objects[sqs_id]['populate_list'][pop_field].replace(RegExp('_0', 'g'), "_" + this.fields_count);
315                                 }
316                             }
317                             for (var req_field in sqs_objects[sqs_id]['required_list']) {
318                                 if (typeof sqs_objects[sqs_id]['required_list'][req_field] == 'string') {
319                                     sqs_objects[sqs_id]['required_list'][req_field] = sqs_objects[sqs_id]['required_list'][req_field].replace(RegExp('_0', 'g'), "_" + this.fields_count);
320                                 }
321                             }
322                         }
323                         
324                         currentNode.name = new_name;
325                         currentNode.id = new_id;
326                         currentNode.value = values['name'];
327                         break;
328                     case "id_" + toreplace:
329                         currentNode.name = new_name.replace(RegExp('_0', 'g'), "_" + this.fields_count);
330                         currentNode.id = new_id.replace(RegExp('_0', 'g'), "_" + this.fields_count);
331                         currentNode.value = values['id'];
332                         break;
333                     case "btn_" + toreplace:
334                         currentNode.name = new_name;
335                         currentNode.attributes['onclick'].value = currentNode.attributes['onclick'].value.replace(re, this.field + "_collection_" + this.fields_count);
336                         currentNode.attributes['onclick'].value = currentNode.attributes['onclick'].value.replace(RegExp(this.field + "_collection_extra_0", 'g'), this.field + "_collection_extra_" + this.fields_count);
337                         break;
338                     case "allow_new_value_" + toreplace:
339                         currentNode.name = new_name;
340                         currentNode.id = new_id;
341                         break;
342                     case "remove_" + toreplace:
343                         currentNode.name = new_name;
344                         currentNode.id = new_id;
345                         currentNode.setAttribute('collection_id', this.field_element_name);
346                         currentNode.setAttribute('remove_id', this.fields_count);
347                         currentNode.onclick = function() { 
348                                collection[this.getAttribute('collection_id')].remove(this.getAttribute('remove_id'));
349                         };
350                         break;
351                     case "primary_" + this.field + "_collection":
352                         currentNode.id = new_id;
353                         currentNode.value = this.fields_count;
354                         currentNode.checked = false; //Firefox
355                         currentNode.setAttribute('defaultChecked', '');
356                         break;
357                     default:
358                         alert(toreplace + '|' + currentNode.name + '|' + name + '|' + new_name);
359                         break;
360                 } //switch
361             } //if-else
362                 
363         },
364         
365         /*
366          * Collapse or expand the rows to show for the editview(depending of the this.more_status attribute).
367          */
368         js_more: function(val){
369             if(this.show_more_image){
370                     var more_ = document.getElementById('more_img_'+this.field_element_name);
371                     var arrow = document.getElementById('arrow_'+this.field);
372                     var radios = this.get_radios();
373                     // if we want to collapse
374                     if(this.more_status == false){
375                         more_.src = "index.php?entryPoint=getImage&themeName="+SUGAR.themes.theme_name+"&imageName=advanced_search.gif";
376                         this.more_status = true;
377                         // show the primary only and hidde the other one.
378                         var hidden_count = 0;
379                         for(var k=0; k< radios.length; k++){
380                             if (radios[k].type && radios[k].type == 'radio') {
381                                 if (radios[k].checked) {
382                                     radios[k].parentNode.parentNode.parentNode.style.display = '';
383                                 } else {
384                                     radios[k].parentNode.parentNode.parentNode.style.display = 'none';
385                                     hidden_count++;
386                                 }
387                             }
388                         }
389                         //rrs - add code to not remove the first field if non if the fields are selected as primary
390                         if(hidden_count == radios.length){
391                                 radios[0].parentNode.parentNode.parentNode.style.display = '';
392                         }
393                         
394                         arrow.value = 'hide';
395                     }else{
396                         more_.src = "index.php?entryPoint=getImage&themeName="+SUGAR.themes.theme_name+"&imageName=basic_search.gif";
397                         this.more_status=false;
398                         // display all the records
399                         for(var k=0; k< radios.length; k++){
400                             if(isInteger(k)){
401                                 radios[k].parentNode.parentNode.parentNode.style.display='';
402                             }
403                         }
404
405                         arrow.value = 'show';
406                     }
407
408                     var more_div = document.getElementById('more_div_'+this.field_element_name);
409                     if(more_div) {
410                       more_div.innerHTML = arrow.value == 'show' ? SUGAR.language.get('app_strings','LBL_HIDE') : SUGAR.language.get('app_strings','LBL_SHOW');
411                     }
412                     
413                 }
414         },
415         /*
416          * Create the clone on load of the page and store it in this.cloneField
417          */
418         create_clone: function() {
419             var oneField = document.getElementById('lineFields_'+this.field_element_name+'_0');
420             this.cloneField[0] = SUGAR.isIE ?
421                 SUGAR.collection.safe_clone(oneField, true) :
422                 oneField.cloneNode(true);
423             this.cloneField[1] = oneField.parentNode;
424             //fixing bug @48829: Team field shows fully expanded multiple teams instead of hiding multiple teams
425             //this.more_status = true;
426             var clone_id = this.form + '_' + this.field + '_collection_0';
427
428             if (typeof sqs_objects != 'undefined' && typeof sqs_objects[clone_id] != 'undefined') {
429                 var clone = YAHOO.lang.JSON.stringify(sqs_objects[clone_id]);
430                 eval('this.sqs_clone=' + clone);
431             }
432         },
433         /**
434          * Validates team set to check if the primary team id has been set or not
435          */
436                 validateTemSet : function(formname, fieldname) {
437                         var table_element_id = formname + '_' + fieldname + '_table';
438                         if(document.getElementById(table_element_id)) {
439                            var input_elements = YAHOO.util.Selector.query('input[type=radio]', document.getElementById(table_element_id));
440                            var has_primary = false;
441                            var primary_field_id = fieldname + '_collection_0';
442                            for(t in input_elements) {
443                                     primary_field_id = fieldname + '_collection_' + input_elements[t].value;
444                                 if(input_elements[t].type && input_elements[t].type == 'radio' && input_elements[t].checked == true) {
445                                    if(document.forms[formname].elements[primary_field_id].value != '') {
446                                           has_primary = true;
447                                    }
448                                    break;
449                                 }                                                                  
450                            }       
451                            if(!has_primary) {
452                                         return false;
453                            }
454                            return true;
455                         }
456                         return true;
457                 }, 
458         /**
459          * return an array of teamids for a team field
460          */
461                 getTeamIdsfromUI: function(formname, fieldname) {
462                         var team_ids = new Array();
463                         var table_element_id = formname + '_' + fieldname + '_table';
464                         if(document.getElementById(table_element_id)) {
465                            input_elements = YAHOO.util.Selector.query('input[type=hidden]', document.getElementById(table_element_id));
466                            for(t = 0; t < input_elements.length; t++) {
467                              if (input_elements[t].id.match( fieldname + "_collection_") != null) {
468                                 team_ids.push(input_elements[t].value);
469                              } // if
470                            } // for                
471                         } // if
472                     return team_ids;
473                 },
474         /**
475          * return a primary team id
476          */
477                 getPrimaryTeamidsFromUI: function(formname, fieldname) {
478                         var table_element_id = formname + '_' + fieldname + '_table';
479                         if(document.getElementById(table_element_id)) {
480                                 var input_elements = YAHOO.util.Selector.query('input[type=radio]', document.getElementById(table_element_id));
481                                 for(t in input_elements) {
482                                         var primary_field_id = 'id_' + document.forms[formname][fieldname].name + '_collection_' + input_elements[t].value;
483                                         if(input_elements[t].type && input_elements[t].type == 'radio' && input_elements[t].checked == true) {
484                                            if(document.forms[formname].elements[primary_field_id].value != '') {
485                                                    return document.forms[formname].elements[primary_field_id].value;
486                                            } // if
487                                         } // if
488                                 } // for
489                         } // if
490                         return '';      
491                 },
492         /*
493          * Change the primary row onchange of the radio button.
494          */
495         changePrimary: function(noAdd){
496             var old_primary = this.primary_field;
497             var radios=this.get_radios();
498             for (var k = 0; k < radios.length; k++) {
499                 var qs_id = radios[k].id.replace('primary_','');
500                 if (radios[k].checked) {
501                     this.primary_field = qs_id;
502                 } else {
503                         qs_id = qs_id + '_' + k;
504                 }
505
506                 qs_id = this.form + '_' + qs_id;
507
508                 if(typeof sqs_objects != 'undefined' && typeof sqs_objects[qs_id] != 'undefined' && sqs_objects[qs_id]['primary_field_list']){
509                     for (var ii = 0; ii < sqs_objects[qs_id]['primary_field_list'].length; ii++) {
510                         if (radios[k].checked && qs_id != old_primary) {
511                             sqs_objects[qs_id]['field_list'].push(sqs_objects[qs_id]['primary_field_list'][ii]);
512                             sqs_objects[qs_id]['populate_list'].push(sqs_objects[qs_id]['primary_populate_list'][ii]);
513                         }else if(old_primary == qs_id && !radios[k].checked){
514                             sqs_objects[qs_id]['field_list'].pop();
515                             sqs_objects[qs_id]['populate_list'].pop();
516                         }
517                     }
518                 }
519             }
520             
521             if (noAdd) {
522                 enableQS(false);
523             }
524             this.first = false;
525         },
526         /*
527          * Collapse or expand the rows to show for the detailview. 
528          */
529         js_more_detail: function(id){
530             var more_img = document.getElementById('more_img_'+id);
531             if(more_img.style.display == 'inline'){
532                 more_img.src = "index.php?entryPoint=getImage&themeName="+SUGAR.themes.theme_name+"&imageName=advanced_search.gif";
533             }else{
534                 more_img.src = "index.php?entryPoint=getImage&themeName="+SUGAR.themes.theme_name+"&imageName=basic_search.gif";
535             }
536         },
537         /*
538          * Replace the first field with the specified values
539          */
540         replace_first: function(values){
541                 for (var i = 0; i <= this.fields_count; i++) {
542                         var div_el = document.getElementById(this.field_element_name + '_input_div_' + i);
543                 if(div_el) { 
544                                 var name_field = document.getElementById(this.field_element_name+"_collection_" + i);
545                                         var id_field = document.getElementById("id_"+this.field_element_name+"_collection_" + i);
546                                 name_field.value = values['name'];
547                                 id_field.value = values['id'];
548                                 break;
549                 }
550                 }
551         },
552         /*
553          * Remove all empty fields from the widget.
554          */
555         clean_up: function(){
556             //clean up any rows that have been added but do not contain any data
557             var divsToClean = new Array();
558             var isFirstFieldEmpty = false;
559             var divCount = 0;
560             for (var i = 0; i <= this.fields_count; i++) {
561                 var div_el = document.getElementById(this.field_element_name + '_input_div_' + i);
562                 if(div_el) {        
563                         input_els = div_el.getElementsByTagName('input');
564                         for ( var x = 0; x < input_els.length; x++ ){
565                                 if(input_els[x].id && input_els[x].name == (this.field + '_collection_' + i) && trim(input_els[x].value) == '') {
566                                         if(divCount == 0){
567                                                 isFirstFieldEmpty = true;
568                                         } else {
569                                                 divsToClean.push(i);
570                                         }
571                                 }
572                                 
573                         }
574                         divCount++;
575                 }
576             }
577
578             for(var j = 0; j < divsToClean.length; j++){
579                 this.remove(divsToClean[j]);
580             }
581             return isFirstFieldEmpty;
582         },
583         
584         show_arrow_label: function(show) {
585             var more_div = document.getElementById('more_div_'+this.field_element_name);
586             if(more_div) {
587                more_div.style.display = show ? '' : 'none';
588             }           
589         },
590         
591         /**
592          * is_expanded
593          * helper function to determine whether or not the widget is expanded (all teams are shown)
594          */
595         is_expanded: function() {
596             var more_div = document.getElementById('more_div_'+this.field_element_name);
597             if(more_div) {
598                return more_div.style.display == '';
599             }
600             return false;
601         }
602     };
603
604         SUGAR.collection.safe_clone = function(e, recursive)
605         {
606                 if (e.nodeName == "#text")
607                 {
608                         return document.createTextNode(e.data);
609                 }
610                 if(!e.tagName) return false;
611                 
612                 var newNode = document.createElement(e.tagName);
613                 if (!newNode) return false;
614
615         var properties = [ 'id', 'class', 'style', 'name', 'type', 'valign', 'border', 'width', 'height', 'top', 'bottom', 'left', 'right', 'scope', 'row', 'columns', 'src', 'href', 'className', 'align', 'nowrap'];
616
617         //clee. - Bug: 44976 - IE7 just does not calculate height properties correctly for input elements
618         if(SUGAR.isIE7 && e.tagName.toLowerCase() == 'input')
619         {
620             var properties = [ 'id', 'class', 'style', 'name', 'type', 'valign', 'border', 'width', 'top', 'bottom', 'left', 'right', 'scope', 'row', 'columns', 'src', 'href', 'className', 'align', 'nowrap'];
621         }
622                 
623                 for (var i in properties)
624                 {
625                         if (e[properties[i]])
626                         {
627                 //There are two groups of conditional checks here:
628                 //The first group is to ignore the style and type attributes for IE browsers
629                 //The second group is to ensure that only <a> and <iframe> tags have href attribute
630                 if ((properties[i] != 'style' || !SUGAR.isIE) &&
631                     //Only <a> and <iframe> tags can have hrefs
632                     (properties[i] != 'href'  || e.tagName == 'a' || e.tagName == 'iframe')) {
633                         if(properties[i] == "type") {
634                             newNode.setAttribute(properties[i], e[properties[i]]);
635                         } else {
636                             newNode[properties[i]] = e[properties[i]];
637                         }
638                 }
639                         }
640                 }
641                 if(recursive)
642                 {
643                         for (var i in e.childNodes)
644                         {
645                                 if(e.childNodes[i].nodeName && (!e.className || e.className != "yui-ac-container"))
646                                 {
647                                         var child = SUGAR.collection.safe_clone(e.childNodes[i], true);
648                                         if (child) newNode.appendChild(child);
649                                 }
650                         }
651                 }
652                 return newNode;
653         }
654 }