Added focus saving and restoring after auto save
[ajatus.git] / js / ajatus.forms.js
blob0654a2c7a3be97562289980b364298b0b5bd8780
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.forms = {
19         active: false,
20         active_type: null
21     };
22     $.extend($.ajatus.forms, {
23         clear_data: function() {
24             $.ajatus.forms.active = false;
25             $.ajatus.forms.active_type = null;
26             $.ajatus.forms.process.has_errors = false;
27             $.ajatus.forms.process.error_fields = {};
28         },
29         register: {
30             normal: function(form, type) {
31                 $.ajatus.events.named_lock_pool.increase('unsaved');
32                 $.ajatus.forms.clear_data();
33                 $.ajatus.forms.active = form;
34                 if (typeof type != 'undefined') {
35                     $.ajatus.forms.active_type = type;                    
36                 }
37                 
38                     jqform = $(form);
39                     jqform.bind('submit',function(e){
40                         return false;
41                     });
43                     $('input[@type=submit][name*=save]', jqform).bind('click', function(){                      
44                     var status = $.ajatus.forms.process.normal(jqform.formToArray(false));
45                     
46                     $.ajatus.forms.active = false;
47                     
48                     return false;
49                     });
50                     $('input[@type=submit][name*=cancel]', jqform).bind('click', function(){
51                     $.ajatus.history.navigate(-1);
52                         
53                         $.ajatus.forms.active = false;
54                         return false;
55                     });
56             },
57             ajax: function(form, callback, type) {
58                 if (typeof callback == 'undefined') {
59                     $.ajatus.forms.register.normal(form);
60                     return;
61                 }
62                 $.ajatus.events.named_lock_pool.increase('unsaved');
63                 $.ajatus.forms.clear_data();
64                 $.ajatus.forms.active = form;
65                 if (typeof type != 'undefined') {
66                     $.ajatus.forms.active_type = type;                    
67                 }
68                 
69                     jqform = $(form);
70                     jqform.bind('submit',function(e){
71                         return false;
72                     });
74                     $('input[@type=submit][name*=save]', jqform).bind('click', function(){
75                     $.ajatus.forms.process.ajax(jqform.formToArray(false), callback);
76                     
77                     $.ajatus.forms.active = false;
78                     return false;
79                     });
80                     $('input[@type=submit][name*=cancel]', jqform).bind('click', function(){
81                     $.ajatus.history.navigate(-1);
82                         
83                         $.ajatus.forms.active = false;
84                         return false;
85                     });
86             },
87             custom: function(form, save_func) {
88                 if (typeof save_func == 'undefined') {
89                     return;
90                 }                
91                 $.ajatus.events.named_lock_pool.increase('unsaved');
92                 $.ajatus.forms.clear_data();
93                 $.ajatus.forms.active = form;
94                 
95                     jqform = $(form);
96                     jqform.bind('submit',function(e){
97                         return false;
98                     });
100                     $('input[@type=submit][name*=save]', jqform).bind('click', function(){
101                     var fn = save_func;
102                     if (typeof save_func == 'string') {
103                         fn = eval(save_func);
104                     }
105                     fn.apply(fn, [jqform.formToArray(false), form]);
106                     
107                     $.ajatus.forms.active = false;
108                     return false;
109                     });
110                     $('input[@type=submit][name*=cancel]', jqform).bind('click', function(){
111                     $.ajatus.history.navigate(-1);
112                         
113                         $.ajatus.forms.active = false;
114                         return false;
115                     });                
116             }
117         },        
118         process: {
119             doc: null,
120             has_errors: false,
121             error_fields: {},
122             
123             common: function(form_data) {
124                 $.ajatus.forms.process.has_errors = false;
125                 $.ajatus.forms.process.error_fields = {};
126                 
127                     var doc = {
128                         _id: '',
129                         _rev: '',
130                         value: {}
131                     };
132                     var form_values = {};
133                     var form_id = '';
134                     var doc_type = 'note';
135                 var additionals = false;
136                 
137                 var parted_names_done = [];
138                 
139                 var prev_values_count = 0;
140                 var changed_values_count = 0;
141                 
142                     $.each(form_data, function(i,row){
143                     // console.log('i: '+i+' row.name: '+row.name+' row.value: '+row.value);
144                     if (row.name.toString().match(/__(.*?)/)) {
145                         return;
146                     }
147                         if (   row.name == '_id'
148                             && (   typeof row.value != 'undefined'
149                                 && row.value != ''))
150                         {
151                             doc['_id'] = String(row.value);
152                             form_id = doc['_id'];
153                         }
154                         else if(   row.name == '_rev'
155                                 && (   typeof row.value != 'undefined'
156                                     && row.value != ''))
157                         {
158                             doc['_rev'] = String(row.value);
159                     }
160                         else if(   row.name == '_additionals'
161                                 && (   typeof row.value != 'undefined'
162                                     && row.value != ''))
163                         {
164                             //additionals = $.ajatus.converter.parseJSON(row.value);
165                         } else {
166                             if (row.name != 'submit') {
167                                 if (row.name == '_type') {
168                                 doc_type = row.value;
169                                 form_values[row.name] = row.value;
170                             }
171                             else if (   row.name.substr(0,6) != "widget"
172                                      && row.name.substr(0,8) != "metadata")
173                             {
174                                 var item = {};
175                                 var widget = {};
176                                 var prev_val = undefined;
177                                 var additional = false;
178                                 var additional_updated = false;
179                                 var field_updated = false;
180                                 var row_key = row.name;
181                                 
182                                 var name_parts = [];
183                                 var name_parts_count = 0;
184                                 if (row_key.toString().match(/\|/g)) {
185                                     name_parts = row_key.toString().split("|");
186                                     name_parts_count = name_parts.length;
187                                     
188                                     if ($.inArray(name_parts[0], parted_names_done) != -1) {
189                                         return;
190                                     }
191                                     
192                                     row_key = name_parts[0];
193                                 }
194                                 
195                                 $.each(form_data, function(x,r){
196                                     if (r.name == 'widget['+row_key+':name]') {
197                                         widget['name'] = r.value;
198                                     } else if (r.name == 'widget['+row_key+':config]') {
199                                             widget['config'] = $.ajatus.converter.parseJSON(r.value);
200                                         } else if (r.name == 'widget['+row_key+':prev_val]') {
201                                             if (r.value == '') {
202                                                 prev_val = r.value;
203                                             } else {
204                                                 prev_val = $.ajatus.converter.parseJSON(r.value);
205                                             }
206                                             prev_values_count += 1;
207                                         } else if (r.name == 'widget['+row_key+':additional]') {
208                                             additional = $.ajatus.converter.parseJSON(r.value);
209                                         } else if (r.name == 'widget['+row_key+':field_updated]') {
210                                         field_updated = $.ajatus.converter.parseJSON(r.value);
211                                     } else if (r.name == 'widget['+row_key+':additional_updated]') {
212                                         additional_updated = $.ajatus.converter.parseJSON(r.value);
213                                         } else if (r.name == 'widget['+row_key+':required]') {
214                                         widget['required'] = $.ajatus.utils.to_boolean(r.value);
215                                     }
216                                         
217                                     });
219                                     if (   additional_updated
220                                         || field_updated)
221                                     {
222                                         prev_values_count += 1;
223                                         changed_values_count += 1;
224                                     }
226                                     var wdgt = new $.ajatus.widget(widget['name'], widget['config']);
228                                 if (typeof widget['required'] != 'undefined') {
229                                         wdgt.required = widget['required'];
230                                 }
231                                     
232                                     if (typeof wdgt.validate == 'function') {
233                                         var status = wdgt.validate(row_key, row.value);
234                                         if (typeof status == 'object') {
235                                             $.ajatus.forms.process.has_errors = true;
236                                             $.ajatus.forms.process.error_fields[row_key] = status;
237                                         }
238                                     }
239                                     
240                                     if (name_parts_count > 0) {
241                                         var row_val = {};
242                                         
243                                         $.each(form_data, function(x,r){
244                                             var np = [];
245                                             if (r.name.toString().match(/\|/g)) {
246                                             // console.log(r.name+" matches with |");
247                                                 np = r.name.toString().split("|");
248                                             // console.log(np);
249                                                 if (np[0] == name_parts[0]) {
250                                                     if (typeof row_val[np[1]] == 'undefined') {
251                                                     row_val[np[1]] = r.value;
252                                                     }
253                                                 }
254                                             }
255                                     });
257                                     parted_names_done.push(name_parts[0]);
258                                     
259                                     item['val'] = wdgt.value_on_save(row_val, prev_val, true);
260                                     } else {
261                                     item['val'] = wdgt.value_on_save(row.value, prev_val, false);
262                                     }
263                                     
264                                     if (typeof prev_val != 'undefined') {
265                                     if (wdgt.has_data_changed(item['val'], prev_val)) {
266                                         changed_values_count += 1;
267                                     }
268                                     }
269                                     
270                                 item['widget'] = widget;
271                                 
272                                 if (additional) {
273                                     item['additional'] = true;
274                                     if (additionals == false) {
275                                         additionals = {};
276                                     }
277                                     additionals[row_key] = additional;
278                                 }
279                                 
280                                 form_values[row_key] = item;
281                             }
282                             else if (row.name.substr(0,8) == "metadata")
283                             {
284                                 if (typeof form_values['metadata'] == 'undefined') {
285                                     form_values['metadata'] = {};
286                                 }
288                                 var re = /\bmetadata\[([a-z]+)\b/;
289                                 var results = re.exec(row.name);
290                                 var key = results[1];
292                                 form_values['metadata'][key] = {
293                                     val: row.value
294                                 };
295                             }
296                             }
297                         }
298                     });
299                     
300                     if (additionals) {
301                         form_values['_additionals'] = additionals;
302                     }
303                     
304                     doc['value'] = form_values;
306                     doc = new $.ajatus.document(doc);
307                 
308                     var now = $.ajatus.formatter.date.js_to_iso8601(new Date());
310                     var new_metadata = {
311                         revised: now,
312                         revisor: $.ajatus.preferences.local.user.email
313                     };
314                     if (   typeof doc._id == 'undefined'
315                         || doc._id == '')
316                     {
317                         new_metadata['created'] = now;
318                         new_metadata['creator'] = $.ajatus.preferences.local.user.email;
319                     }
321                     $.ajatus.forms.process.doc = $.ajatus.document.modify_metadata(doc, new_metadata);
322                     
323                     if (   prev_values_count > 0
324                         && changed_values_count == 0)
325                     {
326                         $.ajatus.forms.process.has_errors = true;
327                         $.ajatus.forms.process.error_fields['form'] = {
328                             msg: $.ajatus.i10n.get('Nothing to update')
329                         };
330                     }
331                     
332                     return $.ajatus.forms.process.doc;
333             },
334             normal: function(form_data) {
335                 $.ajatus.events.named_lock_pool.decrease('unsaved');
336                 
337                 var doc = $.ajatus.forms.process.common(form_data);
338                 
339                 if ($.ajatus.forms.process.has_errors) {
340                     if (   typeof doc._id == 'undefined'
341                         || doc._id == '')
342                     {
343                             $.ajatus.views.system.create.render(doc.value._type, doc);
344                     } else {
345                             $.ajatus.views.system.edit.render(doc.value._type, doc, true);
346                     }
348                     return false;
349                 } else {
350                     $.jqCouch.connection('doc').save($.ajatus.preferences.client.content_database, doc);
351                     doc = new $.ajatus.document(doc);
352                     
353                     $.ajatus.views.system.edit.render(doc._type, doc);
355                     var content_type = $.ajatus.preferences.client.content_types[doc.value._type];
356                     var msg = $.ajatus.elements.messages.create(
357                         $.ajatus.i10n.get('Object saved'),
358                         $.ajatus.i10n.get("%s saved successfully", [content_type.title])
359                     );
360                     
361                     $.ajatus.events.signals.trigger('object_saved', {
362                         doc: doc,
363                         content_type: content_type,
364                         form_type: $.ajatus.forms.active_type
365                     });
366                     
367                     return true;
368                 }
369             },
370             ajax: function(form_data, callback) {
371                 var doc = $.ajatus.forms.process.common(form_data);
372                 $.jqCouch.connection('doc').save($.ajatus.preferences.client.content_database, doc);
373                 doc = new $.ajatus.document(doc);
374                 
375                 $.ajatus.events.named_lock_pool.decrease('unsaved');
377                 if (typeof callback == 'function') {
378                     callback.apply(callback, [doc]);
379                 }
380                 
381                 $.ajatus.events.signals.trigger('object_saved', {
382                     doc: doc,
383                     content_type: $.ajatus.preferences.client.content_types[doc.value._type],
384                     form_type: $.ajatus.forms.active_type
385                 });
386                 
387                     return true;
388             }
389         },
390     });
391     
392 })(jQuery);