Added prev_val and required support to tag widget
[ajatus.git] / js / ajatus.preferences.js
blob1a92b43731f100159b03246cd460b190cafc8120
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($){
16     $.ajatus = $.ajatus || {};    
18     $.ajatus.preferences = {
19         revision: null,
20         modified: false
21     };
22     
23     $.ajatus.preferences.local = {};
24     $.ajatus.preferences.local_defaults = {
25         user: {
26             name: 'Root Ajatus',
27             email: 'root@ajatus.info'
28         },
29         replication: {
30             enabled: false,
31             public_key: '',
32             allowed_keys: ''
33         },
34         layout: {
35             theme_name: 'default',
36             icon_set: 'default'
37         },
38         localization: {
39             language: 'en_GB'
40         },
41         backups: {
42             enabled: false,
43             auto: false
44         },
45         expansions: {
46             active: []
47         },
48         auto_save: {
49             enabled: true,
50             interval: 300
51         }
52     };
53     
54     $.ajatus.preferences.client = {};
55     $.ajatus.preferences.client_defaults = {
56         debug: false,
57         language: null,
58         server_url: '/',
59         theme_url: 'themes/default/',
60         theme_icons_url: 'themes/default/images/icons/',
61         application_url: '/_utils/ajatus/',
62         application_database_identifier: '',
63         content_types: {},
64         custom_views: [],
65         custom_widgets: [],
66         extensions: [],
67         types: {
68             in_use: [
69                 'note', 'contact', 'event', 'expense', 'hour_report'
70             ],
71             system: [
72                 'tag'
73             ]
74         },
75         themes: {
76             available: [
77                 'default'
78             ]
79         }
80     };
81             
82     $.ajatus.preferences.loader = function() {
83         this.loaded = false;
84         
85         var on_success = function(data) {
86             this.loaded = true;
87             
88             $.ajatus.events.lock_pool.decrease();
89             $.ajatus.preferences.revision = data._rev;
90             
91             $.ajatus.preferences.local = data.value;
92             $.each($.ajatus.preferences.local_defaults, function(i,n){
93                 if (typeof $.ajatus.preferences.local[i] == 'undefined') {
94                     $.ajatus.preferences.modified = true;
95                     $.ajatus.preferences.local[i] = n;
96                 }
97                 if (typeof n == 'object') {
98                     $.each(n, function(xi,xn){
99                         if (typeof $.ajatus.preferences.local[i][xi] == 'undefined') {
100                             $.ajatus.preferences.modified = true;
101                             $.ajatus.preferences.local[i][xi] = xn;
102                         }
103                     });
104                 }
105             });
106             
107             return data;
108         };
109         
110         this.dc = $.jqCouch.connection('doc', on_success);
111     }
112     $.extend($.ajatus.preferences.loader.prototype, {
113         load: function() {
114             $.ajatus.events.lock_pool.increase();
115             var data = this.dc.get($.ajatus.preferences.client.application_database + '/preferences');
116             if (! data._id) {
117                 this.loaded = false;
118                 $.ajatus.events.lock_pool.decrease();
119                 $.ajatus.ajax_error(data.request);
120             }
121         }
122     });
123     
124     $.ajatus.preferences.view = {
125         title: 'Preferences',
126         options: {},
127         sections: [
128             'user', 'localization', 'layout', 'replication', 'backups', 'expansions', 'auto_save'
129         ],
130         
131         tab: {
132             on_click: function(e)
133             {
134                 $.ajatus.tabs.on_click(e);
135                 $.ajatus.preferences.view.render();
136             }
137         },
138         
139         render: function() {
140             $.ajatus.application_content_area.html('');
141             $.ajatus.layout.body.set_class('preferences');
142             $.ajatus.views.on_change("#view.preferences");
143             
144             $.ajatus.toolbar.show();
145             
146             var form = $('<form name="preferences" id="preferences_form"/>');
147             form.appendTo($.ajatus.application_content_area);
148             
149             var hidden_data = {
150                 _id: 'preferences',
151                 _rev: $.ajatus.preferences.revision
152             };
153             var hidden_fields = function() {
154                 return [
155                     'input', { type: 'hidden', id: 'preferences_id', name: '_id', value: this._id }, '',
156                     'input', { type: 'hidden', id: 'preferences_revision', name: '_rev', value: this._rev }, ''
157                 ];
158             };
159             $(form).tplAppend(hidden_data, hidden_fields);
160             
161             var form_actions = $('<div class="form_actions"><input type="submit" name="save" value="' + $.ajatus.i10n.get('Save') + '" /><input type="submit" name="cancel" value="' + $.ajatus.i10n.get('Cancel') + '" /></div>');
162             
163             var sections_holder = $('<div id="preference_sections" />');
164             sections_holder.appendTo(form);
165             
166             $.each($.ajatus.preferences.view.sections, function(i,s){
167                 var section_holder = $('<div class="section" id="section_' + s + '" />');
168                 section_holder.appendTo(sections_holder);
169                 
170                 var form_items = $.ajatus.preferences.view.generate_section_form(s);
171                 
172                 if (form_items) {
173                     var title = $('<h3 />').html($.ajatus.i10n.get(s));
174                     title.appendTo(section_holder);
175                     
176                     form_items.appendTo(section_holder);
177                 }
178             });
180             form_actions.appendTo(form);
181             
182             $.ajatus.toolbar.add_item($.ajatus.i10n.get('Save'), 'save.png', function(){
183                 $('#preferences_form input[@type=submit][name*=save]').trigger("click", []);
184             });
185             $.ajatus.toolbar.add_item($.ajatus.i10n.get('Cancel'), 'cancel.png', function(){
186                 $('#preferences_form input[@type=submit][name*=cancel]').trigger("click", []);
187             });
188             
189             $.ajatus.forms.register.custom(form, '$.ajatus.preferences.view.process_form');
190         },
191         
192         process_form: function(form_data, form) {
193             // $.ajatus.debug('Process preferences');
194             // console.log(form_data);
195             
196             var doc = {
197                 _id: '',
198                 _rev: '',
199                 value: {}
200             };
201             var form_values = {};
202             var form_id = '';
203             
204             $.each(form_data, function(i,row){
205                 if (row.name.toString().match(/__(.*?)/)) {
206                     return;
207                 }
208                 if (   row.name == '_id'
209                     && (   row.value != undefined
210                         && row.value != ''))
211                 {
212                     doc['_id'] = String(row.value);
213                     form_id = doc['_id'];
214                 }
215                 else if(   row.name == '_rev'
216                         && (   typeof row.value != "undefined"
217                             && row.value != ''))
218                 {
219                     doc['_rev'] = String(row.value);
220                 } else {
221                     if (row.name != 'submit') {
222                         if (row.name == '_type') {
223                             }
224                             else if (   row.name.substr(0,6) != "widget"
225                                      && row.name.substr(0,8) != "metadata")
226                             {
227                                 var item = {};
228                                 var widget = {};
229                                 var prev_val = false;
230                                 var name_parts = [];
231                                 var name_parts_count = 0;
232                                 if (row.name.toString().match(/;/g)) {
233                                     name_parts = row.name.toString().split(";");
234                                     name_parts_count = name_parts.length;
235                                 }
236                                 
237                                 $.each(form_data, function(x,r){
238                                     if (r.name == 'widget['+row.name+':name]') {
239                                         widget['name'] = r.value;
240                                     } else if (r.name == 'widget['+row.name+':config]') {
241                                     widget['config'] = $.ajatus.converter.parseJSON(r.value);
242                                 } else if (r.name == 'widget['+row.name+':prev_val]') {
243                                     prev_val = $.ajatus.converter.parseJSON(r.value);
244                                 }
245                             });
246                             
247                             var wdgt = new $.ajatus.widget(widget['name'], widget['config']);
248                                 item['val'] = wdgt.value_on_save(row.value, prev_val);
249                                 item['widget'] = widget;
250                                 
251                                 if (name_parts_count > 0) {
252                                     var prevs = [];
253                                     for (var i=0; i < name_parts_count; i++) {                                  
254                                         var arr_keys = false;
255                                         var key_prefix = '';
256                                         
257                                         if (name_parts[i].match(/\[/g)) {
258                                             var arr_keys = name_parts[i].split('[');
259                                             
260                                             name_parts[i] = name_parts[i].replace(/\[/g, '"][');
261                                             var key = '["'+name_parts[i];
262                                         } else {
263                                             var key = "['"+name_parts[i]+"']";
264                                         }
265                                     
266                                     if (prevs.length > 0) {
267                                         $.each(prevs, function(pi, pk){
268                                             key_prefix = "['" + pk + "']" + key_prefix;
269                                         });
270                                         key = key_prefix + key;
271                                     }
272                                                                             
273                                     if (arr_keys) {
274                                         var tmp_key = key_prefix + "['" + arr_keys[0] + "']";
275                                         if (typeof eval("form_values"+tmp_key) == 'undefined') {
276                                             eval("form_values"+tmp_key+"=[];");
277                                         }                    
278                                     }
279                                     
280                                     var multiple = false;
281                                         if (typeof eval("form_values"+key) == 'undefined') {
282                                             if (key_prefix != '') {
283                                             eval("form_values"+key+"=new Array();");
284                                             } else {
285                                             eval("form_values"+key+"={};");                                             
286                                             }
287                                         } else {                                            
288                                             multiple = true;
289                                         }
290                                         
291                                         prevs.push(name_parts[i]);
292                                     if (i == name_parts_count-1) {
293                                         if (typeof item['val'] == 'undefined') {
294                                             return;
295                                         }
296                                         if (multiple) {
297                                             if (typeof item == 'object') {
298                                                 // eval("form_values"+key+".push('"+item.toSource()+"');");
299                                                 if (item.widget.name == 'boolean') {
300                                                     eval("form_values"+key+"="+item.val+";");
301                                                 } else {
302                                                     eval("form_values"+key+".push('"+item.val+"');");                                                    
303                                                 }
304                                             } else {
305                                                 eval("form_values"+key+".push('"+item+"');");
306                                             }                                                
307                                         } else {
308                                             if (typeof item == 'object') {
309                                                 eval("form_values"+key+"='"+item.val+"';");
310                                             } else {
311                                                 eval("form_values"+key+"='"+item.val+"';");
312                                             }
313                                         }
314                                     }
315                                     }
316                                 } else {
317                                     form_values[row.name] = item;
318                                 }
319                             }
320                             else if (row.name.substr(0,8) == "metadata")
321                             {
322                                 if (! form_values['metadata']) {
323                                     form_values['metadata'] = {};
324                                 }
326                                 var re = /\bmetadata\[([a-z]+)\b/;
327                                 var results = re.exec(row.name);
328                                 var key = results[1];
330                                 form_values['metadata'][key] = {
331                                     val: row.value
332                                 };
333                             }
334                     }
335                 }
336             });
337             doc['value'] = form_values;
339             doc = new $.ajatus.document(doc);
341             $.ajatus.preferences.view.save(doc.value);
342         },
343         
344         save: function(preferences) {
345             var saved = false;
347             var on_success = function(data) {
348                 saved = true;
349                 $.ajatus.preferences.revision = data.rev;
350                 $.ajatus.events.named_lock_pool.decrease('unsaved');                
351                 window.location.reload();
352                 
353                 return data;
354             };
355             
356             prefs_doc = new $.ajatus.document({
357                 _id: 'preferences',
358                 _rev: $.ajatus.preferences.revision,
359                 value: preferences
360             });
361             prefs_doc.value._type = 'preferences';
363             var new_metadata = {
364                 revised: $.ajatus.formatter.date.js_to_iso8601(new Date()),
365                 revisor: $.ajatus.preferences.local.user.email
366             };
367             prefs_doc = $.ajatus.document.modify_metadata(prefs_doc, new_metadata);
368             
369             var prefs = {
370                 metadata: prefs_doc.value.metadata
371             };
372             $.each($.ajatus.preferences.local_defaults, function(k,data){                
373                 if (typeof prefs[k] == 'undefined') {
374                     prefs[k] = {};
375                 }
376                 
377                 if (typeof data == 'object') {                    
378                     $.each(data, function(sk, sdata){                        
379                         if (typeof prefs_doc.value[k] == 'undefined') {
380                             prefs[k][sk] = sdata;
381                         } else {
382                             if (typeof prefs_doc.value[k][sk] == 'undefined') {
383                                 prefs[k][sk] = sdata;
384                             } else {
385                                 if (typeof prefs_doc.value[k][sk]['val'] == 'undefined') {
386                                     prefs[k][sk] = prefs_doc.value[k][sk];
387                                 } else {
388                                     prefs[k][sk] = prefs_doc.value[k][sk].val;
389                                 }
390                             }                            
391                         }
392                     });
393                 } else {
394                     if (typeof prefs_doc.value[k] == 'undefined') {
395                         prefs[k] = data;
396                     } else {
397                         if (typeof prefs_doc.value[k]['val'] == 'undefined') {
398                             prefs[k] = prefs_doc.value[k];
399                         } else {
400                             prefs[k] = prefs_doc.value[k].val;
401                         }
402                     }
403                 }                
404             });
406             prefs_doc.value = prefs;
407             
408             $.jqCouch.connection('doc', on_success).save($.ajatus.preferences.client.application_database, prefs_doc);
409             
410             return saved;
411         },
412         
413         generate_section_form: function(section) {
414             if (typeof $.ajatus.preferences.local[section] == 'undefined') {
415                 return false;
416             }
418             var items = false;            
419             var section_data = $.ajatus.preferences.local[section];
420             
421             function auto_gen(section, data) {
422                 var rows = $('<ul/>');
423                 
424                 $.each(data, function(i,s){
425                     // console.log("i: "+i+" s: ");
426                     // console.log(s);
427                     var s_type = typeof(s);
428                     // console.log('type: '+s_type);
429                     var wdgt = null;
430                     var normalized_name = i.toString().replace('_', ' ');
432                     switch (s_type) {
433                         case 'boolean':
434                             wdgt = $.ajatus.widget('boolean');
435                         break;
436                         case 'number':
437                             wdgt = $.ajatus.widget('integer');
438                         break;
439                         case 'string':
440                         default:
441                             wdgt = $.ajatus.widget('text');
442                     };
444                     rows.createAppend(
445                         'li', { id: '_setting_'+section+'_'+i, className: 'row' }, [
446                             'label', { id: '_setting_'+section+'_'+i+'_label' }, $.ajatus.i10n.get(normalized_name),
447                             'div', { id: '_setting_'+section+'_'+i+'_widget', className: wdgt.name }, wdgt.get_edit_tpl(section+';'+i, {val: s}),
448                             'br', { className: 'clear_fix' }, ''
449                         ]
450                     );            
451                     wdgt.init($('#_setting_'+i+'_widget',rows), true);
452                 });
454                 $('li:first', rows).addClass('first');
455                 $('li:last', rows).addClass('last');
456                 
457                 return rows;
458             }
459             
460             function gen_localization(data) {
461                 var rows = $('<ul/>');
462                 var langs = $.ajatus.i10n.get_available_langs();
463                 var lang_opts = {};
464                 
465                 $.each(langs, function(i,l) {
466                     lang_opts[i] = l;
467                 });
469                 wdgt = $.ajatus.widget('selection', {
470                     items: lang_opts
471                 });
472                 rows.createAppend(
473                     'li', { id: '_setting_localization_language', className: 'row' }, [
474                         'label', { id: '_setting_localization_language_label' }, $.ajatus.i10n.get('Language'),
475                         'div', { id: '_setting_localization_language_widget', className: wdgt.name }, wdgt.get_edit_tpl('localization;language', {val: data.language}),
476                         'br', { className: 'clear_fix' }, ''
477                     ]
478                 );            
479                 wdgt.init($('#_setting_localization_language_widget',rows), true);
480                 
481                 return rows;                
482             }
483             
484             function gen_layout(data) {
485                 var rows = $('<ul/>');
486                 var themes = $.ajatus.preferences.client.themes.available;
487                 var theme_opts = {};
488                 
489                 $.each(themes, function(i,l) {
490                     theme_opts[i] = $.ajatus.i10n.get(l);
491                 });
493                 wdgt = $.ajatus.widget('selection', {
494                     items: theme_opts
495                 });
496                 rows.createAppend(
497                     'li', { id: '_setting_layout_theme_name', className: 'row' }, [
498                         'label', { id: '_setting_layout_theme_name_label' }, $.ajatus.i10n.get('Theme'),
499                         'div', { id: '_setting_layout_theme_name_widget', className: wdgt.name }, wdgt.get_edit_tpl('layout;theme_name', {val: data.theme_name}),
500                         'br', { className: 'clear_fix' }, ''
501                     ]
502                 );            
503                 wdgt.init($('#_setting_layout_theme_name_widget', rows), true);
504                 
505                 return rows;
506             }
507             
508             function gen_autosave(data) {
509                 var rows = $('<ul/>');
510                 var section = 'auto_save';
511                 
512                 
513                 $.each(data, function(i,s){
514                     // console.log("i: "+i+" s: ");
515                     // console.log(s);
516                     var s_type = typeof(s);
517                     // console.log('type: '+s_type);
518                     var wdgt = null;
519                     var normalized_name = i.toString().replace('_', ' ');
520                     
521                     switch (i) {
522                         case 'enabled':
523                             wdgt = $.ajatus.widget('boolean');
524                         break;
525                         case 'interval':
526                             wdgt = $.ajatus.widget('integer',{
527                                 value_suffix: 's'
528                             });
529                         break;
530                         default:
531                             wdgt = $.ajatus.widget('text');
532                     };
534                     rows.createAppend(
535                         'li', { id: '_setting_'+section+'_'+i, className: 'row' }, [
536                             'label', { id: '_setting_'+section+'_'+i+'_label' }, $.ajatus.i10n.get(normalized_name),
537                             'div', { id: '_setting_'+section+'_'+i+'_widget', className: wdgt.name }, wdgt.get_edit_tpl(section+';'+i, {val: s}),
538                             'br', { className: 'clear_fix' }, ''
539                         ]
540                     );            
541                     wdgt.init($('#_setting_'+i+'_widget',rows), true);
542                 });
544                 $('li:first', rows).addClass('first');
545                 $('li:last', rows).addClass('last');
546                 
547                 return rows;
548             }
549             
550             // Example how to handle arrays with checkboxes
551             // function gen_types(data) {
552             //     var rows = $('<ul />');
553             //     
554             //     $.each($.ajatus.types.available, function(key,type){
555             //         // console.log("key: "+key);
556             //         // console.log(type);
557             //         
558             //         var selected = false;
559             //         $.each(data.active, function(i,t){
560             //             if (t == key) {
561             //                 selected = true;
562             //             }
563             //         });
564             //         
565             //         var widget = new $.ajatus.widget('boolean', {
566             //             value: key
567             //         });
568             // 
569             //         rows.createAppend(
570             //             'li', { id: '_setting_types_active_'+key, className: 'row' }, [
571             //                 'label', { id: '_setting_types_active_'+key+'_label' }, $.ajatus.i10n.get(type.title),
572             //                 'div', { id: '_setting_types_active_'+key+'_widget', className: widget.name }, widget.get_edit_tpl('types;active', {val: (selected ? key : '')}), //["'+key+'"]
573             //                 'br', { className: 'clear_fix' }, ''
574             //             ]
575             //         );            
576             //         widget.init($('#_setting_types_active_'+key+'_widget',rows), true);
577             //     });
578             //     
579             //     return rows;
580             // }
581             
582             switch (section) {
583                 case 'localization':
584                     items = gen_localization(section_data);
585                 break;
586                 case 'layout':
587                     items = gen_layout(section_data);
588                 break;
589                 case 'auto_save':
590                     items = gen_autosave(section_data);
591                 break;
592                 case 'replication':
593                 case 'backups':
594                 case 'expansions':
595                 break;
596                 default:
597                     items = auto_gen(section, section_data);
598             }
599             
600             return items;
601         }
602     };
603     
604 })(jQuery);