63b3199bb43a98f12974592f3d112bcb01e0d19a
[Packages/TYPO3.CMS.git] / typo3 / jsfunc.tbe_editor.js
1 /***************************************************************
2 * Copyright notice
3 *
4 * (c) 1999-2006 Kasper Skaarhoj (kasperYYYY@typo3.com)
5 * All rights reserved
6 *
7 * This script is part of the TYPO3 project. The TYPO3 project is
8 * free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * The GNU General Public License can be found at
14 * http://www.gnu.org/copyleft/gpl.html.
15 * A copy is found in the textfile GPL.txt and important notices to the license
16 * from the author is found in LICENSE.txt distributed with these scripts.
17 *
18 *
19 * This script is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * This copyright notice MUST APPEAR in all copies of the script!
25 ***************************************************************/
26 /**
27 * Contains JavaScript for TYPO3 Core Form generator - AKA "TCEforms"
28 *
29 * $Id: $
30 *
31 * @author Kasper Skaarhoj <kasperYYYY@typo3.com>
32 * @coauthor Oliver Hader <oh@inpublica.de>
33 */
34
35
36 var TBE_EDITOR = {
37 /* Example:
38 elements: {
39 'data[table][uid]': {
40 'field': {
41 'range': [0, 100],
42 'rangeImg': '',
43 'required': true,
44 'requiredImg': ''
45 }
46 }
47
48 },
49 */
50
51 elements: {},
52 recentUpdatedElements: {},
53 actionChecks: { submit: [] },
54
55 formname: '',
56 formnameUENC: '',
57 loadTime: 0,
58 isChanged: 0,
59 auth_timeout_field: 0,
60
61 backPath: '',
62 prependFormFieldNames: 'data',
63 prependFormFieldNamesUENC: 'data',
64 prependFormFieldNamesCnt: 0,
65
66 isPalettedoc: null,
67 doSaveFieldName: 0,
68
69 labels: {},
70 images: {
71 req: new Image(),
72 cm: new Image(),
73 sel: new Image(),
74 clear: new Image()
75 },
76
77 // Handling of data structures:
78 addElements: function(elements) {
79 TBE_EDITOR.recentUpdatedElements = elements;
80 TBE_EDITOR.elements = $H(TBE_EDITOR.elements).merge(elements);
81 },
82 removeElement: function(record) {
83 if (TBE_EDITOR.elements && TBE_EDITOR.elements[record]) {
84 delete(TBE_EDITOR.elements[record]);
85 }
86 },
87 getElement: function(record, field, type) {
88 var result = null;
89 var element;
90
91 if (TBE_EDITOR.elements && TBE_EDITOR.elements[record] && TBE_EDITOR.elements[record][field]) {
92 element = TBE_EDITOR.elements[record][field];
93 if (type) {
94 if (element[type]) result = element;
95 } else {
96 result = element;
97 }
98 }
99
100 return result;
101 },
102 checkElements: function(type, recentUpdated, record, field) {
103 var result = 1;
104 var elementName, elementData, elementRecord, elementField;
105 var source = recentUpdated ? TBE_EDITOR.recentUpdatedElements : TBE_EDITOR.elements;
106
107 if (type) {
108 if (record && field) {
109 elementName = record+'['+field+']';
110 elementData = TBE_EDITOR.getElement(record, field, type);
111 if (elementData) {
112 if (!TBE_EDITOR.checkElementByType(type, elementName, elementData)) result = 0;
113 }
114
115 } else {
116 var elementFieldList, elRecIndex, elRecCnt, elFldIndex, elFldCnt;
117 var elementRecordList = $H(source).keys();
118 for (elRecIndex=0, elRecCnt=elementRecordList.length; elRecIndex<elRecCnt; elRecIndex++) {
119 elementRecord = elementRecordList[elRecIndex];
120 elementFieldList = $H(source[elementRecord]).keys();
121 for (elFldIndex=0, elFldCnt=elementFieldList.length; elFldIndex<elFldCnt; elFldIndex++) {
122 elementField = elementFieldList[elFldIndex];
123 elementData = TBE_EDITOR.getElement(elementRecord, elementField, type);
124 if (elementData) {
125 elementName = elementRecord+'['+elementField+']';
126 if (!TBE_EDITOR.checkElementByType(type, elementName, elementData)) result = 0;
127 }
128 }
129 }
130 }
131 }
132
133 return result;
134 },
135 checkElementByType: function(type, elementName, elementData) {
136 var result = 1;
137
138 if (type) {
139 if (type == 'required') {
140 if (!document[TBE_EDITOR.formname][elementName].value) {
141 result = 0;
142 TBE_EDITOR.setImage('req_'+elementData.requiredImg, TBE_EDITOR.images.req);
143 }
144 } else if (type == 'range' && elementData.range) {
145 var formObj = document[TBE_EDITOR.formname][elementName+'_list'];
146 if (!formObj) {
147 // special treatment for IRRE fields:
148 var tempObj = document[TBE_EDITOR.formname][elementName];
149 if (tempObj && Element.hasClassName(tempObj, 'inlineRecord')) {
150 formObj = tempObj.value ? tempObj.value.split(',') : [];
151 }
152 }
153 if (!TBE_EDITOR.checkRange(formObj, elementData.range[0], elementData.range[1])) {
154 result = 0;
155 TBE_EDITOR.setImage('req_'+elementData.rangeImg, TBE_EDITOR.images.req);
156 }
157 }
158 }
159
160 return result;
161 },
162 addActionChecks: function(type, checks) {
163 TBE_EDITOR.actionChecks[type].push(checks);
164 },
165
166 // Regular TCEforms JSbottom scripts:
167 loginRefreshed: function() {
168 var date = new Date();
169 TBE_EDITOR.loadTime = Math.floor(date.getTime()/1000);
170 if (top.busy && top.busy.loginRefreshed) { top.busy.loginRefreshed(); }
171 },
172 checkLoginTimeout: function() {
173 var date = new Date();
174 var theTime = Math.floor(date.getTime()/1000);
175 if (theTime > TBE_EDITOR.loadTime+TBE_EDITOR.auth_timeout_field-10) {
176 return true;
177 }
178 },
179 setHiddenContent: function(RTEcontent,theField) {
180 document[TBE_EDITOR.formname][theField].value = RTEcontent;
181 alert(document[TBE_EDITOR.formname][theField].value);
182 },
183 fieldChanged_fName: function(fName,el) {
184 var idx=2+TBE_EDITOR.prependFormFieldNamesCnt;
185 var table = TBE_EDITOR.split(fName, "[", idx);
186 var uid = TBE_EDITOR.split(fName, "[", idx+1);
187 var field = TBE_EDITOR.split(fName, "[", idx+2);
188
189 table = table.substr(0,table.length-1);
190 uid = uid.substr(0,uid.length-1);
191 field = field.substr(0,field.length-1);
192 TBE_EDITOR.fieldChanged(table,uid,field,el);
193 },
194 fieldChanged: function(table,uid,field,el) {
195 var theField = TBE_EDITOR.prependFormFieldNames+'['+table+']['+uid+']['+field+']';
196 var theRecord = TBE_EDITOR.prependFormFieldNames+'['+table+']['+uid+']';
197 TBE_EDITOR.isChanged = 1;
198
199 // Set change image:
200 var imgObjName = "cm_"+table+"_"+uid+"_"+field;
201 TBE_EDITOR.setImage(imgObjName,TBE_EDITOR.images.cm);
202
203 // Set change image
204 if (document[TBE_EDITOR.formname][theField] && document[TBE_EDITOR.formname][theField].type=="select-one" && document[TBE_EDITOR.formname][theField+"_selIconVal"]) {
205 var imgObjName = "selIcon_"+table+"_"+uid+"_"+field+"_";
206 TBE_EDITOR.setImage(imgObjName+document[TBE_EDITOR.formname][theField+"_selIconVal"].value,TBE_EDITOR.images.clear);
207 document[TBE_EDITOR.formname][theField+"_selIconVal"].value = document[TBE_EDITOR.formname][theField].selectedIndex;
208 TBE_EDITOR.setImage(imgObjName+document[TBE_EDITOR.formname][theField+"_selIconVal"].value,TBE_EDITOR.images.sel);
209 }
210
211 // Set required flag:
212 var imgReqObjName = "req_"+table+"_"+uid+"_"+field;
213 if (TBE_EDITOR.getElement(theRecord,field,'required') && document[TBE_EDITOR.formname][theField]) {
214 if (TBE_EDITOR.checkElements('required', false, theRecord, field)) {
215 TBE_EDITOR.setImage(imgReqObjName,TBE_EDITOR.images.clear);
216 } else {
217 TBE_EDITOR.setImage(imgReqObjName,TBE_EDITOR.images.req);
218 }
219 }
220 if (TBE_EDITOR.getElement(theRecord,field,'range') && document[TBE_EDITOR.formname][theField]) {
221 if (TBE_EDITOR.checkElements('range', false, theRecord, field)) {
222 TBE_EDITOR.setImage(imgReqObjName,TBE_EDITOR.images.clear);
223 } else {
224 TBE_EDITOR.setImage(imgReqObjName,TBE_EDITOR.images.req);
225 }
226 }
227
228 if (TBE_EDITOR.isPalettedoc) { TBE_EDITOR.setOriginalFormFieldValue(theField) };
229 },
230 setOriginalFormFieldValue: function(theField) {
231 if (TBE_EDITOR.isPalettedoc && (TBE_EDITOR.isPalettedoc).document[TBE_EDITOR.formname] && (TBE_EDITOR.isPalettedoc).document[TBE_EDITOR.formname][theField]) {
232 (TBE_EDITOR.isPalettedoc).document[TBE_EDITOR.formname][theField].value = document[TBE_EDITOR.formname][theField].value;
233 }
234 },
235 isFormChanged: function(noAlert) {
236 if (TBE_EDITOR.isChanged && !noAlert && confirm(TBE_EDITOR.labels.fieldsChanged)) {
237 return 0;
238 }
239 return TBE_EDITOR.isChanged;
240 },
241 checkAndDoSubmit: function(sendAlert) {
242 if (TBE_EDITOR.checkSubmit(sendAlert)) { TBE_EDITOR.submitForm(); }
243 },
244 /**
245 * Checks if the form can be submitted according to any possible restrains like required values, item numbers etc.
246 * Returns true if the form can be submitted, otherwise false (and might issue an alert message, if "sendAlert" is 1)
247 * If "sendAlert" is false, no error message will be shown upon false return value (if "1" then it will).
248 * If "sendAlert" is "-1" then the function will ALWAYS return true regardless of constraints (except if login has expired) - this is used in the case where a form field change requests a form update and where it is accepted that constraints are not observed (form layout might change so other fields are shown...)
249 */
250 checkSubmit: function(sendAlert) {
251 var funcIndex, funcMax, funcRes;
252 if (TBE_EDITOR.checkLoginTimeout() && confirm(TBE_EDITOR.labels.refresh_login)) {
253 vHWin=window.open(TBE_EDITOR.backPath+'login_frameset.php?','relogin','height=300,width=400,status=0,menubar=0');
254 vHWin.focus();
255 return false;
256 }
257 var OK=1;
258
259 // $this->additionalJS_submit:
260 if (TBE_EDITOR.actionChecks && TBE_EDITOR.actionChecks.submit) {
261 for (funcIndex=0, funcMax=TBE_EDITOR.actionChecks.submit.length; funcIndex<funcMax; funcIndex++) {
262 eval(TBE_EDITOR.actionChecks.submit[funcIndex]);
263 }
264 }
265
266 if(!OK) {
267 if (!confirm(unescape("SYSTEM ERROR: One or more Rich Text Editors on the page could not be contacted. This IS an error, although it should not be regular.\nYou can save the form now by pressing OK, but you will loose the Rich Text Editor content if you do.\n\nPlease report the error to your administrator if it persists."))) {
268 return false;
269 } else {
270 OK = 1;
271 }
272 }
273 // $reqLinesCheck
274 if (!TBE_EDITOR.checkElements('required', false)) { OK = 0; }
275 // $reqRangeCheck
276 if (!TBE_EDITOR.checkElements('range', false)) { OK = 0; }
277
278 if (OK || sendAlert==-1) {
279 return true;
280 } else {
281 if(sendAlert) alert(TBE_EDITOR.labels.fieldsMissing);
282 return false;
283 }
284 },
285 checkRange: function(el,lower,upper) {
286 if (el && el.length>=lower && el.length<=upper) {
287 return true;
288 } else {
289 return false;
290 }
291 },
292 initRequired: function() {
293 // $reqLinesCheck
294 TBE_EDITOR.checkElements('required', true);
295
296 // $reqRangeCheck
297 TBE_EDITOR.checkElements('range', true);
298 },
299 setImage: function(name,image) {
300 if (document[name]) {
301 if (typeof image == 'object') {
302 document[name].src = image.src;
303 } else {
304 document[name].src = eval(image+'.src');
305 }
306 }
307 },
308 submitForm: function() {
309 if (TBE_EDITOR.doSaveFieldName) {
310 document[TBE_EDITOR.formname][TBE_EDITOR.doSaveFieldName].value=1;
311 }
312 document[TBE_EDITOR.formname].submit();
313 },
314 split: function(theStr1, delim, index) {
315 var theStr = ""+theStr1;
316 var lengthOfDelim = delim.length;
317 sPos = -lengthOfDelim;
318 if (index<1) {index=1;}
319 for (var a=1; a<index; a++) {
320 sPos = theStr.indexOf(delim, sPos+lengthOfDelim);
321 if (sPos==-1) { return null; }
322 }
323 ePos = theStr.indexOf(delim, sPos+lengthOfDelim);
324 if(ePos == -1) { ePos = theStr.length; }
325 return (theStr.substring(sPos+lengthOfDelim,ePos));
326 },
327 palUrl: function(inData,fieldList,fieldNum,table,uid,isOnFocus) {
328 var url = TBE_EDITOR.backPath+'alt_palette.php?inData='+inData+'&formName='+TBE_EDITOR.formnameUENC+'&prependFormFieldNames='+TBE_EDITOR.prependFormFieldNamesUENC;
329 var field = "";
330 var theField="";
331 for (var a=0; a<fieldNum;a++) {
332 field = TBE_EDITOR.split(fieldList, ",", a+1);
333 theField = TBE_EDITOR.prependFormFieldNames+'['+table+']['+uid+']['+field+']';
334 if (document[TBE_EDITOR.formname][theField]) url+="&rec["+field+"]="+TBE_EDITOR.rawurlencode(document[TBE_EDITOR.formname][theField].value);
335 }
336 if (top.topmenuFrame) {
337 top.topmenuFrame.location.href = url+"&backRef="+(top.content.list_frame ? (top.content.list_frame.view_frame ? "top.content.list_frame.view_frame" : "top.content.list_frame") : "top.content");
338 } else if (!isOnFocus) {
339 var vHWin=window.open(url,"palette","height=300,width=200,status=0,menubar=0,scrollbars=1");
340 vHWin.focus();
341 }
342 },
343 curSelected: function(theField) {
344 var fObjSel = document[TBE_EDITOR.formname][theField];
345 var retVal="";
346 if (fObjSel) {
347 if (fObjSel.type=='select-multiple' || fObjSel.type=='select-one') {
348 var l=fObjSel.length;
349 for (a=0;a<l;a++) {
350 if (fObjSel.options[a].selected==1) {
351 retVal+=fObjSel.options[a].value+",";
352 }
353 }
354 }
355 }
356 return retVal;
357 },
358 rawurlencode: function(str,maxlen) {
359 var output = str;
360 if (maxlen) output = output.substr(0,200);
361 output = escape(output);
362 output = TBE_EDITOR.str_replace("*","%2A", output);
363 output = TBE_EDITOR.str_replace("+","%2B", output);
364 output = TBE_EDITOR.str_replace("/","%2F", output);
365 output = TBE_EDITOR.str_replace("@","%40", output);
366 return output;
367 },
368 str_replace: function(match,replace,string) {
369 var input = ''+string;
370 var matchStr = ''+match;
371 if (!matchStr) { return string; }
372 var output = '';
373 var pointer=0;
374 var pos = input.indexOf(matchStr);
375 while (pos!=-1) {
376 output+=''+input.substr(pointer, pos-pointer)+replace;
377 pointer=pos+matchStr.length;
378 pos = input.indexOf(match,pos+1);
379 }
380 output+=''+input.substr(pointer);
381 return output;
382 }
383 };
384
385 function typoSetup () {
386 this.passwordDummy = '********';
387 this.decimalSign = '.';
388 }
389 var TS = new typoSetup();
390 var evalFunc = new evalFunc();
391
392 // backwards compatibility for extensions
393 var TBE_EDITOR_loginRefreshed = TBE_EDITOR.loginRefreshed;
394 var TBE_EDITOR_checkLoginTimeout = TBE_EDITOR.checkLoginTimeout;
395 var TBE_EDITOR_setHiddenContent = TBE_EDITOR.setHiddenContent;
396 var TBE_EDITOR_isChanged = TBE_EDITOR.isChanged;
397 var TBE_EDITOR_fieldChanged_fName = TBE_EDITOR.fieldChanged_fName;
398 var TBE_EDITOR_fieldChanged = TBE_EDITOR.fieldChanged;
399 var TBE_EDITOR_setOriginalFormFieldValue = TBE_EDITOR.setOriginalFormFieldValue;
400 var TBE_EDITOR_isFormChanged = TBE_EDITOR.isFormChanged;
401 var TBE_EDITOR_checkAndDoSubmit = TBE_EDITOR.checkAndDoSubmit;
402 var TBE_EDITOR_checkSubmit = TBE_EDITOR.checkSubmit;
403 var TBE_EDITOR_checkRange = TBE_EDITOR.checkRange;
404 var TBE_EDITOR_initRequired = TBE_EDITOR.initRequired;
405 var TBE_EDITOR_setImage = TBE_EDITOR.setImage;
406 var TBE_EDITOR_submitForm = TBE_EDITOR.submitForm;
407 var TBE_EDITOR_split = TBE_EDITOR.split;
408 var TBE_EDITOR_palUrl = TBE_EDITOR.palUrl;
409 var TBE_EDITOR_curSelected = TBE_EDITOR.curSelected;
410 var TBE_EDITOR_rawurlencode = TBE_EDITOR.rawurlencode;
411 var TBE_EDITOR_str_replace = TBE_EDITOR.str_replace;
412
413
414 var typo3form = {
415 fieldSet: function(theField, evallist, is_in, checkbox, checkboxValue) {
416 if (document[TBE_EDITOR.formname][theField]) {
417 var theFObj = new evalFunc_dummy (evallist,is_in, checkbox, checkboxValue);
418 var theValue = document[TBE_EDITOR.formname][theField].value;
419 if (checkbox && theValue==checkboxValue) {
420 document[TBE_EDITOR.formname][theField+"_hr"].value="";
421 if (document[TBE_EDITOR.formname][theField+"_cb"]) document[TBE_EDITOR.formname][theField+"_cb"].checked = "";
422 } else {
423 document[TBE_EDITOR.formname][theField+"_hr"].value = evalFunc.outputObjValue(theFObj, theValue);
424 if (document[TBE_EDITOR.formname][theField+"_cb"]) document[TBE_EDITOR.formname][theField+"_cb"].checked = "on";
425 }
426 }
427 },
428 fieldGet: function(theField, evallist, is_in, checkbox, checkboxValue, checkbox_off, checkSetValue) {
429 if (document[TBE_EDITOR.formname][theField]) {
430 var theFObj = new evalFunc_dummy (evallist,is_in, checkbox, checkboxValue);
431 if (checkbox_off) {
432 if (document[TBE_EDITOR.formname][theField+"_cb"].checked) {
433 document[TBE_EDITOR.formname][theField].value=checkSetValue;
434 } else {
435 document[TBE_EDITOR.formname][theField].value=checkboxValue;
436 }
437 }else{
438 document[TBE_EDITOR.formname][theField].value = evalFunc.evalObjValue(theFObj, document[TBE_EDITOR.formname][theField+"_hr"].value);
439 }
440 typo3form.fieldSet(theField, evallist, is_in, checkbox, checkboxValue);
441 }
442 }
443 };
444
445 // backwards compatibility for extensions
446 var typo3FormFieldSet = typo3form.fieldSet;
447 var typo3FormFieldGet = typo3form.fieldGet;