Index: t3lib/class.t3lib_querygenerator.php =================================================================== --- t3lib/class.t3lib_querygenerator.php (revision 6707) +++ t3lib/class.t3lib_querygenerator.php (working copy) @@ -1508,8 +1508,8 @@ function JSbottom($formname) { if ($this->extJSCODE) { $out.=' - - + + + $output=' '; $subcat=''; if (is_array($this->categories[$category])) { Index: t3lib/js/adminpanel.js =================================================================== --- t3lib/js/adminpanel.js (revision 6707) +++ t3lib/js/adminpanel.js (working copy) @@ -1,4 +1,10 @@ /*************************************************************** +* ! DEPRECATED ! +* This file will be removed in TYPO3 4.6 +* This file is now located at t3lib/js/jsfunc.adminpanel.js +****************************************************************/ + +/*************************************************************** * Admin Panel drag and drop * * $Id$ Index: t3lib/js/jsfunc.adminpanel.js =================================================================== --- t3lib/js/jsfunc.adminpanel.js (revision 0) +++ t3lib/js/jsfunc.adminpanel.js (revision 0) @@ -0,0 +1,123 @@ +/*************************************************************** + * Admin Panel drag and drop + * + * $Id: adminpanel.js 6539 2009-11-25 14:49:14Z stucki $ + * + * Copyright notice + * + * (c) 2009 Ingo Renner + * All rights reserved + * + * This script is part of the TYPO3 project. The TYPO3 project is + * free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * The GNU General Public License can be found at + * http://www.gnu.org/copyleft/gpl.html. + * + * This script is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * This copyright notice MUST APPEAR in all copies of the script! + ***************************************************************/ + +/** + * @author Ingo Renner + * @author Oliver Hader + * @author Ingmar Schlecht + * @author Jonas Dübi + */ + +var TYPO3AdminPanel = { + + positionRestored: false, + dragObject: null, + dragX: 0, + dragY: 0, + posX: 0, + posY: 0, + + savePosition: function(panel) { + var admPanelPosX = panel.offsetLeft; + var admPanelPosY = panel.offsetTop; + + TYPO3AdminPanel.setCookie('admPanelPosX', admPanelPosX, '', '/'); + TYPO3AdminPanel.setCookie('admPanelPosY', admPanelPosY, '', '/'); + }, + + restorePosition: function() { + if (TYPO3AdminPanel.positionRestored == false) { + + var admPanelPosX = TYPO3AdminPanel.getCookie('admPanelPosX'); + if (admPanelPosX > 0) { + document.getElementById('admPanel').style.left = admPanelPosX + 'px'; + } + + var admPanelPosY = TYPO3AdminPanel.getCookie('admPanelPosY'); + if (admPanelPosY > 0) { + document.getElementById('admPanel').style.top = admPanelPosY + 'px'; + } + + TYPO3AdminPanel.positionRestored = true; + } + }, + + setCookie: function(name, value, expires, path, domain, secure) { + document.cookie = name + '=' + escape(value) + + (expires ? '; expires=' + expires.toGMTString() : '') + + (path ? '; path=' + path : '') + + (domain ? '; domain=' + domain : '') + + (secure ? '; secure' : ''); + }, + + getCookie: function(name) { + var dc = document.cookie; + var prefix = name + '='; + var begin = dc.indexOf('; ' + prefix); + + if (begin == -1) { + begin = dc.indexOf(prefix); + if (begin != 0) { + return null; + } + } else { + begin += 2; + } + + var end = dc.indexOf(';', begin); + if (end == -1) { + end = dc.length; + } + + return unescape(dc.substring(begin + prefix.length, end)); + }, + + dragInit: function() { + document.onmousemove = TYPO3AdminPanel.drag; + document.onmouseup = TYPO3AdminPanel.dragStop; + }, + + dragStart: function(element) { + TYPO3AdminPanel.dragObject = element; + TYPO3AdminPanel.dragX = TYPO3AdminPanel.posX - TYPO3AdminPanel.dragObject.offsetLeft; + TYPO3AdminPanel.dragY = TYPO3AdminPanel.posY - TYPO3AdminPanel.dragObject.offsetTop; + }, + + dragStop: function() { + TYPO3AdminPanel.dragObject = null; + }, + + drag: function(dragEvent) { + TYPO3AdminPanel.posX = document.all ? window.event.clientX : dragEvent.pageX; + TYPO3AdminPanel.posY = document.all ? window.event.clientY : dragEvent.pageY; + + if (TYPO3AdminPanel.dragObject != null) { + TYPO3AdminPanel.dragObject.style.left = (TYPO3AdminPanel.posX - TYPO3AdminPanel.dragX) + 'px'; + TYPO3AdminPanel.dragObject.style.top = (TYPO3AdminPanel.posY - TYPO3AdminPanel.dragY) + 'px'; + } + } +}; Index: t3lib/js/jsfunc.evalfield.js =================================================================== --- t3lib/js/jsfunc.evalfield.js (revision 0) +++ t3lib/js/jsfunc.evalfield.js (revision 0) @@ -0,0 +1,524 @@ +/*************************************************************** +* +* Evaluation of TYPO3 form field content +* +* $Id: jsfunc.evalfield.js 5460 2009-05-20 15:45:50Z steffenk $ +* +* +* +* Copyright notice +* +* (c) 1998-2009 Kasper Skaarhoj +* All rights reserved +* +* This script is part of the TYPO3 t3lib/ library provided by +* Kasper Skaarhoj together with TYPO3 +* +* Released under GNU/GPL (see license file in typo3/sysext/cms/tslib/) +* +* This script is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +* +* This copyright notice MUST APPEAR in all copies of this script +***************************************************************/ + + +function evalFunc() { + this.input = evalFunc_input; + this.output = evalFunc_output; + this.parseInt = evalFunc_parseInt; + this.getNumChars = evalFunc_getNumChars; + this.parseDouble = evalFunc_parseDouble; + this.noSpace = evalFunc_noSpace; + this.getSecs = evalFunc_getSecs; + this.getYear = evalFunc_getYear; + this.getTimeSecs = evalFunc_getTimeSecs; + this.getTime = evalFunc_getTime; + this.getDate = evalFunc_getDate; + this.getTimestamp = evalFunc_getTimestamp; + this.caseSwitch = evalFunc_caseSwitch; + this.evalObjValue = evalFunc_evalObjValue; + this.outputObjValue = evalFunc_outputObjValue; + this.split = evalFunc_splitStr; + this.pol = evalFunc_pol; + this.convertClientTimestampToUTC = evalFunc_convertClientTimestampToUTC; + + this.ltrim = evalFunc_ltrim; + this.btrim = evalFunc_btrim; + var today = new Date(); + this.lastYear = this.getYear(today); + this.lastDate = this.getDate(today); + this.lastTime = 0; + this.refDate = today; + this.isInString = ''; + this.USmode = 0; +} +function evalFunc_pol(fortegn, value) { + return eval (((fortegn=="-")?'-':'')+value); +} +function evalFunc_evalObjValue(FObj,value) { + var evallist = FObj.evallist; + this.isInString = (FObj.is_in) ? ''+FObj.is_in : ''; + var index=1; + var theEvalType = (FObj.evallist) ? this.split(evallist, ",", index) : false; + var newValue=value; + while (theEvalType) { + if (theEvalType.slice(0, 3) == 'tx_') { + if(typeof window[theEvalType] == 'function') { + newValue = window[theEvalType](newValue); // variable function call, calling functions like tx_myext_myeval(value) + } + } else { + newValue = evalFunc.input(theEvalType, newValue); + } + index++; + theEvalType = this.split(evallist, ",", index); + } + return newValue; +} +function evalFunc_outputObjValue(FObj,value) { + var evallist = FObj.evallist; + var index=1; + var theEvalType = this.split(evallist, ",", index); + var newValue=value; + while (theEvalType) { + if (theEvalType != 'required') { + newValue = evalFunc.output(theEvalType, value, FObj); + } + index++; + theEvalType = this.split(evallist, ",", index); + } + return newValue; +} +function evalFunc_caseSwitch(type,inVal) { + var theVal = ''+inVal; + var newString = ''; + switch (type) { + case "alpha": + case "num": + case "alphanum": + case "alphanum_x": + for (var a=0;a='a'&&theChar<='z') || (theChar>='A'&&theChar<='Z'); + var num = (theChar>='0' && theChar<='9'); + switch(type) { + case "alphanum": special=0; break; + case "alpha": num=0; special=0; break; + case "num": alpha=0; special=0; break; + } + if (alpha || num || theChar==' ' || special) { + newString+=theChar; + } + } + break; + case "is_in": + if (this.isInString) { + for (var a=0;a0;a--) { + if (theVal.substr(a-1,1)!=' ') { + return theVal.substr(0,a); + } + } + return ''; +} +function evalFunc_splitSingle(value) { + var theVal = ''+value; + this.values = new Array(); + this.pointer = 3; + this.values[1]=theVal.substr(0,2); + this.values[2]=theVal.substr(2,2); + this.values[3]=theVal.substr(4,10); +} +function evalFunc_split(value) { + this.values = new Array(); + this.valPol = new Array(); + this.pointer = 0; + var numberMode = 0; + var theVal = ""; + value+=" "; + for (var a=0;a"9") { + if (numberMode) { + this.pointer++; + this.values[this.pointer]=theVal; + theVal = ""; + numberMode=0; + } + if (theChar=="+" || theChar=="-") { + this.valPol[this.pointer+1] = theChar; + } + } else { + theVal+=theChar; + numberMode=1; + } + } +} +function evalFunc_input(type,inVal) { + if (type=="md5") { + return MD5(inVal); + } + if (type=="trim") { + return this.ltrim(this.btrim(inVal)); + } + if (type=="int") { + return this.parseInt(inVal); + } + if (type=="double2") { + return this.parseDouble(inVal); + } + + var today = new Date(); + var add=0; + var value = this.ltrim(inVal); + var values = new evalFunc_split(value); + var theCmd = value.substr(0,1); + value = this.caseSwitch(type,value); + if (value=="") { + return ""; + return 0; // Why would I ever return a zero??? (20/12/01) + } + switch (type) { + case "datetime": + switch (theCmd) { + case "d": + case "t": + case "n": + this.lastTime = this.convertClientTimestampToUTC(this.getTimestamp(today), 0); + if (values.valPol[1]) { + add = this.pol(values.valPol[1],this.parseInt(values.values[1])); + } + break; + case "+": + case "-": + if (this.lastTime == 0) { + this.lastTime = this.convertClientTimestampToUTC(this.getTimestamp(today), 0); + } + if (values.valPol[1]) { + add = this.pol(values.valPol[1],this.parseInt(values.values[1])); + } + break; + default: + var index = value.indexOf(' '); + if (index!=-1) { + var dateVal = this.input("date",value.substr(index,value.length)); + // set refDate so that evalFunc_input on time will work with correct DST information + this.refDate = new Date(dateVal*1000); + this.lastTime = dateVal + this.input("time",value.substr(0,index)); + } else { + // only date, no time + this.lastTime = this.input("date", value); + } + } + this.lastTime+=add*24*60*60; + return this.lastTime; + break; + case "year": + switch (theCmd) { + case "d": + case "t": + case "n": + this.lastYear = this.getYear(today); + if (values.valPol[1]) { + add = this.pol(values.valPol[1],this.parseInt(values.values[1])); + } + break; + case "+": + case "-": + if (values.valPol[1]) { + add = this.pol(values.valPol[1],this.parseInt(values.values[1])); + } + break; + default: + if (values.valPol[2]) { + add = this.pol(values.valPol[2],this.parseInt(values.values[2])); + } + var year = (values.values[1])?this.parseInt(values.values[1]):this.getYear(today); + if ( (year>=0&&year<38) || (year>=70&&year<100) || (year>=1902&&year<2038) ) { + if (year<100) { + year = (year<38) ? year+=2000 : year+=1900; + } + } else { + year = this.getYear(today); + } + this.lastYear = year; + } + this.lastYear+=add; + return this.lastYear; + break; + case "date": + switch (theCmd) { + case "d": + case "t": + case "n": + this.lastDate = this.getTimestamp(today); + if (values.valPol[1]) { + add = this.pol(values.valPol[1],this.parseInt(values.values[1])); + } + break; + case "+": + case "-": + if (values.valPol[1]) { + add = this.pol(values.valPol[1],this.parseInt(values.values[1])); + } + break; + default: + var index = 4; + if (values.valPol[index]) { + add = this.pol(values.valPol[index],this.parseInt(values.values[index])); + } + if (values.values[1] && values.values[1].length>2) { + if (values.valPol[2]) { + add = this.pol(values.valPol[2],this.parseInt(values.values[2])); + } + var temp = values.values[1]; + values = new evalFunc_splitSingle(temp); + } + + var year = (values.values[3])?this.parseInt(values.values[3]):this.getYear(today); + if ( (year>=0&&year<38) || (year>=70&&year<100) || (year>=1902&&year<2038) ) { + if (year<100) { + year = (year<38) ? year+=2000 : year+=1900; + } + } else { + year = this.getYear(today); + } + var month = (values.values[this.USmode?1:2])?this.parseInt(values.values[this.USmode?1:2]):today.getUTCMonth()+1; + var day = (values.values[this.USmode?2:1])?this.parseInt(values.values[this.USmode?2:1]):today.getUTCDate(); + + var theTime = new Date(parseInt(year), parseInt(month)-1, parseInt(day)); + + // Substract timezone offset from client + this.lastDate = this.convertClientTimestampToUTC(this.getTimestamp(theTime), 0); + } + this.lastDate+=add*24*60*60; + return this.lastDate; + break; + case "time": + case "timesec": + switch (theCmd) { + case "d": + case "t": + case "n": + this.lastTime = this.getTimeSecs(today); + if (values.valPol[1]) { + add = this.pol(values.valPol[1],this.parseInt(values.values[1])); + } + break; + case "+": + case "-": + if (this.lastTime == 0) { + this.lastTime = this.getTimeSecs(today); + } + if (values.valPol[1]) { + add = this.pol(values.valPol[1],this.parseInt(values.values[1])); + } + break; + default: + var index = (type=="timesec")?4:3; + if (values.valPol[index]) { + add = this.pol(values.valPol[index],this.parseInt(values.values[index])); + } + if (values.values[1] && values.values[1].length>2) { + if (values.valPol[2]) { + add = this.pol(values.valPol[2],this.parseInt(values.values[2])); + } + var temp = values.values[1]; + values = new evalFunc_splitSingle(temp); + } + var sec = (values.values[3])?this.parseInt(values.values[3]):today.getUTCSeconds(); + if (sec > 59) {sec=59;} + var min = (values.values[2])?this.parseInt(values.values[2]):today.getUTCMinutes(); + if (min > 59) {min=59;} + var hour = (values.values[1])?this.parseInt(values.values[1]):today.getUTCHours(); + if (hour > 23) {hour=23;} + + var theTime = new Date(this.getYear(this.refDate), this.refDate.getUTCMonth(), this.refDate.getUTCDate(), hour, min, ((type=="timesec")?sec:0)); + + // Substract timezone offset from client + this.lastTime = this.convertClientTimestampToUTC(this.getTimestamp(theTime), 1); + } + this.lastTime+=add*60; + if (this.lastTime<0) {this.lastTime+=24*60*60;} + return this.lastTime; + break; + default: + return value; + } +} +function evalFunc_output(type,value,FObj) { + var theString = ""; + switch (type) { + case "date": + if (!parseInt(value)) {return '';} + var theTime = new Date(parseInt(value) * 1000); + if (this.USmode) { + theString = (theTime.getUTCMonth()+1)+'-'+theTime.getUTCDate()+'-'+this.getYear(theTime); + } else { + theString = theTime.getUTCDate()+'-'+(theTime.getUTCMonth()+1)+'-'+this.getYear(theTime); + } + break; + case "datetime": + if (!parseInt(value)) {return '';} + theString = this.output("time",value)+' '+this.output("date",value); + break; + case "time": + case "timesec": + if (!parseInt(value)) {return '';} + var theTime = new Date(parseInt(value) * 1000); + var h = theTime.getUTCHours(); + var m = theTime.getUTCMinutes(); + var s = theTime.getUTCSeconds(); + theString = h+':'+((m<10)?'0':'')+m + ((type=="timesec")?':'+((s<10)?'0':'')+s:''); + break; + case "password": + theString = (value) ? TS.passwordDummy : ""; + break; + case "int": + theString = (FObj.checkbox && value==FObj.checkboxValue)?'':value; + break; + default: + theString = value; + } + return theString; +} +function evalFunc_getSecs(timeObj) { + return Math.round(timeObj.getUTCSeconds()/1000); +} +// Seconds since midnight: +function evalFunc_getTime(timeObj) { + return timeObj.getUTCHours()*60*60+timeObj.getUTCMinutes()*60+Math.round(timeObj.getUTCSeconds()/1000); +} +function evalFunc_getYear(timeObj) { + return timeObj.getUTCFullYear(); +} +// Seconds since midnight with client timezone offset: +function evalFunc_getTimeSecs(timeObj) { + return timeObj.getHours()*60*60+timeObj.getMinutes()*60+timeObj.getSeconds(); +} +function evalFunc_getDate(timeObj) { + var theTime = new Date(this.getYear(timeObj), timeObj.getUTCMonth(), timeObj.getUTCDate()); + return this.getTimestamp(theTime); +} +function evalFunc_dummy (evallist,is_in,checkbox,checkboxValue) { + this.evallist = evallist; + this.is_in = is_in; + this.checkboxValue = checkboxValue; + this.checkbox = checkbox; +} +function evalFunc_splitStr(theStr1, delim, index) { + var theStr = ''+theStr1; + var lengthOfDelim = delim.length; + sPos = -lengthOfDelim; + if (index<1) {index=1;} + for (a=1; a +* All rights reserved +* +* This script is part of the TYPO3 project. The TYPO3 project is +* free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* The GNU General Public License can be found at +* http://www.gnu.org/copyleft/gpl.html. +* +* This script is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* This copyright notice MUST APPEAR in all copies of the script! +***************************************************************/ + +var inline = { + structureSeparator: '-', + prependFormFieldNames: 'data', + noTitleString: '[No title]', + lockedAjaxMethod: {}, + sourcesLoaded: {}, + data: {}, + + addToDataArray: function(object) { + $H(object).each(function(pair) { + inline.data[pair.key] = $H(inline.data[pair.key]).merge(pair.value).toObject(); + }); + }, + setPrependFormFieldNames: function(value) { this.prependFormFieldNames = value; }, + setNoTitleString: function(value) { this.noTitleString = value; }, + + expandCollapseRecord: function(objectId, expandSingle) { + var currentUid = this.parseObjectId('none', objectId, 1); + var objectPrefix = this.parseObjectId('full', objectId, 0, 1); + + var currentState = ''; + var collapse = new Array(); + var expand = new Array(); + + // if only a single record should be visibly for that set of records + // and the record clicked itself is no visible, collapse all others + if (expandSingle && !Element.visible(objectId+'_fields')) + collapse = this.collapseAllRecords(objectId, objectPrefix, currentUid); + + Element.toggle(objectId+'_fields'); + currentState = Element.visible(objectId+'_fields') ? 1 : 0 + + if (this.isNewRecord(objectId)) + this.updateExpandedCollapsedStateLocally(objectId, currentState); + else if (currentState) + expand.push(currentUid); + else if (!currentState) + collapse.push(currentUid); + + this.setExpandedCollapsedState(objectId, expand.join(','), collapse.join(',')); + + return false; + }, + + collapseAllRecords: function(objectId, objectPrefix, callingUid) { + // get the form field, where all records are stored + var objectName = this.prependFormFieldNames+this.parseObjectId('parts', objectId, 3, 2, true); + var formObj = document.getElementsByName(objectName); + var collapse = []; + + if (formObj.length) { + // the uid of the calling object (last part in objectId) + var recObjectId = ''; + + var records = formObj[0].value.split(','); + for (var i=0; i tag (e.g. for RTEhtmlarea): + if (json.headData) { + var head = inline.getDomHeadTag(); + var headTags = inline.getDomHeadChildren(head); + $A(json.headData).each(function(addTag) { + if (!restart) { + if (addTag && (addTag.innerHTML || !inline.searchInDomTags(headTags, addTag))) { + if (addTag.name=='SCRIPT' && addTag.innerHTML && processedCount) { + restart = true; + return false; + } else { + if (addTag.name=='SCRIPT' && addTag.innerHTML) { + try { + eval(addTag.innerHTML); + } catch(e) { + errorCatch.push(e); + } + } else { + element = inline.createNewDomElement(addTag); + // Set onload handler for external JS scripts: + if (addTag.name=='SCRIPT' && element.src) { + element.onload = inline.sourceLoadedHandler(element); + sourcesWaiting.push(element.src); + } + head.appendChild(element); + processedCount++; + } + json.headData.shift(); + } + } + } + }); + } + if (restart || processedCount) { + window.setTimeout(function() { inline.reprocessAjaxResponse(method, json, sourcesWaiting); }, 40); + } else { + if (method) { + inline.unlockAjaxMethod(method); + } + if (json.scriptCall && json.scriptCall.length) { + $A(json.scriptCall).each(function(value) { eval(value); }); + } + } + }, + + // Check if dynamically added scripts are loaded and restart inline.processAjaxResponse(): + reprocessAjaxResponse: function (method, json, sourcesWaiting) { + var sourcesLoaded = true; + if (sourcesWaiting && sourcesWaiting.length) { + $A(sourcesWaiting).each(function(source) { + if (!inline.sourcesLoaded[source]) { + sourcesLoaded = false; + return false; + } + }); + } + if (sourcesLoaded) { + $A(sourcesWaiting).each(function(source) { + delete(inline.sourcesLoaded[source]); + }); + window.setTimeout(function() { inline.processAjaxResponse(method, null, json); }, 80); + } else { + window.setTimeout(function() { inline.reprocessAjaxResponse(method, json, sourcesWaiting); }, 40); + } + }, + + sourceLoadedHandler: function(element) { + if (element && element.src) { + inline.sourcesLoaded[element.src] = true; + } + }, + + showAjaxFailure: function(method, xhr) { + inline.unlockAjaxMethod(method); + alert('Error: '+xhr.status+"\n"+xhr.statusText); + }, + + // foreign_selector: used by selector box (type='select') + importNewRecord: function(objectId) { + var selector = $(objectId+'_selector'); + if (selector.selectedIndex != -1) { + var selectedValue = selector.options[selector.selectedIndex].value; + if (!this.data.unique || !this.data.unique[objectId]) { + selector.options[selector.selectedIndex].selected = false; + } + this.makeAjaxCall('createNewRecord', [this.getNumberOfRTE(), objectId, selectedValue], true); + } + return false; + }, + + // foreign_selector: used by element browser (type='group/db') + importElement: function(objectId, table, uid, type) { + window.setTimeout( + function() { + inline.makeAjaxCall('createNewRecord', [this.getNumberOfRTE(), objectId, uid], true); + }, + 10 + ); + }, + + // Check uniqueness for element browser: + checkUniqueElement: function(objectId, table, uid, type) { + if (this.checkUniqueUsed(objectId, uid, table)) { + return {passed: false,message: 'There is already a relation to the selected element!'}; + } else { + return {passed: true}; + } + }, + + // Checks if a record was used and should be unique: + checkUniqueUsed: function(objectId, uid, table) { + if (this.data.unique && this.data.unique[objectId]) { + var unique = this.data.unique[objectId]; + var values = $H(unique.used).values(); + + // for select: only the uid is stored + if (unique['type'] == 'select') { + if (values.indexOf(uid) != -1) return true; + + // for group/db: table and uid is stored in a assoc array + } else if (unique.type == 'groupdb') { + for (var i=values.length-1; i>=0; i--) { + // if the pair table:uid is already used: + if (values[i].table==table && values[i].uid==uid) return true; + } + } + } + return false; + }, + + setUniqueElement: function(objectId, table, uid, type, elName) { + var recordUid = this.parseFormElementName('none', elName, 1, 1); + // alert(objectId+'/'+table+'/'+uid+'/'+recordUid); + this.setUnique(objectId, recordUid, uid); + }, + + // this function is applied to a newly inserted record by AJAX + // it removes the used select items, that should be unique + setUnique: function(objectId, recordUid, selectedValue) { + if (this.data.unique && this.data.unique[objectId]) { + var unique = this.data.unique[objectId]; + + if (unique.type == 'select') { + // remove used items from each select-field of the child records + if (!(unique.selector && unique.max == -1)) { + var formName = this.prependFormFieldNames+this.parseObjectId('parts', objectId, 3, 1, true); + + var fieldObj = document.getElementsByName(elName); + var values = $H(unique.used).values(); + + if (fieldObj.length) { + // remove all items from the new select-item which are already used in other children + for (var i=0; i 0 && current > 0) { + records[current] = records[current-1]; + records[current-1] = callingUid; + changed = true; + + // move down + } else if (direction < 0 && current < records.length-1) { + records[current] = records[current+1]; + records[current+1] = callingUid; + changed = true; + } + + if (changed) { + formObj[0].value = records.join(','); + var cAdj = direction > 0 ? 1 : 0; // adjustment + $(objectId+'_div').parentNode.insertBefore( + $(objectPrefix + this.structureSeparator + records[current-cAdj] + '_div'), + $(objectPrefix + this.structureSeparator + records[current+1-cAdj] + '_div') + ); + this.redrawSortingButtons(objectPrefix, records); + } + } + + return false; + }, + + dragAndDropSorting: function(element) { + var objectId = element.getAttribute('id').replace(/_records$/, ''); + var objectName = inline.prependFormFieldNames+inline.parseObjectId('parts', objectId, 3, 0, true); + var formObj = document.getElementsByName(objectName); + + if (formObj.length) { + var checked = new Array(); + var order = Sortable.sequence(element); + var records = formObj[0].value.split(','); + + // check if ordered uid is really part of the records + // virtually deleted items might still be there but ordering shouldn't saved at all on them + for (var i=0; i 0 ? 'button_unhide.gif' : 'button_hide.gif'); + } + + return false; + }, + + deleteRecord: function(objectId, options) { + var i, j, inlineRecords, records, childObjectId, childTable; + var objectPrefix = this.parseObjectId('full', objectId, 0 , 1); + var elName = this.parseObjectId('full', objectId, 2, 0, true); + var shortName = this.parseObjectId('parts', objectId, 2, 0, true); + var recordUid = this.parseObjectId('none', objectId, 1); + var beforeDeleteIsBelowMax = this.isBelowMax(objectPrefix); + + // revert the unique settings if available + this.revertUnique(objectPrefix, elName, recordUid); + + // Remove from TBE_EDITOR (required fields, required range, etc.): + if (TBE_EDITOR && TBE_EDITOR.removeElement) { + var removeStack = []; + inlineRecords = Element.select(objectId+'_div', '.inlineRecord'); + // Remove nested child records from TBE_EDITOR required/range checks: + for (i=inlineRecords.length-1; i>=0; i--) { + if (inlineRecords[i].value.length) { + records = inlineRecords[i].value.split(','); + childObjectId = this.data.map[inlineRecords[i].name]; + childTable = this.data.config[childObjectId].table; + for (j=records.length-1; j>=0; j--) { + removeStack.push(this.prependFormFieldNames+'['+childTable+']['+records[j]+']'); + } + } + } + removeStack.push(this.prependFormFieldNames+shortName); + TBE_EDITOR.removeElementArray(removeStack); + } + + // If the record is new and was never saved before, just remove it from DOM: + if (this.isNewRecord(objectId) || options && options.forceDirectRemoval) { + this.fadeAndRemove(objectId+'_div'); + // If the record already exists in storage, mark it to be deleted on clicking the save button: + } else { + document.getElementsByName('cmd'+shortName+'[delete]')[0].disabled = false; + new Effect.Fade(objectId+'_div'); + } + + var recordCount = this.memorizeRemoveRecord( + this.prependFormFieldNames+this.parseObjectId('parts', objectId, 3, 2, true), + recordUid + ); + + if (recordCount <= 1) { + this.destroyDragAndDropSorting(this.parseObjectId('full', objectId, 0 , 2)+'_records'); + } + this.redrawSortingButtons(objectPrefix); + + // if the NEW-button was hidden and now we can add again new children, show the button + if (!beforeDeleteIsBelowMax && this.isBelowMax(objectPrefix)) { + var objectParent = this.parseObjectId('full', objectPrefix, 0 , 1); + var md5 = this.getObjectMD5(objectParent); + this.showElementsWithClassName('.inlineNewButton'+(md5 ? '.'+md5 : ''), objectParent); + } + return false; + }, + + parsePath: function(path) { + var backSlash = path.lastIndexOf('\\'); + var normalSlash = path.lastIndexOf('/'); + + if (backSlash > 0) + path = path.substring(0,backSlash+1); + else if (normalSlash > 0) + path = path.substring(0,normalSlash+1); + else + path = ''; + + return path; + }, + + parseFormElementName: function(wrap, formElementName, rightCount, skipRight) { + var idParts = this.splitFormElementName(formElementName); + + if (!wrap) wrap = 'full'; + if (!skipRight) skipRight = 0; + + var elParts = new Array(); + for (var i=0; i 0) { + for (var i=0; i '...|...' + formElementName = formElementName.substr(0, formElementName.lastIndexOf(']')).substr(formElementName.indexOf('[')+1); + var parts = objectId.split(']['); + + return parts; + }, + + splitObjectId: function(objectId) { + objectId = objectId.substr(objectId.indexOf(this.structureSeparator)+1); + var parts = objectId.split(this.structureSeparator); + + return parts; + }, + + constructFormElementName: function(wrap, parts) { + var elReturn; + + if (wrap == 'full') { + elReturn = this.prependFormFieldNames+'['+parts.join('][')+']'; + } else if (wrap == 'parts') { + elReturn = '['+parts.join('][')+']'; + } else if (wrap == 'none') { + elReturn = parts.length > 1 ? parts : parts.join(''); + } + + return elReturn; + }, + + constructObjectId: function(wrap, parts) { + var elReturn; + + if (wrap == 'full') { + elReturn = this.prependFormFieldNames+this.structureSeparator+parts.join(this.structureSeparator); + } else if (wrap == 'parts') { + elReturn = this.structureSeparator+parts.join(this.structureSeparator); + } else if (wrap == 'none') { + elReturn = parts.length > 1 ? parts : parts.join(''); + } + + return elReturn; + }, + + parseObjectId: function(wrap, objectId, rightCount, skipRight, returnAsFormElementName) { + var idParts = this.splitObjectId(objectId); + + if (!wrap) wrap = 'full'; + if (!skipRight) skipRight = 0; + + var elParts = new Array(); + for (var i=0; i 0) { + for (var i=0; i= this.data.config[objectPrefix].max) isBelowMax = false; + } + if (isBelowMax && this.data.unique && this.data.unique[objectPrefix]) { + var unique = this.data.unique[objectPrefix]; + if (this.arrayAssocCount(unique.used) >= unique.max && unique.max >= 0) isBelowMax = false; + } + return isBelowMax; + }, + + getOptionsHash: function(selectObj) { + var optionsHash = {}; + for (var i=0; i tag + var readdOption = document.createElement('option'); + readdOption.text = unique.possible[value]; + readdOption.value = value; + // add the