1 // © Benoît PIN 2006-2008
4 // $Id: growable_table.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/growable_table.js $
6 // GrowableTable: functions to edit quickly table form entries.
8 function GrowableTable(tbody
, fieldsDescription
, submitExtName
, skipFormManagerInit
) {
9 this.fieldsDescription
= fieldsDescription
;
11 this.length
= tbody
.getElementsByTagName('tr').length
;
12 this.submitExtName
= submitExtName
;
14 var form
= this.tbody
.parentNode
;
15 while (form
.tagName
!= 'FORM')
16 form
= form
.parentNode
;
18 var thisManager
= this;
20 if (!skipFormManagerInit
) {
21 var formManager
= new FormManager(form
);
22 formManager
.onBeforeSubmit = function(m
, e
){return thisManager
.onBeforeSubmit(m
, e
)};
23 formManager
.onResponseLoad = function(req
){thisManager
.loadResponse(req
);};
26 addListener(this.tbody
.parentNode
, 'click', function(evt
){thisManager
.tbodyClick(evt
);});
29 var links
= tbody
.parentNode
.getElementsByTagName('a');
30 for (var i
=0 ; i
<links
.length
; i
++) {
32 if (addButton
.name
== 'addrow')
35 this.addButton
= addButton
;
36 this.submittedRow
= null;
37 this.editedRowInitialValues
= null;
42 GrowableTable
.prototype.tbodyClick = function(evt
) {
43 var ob
= getTargetedObject(evt
);
44 if (ob
.tagName
== 'IMG') {
45 disablePropagation(evt
);
48 var link
= ob
.parentNode
;
49 var name
= link
.getAttribute('name');
54 this.removeRow(ob
, name
);
57 while (ob
.tagName
!= 'TBODY') {
58 if (ob
.tagName
== 'SPAN')
64 if (ob
.tagName
== 'SPAN') {
65 disablePropagation(evt
);
67 this.replaceRowByFields(ob
);
72 GrowableTable
.prototype.replaceRowByFields = function(ob
) {
73 if (this.editedRowInitialValues
)
75 this.addButton
.className
= 'hidden';
77 while (tr
.tagName
!= 'TR')
80 var span
, cell
, input
, elementName
, text
;
81 var cells
= tr
.getElementsByTagName('td');
82 elementName
= cells
[0].getElementsByTagName('a')[0].getAttribute('name');
84 this.editedRowInitialValues
= new Array();
86 for (var i
=1; i
< cells
.length
; i
++) {
88 span
= cell
.getElementsByTagName('span')[0];
89 this.editedRowInitialValues
[i
-1] = span
.innerHTML
;
91 if (span
.firstChild
&& span
.firstChild
.className
== 'hidden_value')
92 text
= span
.firstChild
.innerHTML
;
94 text
= span
.innerHTML
;
96 input
= document
.createElement('input');
99 name
=this.fieldsDescription
[i
-1][0];
100 size
=this.fieldsDescription
[i
-1][1];
103 cell
.replaceChild(input
, span
);
105 if (i
== cells
.length
- 1) {
106 var hiddenNameInput
= document
.createElement('input');
107 with (hiddenNameInput
){
109 name
='row_edit' + this.submitExtName
;
113 var validButton
= document
.createElement('input');
114 with (validButton
) {type
= 'image'; name
= 'row_edit_valid'; src
= portal_url() + '/validate.gif'; alt
= 'Validate'; height
='16'; width
='16'}
116 var cancelButton
= document
.createElement('input');
117 with (cancelButton
) {type
= 'image'; name
= 'row_edit_cancel'; src
= portal_url() + '/cancel.gif'; alt
= 'Cancel';}
119 cell
.appendChild(hiddenNameInput
)
120 cell
.appendChild(validButton
);
121 cell
.appendChild(cancelButton
);
127 GrowableTable
.prototype.cancelEditRow = function(ob
) {
129 while(tr
.tagName
!= 'TR')
132 var cells
= tr
.getElementsByTagName('td');
134 for (var i
=1 ; i
< cells
.length
; i
++) {
136 while (td
.firstChild
)
137 td
.removeChild(td
.firstChild
);
139 span
= document
.createElement('span');
140 td
.appendChild(span
);
141 span
.innerHTML
= this.editedRowInitialValues
[i
-1];
144 this.editedRowInitialValues
= null;
145 this.addButton
.className
= '';
148 GrowableTable
.prototype.onBeforeSubmit = function(m
, evt
) {
149 var target
= getTargetedObject(evt
);
150 var submitElement
, form
;
152 switch (target
.tagName
) {
154 submitElement
= target
;
158 submitElement
= m
.submitButton
;
163 switch(submitElement
.name
) {
165 this.cancelRow(submitElement
);
167 case 'row_edit_cancel':
168 this.cancelEditRow(submitElement
);
169 return 'cancelSubmit';
172 var submittedRow
= submitElement
;
173 while(submittedRow
.tagName
!= 'TR')
174 submittedRow
= submittedRow
.parentNode
;
175 this.submittedRow
= submittedRow
;
180 return 'cancelSubmit';
183 GrowableTable
.prototype.loadResponse = function(req
) {
184 var doc
= req
.responseXML
.documentElement
;
185 switch (doc
.nodeName
) {
186 case 'computedField':
187 var copy
= getCopyOfNode(doc
.firstChild
);
188 this.tbody
.replaceChild(copy
, this.submittedRow
);
189 this.addButton
.className
= '';
190 this.submittedRow
= null;
191 this.editedRowInitialValues
= null;
194 alert(doc
.firstChild
.nodeValue
);
199 GrowableTable
.prototype.addRow = function(evt
) {
200 var fieldDescription
, input
, fieldName
, fieldSize
;
202 var tr
= document
.createElement('tr');
203 var td
= document
.createElement('td');
204 var hiddenInputAddRowFlag
= document
.createElement('input');
205 with (hiddenInputAddRowFlag
){
207 name
='row_add' + this.submitExtName
;
210 td
.appendChild(hiddenInputAddRowFlag
);
213 for (var i
=0 ; i
< this.fieldsDescription
.length
; i
++) {
214 fieldDescription
= this.fieldsDescription
[i
];
215 fieldName
= fieldDescription
[0];
216 fieldSize
= fieldDescription
[1];
218 td
= document
.createElement('td');
219 input
= document
.createElement('input')
220 with(input
){type
='text'; name
=fieldName
; size
=fieldSize
; }
221 td
.appendChild(input
);
225 if (i
== this.fieldsDescription
.length
-1) {
226 var validButton
= document
.createElement('input');
227 with (validButton
) {type
= 'image'; name
= 'row_valid'; src
= portal_url() + '/validate.gif'; alt
= 'Validate'; height
='16'; width
='16'}
229 var cancelButton
= document
.createElement('input');
230 with (cancelButton
) {type
= 'image'; name
= 'row_cancel'; src
= portal_url() + '/cancel.gif'; alt
= 'Cancel';}
232 td
.appendChild(validButton
);
233 td
.appendChild(cancelButton
);
237 this.tbody
.appendChild(tr
);
240 this.addButton
.className
= 'hidden';
244 GrowableTable
.prototype.removeRow = function(ob
, name
) {
246 while (tr
.tagName
!= 'TR')
250 while (form
.tagName
!= 'FORM')
251 form
= form
.parentNode
;
253 var req
= new XMLHttpRequest();
254 var thisManager
= this;
255 req
.onreadystatechange = function() {
256 switch (req
.readyState
) {
262 if (req
.status
== '200') {
263 if (req
.responseXML
.documentElement
.tagName
== 'done')
264 thisManager
.tbody
.removeChild(tr
);
265 thisManager
.onAfterRemove(name
);
268 alert('Error: ' + req
.status
);
272 var url
= form
.action
;
273 req
.open("POST", url
, true);
274 req
.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");
275 req
.send('name=' + name
+ '&rm=rm');
278 GrowableTable
.prototype.onAfterRemove = function(name
) { }
280 GrowableTable
.prototype.cancelRow = function(element
) {
281 /* element must be on the "descendant-or-self" axis of the row to remove */
282 while (element
.tagName
!= 'TR')
283 element
= element
.parentNode
;
284 this.tbody
.removeChild(element
);
285 this.addButton
.className
= undefined;
290 * http://www.sitepoint.com/blogs/2006/01/17/javascript-inheritance/
293 function copyPrototype(descendant
, parent
) {
294 var sConstructor
= parent
.toString();
295 var aMatch
= sConstructor
.match( /\s*function (.*)\(/ );
296 if ( aMatch
!= null ) { descendant
.prototype[aMatch
[1]] = parent
; }
297 for (var m
in parent
.prototype) {
298 descendant
.prototype[m
] = parent
.prototype[m
];