1 if(typeof Rico=='undefined') throw("LiveGridForms requires the Rico JavaScript framework");
\r
2 if(typeof RicoUtil=='undefined') throw("LiveGridForms requires the RicoUtil object");
\r
3 if(typeof RicoTranslate=='undefined') throw("LiveGridForms requires the RicoTranslate object");
\r
6 Rico.TableEdit = Class.create();
\r
8 Rico.TableEdit.prototype = {
\r
10 initialize: function(liveGrid) {
\r
11 Rico.writeDebugMsg('Rico.TableEdit initialize: '+liveGrid.tableId);
\r
14 maxDisplayLen : 20, // max displayed text field length
\r
15 panelHeight : 200, // size of tabbed panels
\r
17 hoverClass : 'tabHover',
\r
18 selectedClass : 'tabSelected',
\r
19 compact : false, // compact corners
\r
20 RecordName : 'record',
\r
21 readOnlyColor : '#AAA', // read-only fields displayed using this color
\r
22 showSaveMsg : 'errors' // disposition of database update responses (full - show full response, errors - show full response for errors and short response otherwise)
24 Object.extend(this.options, liveGrid.options);
25 this.menu=liveGrid.menu;
\r
26 this.menu.options.dataMenuHandler=this.editMenu.bind(this);
\r
27 this.menu.ignoreClicks();
\r
28 RicoEditControls.atLoad();
\r
29 this.createEditDiv();
\r
30 this.saveMsg=$(liveGrid.tableId+'_savemsg');
\r
31 Event.observe(document,"click", this.clearSaveMsg.bindAsEventListener(this), false);
\r
33 this.extraMenuItems=new Array();
\r
34 this.responseHandler=this.processResponse.bind(this);
\r
37 createEditDiv: function() {
\r
39 // create editDiv (form)
\r
41 this.requestCount=1;
\r
42 this.editDiv = this.grid.createDiv('edit',document.body);
\r
43 this.editDiv.style.display='none';
\r
44 if (this.options.canEdit || this.options.canAdd) {
\r
46 this.createForm(this.form);
\r
48 var button=this.createButton("Close");
\r
49 Event.observe(button,"click", this.cancelEdit.bindAsEventListener(this), false);
50 this.createForm(this.editDiv);
\r
52 this.editDivCreated=true;
\r
53 this.formPopup=new Rico.Popup({ignoreClicks:true},this.editDiv);
\r
55 // create responseDialog
\r
57 this.responseDialog = this.grid.createDiv('editResponse',document.body);
\r
58 this.responseDialog.style.display='none';
\r
60 var button = document.createElement('button');
\r
61 button.appendChild(document.createTextNode('OK'));
\r
62 button.onclick=this.ackResponse.bindAsEventListener(this);
63 this.responseDialog.appendChild(button);
65 this.responseDiv = this.grid.createDiv('editResponseText',this.responseDialog);
\r
67 if (this.panelGroup) {
\r
68 Rico.writeDebugMsg("createEditDiv complete, requestCount="+this.requestCount);
69 setTimeout(this.initPanelGroup.bind(this),50);
\r
73 initPanelGroup: function() {
\r
74 this.requestCount--;
\r
75 Rico.writeDebugMsg("initPanelGroup: "+this.requestCount);
76 if (this.requestCount>0) return;
\r
77 var wi=parseInt(this.options.panelWidth);
\r
78 this.form.style.width=(wi+10)+'px';
79 if (Prototype.Browser.WebKit) this.editDiv.style.display='block'; // this causes display to flash briefly
\r
80 this.options.bgColor = Rico.Color.createColorFromBackground(this.form);
\r
81 this.editDiv.style.display='none';
\r
82 this.options.panelHdrWidth=(Math.floor(wi / this.options.panels.length)-4)+'px';
\r
83 this.Accordion=new Rico.TabbedPanel(this.panelHdr.findAll(this.notEmpty), this.panelContent.findAll(this.notEmpty), this.options);
\r
86 notEmpty: function(v) {
\r
87 return typeof(v)!='undefined';
\r
90 startForm: function() {
\r
91 this.form = document.createElement('form');
\r
92 this.form.onsubmit=function() {return false;};
93 this.editDiv.appendChild(this.form);
\r
95 var tab = document.createElement('table');
\r
96 var row = tab.insertRow(-1);
97 var cell = row.insertCell(-1);
98 var button=cell.appendChild(this.createButton("Save \t"+this.options.RecordName));
\r
99 Event.observe(button,"click", this.TESubmit.bindAsEventListener(this), false);
100 var cell = row.insertCell(-1);
101 var button=cell.appendChild(this.createButton("Cancel"));
\r
102 Event.observe(button,"click", this.cancelEdit.bindAsEventListener(this), false);
103 this.form.appendChild(tab);
106 this.hiddenFields = document.createElement('div');
107 this.hiddenFields.style.display='none';
\r
108 this.action = this.appendHiddenField(this.grid.tableId+'__action','');
\r
109 for (var i=0; i<this.grid.columns.length; i++) {
\r
110 var fldSpec=this.grid.columns[i].format;
\r
111 if (fldSpec && fldSpec.FormView && fldSpec.FormView=="hidden")
\r
112 this.appendHiddenField(fldSpec.FieldName,fldSpec.ColData);
\r
114 this.form.appendChild(this.hiddenFields);
117 createButton: function(buttonLabel) {
\r
118 var button = document.createElement('button');
\r
119 buttonLabel=RicoTranslate.getPhrase(buttonLabel);
\r
120 button.innerHTML="<span style='text-decoration:underline;'>"+buttonLabel.charAt(0)+"</span>"+buttonLabel.substr(1);
\r
121 button.accessKey=buttonLabel.charAt(0);
\r
125 createPanel: function(i) {
\r
126 var hasFields=false;
\r
127 for (var j=0; j<this.grid.columns.length; j++) {
\r
128 var fldSpec=this.grid.columns[j].format;
\r
129 if (!fldSpec) continue;
\r
130 if (!fldSpec.EntryType) continue
\r
131 if (fldSpec.EntryType=='H') continue;
\r
132 var panelIdx=fldSpec.panelIdx || 0;
\r
138 if (!hasFields) return false;
\r
139 this.panelHdr[i] = document.createElement('div');
\r
140 this.panelHdr[i].className='tabHeader';
\r
141 this.panelHdr[i].innerHTML=this.options.panels[i];
142 this.panelHdrs.appendChild(this.panelHdr[i]);
143 this.panelContent[i] = document.createElement('div');
144 this.panelContent[i].className='tabContent';
\r
145 this.panelContents.appendChild(this.panelContent[i]);
\r
149 createForm: function(parentDiv) {
\r
152 this.panelContent=[];
\r
153 if (this.options.panels) {
\r
154 this.panelGroup = document.createElement('div');
\r
155 this.panelGroup.className='tabPanelGroup';
156 this.panelHdrs = document.createElement('div');
\r
157 this.panelGroup.appendChild(this.panelHdrs);
\r
158 this.panelContents = document.createElement('div');
\r
159 this.panelContents.className='tabContentContainer';
160 this.panelGroup.appendChild(this.panelContents);
\r
161 parentDiv.appendChild(this.panelGroup);
\r
162 if (this.grid.direction=='rtl') {
\r
163 for (var i=this.options.panels.length-1; i>=0; i--)
\r
164 if (this.createPanel(i))
\r
165 tables[i]=this.createFormTable(this.panelContent[i],'tabContent');
\r
167 for (var i=0; i<this.options.panels.length; i++)
\r
168 if (this.createPanel(i))
\r
169 tables[i]=this.createFormTable(this.panelContent[i],'tabContent');
\r
171 parentDiv.appendChild(this.panelGroup);
\r
173 var div=document.createElement('div');
174 div.className='noTabContent';
\r
175 tables[0]=this.createFormTable(div);
\r
176 parentDiv.appendChild(div);
\r
178 for (var i=0; i<this.grid.columns.length; i++) {
\r
179 var fldSpec=this.grid.columns[i].format;
\r
180 if (!fldSpec) continue;
\r
181 var panelIdx=fldSpec.panelIdx || 0;
\r
182 if (tables[panelIdx]) this.appendFormField(this.grid.columns[i],tables[panelIdx]);
\r
186 createFormTable: function(div) {
\r
187 var tab=document.createElement('table');
\r
189 div.appendChild(tab);
193 appendHiddenField: function(name,value) {
\r
194 var field=RicoUtil.createFormField(this.hiddenFields,'input','hidden',name,name);
\r
199 appendFormField: function(column, table) {
\r
200 if (!column.format.EntryType) return;
\r
201 if (column.format.EntryType=="H") return;
\r
202 if (column.format.FormView) return;
\r
203 Rico.writeDebugMsg('appendFormField: '+column.format.Hdg+' - '+column.format.EntryType);
\r
204 var row = table.insertRow(-1);
\r
205 var hdr = row.insertCell(-1);
206 column.formLabel=hdr;
207 if (hdr.noWrap) hdr.noWrap=true;
208 var entry = row.insertCell(-1);
\r
209 if (entry.noWrap) entry.noWrap=true;
210 hdr.innerHTML=column.format.Hdg;
\r
211 hdr.className='ricoEditLabel';
\r
212 if (column.format.Help) {
\r
213 hdr.title=column.format.Help;
\r
214 hdr.className='ricoEditLabelWithHelp';
\r
216 var field, name=column.format.FieldName;
\r
217 switch (column.format.EntryType) {
\r
218 case 'TA','tinyMCE':
\r
219 field=RicoUtil.createFormField(entry,'textarea',null,name);
\r
220 field.cols=column.format.TxtAreaCols;
\r
221 field.rows=column.format.TxtAreaRows;
\r
222 field.innerHTML=column.format.ColData;
\r
223 hdr.style.verticalAlign='top';
\r
227 field=RicoUtil.createFormField(entry,'div',null,name);
\r
228 if (column.format.isNullable)
\r
229 this.addSelectOption(field,this.options.TableSelectNone,"(none)");
\r
230 this.selectValuesRequest(field,column.format);
\r
233 field=RicoUtil.createFormField(entry,'select',null,name);
\r
234 if (column.format.isNullable)
\r
235 this.addSelectOption(field,this.options.TableSelectNone,"(none)");
\r
236 field.onchange=this.checkSelectNew.bindAsEventListener(this);
\r
237 this.selectValuesRequest(field,column.format);
\r
238 field=document.createElement('span');
\r
239 field.className='ricoEditLabel';
\r
240 field.id='labelnew__'+column.format.FieldName;
\r
241 field.innerHTML=' New value:';
\r
242 entry.appendChild(field);
\r
243 name='textnew__'+column.format.FieldName;
\r
244 field=RicoUtil.createFormField(entry,'input','text',name,name);
\r
248 field=RicoUtil.createFormField(entry,'select',null,name);
\r
249 if (column.format.isNullable)
\r
250 this.addSelectOption(field,this.options.TableSelectNone,"(none)");
\r
251 this.selectValuesRequest(field,column.format);
\r
254 field=RicoUtil.createFormField(entry,'input','text',name,name);
\r
255 if (column.format.Length) {
\r
256 field.maxLength=column.format.Length;
\r
257 field.size=Math.min(column.format.Length, this.options.maxDisplayLen);
\r
259 field.value=column.format.ColData;
\r
263 if (column.format.SelectCtl)
\r
264 RicoEditControls.applyTo(column,field);
\r
268 checkSelectNew: function(e) {
\r
269 this.updateSelectNew(Event.element(e));
\r
272 updateSelectNew: function(SelObj) {
\r
273 var vis=(SelObj.value==this.options.TableSelectNew) ? "" : "hidden";
\r
274 $("labelnew__" + SelObj.id).style.visibility=vis
\r
275 $("textnew__" + SelObj.id).style.visibility=vis
\r
278 selectValuesRequest: function(elem,fldSpec) {
\r
279 if (fldSpec.SelectValues) {
\r
280 var valueList=fldSpec.SelectValues.split(',');
\r
281 for (var i=0; i<valueList.length; i++)
\r
282 this.addSelectOption(elem,valueList[i],valueList[i],i);
\r
284 this.requestCount++;
\r
286 Object.extend(options, this.grid.buffer.ajaxOptions);
\r
287 options.parameters = 'id='+fldSpec.FieldName+'&offset=0&page_size=-1';
288 options.onComplete = this.selectValuesUpdate.bind(this);
289 new Ajax.Request(this.grid.buffer.dataSource, options);
290 Rico.writeDebugMsg("selectValuesRequest: "+options.parameters);
294 selectValuesUpdate: function(request) {
\r
295 var response = request.responseXML.getElementsByTagName("ajax-response");
296 Rico.writeDebugMsg("selectValuesUpdate: "+request.status);
297 if (response == null || response.length != 1) return;
298 response=response[0];
299 var error = response.getElementsByTagName('error');
300 if (error.length > 0) {
301 Rico.writeDebugMsg("Data provider returned an error:\n"+RicoUtil.getContentAsString(error[0],this.grid.buffer.isEncoded));
302 alert(RicoTranslate.getPhrase("The request returned an error")+":\n"+RicoUtil.getContentAsString(error[0],this.grid.buffer.isEncoded));
305 response=response.getElementsByTagName('response')[0];
\r
306 var id = response.getAttribute("id").slice(0,-8);
307 var rowsElement = response.getElementsByTagName('rows')[0];
\r
308 var rows = this.grid.buffer.dom2jstable(rowsElement);
\r
310 //alert('selectValuesUpdate:'+id+' '+elem.tagName);
311 Rico.writeDebugMsg("selectValuesUpdate: id="+id+' rows='+rows.length);
312 for (var i=0; i<rows.length; i++) {
\r
313 if (rows[i].length>0) {
\r
314 var c0=rows[i][0].content;
\r
315 var c1=(rows[i].length>1) ? rows[i][1].content : c0;
\r
316 this.addSelectOption(elem,c0,c1,i);
\r
319 if ($('textnew__'+id))
\r
320 this.addSelectOption(elem,this.options.TableSelectNew,"(new value)");
\r
321 if (this.panelGroup)
\r
322 setTimeout(this.initPanelGroup.bind(this),50);
\r
325 addSelectOption: function(elem,value,text,idx) {
\r
326 switch (elem.tagName.toLowerCase()) {
\r
328 var opt=RicoUtil.createFormField(elem,'input','radio',elem.id+'_'+idx,elem.id);
\r
330 var lbl=document.createElement('label');
\r
331 lbl.innerHTML=text;
\r
332 lbl.htmlFor=opt.id;
\r
333 elem.appendChild(lbl);
\r
336 var opt=document.createElement('option');
\r
339 //elem.options.add(opt);
\r
340 if (Prototype.Browser.IE)
\r
343 elem.add(opt,null);
\r
348 clearSaveMsg: function() {
\r
349 if (this.saveMsg) this.saveMsg.innerHTML="";
\r
352 addMenuItem: function(menuText,menuAction,enabled) {
\r
353 this.extraMenuItems.push({menuText:menuText,menuAction:menuAction,enabled:enabled});
\r
356 editMenu: function(grid,r,c,onBlankRow) {
\r
357 this.clearSaveMsg();
\r
358 if (this.grid.buffer.sessionExpired==true || this.grid.buffer.startPos<0) return;
\r
360 var elemTitle=$('pageTitle');
\r
361 var pageTitle=elemTitle ? elemTitle.innerHTML : document.title;
\r
362 this.menu.addMenuHeading(pageTitle);
\r
363 for (var i=0; i<this.extraMenuItems.length; i++) {
\r
364 this.menu.addMenuItem(this.extraMenuItems[i].menuText,this.extraMenuItems[i].menuAction,this.extraMenuItems[i].enabled);
\r
366 if (onBlankRow==false) {
\r
367 this.menu.addMenuItem("Edit\t this "+this.options.RecordName,this.editRecord.bindAsEventListener(this),this.options.canEdit);
\r
368 this.menu.addMenuItem("Delete\t this "+this.options.RecordName,this.deleteRecord.bindAsEventListener(this),this.options.canDelete);
\r
370 this.menu.addMenuItem("Add\t new "+this.options.RecordName,this.addRecord.bindAsEventListener(this),this.options.canAdd);
\r
374 cancelEdit: function(e) {
\r
376 for (var i=0; i<this.grid.columns.length; i++)
\r
377 if (this.grid.columns[i].format && this.grid.columns[i].format.SelectCtl)
\r
378 RicoEditControls.close(this.grid.columns[i].format.SelectCtl);
\r
379 this.makeFormInvisible();
\r
380 this.grid.highlightEnabled=true;
\r
381 this.menu.cancelmenu();
\r
385 setField: function(fldSpec,fldvalue) {
\r
386 var e=$(fldSpec.FieldName);
\r
388 //alert('setField: '+fldSpec.FieldName+'='+fldvalue);
\r
389 switch (e.tagName.toUpperCase()) {
\r
391 var elems=e.getElementsByTagName('INPUT');
\r
392 var fldcode=this.getLookupValue(fldvalue)[0];
\r
393 for (var i=0; i<elems.length; i++)
\r
394 elems[i].checked=(elems[i].value==fldcode);
\r
397 if (fldSpec.SelectCtl)
\r
398 fldvalue=this.getLookupValue(fldvalue)[0];
\r
399 switch (e.type.toUpperCase()) {
\r
407 var opts=e.options;
\r
408 var fldcode=this.getLookupValue(fldvalue)[0];
\r
409 //alert('setField SELECT: id='+e.id+'\nvalue='+fldcode+'\nopt cnt='+opts.length)
\r
410 for (var i=0; i<opts.length; i++) {
\r
411 if (opts[i].value==fldcode) {
\r
416 if (fldSpec.EntryType=='N') {
\r
417 var txt=$('textnew__'+e.id);
\r
418 if (!txt) alert('Warning: unable to find id "textnew__'+e.id+'"');
\r
419 txt.value=fldvalue;
\r
420 if (e.selectedIndex!=i) e.selectedIndex=opts.length-1;
\r
421 this.updateSelectNew(e);
\r
426 if (fldSpec.EntryType=='tinyMCE' && typeof(tinyMCE)!='undefined' && this.initialized)
\r
427 tinyMCE.updateContent(e.id);
\r
432 getLookupValue: function(value) {
\r
433 if (typeof value!='string')
\r
435 else if (value.match(/<span\s+class=(['"]?)ricolookup\1>(.*)<\/span>/i))
\r
436 return [RegExp.$2,RegExp.leftContext];
\r
438 return [value,value];
\r
441 // use with care: Prototype 1.5 does not include disabled fields in the post-back
\r
442 setReadOnly: function(addFlag) {
\r
443 for (var i=0; i<this.grid.columns.length; i++) {
\r
444 var fldSpec=this.grid.columns[i].format;
\r
445 if (!fldSpec) continue;
\r
446 var e=$(fldSpec.FieldName);
\r
448 var ro=!fldSpec.Writeable || fldSpec.ReadOnly || (fldSpec.InsertOnly && !addFlag) || (fldSpec.UpdateOnly && addFlag);
\r
449 var color=ro ? this.options.readOnlyColor : '';
\r
450 switch (e.tagName.toUpperCase()) {
\r
452 var elems=e.getElementsByTagName('INPUT');
\r
453 for (var j=0; j<elems.length; j++)
\r
454 elems[j].disabled=ro;
\r
457 if (fldSpec.EntryType=='N') {
\r
458 var txt=$('textnew__'+e.id);
\r
466 e.style.color=color;
\r
467 if (fldSpec.selectIcon) fldSpec.selectIcon.style.display=ro ? 'none' : '';
\r
473 hideResponse: function(msg) {
\r
474 this.responseDiv.innerHTML=msg;
\r
475 this.responseDialog.style.display='none';
\r
478 showResponse: function() {
\r
479 var offset=Position.page(this.grid.outerDiv);
\r
480 offset[1]+=RicoUtil.docScrollTop();
\r
481 this.responseDialog.style.top=offset[1]+"px";
\r
482 this.responseDialog.style.display='';
\r
485 processResponse: function() {
\r
486 var ch=this.responseDiv.childNodes;
\r
487 for (var i=ch.length-1; i>=0; i--) {
\r
488 if (ch[i].nodeType==1 && ch[i].nodeName!='P' && ch[i].nodeName!='DIV' && ch[i].nodeName!='BR')
\r
489 this.responseDiv.removeChild(ch[i]);
\r
491 var responseText=this.responseDiv.innerHTML;
\r
492 if (responseText.toLowerCase().indexOf('error')==-1 && this.options.showSaveMsg!='full') {
\r
493 this.hideResponse('');
\r
494 this.grid.resetContents();
\r
495 this.grid.buffer.foundRowCount = false;
\r
496 this.grid.buffer.fetch(this.grid.lastRowPos || 0);
\r
497 if (this.saveMsg) this.saveMsg.innerHTML=' '+responseText.stripTags()+' ';
\r
499 this.processCallback(this.options.onSubmitResponse);
\r
502 processCallback: function(callback) {
\r
503 switch (typeof callback) {
\r
504 case 'string': eval(callback); break;
\r
505 case 'function': callback(); break;
\r
509 // called when ok pressed on error response message
\r
510 ackResponse: function() {
\r
511 this.hideResponse('');
\r
512 this.grid.highlightEnabled=true;
\r
515 editRecord: function(e) {
\r
516 this.grid.highlightEnabled=false;
\r
517 this.menu.hidemenu();
\r
518 this.hideResponse('Saving...');
\r
519 this.grid.outerDiv.style.cursor = 'auto';
\r
520 this.action.value="upd";
\r
521 for (var i=0; i<this.grid.columns.length; i++) {
\r
522 if (this.grid.columns[i].format) {
\r
523 var v=this.grid.columns[i].getValue(this.rowIdx);
\r
524 this.setField(this.grid.columns[i].format,v);
\r
525 if (this.grid.columns[i].format.selectDesc)
\r
526 this.grid.columns[i].format.selectDesc.innerHTML=this.grid.columns[i]._format(v);
\r
529 this.setReadOnly(false);
\r
530 this.key=this.getKey();
\r
531 this.makeFormVisible(this.rowIdx);
\r
534 addRecord: function() {
\r
535 this.menu.hidemenu();
\r
536 this.hideResponse('Saving...');
\r
537 this.setReadOnly(true);
\r
539 this.action.value="ins";
\r
540 for (var i=0; i<this.grid.columns.length; i++) {
\r
541 if (this.grid.columns[i].format) {
\r
542 this.setField(this.grid.columns[i].format,this.grid.columns[i].format.ColData);
\r
543 if (this.grid.columns[i].format.SelectCtl)
\r
544 RicoEditControls.resetValue(this.grid.columns[i]);
\r
548 this.makeFormVisible(-1);
\r
549 if (this.Accordion) this.Accordion.selectionSet.selectIndex(0);
\r
552 drillDown: function(e,masterColNum,detailColNum) {
\r
553 var cell=Event.element(e || window.event);
\r
554 cell=RicoUtil.getParentByTagName(cell,'div','ricoLG_cell');
\r
556 this.grid.unhighlight();
\r
557 var idx=this.grid.winCellIndex(cell);
\r
558 this.grid.menuIdx=idx; // ensures selection gets cleared when menu is displayed
\r
559 this.grid.highlight(idx);
\r
560 var drillValue=this.grid.columns[masterColNum].getValue(idx.row);
\r
561 for (var i=3; i<arguments.length; i++)
\r
562 arguments[i].setDetailFilter(detailColNum,drillValue);
\r
566 // set filter on a detail grid that is in a master-detail relationship
\r
567 setDetailFilter: function(colNumber,filterValue) {
\r
568 var c=this.grid.columns[colNumber];
\r
569 c.format.ColData=filterValue;
\r
570 c.setSystemFilter('EQ',filterValue);
\r
573 makeFormVisible: function(row) {
\r
574 this.editDiv.style.display='block';
\r
576 // set left position
\r
577 var editWi=this.editDiv.offsetWidth;
\r
578 var odOffset=Position.page(this.grid.outerDiv);
\r
579 var winWi=RicoUtil.windowWidth();
\r
580 if (editWi+odOffset[0] > winWi)
\r
581 this.editDiv.style.left=(winWi-editWi)+'px';
\r
583 this.editDiv.style.left=(odOffset[0]+1)+'px';
\r
585 // set top position
\r
586 var scrTop=RicoUtil.docScrollTop();
\r
587 var editHt=this.editDiv.offsetHeight;
\r
588 var newTop=odOffset[1]+this.grid.hdrHt+scrTop;
\r
589 var bottom=RicoUtil.windowHeight()+scrTop;
\r
591 newTop+=(row+1)*this.grid.rowHeight;
\r
592 if (newTop+editHt>bottom) newTop-=(editHt+this.grid.rowHeight);
\r
594 if (newTop+editHt>bottom) newTop=bottom-editHt;
\r
596 this.processCallback(this.options.formOpen);
\r
597 this.formPopup.openPopup(null,Math.max(newTop,scrTop));
\r
598 this.editDiv.style.visibility='visible';
\r
599 if (this.initialized) return;
\r
600 for (i = 0; i < this.grid.columns.length; i++) {
\r
601 spec=this.grid.columns[i].format;
\r
602 if (!spec || !spec.EntryType || !spec.FieldName) continue;
\r
603 switch (spec.EntryType) {
\r
605 if (typeof tinyMCE!='undefined') tinyMCE.execCommand('mceAddControl', true, spec.FieldName);
\r
609 this.formPopup.openPopup(); // tinyMCE may have changed the dimensions of the form
\r
610 this.initialized=true;
\r
613 makeFormInvisible: function() {
\r
614 this.editDiv.style.visibility='hidden';
\r
615 this.formPopup.closePopup();
\r
616 this.processCallback(this.options.formClose);
\r
619 getConfirmDesc: function(rowIdx) {
\r
620 var desc=this.grid.columns[this.options.ConfirmDeleteCol].cell(rowIdx).innerHTML;
\r
621 desc=this.getLookupValue(desc)[1];
\r
622 return desc.stripTags();
\r
625 deleteRecord: function() {
\r
626 this.menu.hidemenu();
\r
628 if (this.options.ConfirmDeleteCol < 0) {
\r
629 desc=RicoTranslate.getPhrase("this "+this.options.RecordName);
\r
631 desc=this.getConfirmDesc(this.rowIdx);
\r
632 if (desc.length>50) desc=desc.substring(0,50)+'...';
\r
633 desc='\"' + desc + '\"'
\r
635 if (!this.options.ConfirmDelete.valueOf || confirm(RicoTranslate.getPhrase("Are you sure you want to delete ") + desc + " ?")) {
\r
636 this.hideResponse('Deleting...');
\r
637 this.showResponse();
\r
638 var parms=this.action.name+"=del"+this.getKey();
\r
640 new Ajax.Updater(this.responseDiv, window.location.pathname, {parameters:parms,onComplete:this.processResponse.bind(this)});
\r
642 this.menu.cancelmenu();
\r
645 getKey: function() {
\r
647 for (var i=0; i<this.grid.columns.length; i++) {
\r
648 if (this.grid.columns[i].format && this.grid.columns[i].format.isKey) {
\r
649 var value=this.grid.columns[i].getValue(this.rowIdx);
\r
650 value=this.getLookupValue(value)[0];
\r
651 key+='&_k'+i+'='+value;
\r
657 TESubmit: function(e) {
\r
658 var i,lbl,spec,elem,entrytype;
\r
660 if (!e) e=window.event;
\r
663 // check fields that are supposed to be non-blank
\r
665 for (i = 0; i < this.grid.columns.length; i++) {
\r
666 spec=this.grid.columns[i].format;
\r
667 if (!spec || !spec.EntryType || !spec.FieldName) continue;
\r
668 entrytype=spec.EntryType.charAt(0).toLowerCase();
\r
669 if (!entrytype.match(/d|i|b/)) continue;
\r
670 if (spec.isNullable==true && entrytype!='b') continue;
\r
671 elem=$(spec.FieldName);
\r
672 if (!elem) continue;
\r
673 //alert("nonblank check: " + spec.FieldName);
\r
674 if (elem.tagName.toLowerCase()!='input') continue;
\r
675 if (elem.type.toLowerCase()!='text') continue;
\r
676 if (elem.value.length == 0) {
\r
677 alert(RicoTranslate.getPhrase("Please enter\t a value for")+" \"" + this.grid.columns[i].formLabel.innerHTML + "\"");
\r
678 //setTimeout("FocusField(document." + this.form.name + "." + this.options.NonBlanks[i] + ")",2000);
\r
683 // recheck any elements on the form with an onchange event
\r
685 var InputFields = this.form.getElementsByTagName("input");
\r
686 this.TEerror=false;
\r
687 for (i=0; i < InputFields.length; i++) {
\r
688 if (InputFields[i].type=="text" && InputFields[i].onchange) {
\r
689 InputFields[i].onchange();
\r
690 if (this.TEerror) return false;
\r
693 if (typeof tinyMCE!='undefined') tinyMCE.triggerSave();
\r
694 this.makeFormInvisible();
\r
695 this.showResponse();
\r
696 var parms=Form.serialize(this.form)+this.key
\r
697 Rico.writeDebugMsg("TESubmit:"+parms);
\r
698 new Ajax.Updater(this.responseDiv, window.location.pathname, {parameters:parms,onComplete:this.responseHandler});
\r
699 this.menu.cancelmenu();
\r
703 FocusField: function(elem) {
\r
708 TableEditCheckInt: function(TxtObj) {
\r
709 var val=TxtObj.value;
\r
710 if (val=='') return;
\r
711 if (val!=parseInt(val)) {
\r
712 alert(RicoTranslate.getPhrase("Please enter\t an integer value for")+" \"" + $("lbl_"+TxtObj.id).innerHTML + "\"");
\r
713 setTimeout(this.FocusField.bind(this,TxtObj),0);
\r
718 TableEditCheckPosInt: function(TxtObj) {
\r
719 var val=TxtObj.value;
\r
720 if (val=='') return;
\r
721 if (val!=parseInt(val) || val<0) {
\r
722 alert(RicoTranslate.getPhrase("Please enter\t a positive integer value for")+" \"" + $("lbl_"+TxtObj.id).innerHTML + "\"");
\r
723 setTimeout(this.FocusField.bind(this,TxtObj),0);
\r
730 // Registers custom popup widgets to fill in a text box (e.g. ricoCalendar and ricoTree)
\r
732 // Custom widget must implement:
\r
733 // open() method (make control visible)
\r
734 // close() method (hide control)
\r
735 // container property (div element that contains the control)
\r
736 // id property (uniquely identifies the widget class)
\r
738 // widget calls returnValue method to return a value to the caller
\r
740 // this object handles clicks on the control's icon and positions the control appropriately.
\r
741 var RicoEditControls = {
\r
745 register: function(widget, imgsrc) {
\r
747 tmp[widget.id]={imgsrc:imgsrc, widget:widget, currentEl:''};
\r
748 this.widgetList=this.widgetList.merge(tmp);
\r
749 widget.returnValue=this.setValue.bind(this,widget);
\r
750 Rico.writeDebugMsg("RicoEditControls.register:"+widget.id);
\r
753 atLoad: function() {
\r
754 var k=this.widgetList.keys();
\r
755 for (var i=0; i<k.length; i++) {
\r
756 var w=this.widgetList[k[i]].widget;
\r
757 if (w.atLoad) w.atLoad();
\r
761 applyTo: function(column,inputCtl) {
\r
762 var wInfo=this.widgetList[column.format.SelectCtl];
\r
763 if (!wInfo) return null;
\r
764 Rico.writeDebugMsg('RicoEditControls.applyTo: '+column.displayName+' : '+column.format.SelectCtl);
\r
765 var descSpan = document.createElement('span');
766 var newimg = document.createElement('img');
767 newimg.style.paddingLeft='4px';
768 newimg.style.cursor='pointer';
\r
770 newimg.src=wInfo.imgsrc;
\r
771 newimg.id=this.imgId(column.format.FieldName);
\r
772 newimg.onclick=this.processClick.bindAsEventListener(this);
\r
773 inputCtl.parentNode.appendChild(descSpan);
774 inputCtl.parentNode.appendChild(newimg);
775 inputCtl.style.display='none'; // comment out this line for debugging
\r
776 var tmp=new Object();
\r
777 tmp[newimg.id]={descSpan:descSpan, inputCtl:inputCtl, widget:wInfo.widget, listObj:wInfo, column:column};
\r
778 this.elemList=this.elemList.merge(tmp);
\r
779 column.format.selectIcon=newimg;
\r
780 column.format.selectDesc=descSpan;
\r
783 processClick: function(e) {
\r
784 var elem=Event.element(e);
\r
785 var el=this.elemList[elem.id];
\r
787 if (el.listObj.currentEl==elem.id && el.widget.container.style.display!='none') {
\r
789 el.listObj.currentEl='';
\r
791 el.listObj.currentEl=elem.id;
\r
792 Rico.writeDebugMsg('RicoEditControls.processClick: '+el.widget.id+' : '+el.inputCtl.value);
\r
793 RicoUtil.positionCtlOverIcon(el.widget.container,elem);
\r
794 el.widget.open(el.inputCtl.value);
\r
798 imgId: function(fieldname) {
\r
799 return 'icon_'+fieldname;
\r
802 resetValue: function(column) {
\r
803 var el=this.elemList[this.imgId(column.format.FieldName)];
\r
805 el.inputCtl.value=column.format.ColData;
\r
806 el.descSpan.innerHTML=column._format(column.format.ColData);
\r
809 setValue: function(widget,newVal,newDesc) {
\r
810 var wInfo=this.widgetList[widget.id];
\r
811 if (!wInfo) return null;
\r
812 var id=wInfo.currentEl;
\r
813 if (!id) return null;
\r
814 var el=this.elemList[id];
\r
815 if (!el) return null;
\r
816 el.inputCtl.value=newVal;
\r
817 if (!newDesc) newDesc=el.column._format(newVal);
\r
818 el.descSpan.innerHTML=newDesc;
\r
819 //alert(widget.id+':'+id+':'+el.inputCtl.id+':'+el.inputCtl.value+':'+newDesc);
\r
822 close: function(id) {
\r
823 var wInfo=this.widgetList[id];
\r
824 if (!wInfo) return;
\r
825 if (wInfo.widget.container.style.display!='none')
\r
826 wInfo.widget.close();
\r
830 Rico.includeLoaded('ricoLiveGridForms.js');