Fixed dynamic style loading for Safari
[ajatus.git] / js / ajatus.document.js
blob536d7a61b7de67ed0ed28fe6c23be960450e36ea
1 /*
2  * This file is part of
3  *
4  * Ajatus - Distributed CRM
5  * @requires jQuery v1.2.1
6  * 
7  * Copyright (c) 2007 Jerry Jalava <jerry.jalava@gmail.com>
8  * Copyright (c) 2007 Nemein Oy <http://nemein.com>
9  * Website: http://ajatus.info
10  * Licensed under the GPL license
11  * http://www.gnu.org/licenses/gpl.html
12  * 
13  */
15 (function($){
17     $.ajatus.document = function(doc, check_metadata, check_schema) {
18         if (typeof check_metadata == 'undefined') {
19             var check_metadata = true;
20         }
21         if (typeof check_schema == 'undefined') {
22             var check_schema = false;
23         }
24         
25         // console.log("Check schema: "+check_schema);
26         // console.log("Check metadata: "+check_metadata);
27                 
28         var self = this;
29         this.ready_doc = {};
30         
31         $.each(doc, function(i,n){
32             if (   (i == '_id' && n != '')
33                 || i == 'id' && n != '')
34             {
35                 self.ready_doc['_id'] = n;
36             } else if (i == '_rev' && n != '') {
37                 self.ready_doc[i] = n;
38             } else if (i == 'key' && n != '') {
39                 self.ready_doc[i] = n;
40             } else if (i == 'value' && n != '') {
41                 self.ready_doc[i] = n;
42             }
43         });
44         
45         if (typeof this.ready_doc['value'] == 'undefined') {
46             $.ajatus.debug("Error: Document didn't have value field defined!", "ajatus.document");            
47             return this.ready_doc;
48         }
49         
50         if (check_metadata) {
51             if (! this.ready_doc.value.metadata) {
52                 this.add_metadata();
53             } else {
54                 this.check_metadata();
55             }
56         }
58         if (! $.ajatus.preferences.client.content_types[this.ready_doc.value._type]) {
59             this.ready_doc.value._type = 'note';
60         }
62         if (check_schema) {
63             this.check_schema();
64         }
65         
66         this.prepare_doc_title();
67         
68         return this.ready_doc;
69     }
70     $.extend($.ajatus.document.prototype, {
71         check_schema: function() {
72             var self = this;
73             var type = $.ajatus.preferences.client.content_types[this.ready_doc.value._type];
74             var changed = false;
75             var new_schema_parts = {};
77             $.each(type.original_schema, function(k,si){
78                 // console.log("self.ready_doc.value.metadata["+k+"]:"+self.ready_doc.value.metadata[k])
79                 if (typeof(self.ready_doc.value[k]) == 'undefined') {
80                     def_val = '';
81                     if (typeof si['def_val'] != 'undefined') {
82                         def_val = si['def_val'];
83                     }
84                     new_schema_parts[k] = {
85                         val: def_val,
86                         widget: si.widget
87                     };
88                     changed = true;
89                 } else {
90                     def_val = self.ready_doc.value[k].val || '';
91                     if (typeof si['def_val'] != 'undefined') {
92                         def_val = si['def_val'];
93                     }                    
94                     self.ready_doc.value[k] = $.extend({
95                         val: def_val,
96                         widget: si.widget                        
97                     }, self.ready_doc.value[k]);
98                 }
99             });
100             
101             if (changed) {
102                 // console.log("Found schema parts that need to be updated:");
103                 // console.log(new_schema_parts);
104                 self._fix_doc_schema(new_schema_parts);
105             }            
106         },
107         _fix_doc_schema: function(new_parts) {
108             // console.log("FIX SCHEMA:");
109             // console.log(new_parts);
110             var _self = this;
112             doc = _self.ready_doc;//new $.ajatus.document.loader(_self.ready_doc._id, _self.ready_doc._rev, false, false);
113             doc.value = $.extend(doc.value, new_parts);
114             
115             var db_path = $.ajatus.preferences.client.content_database;
116             
117             $.jqCouch.connection('doc').save(db_path, doc);
118             _self.ready_doc = doc;//new $.ajatus.document(doc);
119         },
120         add_metadata: function() {
121             var self = this;
122             this.ready_doc.value.metadata = {};
123             $.each($.ajatus.document.metadata, function(k,m){
124                 self.ready_doc.value.metadata[k] = {
125                     val: '',
126                     widget: m.widget
127                 };
128             });
129         },
130         check_metadata: function() {
131             // console.log("check metadata");
132             var self = this;
133             var changed = false;
134             var new_md_parts = {};
135             $.each($.ajatus.document.metadata, function(k,m){
136                 // console.log("self.ready_doc.value.metadata["+k+"]:"+self.ready_doc.value.metadata[k])
137                 if (typeof(self.ready_doc.value.metadata[k]) == 'undefined') {
138                     def_val = '';
139                     if (typeof m['def_val'] != 'undefined') {
140                         def_val = m['def_val'];
141                     }
142                     new_md_parts[k] = {
143                         val: def_val,
144                         widget: m.widget
145                     };
146                     changed = true;
147                 } else {
148                     def_val = self.ready_doc.value.metadata[k].val || '';
149                     if (typeof m['def_val'] != 'undefined') {
150                         def_val = m['def_val'];
151                     }                    
152                     self.ready_doc.value.metadata[k] = $.extend({
153                         val: def_val,
154                         widget: m.widget                        
155                     }, self.ready_doc.value.metadata[k]);
156                 }
157             });
158             
159             if (changed) {
160                 self._fix_metadata(new_md_parts);
161             }
162         },
163         _fix_metadata: function(new_metadata) {
164             var _self = this;
165             
166             // console.log("_fix_metadata for: "+_self.ready_doc._id);
167             // console.log(new_metadata);
168             
169             doc = new $.ajatus.document.loader(_self.ready_doc._id, _self.ready_doc._rev, false);
171             // console.log("Before:");
172             // console.log(doc.value.metadata);
173             
174             doc.value.metadata = $.extend({}, doc.value.metadata, new_metadata);
175             
176             // console.log("After:");
177             // console.log(doc.value.metadata);
178             
179             var db_path = $.ajatus.preferences.client.content_database;
180             
181             $.jqCouch.connection('doc').save(db_path, doc);
182             _self.ready_doc = new $.ajatus.document(doc);
183         },
184         prepare_doc_title: function() {
185             var self = this;
187             if ($.ajatus.preferences.client.content_types[this.ready_doc.value._type]['title_item']) {
188                 $.ajatus.preferences.client.content_types[this.ready_doc.value._type].schema['title'] = {
189                     label: 'Title',
190                     widget: {
191                         name: 'text',
192                         config: {}
193                     },
194                     hidden: true
195                 };
197                 var title_val = '';
198                 $.each($.ajatus.preferences.client.content_types[this.ready_doc.value._type]['title_item'], function(i,part){
199                     if (self.ready_doc.value[part]) {
200                         var widget = new $.ajatus.widget(self.ready_doc.value[part].widget.name, self.ready_doc.value[part].widget.config);
201                         var val = widget.value_on_view(self.ready_doc.value[part].val, 'plain');
202                         if (typeof val != 'string') {
203                             val = self.ready_doc.value[part].val;
204                         }
205                         title_val += val;
206                     } else {
207                         title_val += $.ajatus.i10n.get(part);
208                     }
209                 });
211                 this.ready_doc.value['title'] = {
212                     val: title_val,
213                     widget: $.ajatus.preferences.client.content_types[this.ready_doc.value._type].schema['title'].widget
214                 };
215             }
216         }
217     });
218     $.ajatus.document.loader = function(id, rev, check_metadata) {
219         if (typeof check_metadata == 'undefined') {
220             var check_metadata = true;            
221         }
222         
223         var args = {};
224         if (   typeof rev != 'undefined'
225             && rev != '')
226         {
227             args['rev'] = rev;
228         }
229         
230         return new $.ajatus.document(
231             $.jqCouch.connection('doc').get($.ajatus.preferences.client.content_database + '/' + id, args),
232             check_metadata,
233             true
234         );
235     };
236     $.ajatus.document.revisions = {
237         get: function(doc) {
238             // console.log("get_revisions for "+doc._id);
239             if (typeof doc._revs_info == 'undefined') {
240                 doc = $.jqCouch.connection('doc').get($.ajatus.preferences.client.content_database + '/' + doc._id, {
241                     _rev: doc._rev,
242                     revs_info: true
243                 });
244             }
246             var available_revs = [];
247             var active_rev_status = false;
248             $.each(doc._revs_info, function(i,n){
249                 if (n.rev == doc._rev) {
250                     active_rev_status = n.status;
251                 } else {
252                     if (n.status == 'disk') {
253                         available_revs.push(n);
254                     }
255                 }
256             });
258             var revs_data = {};
259             revs_data['active'] = {
260                 rev: doc._rev,
261                 status: active_rev_status
262             };
263             revs_data['available'] = available_revs;
264             revs_data['all'] = doc._revs_info;
266             // console.log("Revs data:");
267             // console.log(revs_data);
269             return revs_data;            
270         },
271         navigate_to: function(pos, current, rev_data) {
272             // console.log("Navigate_to ("+pos+"), current rev: "+current);
273             
274             var behind = [];
275             var ahead = [];
276             var revisions = rev_data.all;
277             
278             var put_behind = true;
279             var rev_idxs = {};
280             $.each(revisions, function(i,n){
281                 rev_idxs[n.rev] = i;
282                 if (n.rev == current) {
283                     put_behind = false;
284                     return;
285                 }
286                 if (put_behind) {
287                     behind.push(n.rev);
288                 } else {
289                     ahead.push(n.rev);
290                 }
291             });
292             
293             var curr_key = rev_idxs[current];
294             
295             // console.log("Behind:");
296             // console.log(behind);
297             // console.log("Ahead:");
298             // console.log(ahead);
299             
300             var return_rev = null;
301             
302             switch(pos) {
303                 case 'first':
304                     if (typeof ahead[(ahead.length-1)] != 'undefined') {
305                         return_rev = ahead[(ahead.length-1)];
306                         curr_key = rev_idxs[return_rev];
307                     }
308                 break;
309                 case 'last':
310                     if (typeof behind[0] != 'undefined') {
311                         return_rev = behind[0];
312                         curr_key = rev_idxs[return_rev];
313                     }
314                     if (rev_data.active.rev == current) {
315                         curr_key = rev_idxs[current];
316                         return_rev = null;
317                     }
318                 break;
319                 case 'next':
320                     if (typeof behind[(behind.length-1)] != 'undefined') {
321                         return_rev = behind[(behind.length-1)];
322                         curr_key = rev_idxs[return_rev];                        
323                     } else if (typeof ahead[0] != 'undefined') {
324                         return_rev = ahead[0];
325                         curr_key = rev_idxs[return_rev];
326                     }
327                     
328                     if (rev_data.active.rev == current) {
329                         curr_key = rev_idxs[current];
330                         return_rev = null;
331                     }
332                 break;
333                 case 'prev':
334                     if (typeof ahead[0] != 'undefined') {
335                         return_rev = ahead[0];
336                         curr_key = rev_idxs[return_rev];
337                     }
338                 break
339             }
341             // console.log("Total revs: "+revisions.length);
342             // console.log("curr_key: "+curr_key);
343             // console.log("Current: "+(revisions.length - (curr_key)));
344             // 
345             // console.log("Return rev: "+return_rev);
346             
347             return {
348                 total: revisions.length,
349                 current: (revisions.length - curr_key),
350                 rev: return_rev
351             };
352         }
353     };
354     $.ajatus.document.metadata = {
355         creator: {
356             label: 'Creator',
357             widget: {
358                 name: 'text',
359                 config: {}
360             }
361         },
362         created: {
363             label: 'Created',
364             widget: {
365                 name: 'date',
366                 config: {
367                     use_time: true
368                 }
369             }
370         },
371         revisor: {
372             label: 'Revisor',
373             widget: {
374                 name: 'text',
375                 config: {}
376             }
377         },
378         revised: {
379             label: 'Revised',
380             widget: {
381                 name: 'date',
382                 config: {
383                     use_time: true
384                 }
385             }
386         },
387         archived: {
388             label: 'Archived',
389             widget: {
390                 name: 'boolean',
391                 config: {}
392             },
393             def_val: false
394         },
395         deleted: {
396             label: 'Deleted',
397             widget: {
398                 name: 'boolean',
399                 config: {}
400             },
401             def_val: false
402         }
403     };
404     $.ajatus.document.modify_metadata = function(doc, metadata) {
405         $.each(metadata, function(k,v){
406             if ($.ajatus.document.metadata[k])
407             {
408                 var wdgt = new $.ajatus.widget($.ajatus.document.metadata[k].widget.name, $.ajatus.document.metadata[k].widget.config);
409                 doc.value.metadata[k] = {
410                     val: wdgt.value_on_save(wdgt.value_on_save(v)),
411                     widget: $.ajatus.document.metadata[k].widget
412                 };
413             }
414         });
415         
416         return doc;
417     };
418     $.ajatus.document.actions = {        
419         execute: function(action, tmpdoc, force_load_rev) {
420             if (typeof force_load_rev == 'undefined') {
421                 force_load_rev = false;
422             }
423             
424             if (   typeof tmpdoc._rev != 'undefined'
425                 && tmpdoc._rev != null
426                 && !force_load_rev)
427             {
428                 var doc = new $.ajatus.document.loader(tmpdoc._id, tmpdoc._rev);
429             } else {
430                 var doc = new $.ajatus.document.loader(tmpdoc._id);
431             }
432             
433             var act_info = $.ajatus.document.actions._get_action_info(action);
434             if (! act_info) {
435                 var msg = $.ajatus.elements.messages.create(
436                     $.ajatus.i10n.get('Unknown document action'),
437                     $.ajatus.i10n.get('Unknown action %s requested for object %s!', [action, doc.value.title.val])
438                 );
439                 return false;
440             }
441             
442             if (act_info.pool_action)
443             {
444                 var pa = act_info.pool_action;
445                 var pai = $.ajatus.document.actions._get_action_info(fa);
446                 if (pai) {
447                     var pool_action = {
448                         action: fa,
449                         doc: doc
450                     };
451                     var pool_id = $.ajatus.document.history.pool.add(pool_action);
452                 }
453             }
454             
455             if (act_info.undoable) {                
456                 $.ajatus.document.actions._execute_temp(act_info.action, doc);
457             } else {
458                 $.ajatus.document.actions._execute_final(act_info.action, doc);
459             }
460         },
461         _execute_temp: function(action, doc) {
462             // console.log("_execute_temp: "+action);
463             switch(action) {
464                 case 'delete':
465                     var on_success = function(data) {
466                         var tmpdoc = {
467                             _id: doc._id,
468                             _rev: doc._rev
469                         };
470                         var msg = $.ajatus.elements.messages.create(
471                             $.ajatus.i10n.get('Object deleted'),
472                             $.ajatus.i10n.get('Object %s moved to trash.', [doc.value.title.val]) + ' <a href="#undelete.'+doc.value._type+'.'+doc._id+'" class="undo">' + $.ajatus.i10n.get('Undo') + '</a>'
473                         );
474                         msg.bind_in_content('click', 'a.undo', function(e){
475                             $.ajatus.document.actions.execute("undelete", tmpdoc, true);
476                             msg.fade('out', true);
477                         });
478                         
479                         return data;
480                     };
482                     doc = $.ajatus.document.modify_metadata(doc, {
483                         deleted: true,
484                         revised: $.ajatus.formatter.date.js_to_iso8601(new Date()),
485                         revisor: $.ajatus.preferences.local.user.email
486                     });
487                     
488                     $.jqCouch.connection('doc', on_success).save($.ajatus.preferences.client.content_database, doc);
489                     
490                     $('#object_'+doc._id, $.ajatus.application_content_area).hide().addClass('deleted');
491                 break;
492                 case 'archive':
493                     var on_success = function(data) {
494                         var tmpdoc = {
495                             _id: doc._id,
496                             _rev: doc._rev
497                         };
498                         var msg = $.ajatus.elements.messages.create(
499                             $.ajatus.i10n.get('Object archived'),
500                             $.ajatus.i10n.get('Object %s moved to archive.', [doc.value.title.val]) + ' <a href="#unarchive.'+doc.value._type+'.'+doc._id+'" class="undo">' + $.ajatus.i10n.get('Undo') + '</a>'
501                         );
502                         msg.bind_in_content('click', 'a.undo', function(e){
503                             $.ajatus.document.actions.execute("unarchive", tmpdoc, true);
504                             msg.fade('out', true);
505                         });
506                         
507                         return data;
508                     };
510                     doc = $.ajatus.document.modify_metadata(doc, {
511                         revised: $.ajatus.formatter.date.js_to_iso8601(new Date()),
512                         revisor: $.ajatus.preferences.local.user.email,
513                         archived: true
514                     });
515                     
516                     $.jqCouch.connection('doc', on_success).save($.ajatus.preferences.client.content_database, doc);
517                     
518                     $('#object_'+doc._id, $.ajatus.application_content_area).hide().addClass('archived');
519                 break;
520             };
521         },
522         _execute_final: function(action, doc) {
523             switch(action) {
524                 case 'delete':
525                     var on_success = function(data) {
526                         var msg = $.ajatus.elements.messages.create(
527                             $.ajatus.i10n.get('Object deleted'),
528                             $.ajatus.i10n.get('Object %s removed from Ajatus.', [doc.value.title.val])
529                         );
530                         
531                         return data;
532                     };
533                     $.jqCouch.connection('doc', on_success).del($.ajatus.preferences.client.content_database, doc);
534                     $('#object_'+doc._id, $.ajatus.application_content_area).remove();
535                 break;
536                 case 'undelete':
537                     var on_success = function(data) {
538                         var msg = $.ajatus.elements.messages.create(
539                             $.ajatus.i10n.get('Object restored'),
540                             $.ajatus.i10n.get('Object %s restored succesfully.', [doc.value.title.val])
541                         );
542                         
543                         return data;
544                     };
545                     doc = $.ajatus.document.modify_metadata(doc, {
546                         deleted: false,
547                         revised: $.ajatus.formatter.date.js_to_iso8601(new Date()),
548                         revisor: $.ajatus.preferences.local.user.email
549                     });
550                     $.jqCouch.connection('doc', on_success).save($.ajatus.preferences.client.content_database, doc);
551                     
552                     $('#object_'+doc._id, $.ajatus.application_content_area).not('.deleted').remove();
553                     $('#object_'+doc._id, $.ajatus.application_content_area).filter('.deleted').show().removeClass('deleted');
554                 break;
555                 case 'unarchive':
556                     var on_success = function(data) {
557                         var msg = $.ajatus.elements.messages.create(
558                             $.ajatus.i10n.get('Object restored'),
559                             $.ajatus.i10n.get('Object %s restored succesfully.', [doc.value.title.val])
560                         );
561                         
562                         return data;
563                     };
564                     doc = $.ajatus.document.modify_metadata(doc, {
565                         revised: $.ajatus.formatter.date.js_to_iso8601(new Date()),
566                         revisor: $.ajatus.preferences.local.user.email,
567                         archived: false
568                     });
569                     $.jqCouch.connection('doc', on_success).save($.ajatus.preferences.client.content_database, doc);
570                     
571                     $('#object_'+doc._id, $.ajatus.application_content_area).filter('.archived').show().removeClass('archived');
572                 break;
573             };
574         },
575         empty_pool: function () {
576             var items = $.ajatus.document.history.pool.get_all();
577             if (items.length > 0) {
578                 var msg = $.ajatus.elements.messages.create(
579                     $.ajatus.i10n.get('Emptying action pool'),
580                     $.ajatus.i10n.get('Running %d pooled actions.', [items.length])
581                 );                
582             }
583             $.each(items, function(i,item){
584                 $.ajatus.document.history.pool.remove(i);
585                 $.ajatus.document.actions.execute(item.action, item.doc);
586             });
587         },
588         _get_action_info: function(action) {
589             switch(action) {
590                 case 'delete':
591                     return {
592                         action: 'delete',
593                         label: $.ajatus.i10n.get('Delete'),
594                         undoable: true,
595                         undo_label: $.ajatus.i10n.get('Undelete'),
596                         pool_action: false
597                     }
598                 break;
599                 case 'delete_final':
600                     return {
601                         action: 'delete',
602                         label: $.ajatus.i10n.get('Delete'),
603                         undoable: false,
604                         pool_action: false
605                     }
606                 break;
607                 case 'undelete':
608                     return {
609                         action: 'undelete',
610                         label: $.ajatus.i10n.get('Undelete'),
611                         undoable: false,
612                         pool_action: false
613                     }
614                 break;
615                 case 'archive':
616                     return {
617                         action: 'archive',
618                         label: $.ajatus.i10n.get('Archive'),
619                         undoable: true,
620                         undo_label: $.ajatus.i10n.get('Restore'),
621                         pool_action: false
622                     }
623                 break;
624                 case 'unarchive':
625                     return {
626                         action: 'unarchive',
627                         label: $.ajatus.i10n.get('Restore'),
628                         undoable: false,
629                         pool_action: false
630                     }
631                 break;
632                 default:
633                     return false;
634             }
635         }
636     };
637     
638     $.ajatus.document.history = {};
639     $.ajatus.document.history.pool = {
640         items: [],
641         
642         add: function(action) {
643             var new_length = $.ajatus.document.history.pool.items.push(action);
644             var pool_id = new_length-1;
645             return pool_id;
646         },        
647         remove: function(item_id) {
648             $.ajatus.document.history.pool.items = $.grep($.ajatus.document.history.pool.items, function(n,i){
649                 return i != item_id;
650             });
651         },        
652         get_item: function(item_id) {
653             if (items[item_id]) {
654                 return items[item_id];
655             } else {
656                 return false;
657             }
658         },        
659         get_all: function() {
660             return $.ajatus.document.history.pool.items;
661         }
662     };
663     
664     $.ajatus.document.scheme = {
665         
666     };
667     $.ajatus.document.scheme.items = {
668         configure: function(name, widget) {
669             var dialog = new $.ajatus.elements.dialog($.ajatus.i10n.get('Edit field %s', [name]), '', {
670                 modal: false,
671                 dialog: {
672                     height: "200px"                    
673                 }
674             });
676             var prev_vals = $.ajatus.document.scheme.items._read_settings(name, $.ajatus.forms.active, widget);
677             var on_save = '$.ajatus.document.scheme.items.save_config';
678             
679             var content_holder = $.ajatus.document.scheme.items._create_structure( dialog );
680             
681             var jqform = $('.form', content_holder);
682             var contents = $('.contents', content_holder);
683             
684             var wdgt_settings = $('<div id="widget_settings_holder" />');
685             wdgt_settings.appendTo(contents);
686             wdgt_settings.html($.ajatus.document.scheme.items._generate_widget_settings(widget, prev_vals));
687             
688             $('.actions #submit_save', content_holder).bind('click', function(e){
689                 var fn = on_save;
690                     if (typeof on_save == 'string') {
691                     fn = eval(on_save);
692                 }
693                 var result = fn.apply(fn, [name, jqform.formToArray(false)]);
694                 
695                 if (result) {
696                     dialog.close();
697                 }
698             });
699             
700             dialog.open();
701         },
702         generate_actions_tpl: function(name, widget, data, row_holder) {
703             var item_data = data;
704             return [
705                 'img', { className: 'edit_settings_btn', src: $.ajatus.preferences.client.theme_icons_url + 'preferences.png', title: $.ajatus.i10n.get('Settings'), alt: $.ajatus.i10n.get('Settings'), onclick: function(){$.ajatus.document.scheme.items.configure(name, widget);} }, ''
706             ];
707         },
708         save_config: function(name, form_data) {
709             var form_values = {};
710             
711             $.ajatus.document.scheme.items._process_widget_settings(form_data, form_values);
712             
713             var config = {};
714             $.each(form_values, function(i,n){
715                 config[i] = n.val;
716             });
717             
718             var row = $('#_element_'+name, $.ajatus.forms.active);
720             var add_upd_elem = $('input[name="widget['+name+':additional_updated]"]', row);
721             if (typeof add_upd_elem[0] == 'undefined') {
722                     row.createAppend(
723                         'input', { type: 'hidden', name: 'widget['+name+':field_updated]', value: $.ajatus.converter.toJSON(true) }, ''
724                 );
725             } else {
726                 add_upd_elem.val($.ajatus.converter.toJSON(true));
727             }
728             
729             var widget_config_input = $('#_element_'+name+'_widget input[name="widget['+name+':config]"]', $.ajatus.forms.active)
730                 .val($.ajatus.converter.toJSON(config));
731             
732             return true;
733         },
734         _create_structure: function(dialog) {
735             var cholder = dialog.get_content_holder();
736             
737             var title = $('<h2 class="title"/>');
738             var form = $('<form id="additionals_window_form" class="form" />');
739             var form_errors = $('<div class="form_errors" />').hide();
740             var content_area = $('<div class="contents"/>');
741             var actions = $('<div class="actions" />').html('<input type="submit" id="submit_save" name="save" value="' + $.ajatus.i10n.get('Save') + '" /><input type="submit" id="submit_cancel" name="cancel" value="' + $.ajatus.i10n.get('Cancel') + '" />');
742                                     
743             title.appendTo(cholder);
744             form.appendTo(cholder);
745             form_errors.appendTo(form);
746             content_area.appendTo(form);
747             actions.appendTo(cholder);
749             $('#submit_cancel', actions).bind('click', function(e){
750                 dialog.close();
751                 return false;
752             });
753             
754             return cholder;
755         },
756         _read_settings: function(name, form, widget) {
757             var prev_vals = {};
758             
759             if (typeof form == 'undefined') {
760                 var form = $.ajatus.forms.active;
761             }            
762             if (typeof widget != 'undefined') {
763                 prev_vals = widget.config;
764             }
765             
766             var widget_config_input = $('#_element_'+name+'_widget input[name="widget['+name+':config]"]', form);
767             if (typeof widget_config_input[0] != 'undefined') {
768                 prev_vals = $.ajatus.converter.parseJSON(widget_config_input.val());
769             }
770             
771             return prev_vals;
772         },
773         _generate_widget_settings: function(widget_name, data) {
774             var widget = $.ajatus.widget(widget_name);
775             var details = $('<p>' + $.ajatus.i10n.get("Widget %s doesn't support dynamic settings.", [$.ajatus.i10n.get(widget_name)]) + '</p>');
776             if (typeof(widget['create_widget_settings']) == 'function') {
777                 details = widget.create_widget_settings(data || {});
778             }
779             
780             return details;
781         },
782         _process_widget_settings: function(form_data, form_values) {
783             $.each(form_data, function(i,row){
784                 if (row.name.toString().match(/__(.*?)/)) {
785                     return;
786                 }
787                     if (row.name.substr(0,6) != "widget") {
788                         var item = {};
789                         var widget = {};
790                         var prev_val = false;
791                         var name_parts = [];
792                         var name_parts_count = 0;
793                         if (row.name.toString().match(/;/g)) {
794                             name_parts = row.name.toString().split(";");
795                             name_parts_count = name_parts.length;
796                         }
797                         
798                         $.each(form_data, function(x,r){
799                             if (r.name == 'widget['+row.name+':name]') {
800                                 widget['name'] = r.value;
801                             } else if (r.name == 'widget['+row.name+':config]') {
802                             widget['config'] = $.ajatus.converter.parseJSON(r.value);
803                         } else if (r.name == 'widget['+row.name+':prev_val]') {
804                             prev_val = $.ajatus.converter.parseJSON(r.value);
805                         }
806                     });
808                     var wdgt = new $.ajatus.widget(widget['name'], widget['config']);
810                         item['val'] = wdgt.value_on_save(row.value, prev_val);
811                         item['widget'] = widget;
812                         
813                         if (name_parts_count > 0) {
814                             var prevs = [];
815                             for (var i=0; i < name_parts_count; i++) {
816                                 var key = "['"+name_parts[i]+"']";
817                             
818                             if (prevs.length > 0) {
819                                 var key_prefix = '';
820                                 $.each(prevs, function(pi, pk){
821                                     key_prefix = "['" + pk + "']" + key_prefix;
822                                 });
823                                 key = key_prefix + key;
824                             }
825                             
826                                 if (typeof eval("form_values"+key) == 'undefined') {
827                                     eval("form_values"+key+"={};");
828                                 }
829                                 
830                                 prevs.push(name_parts[i]);
831                             if (i == name_parts_count-1) {
832                                 if ($.browser.mozilla) {
833                                     if (typeof item == 'object') {
834                                         eval("form_values"+key+"="+item.toSource()+";");
835                                     } else {
836                                         eval("form_values"+key+"="+item+";");
837                                     }
838                                 } else {
839                                     eval("form_values"+key+"="+item+";");
840                                 }
841                             }
842                             }
843                         } else {
844                             form_values[row.name] = item;
845                         }
846                     }
847             });
848         }
849     };
850     
851     $.ajatus.document.additionals = {
852         defaults: {
853             auto_show: true
854         },
855         open: [],
856         active: null,
857         top_start: 17,
858         left_start: 50
859     };
860     $.extend($.ajatus.document.additionals, {
861         create: function(content_type, row_holder, opts) {
862             $.ajatus.document.additionals._reset();
863             
864             var dialog = new $.ajatus.elements.dialog($.ajatus.i10n.get('Add field'), '', {
865                 modal: false,
866                 dialog: {
867                     height: 280
868                 }
869             });
870             
871             var content_holder = $.ajatus.document.scheme.items._create_structure( dialog );
872             
873             var jqform = $('.form', content_holder);
874             var contents = $('.contents', content_holder);
875             var form_errors = $('.form_errors', content_holder);
876             var wdgts = $.ajatus.document.additionals._generate_widget_list();
878             $('<label for="widget"/>').html($.ajatus.i10n.get('Widget')).appendTo(contents);
879             var wdgt_sel_holder = $('<div id="widget_selection_holder"/>');
880             wdgt_sel_holder.html(wdgts).appendTo(contents);
881             
882             var wdgt_details = $('<div id="widget_details_holder"/>');
883             wdgt_details.appendTo(contents);
884             
885             var wdgts_on_change = function(e){
886                 var sel_w = e.currentTarget.value;
887                 if (sel_w != '') {
888                     wdgt_sel_holder.html($.ajatus.i10n.get(sel_w));
889                     wdgt_sel_holder.addClass('selected');
890                     wdgt_details.html($.ajatus.document.additionals._generate_widget_details(sel_w));
892                     var field = $('<input type="hidden" />').attr({
893                         name: '_widget',
894                         value: sel_w
895                     });
896                     field.appendTo(jqform);
897                 }
898             };
899             
900             wdgts.bind('change', wdgts_on_change);
901             
902             wdgt_sel_holder.bind('dblclick', function(e){
903                 wdgt_sel_holder.removeClass('selected');
904                 wdgt_sel_holder.html(wdgts);
905                 wdgts.bind('change', wdgts_on_change);
906             });
908             $('.actions #submit_save', content_holder).bind('click', function(e){
909                 var result = $.ajatus.document.additionals.save_widget(jqform.formToArray(false), jqform);
910                 
911                 if (result == true) {
912                     $.ajatus.document.additionals.close(dialog);
913                 } else {
914                     if (typeof result == 'object') {
915                         form_errors.html('');
916                             var error_holder = $('<ul />');
917                             $.each(result, function(field, data){
918                                 $('<li class="error" />').html(data.msg).appendTo(error_holder);
919                             });
920                             error_holder.appendTo(form_errors);
921                             form_errors.show();
922                     }
923                 }
924                 
925                 return false;
926             });
928             $.ajatus.document.additionals.show(dialog);
929         },
930         edit: function(widget, row_holder, name, data, opts) {
931             $.ajatus.document.additionals._reset();
933             var dialog = new $.ajatus.elements.dialog($.ajatus.i10n.get('Edit field %s', [name]), '', {
934                 modal: false,
935                 dialog: {
936                     height: 280
937                 }
938             });
939             
940             var content_holder = $.ajatus.document.scheme.items._create_structure( dialog );
941             
942             var jqform = $('.form', content_holder);
943             var contents = $('.contents', content_holder);
944             var form_errors = $('.form_errors', content_holder);
946             if (typeof data['widget'] != 'undefined') {
947                 data.widget.config = $.ajatus.document.additionals._read_settings(name, $.ajatus.forms.active, widget);
948             }
950             var prev_value = null;
951             var prev_val_input = $('#_element_'+name+'_widget input[name="widget['+name+':prev_val]"]', $.ajatus.forms.active);
952             if (typeof prev_val_input[0] != 'undefined') {
953                 prev_value = $.ajatus.converter.parseJSON(prev_val_input.val());
954             }
956             var wdgt_details = $('<div id="widget_details_holder"/>');
957             wdgt_details.appendTo(contents);
958             
959             wdgt_details.html($.ajatus.document.additionals._generate_widget_details(widget.name, name, data));
961             $('.actions #submit_save', content_holder).bind('click', function(e){
962                 var prev_data = {
963                     name: name,
964                     data: data
965                 };
966                 if (prev_value != null) {
967                     prev_data.value = prev_value;
968                 }
969                 var result = $.ajatus.document.additionals.save_widget(jqform.formToArray(false), jqform, prev_data);
970                 
971                 if (result == true) {
972                     $.ajatus.document.additionals.close(dialog);
973                 } else {
974                     if (typeof result == 'object') {
975                         form_errors.html('');
976                         var error_holder = $('<ul />');                     
977                         $.each(result, function(field, data){
978                             $('<li class="error" />').html(data.msg).appendTo(error_holder);
979                         });
980                         error_holder.appendTo(form_errors);
981                         form_errors.show();
982                     }
983                 }
984             });
985             
986             $.ajatus.document.additionals.show(dialog);
987         },
988         config: function(widget, prev_vals, on_save, parent, name) {
989             var dialog = new $.ajatus.elements.dialog($.ajatus.i10n.get('Configure widget %s', [$.ajatus.i10n.get(widget.name)]), '', {
990                 modal: false,
991                 dialog: {
992                     height: 310,
993                     nested: true
994                 }
995             });
996             
997             var content_holder = $.ajatus.document.scheme.items._create_structure( dialog );
998             
999             if (typeof prev_vals == 'undefined') {
1000                 var prev_vals = {};
1001             }
1002             if (typeof on_save == 'undefined') {
1003                 var on_save = '$.ajatus.document.additionals.save_widget_settings';
1004             }
1006             var jqform = $('.form', content_holder);
1007             var contents = $('.contents', content_holder);
1009             var wdgt_settings = $('<div id="widget_settings_holder" />');
1010             wdgt_settings.appendTo(contents);
1011             wdgt_settings.html($.ajatus.document.additionals._generate_widget_settings(widget, prev_vals));
1012             
1013             $('.actions #submit_save', content_holder).bind('click', function(e){
1014                 var parent_dialog = parent;
1015                 if (typeof parent == 'undefined') {
1016                     parent_dialog = $.ajatus.document.additionals._get_parent(dialog.id);
1017                 }
1019                 var fn = on_save;
1020                     if (typeof on_save == 'string') {
1021                     fn = eval(on_save);
1022                 }
1023                 var result = fn.apply(fn, [jqform.formToArray(false), parent_dialog, name, jqform]);
1024                 
1025                 if (result) {                    
1026                     $.ajatus.document.additionals.close(dialog);
1027                 }
1028             });
1029             
1030             $.ajatus.document.additionals.show(dialog);
1031         },
1032         del: function(widget, row_holder, name, data) {            
1033             var label = name;
1034             if (   typeof data == 'object'
1035                 && typeof data.label != 'undefined')
1036             {
1037                 label = data.label;
1038             }
1039         
1040             var confirmation = confirm($.ajatus.i10n.get("Do you really wan't to delete item %s", [label]));
1041             
1042             if (confirmation == true) {
1043                 $('#_element_'+name, row_holder).remove();                
1044             }
1045         },
1046         show: function(dialog) {
1047             var dlg = dialog.get_dialog();
1048             dlg.addClass('additionals_window');
1049             
1050             dialog.open();
1051             $.ajatus.document.additionals.open.push(dialog.id);
1052             $.ajatus.document.additionals._position(dlg);
1053         },
1054         close: function(dialog) {            
1055             dialog.close();
1056             
1057             $.ajatus.document.additionals.open = $.grep($.ajatus.document.additionals.open, function(n,i){
1058                 if (n != dialog.id) {
1059                     return true;
1060                 } else {
1061                     return false;
1062                 }
1063             });
1064         },
1065         _position: function(dialog) {
1066             var top = $.ajatus.document.additionals.top_start;
1067             var left = $.ajatus.document.additionals.left_start;
1068             
1069             if ($.ajatus.document.additionals.open.length > 1) {
1070                 var incr = $.ajatus.document.additionals.open.length * 2;
1071                 top += incr;
1072                 left += incr;
1073             }
1075             dialog.css({
1076                 top: top+'%',
1077                 left: left+'%'
1078             });
1079         },
1080         _process_widget_settings: function(form_data, form_values) {
1081             $.ajatus.document.scheme.items._process_widget_settings(form_data, form_values);
1082         },
1083         _settings_to_saved: function(values, holder) {
1084             $.each(values, function(k,item){
1085                 var field = $('<input type="hidden" />').attr({
1086                     name: 'widget[config;'+k+':name]',
1087                     value: item.widget.name
1088                 });
1089                 field.appendTo(holder);
1090                 
1091                 var field = $('<input type="hidden" />').attr({
1092                     name: 'widget[config;'+k+':config]',
1093                     value: $.ajatus.converter.toJSON(item.widget.config)
1094                 });
1095                 field.appendTo(holder);
1096                 
1097                 var field = $('<input type="hidden" />').attr({
1098                     name: 'config;'+k,
1099                     value: item.val != '' ? $.ajatus.converter.toJSON(item.val) : ''
1100                 });
1101                 field.appendTo(holder);
1102             });            
1103         },
1104         save_widget_settings: function(form_data, parent_dialog, name, form) {
1105             var form_values = {};
1106             
1107             $.ajatus.document.additionals._process_widget_settings(form_data, form_values);
1108             
1109             var config_holder = $('.saved_settings', parent_dialog);
1110             config_holder.html('');
1111             
1112             $.ajatus.document.additionals._settings_to_saved(form_values, config_holder);
1113             
1114             return true;
1115         },
1116         _read_settings: function(name, form, widget) {
1117             if (typeof form == 'undefined') {
1118                 var form = $.ajatus.forms.active;
1119             }
1120                     
1121             var prev_vals = {};
1122         
1123             if (typeof widget != 'undefined') {
1124                 prev_vals = widget.config;
1125             }
1126         
1127             var widget_config_input = $('#_element_'+name+'_widget input[name="widget['+name+':config]"]', form);
1128             if (typeof widget_config_input[0] != 'undefined') {
1129                 prev_vals = $.ajatus.converter.parseJSON(widget_config_input.val());
1130             }
1131         
1132             return prev_vals;
1133         },
1134         update_widget_settings: function(form_data, parent_form, name, form) {
1135             var form_values = {};
1136             
1137             $.ajatus.document.additionals._process_widget_settings(form_data, form_values);
1138             
1139             var config = {};
1140             $.each(form_values, function(i,n){
1141                 config[i] = n.val;
1142             });
1143             
1144             var row = $('#_element_'+name, parent_form);
1146             var add_upd_elem = $('input[name="widget['+name+':additional_updated]"]', row);
1147             if (typeof add_upd_elem[0] == 'undefined') {
1148                     row.createAppend(
1149                         'input', { type: 'hidden', name: 'widget['+name+':additional_updated]', value: $.ajatus.converter.toJSON(true) }, ''
1150                 );
1151             } else {
1152                 add_upd_elem.val($.ajatus.converter.toJSON(true));
1153             }
1154             
1155             var additional_input = $('#_element_'+name+' input[name="widget['+name+':additional]"]', parent_form);
1156             var widget_config_input = $('#_element_'+name+'_widget input[name="widget['+name+':config]"]', parent_form);
1157             
1158             var add_data = $.ajatus.converter.parseJSON(additional_input.val());
1159             if (   typeof add_data.widget != 'undefined'
1160                 && typeof add_data.widget.config != 'undefined')
1161             {
1162                 add_data.widget.config = config;          
1163             }
1164             
1165             additional_input.val($.ajatus.converter.toJSON(add_data));
1166             widget_config_input.val($.ajatus.converter.toJSON(config));
1167             
1168             return true;
1169         },
1170         save_widget: function(form_data, form, prev_data) {
1171             var form_values = {};
1172             var sel_widget = 'text';
1173             
1174             var has_errors = false;
1175             var error_fields = {};
1176             
1177             $.each(form_data, function(i,row){                  
1178                 if (row.name.toString().match(/__(.*?)/)) {
1179                     return;
1180                 }
1181                 if (row.name == '_widget') {
1182                     sel_widget = String(row.value);
1183                 }
1184                     else if (row.name.substr(0,6) != "widget") {
1185                         var item = {};
1186                         var widget = {};
1187                         var prev_val = false;
1188                         var name_parts = [];
1189                         var name_parts_count = 0;
1190                         var row_key = row.name;
1191                         
1192                         if (row.name.toString().match(/;/g)) {
1193                             name_parts = row.name.toString().split(";");
1194                             name_parts_count = name_parts.length;
1195                             
1196                             row_key = name_parts[0];
1197                         }
1198                         
1199                         $.each(form_data, function(x,r){
1200                             if (r.name == 'widget['+row.name+':name]') {
1201                                 widget['name'] = r.value;
1202                             } else if (r.name == 'widget['+row.name+':config]') {
1203                             widget['config'] = $.ajatus.converter.parseJSON(r.value);
1204                         } else if (r.name == 'widget['+row.name+':prev_val]') {
1205                             if (r.value == '') {
1206                                 prev_val = r.value;
1207                             } else {
1208                                 prev_val = $.ajatus.converter.parseJSON(r.value);
1209                             }
1210                         } else if (r.name == 'widget['+row.name+':required]') {
1211                             widget['required'] = $.ajatus.utils.to_boolean(r.value);
1212                         }
1213                     });
1214                     
1215                     var wdgt = new $.ajatus.widget(widget['name'], widget['config']);
1216                     
1217                     if (typeof widget['required'] != 'undefined') {
1218                         wdgt.required = widget['required'];
1219                         }
1220                     
1221                     if (typeof wdgt.validate == 'function') {
1222                         var status = wdgt.validate(row_key, row.value);
1223                         if (typeof status == 'object') {
1224                             has_errors = true;
1225                             error_fields[row_key] = status;
1226                         }
1227                     }
1229                         item['val'] = wdgt.value_on_save(row.value, prev_val);
1231                         item['widget'] = widget;
1232                         
1233                         if (name_parts_count > 0) {
1234                             var prevs = [];
1235                             for (var i=0; i < name_parts_count; i++) {                                  
1236                                 var arr_keys = false;
1237                                 var key_prefix = '';
1238                                 
1239                                 if (name_parts[i].match(/\[/g)) {
1240                                     var arr_keys = name_parts[i].split('[');
1241                                     
1242                                     name_parts[i] = name_parts[i].replace(/\[/g, '"][');
1243                                     var key = '["'+name_parts[i];
1244                                 } else {
1245                                     var key = "['"+name_parts[i]+"']";
1246                                 }
1247                             
1248                             if (prevs.length > 0) {
1249                                 $.each(prevs, function(pi, pk){
1250                                     key_prefix = "['" + pk + "']" + key_prefix;
1251                                 });
1252                                 key = key_prefix + key;
1253                             }
1254                             
1255                             if (arr_keys) {
1256                                 var tmp_key = key_prefix + "['" + arr_keys[0] + "']";
1257                                 if (typeof eval("form_values"+tmp_key) == 'undefined') {
1258                                     eval("form_values"+tmp_key+"=[];");
1259                                 }                    
1260                             }
1261                             
1262                             var multiple = false;
1263                                 if (typeof eval("form_values"+key) == 'undefined') {
1264                                     if (key_prefix != '') {
1265                                     eval("form_values"+key+"=new Array();");
1266                                     } else {
1267                                     eval("form_values"+key+"={};");                                             
1268                                     }
1269                                 } else {                         
1270                                     multiple = true;
1271                                 }
1272                                 
1273                                 prevs.push(name_parts[i]);
1274                                 
1275                             if (i == name_parts_count-1) {
1276                                 if (typeof item['val'] == 'undefined') {
1277                                     return;
1278                                 }
1279                                 if (multiple) {
1280                                     if (typeof item == 'object') {
1281                                         if (item.widget.name == 'boolean') {
1282                                             eval("form_values"+key+"="+item.val+";");
1283                                         } else {
1284                                             eval("form_values"+key+".push('"+item.val+"');");                                                    
1285                                         }
1286                                     } else {
1287                                         eval("form_values"+key+".push('"+item+"');");
1288                                     }                                                
1289                                 } else {
1290                                     if (typeof item == 'object') {
1291                                         eval("form_values"+key+"='"+item.val+"';");
1292                                     } else {
1293                                         eval("form_values"+key+"='"+item.val+"';");
1294                                     }
1295                                 }
1296                             }
1297                             }
1298                         } else {
1299                             form_values[row.name] = item;
1300                         }
1301                     }
1302             });
1303             
1304             var config = {};
1305             if (typeof form_values['config'] != 'undefined') {
1306                 $.each(form_values['config'], function(i,n){
1307                     if (typeof n == 'object') {
1308                         config[i] = n.val != '' ? $.ajatus.converter.parseJSON(n.val) : '';
1309                     } else {
1310                         config[i] = n != '' ? $.ajatus.converter.parseJSON(n) : '';
1311                     }
1312                 });
1313             }
1314             
1315             var item_name = form_values.name.val.toString().toLowerCase();            
1316             
1317             if (has_errors) {
1318                 return error_fields;
1319             }
1320             
1321             
1322             var additional_item = {
1323                 label: form_values.label.val,
1324                 widget: {
1325                     name: sel_widget,
1326                     config: config
1327                 },
1328                 def_val: form_values.def_val.val,
1329                 required: form_values.required.val
1330             };
1331             
1332             var row_holder = $('.form_structure ul.row_holder:eq(0)', $.ajatus.forms.active);
1333             
1334             if (typeof prev_data != 'undefined') {
1335                 if (typeof prev_data.value != 'undefined') {
1336                     additional_item.value = prev_data.value;                    
1337                 }
1338                 
1339                 $.ajatus.renderer.form_helpers._add_additional_row('edit', row_holder, item_name, additional_item, {}, prev_data.name);
1340                 
1341                 return true;
1342             }
1344             $.ajatus.renderer.form_helpers._add_additional_row('create', row_holder, item_name, additional_item);
1345             
1346             return true;
1347         },
1348         edit_existing_config: function(name, widget) {            
1349             var prev_vals = $.ajatus.document.additionals._read_settings(name, $.ajatus.forms.active, widget);
1350             
1351             var on_save = '$.ajatus.document.additionals.update_widget_settings';
1352             
1353             $.ajatus.document.additionals.config(widget, prev_vals, on_save, $.ajatus.forms.active, name);            
1354         },
1355         generate_item_actions_tpl: function(name, widget, data, doc, row_holder) {
1356             var item_data = data;
1357             return [
1358                 'img', { className: 'additional_edit_btn', src: $.ajatus.preferences.client.theme_icons_url + 'edit.png', title: $.ajatus.i10n.get('Edit'), alt: $.ajatus.i10n.get('Edit'), onclick: function(){$.ajatus.document.additionals.edit(widget, row_holder, name, item_data, {});} }, '',
1359                 'img', { className: 'additional_delete_btn', src: $.ajatus.preferences.client.theme_icons_url + 'trash.png', title: $.ajatus.i10n.get('Delete'), alt: $.ajatus.i10n.get('Delete'), onclick: function() {$.ajatus.document.additionals.del(widget, row_holder, name, item_data);} }, ''
1360             ];
1361         },
1362         _get_parent: function() {            
1363             var parent_id = $.ajatus.document.additionals.open[$.ajatus.document.additionals.open.length-2];
1364             return $('#'+parent_id);
1365         },
1366         _create_structure: function(id, options) {            
1367             var af_win = $('<div class="additionals_window" />').attr({
1368                 id: id
1369             }).hide();
1370             var title = $('<h2 class="title"/>');
1371             var form = $('<form id="additionals_window_form" class="form" />');
1372             var form_errors = $('<div class="form_errors" />').hide();
1373             var content_area = $('<div class="contents"/>');
1374             var actions = $('<div class="actions" />').html('<input type="submit" id="submit_save" name="save" value="' + $.ajatus.i10n.get('Save') + '" /><input type="submit" id="submit_cancel" name="cancel" value="' + $.ajatus.i10n.get('Cancel') + '" />');
1375                                     
1376             af_win.appendTo($.ajatus.application_dynamic_elements);
1377             title.appendTo(af_win);
1378             form.appendTo(af_win);
1379             form_errors.appendTo(form);
1380             content_area.appendTo(form);
1381             actions.appendTo(af_win);
1383             $('#submit_cancel', actions).bind('click', function(e){
1384                 $.ajatus.document.additionals.close(id);
1385                 return false;
1386             });
1387             
1388             return af_win;
1389         },
1390         _generate_widget_list: function() {
1391             var select = $('<select id="widget" name="widget" />');
1392                         
1393             $.each($.ajatus.widgets.loaded_widgets, function(i,w){
1394                 var opt = $('<option />').attr({
1395                     value: w
1396                 }).html($.ajatus.i10n.get(w));
1397                 opt.appendTo(select);
1398             });
1400             var opt = $('<option />').attr({
1401                 value: '',
1402                 selected: 'selected'
1403             }).html($.ajatus.i10n.get('Select one') + '&nbsp;');
1404             opt.prependTo(select);
1405             
1406             return select;
1407         },
1408         _generate_widget_details: function(widget_name, name, data) {
1409             var widget = $.ajatus.widget(widget_name);
1410             var details = $('<p>' + $.ajatus.i10n.get("Widget %s doesn't support dynamic creation.", [$.ajatus.i10n.get(widget_name)]) + '</p>');
1411             if (typeof(widget['create_widget_details']) == 'function') {
1412                 details = widget.create_widget_details(data || {}, name);
1413             }
1414             
1415             return details;
1416         },
1417         _generate_widget_settings: function(widget_name, data) {
1418             return $.ajatus.document.scheme.items._generate_widget_settings(widget_name, data);
1419         },
1420         _reset: function() {
1421             $.ajatus.document.additionals.open = [];
1422             $.ajatus.application_dynamic_elements.html('');
1423         }
1424     });
1426 })(jQuery);