e22a1802da3ef1c5ca3b820fee6d7ab41fd81850
[Plinn.git] / skins / ajax_scripts / widget_form_manager.js
1 // © 2009 Benoît Pin
2 // http://plinn.org
3 // Licence GPL
4 // $Id: widget_form_manager.js 1473 2009-03-06 17:02:21Z pin $
5 // $URL: http://svn.cri.ensmp.fr/svn/Plinn/branches/CMF-2.1/skins/ajax_scripts/widget_form_manager.js $
6
7 var WidgetBasedFormManager;
8
9 (function(){
10 WidgetBasedFormManager = function(widgets, editingArea, dataArea, dataAreaSpecs) {
11 var thisWgtManager = this;
12 this.widgets = widgets;
13 this.openedWidget = null;
14 this.dataArea = dataArea;
15 this.dataAreaSpecs = dataAreaSpecs;
16
17 var form = editingArea.getElementsByTagName('form')[0];
18 this.form = form;
19 var fm = new FormManager(form);
20 fm.onBeforeSubmit = function(fm, evt){return thisWgtManager.onBeforeSubmit(fm, evt);};
21 fm.onResponseLoad = function(req){thisWgtManager.loadResponse(req);};
22
23 addListener(this.form, 'click', function(evt){thisWgtManager.clickHandler(evt);});
24
25 };
26
27 WidgetBasedFormManager.prototype.showAddWidget = function(dest) {
28 if (this.openedWidget)
29 return;
30 var wdgtCopy = this.widgets['add'].cloneNode(true);
31 wdgtCopy.removeAttribute('id');
32 this.openedWidget = wdgtCopy;
33 dest.appendChild(wdgtCopy);
34 if (this.addButton)
35 this.addButton.style.visibility = 'hidden';
36 };
37
38 WidgetBasedFormManager.prototype.showPopulatedWidget = function(dest, url) {
39 var req = new XMLHttpRequest();
40 req.open("GET", url, false);
41 showProgressImage();
42 req.send(null);
43 hideProgressImage();
44
45 if (req.status != 200){
46 alert(req.status);
47 return;
48 }
49
50 var wdgtCopy = this.widgets['edit'].cloneNode(true);
51 wdgtCopy.removeAttribute('id');
52 var tmpForm = document.createElement('form');
53 tmpForm.appendChild(wdgtCopy);
54
55 var fields = req.responseXML.documentElement.childNodes;
56 var input, field, value;
57 for (var i = 0 ; i<fields.length; i++) {
58 field = fields[i];
59 if (!field.firstChild)
60 continue;
61
62 value = field.firstChild.nodeValue;
63 input = tmpForm.elements.namedItem(field.nodeName);
64
65 switch (input.tagName) {
66 case 'INPUT':
67 input.value = value;
68 break;
69 case 'TEXTAREA':
70 input.appendChild(document.createTextNode(value));
71 }
72 }
73 dest.appendChild(wdgtCopy);
74 };
75
76 WidgetBasedFormManager.prototype.cancelWidget = function() {
77 var parent = this.openedWidget.parentNode;
78 parent.removeChild(this.openedWidget);
79 this.openedWidget = null;
80 if (this.addButton)
81 this.addButton.style.visibility = 'visible';
82 if (this.previousRecState) {
83 this.previousRecState.style.display = '';
84 this.previousRecState = null;
85 }
86 };
87
88 WidgetBasedFormManager.prototype.updateEditedRecord = function(node) {
89 var parent = this.openedWidget.parentNode;
90 parent.removeChild(this.openedWidget);
91 this.openedWidget = null;
92 if (this.addButton)
93 this.addButton.style.visibility = 'visible';
94
95 parent = this.previousRecState.parentNode;
96 parent.replaceChild(node, this.previousRecState);
97 };
98
99 WidgetBasedFormManager.prototype.clickHandler = function(evt) {
100 var target = getTargetedObject(evt);
101 if (target.tagName == 'IMG') {
102 var parent = target.parentNode;
103 if (parent.tagName == 'A') {
104 switch (parent.name) {
105 case 'add' :
106 disableDefault(evt);
107 disablePropagation(evt);
108 parent.blur();
109 this.addButton = parent;
110 this.showAddWidget(this.form);
111 break;
112 case 'rm' :
113 disableDefault(evt);
114 disablePropagation(evt);
115 this.deleteRecord(parent);
116 break;
117 case 'edit' :
118 disableDefault(evt);
119 disablePropagation(evt);
120 if (!this.openedWidget) {
121 var rec = this._storePreviousState(parent);
122 var container = this._prepareEditingContainer(rec);
123 this.showPopulatedWidget(container, parent.href);
124 }
125 break;
126 }
127 }
128 }
129 };
130
131 WidgetBasedFormManager.prototype._storePreviousState = function(recChild) {
132 var rec = recChild;
133 while(!(this.isRootRecordElement(rec)))
134 rec = rec.parentNode;
135 rec.style.display = 'none';
136 this.previousRecState = rec;
137 return rec
138 };
139
140 WidgetBasedFormManager.prototype._prepareEditingContainer = function(rec) {
141 /* default behaviour. May be redefined by an instance */
142 var tbody = document.createElement('tbody');
143 var tr = document.createElement('tr');
144 var td = document.createElement('td')
145 td.colSpan = this.dataAreaSpecs;
146
147 tbody.appendChild(tr);
148 tr.appendChild(td)
149
150 if (rec.nextSibling)
151 rec.parentNode.insertBefore(tbody, rec.nextSibling);
152 else
153 rec.parentNode.appendChild(tbody);
154
155 this.openedWidget = tbody;
156 return td
157 };
158
159
160
161 WidgetBasedFormManager.prototype.deleteRecord = function(link) {
162 var req = new XMLHttpRequest();
163
164 var thisManager = this;
165 req.onreadystatechange = function() {
166 switch (req.readyState) {
167 case 1 :
168 showProgressImage();
169 break;
170 case 4 :
171 hideProgressImage();
172 if (req.status == 200)
173 thisManager._deleteHtmlRecord(req, link);
174 else
175 alert('Error: ' + req.status);
176 };
177 };
178 var url = link.href;
179 req.open("POST", url, true);
180 req.send(null);
181 };
182
183
184 WidgetBasedFormManager.prototype._deleteHtmlRecord = function(req, link) {
185 var doc = req.responseXML.documentElement;
186 switch (doc.nodeName) {
187 case 'done':
188 var rec = link.parentNode;
189 while(!(this.isRootRecordElement(rec)))
190 rec = rec.parentNode;
191 this.dataArea.removeChild(rec);
192 break;
193 case 'error':
194 alert(doc.firstChild.nodeValue);
195 break;
196 }
197 };
198
199 WidgetBasedFormManager.prototype.isRootRecordElement = function(e) {
200 /* default behaviour. May be redefined by an instance */
201 return (e.tagName == 'TBODY')
202 };
203
204 WidgetBasedFormManager.prototype.onBeforeSubmit = function(fm, evt) {
205 if (fm.submitButton.name == 'cancel'){
206 this.cancelWidget();
207 return 'cancelSubmit';
208 }
209 };
210
211
212 WidgetBasedFormManager.prototype.loadResponse = function(req) {
213 if (req.status == 200) {
214 var doc = req.responseXML.documentElement;
215 switch (doc.nodeName) {
216 case 'computedField':
217 switch(doc.getAttribute('type')) {
218 case 'added' :
219 this.cancelWidget();
220 this.dataArea.appendChild(getCopyOfNode(doc.firstChild));
221 break;
222
223 case 'edited' :
224 this.updateEditedRecord(getCopyOfNode(doc.firstChild));
225 }
226 break;
227
228 case 'error':
229 alert(doc.firstChild.nodeValue);
230 break;
231
232 case 'fragments' :
233 var fragments = req.responseXML.documentElement.childNodes;
234 var fragment, dest, scripts;
235 for (var i=0 ; i<fragments.length ; i++) {
236 fragment = fragments[i];
237 if (fragment.nodeName == 'fragment') {
238 dest = document.getElementById(fragment.getAttribute('id'));
239 dest.innerHTML = fragment.firstChild.nodeValue;
240
241 scripts = dest.getElementsByTagName('script');
242 for (var j=0 ; j < scripts.length ; j++)
243 globalScriptRegistry.loadScript(scripts[j]);
244 }
245 }
246 break;
247 }
248 }
249 else
250 alert(req.statut);
251 };
252
253 })();