Commit 1d995d96 authored by Carsten  Rose's avatar Carsten Rose
Browse files

Implemented generating of 'id' per FormElement.

Support.php: new function insertAttribute().
AbstractBuildForm.php: added 'id' to all FormElements.
BuildFormBootstrap: extended customWrap to insert 'id' in every wrap element.
QuickFormQuery.php: Add 'id' to Form ToolTip.
parent 01d39f60
......@@ -398,15 +398,10 @@ abstract class AbstractBuildForm {
//In case the current element is a 'RETYPE' element: take the element name of the source FormElement. Needed in the next row to retrieve the default value.
$name = (isset($formElement[FE_RETYPE_SOURCE_NAME])) ? $formElement[FE_RETYPE_SOURCE_NAME] : $formElement[FE_NAME];
// Get default value
// $value = ($formElement[FE_VALUE] === '') ? $this->store->getVar($name, $storeUse,
// $formElement['checkType']) : $formElement[FE_VALUE];
// If there is a value explicit defined: take it
$value = $formElement[FE_VALUE];
//
if ($value === '') {
// Only take the default, if the FE is a real tablecolumn.
// Only take the default, if the FE is a real tablecolumn. See #2064
if ($this->store->getVar($formElement[FE_NAME], STORE_TABLE_COLUMN_TYPES) !== false) {
$value = $this->store->getVar($name, $storeUse, $formElement['checkType']);
}
......@@ -445,7 +440,7 @@ abstract class AbstractBuildForm {
if ($flagOutput) {
// debugStack as Tooltip
if ($this->showDebugInfo && count($debugStack) > 0) {
$elementHtml .= Support::doTooltip($formElement[FE_HTML_ID], implode("\n", $debugStack));
$elementHtml .= Support::doTooltip($formElement[FE_HTML_ID] . HTML_ID_EXTENSION_TOOLTIP, implode("\n", $debugStack));
}
// Construct Marshaller Name: buildRow
......@@ -690,17 +685,19 @@ abstract class AbstractBuildForm {
*
*
* @param array $formElement
* @param $htmlFormElementName
* @param $value
* @param string $htmlFormElementName
* @param string $value
* @param array $json
* @param string $mode FORM_LOAD | FORM_UPDATE | FORM_SAVE
* @return string
* @return string complete rendered HTML input element.
* @throws \qfq\UserFormException
*/
public function buildInput(array $formElement, $htmlFormElementName, $value, array &$json, $mode = FORM_LOAD) {
$textarea = '';
$attribute = '';
$attribute = Support::doAttribute('name', $htmlFormElementName);
$attribute .= Support::doAttribute('id', $formElement[FE_HTML_ID]);
$attribute .= Support::doAttribute('name', $htmlFormElementName);
$attribute .= Support::doAttribute('class', 'form-control');
if (isset($formElement[FE_RETYPE_SOURCE_NAME])) {
......@@ -708,7 +705,7 @@ abstract class AbstractBuildForm {
$attribute .= Support::doAttribute('data-match', '[name=' . str_replace(':', '\\:', $htmlFormElementNamePrimary) . ']');
}
// Check for input type 'textarea'
// Check for input type 'textarea'.
$colsRows = explode(',', $formElement['size'], 2);
if (count($colsRows) === 2) {
// <textarea>
......@@ -723,9 +720,9 @@ abstract class AbstractBuildForm {
$this->adjustMaxLength($formElement);
if ($formElement['maxLength'] > 0 && $value !== '') {
if ($formElement[FE_MAX_LENGTH] > 0 && $value !== '') {
// crop string only if it's not empty (substr returns false on empty strings)
$value = substr($value, 0, $formElement['maxLength']);
$value = substr($value, 0, $formElement[FE_MAX_LENGTH]);
}
// 'maxLength' needs an upper 'L': naming convention for DB tables!
......@@ -1217,6 +1214,7 @@ abstract class AbstractBuildForm {
$html = '';
$valueJson = false;
$attribute .= Support::doAttribute('id', $formElement[FE_HTML_ID]);
$attribute .= Support::doAttribute('name', $htmlFormElementName);
$attribute .= Support::doAttribute('value', $formElement['checked'], false);
$attribute .= Support::doAttribute('title', $formElement['tooltip']);
......@@ -1271,6 +1269,7 @@ abstract class AbstractBuildForm {
$html = '';
$valueJson = false;
$attribute .= Support::doAttribute('id', $formElement[FE_HTML_ID]);
$attribute .= Support::doAttribute('name', $htmlFormElementName);
$attribute .= Support::doAttribute('value', $formElement['checked'], false);
$attribute .= Support::doAttribute('title', $formElement['tooltip']);
......@@ -1360,6 +1359,7 @@ abstract class AbstractBuildForm {
$jsonValue = false;
$classActive = '';
$htmlFormElementNameUniq = HelperFormElement::prependFormElementNameCheckBoxMulti($htmlFormElementName, $ii);
$attribute .= Support::doAttribute('id', $formElement[FE_HTML_ID] . '-' . $ii);
$attribute .= Support::doAttribute('name', $htmlFormElementNameUniq);
$attribute .= Support::doAttribute('value', $itemKey[$ii]);
......@@ -1416,7 +1416,7 @@ abstract class AbstractBuildForm {
$html = $this->buildNativeHidden(HelperFormElement::prependFormElementNameCheckBoxMulti($htmlFormElementName, 'h'), '');
$orientation = ($formElement['maxLength'] > 1) ? ALIGN_HORIZONTAL : ALIGN_VERTICAL;
$orientation = ($formElement[FE_MAX_LENGTH] > 1) ? ALIGN_HORIZONTAL : ALIGN_VERTICAL;
$checkboxClass = ($orientation === ALIGN_HORIZONTAL) ? 'checkbox-inline' : 'checkbox';
$br = '';
......@@ -1425,6 +1425,7 @@ abstract class AbstractBuildForm {
$jsonValue = false;
$attribute = $attributeBase;
$htmlFormElementNameUniq = HelperFormElement::prependFormElementNameCheckBoxMulti($htmlFormElementName, $ii);
$attribute .= Support::doAttribute('id', $formElement[FE_HTML_ID] . '-' . $ii);
$attribute .= Support::doAttribute('name', $htmlFormElementNameUniq);
// Do this only the first round.
......@@ -1455,9 +1456,9 @@ abstract class AbstractBuildForm {
$htmlElement = Support::wrapTag("<div class='$checkboxClass'>", $htmlElement, true);
// control orientation
if ($formElement['maxLength'] > 1) {
if ($formElement[FE_MAX_LENGTH] > 1) {
if ($jj == $formElement['maxLength']) {
if ($jj == $formElement[FE_MAX_LENGTH]) {
$jj = 0;
$br = '<br>';
} else {
......@@ -1567,6 +1568,7 @@ abstract class AbstractBuildForm {
$attributeBase = $this->getAttributeFeMode($formElement[FE_MODE]);
$attributeBase .= $this->getAttributeList($formElement, [F_FE_DATA_PATTERN_ERROR, F_FE_DATA_REQUIRED_ERROR, F_FE_DATA_MATCH_ERROR, F_FE_DATA_ERROR]);
$attributeBase .= Support::doAttribute('id', $formElement[FE_HTML_ID]);
$attributeBase .= Support::doAttribute('name', $htmlFormElementName);
$attributeBase .= Support::doAttribute('type', $formElement[FE_TYPE]);
$attributeBase .= Support::doAttribute('data-load', ($formElement[FE_DYNAMIC_UPDATE] === 'yes') ? 'data-load' : '');
......@@ -1624,6 +1626,7 @@ abstract class AbstractBuildForm {
* @throws \qfq\UserFormException
*/
private function constructRadioPlain(array $formElement, $htmlFormElementName, $value, array &$json, $mode = FORM_LOAD) {
$attributeBase = '';
if (isset($formElement[FE_BUTTON_CLASS])) {
return $this->constructRadioButton($formElement, $htmlFormElementName, $value, $json, $mode);
......@@ -1636,15 +1639,16 @@ abstract class AbstractBuildForm {
// Fill $itemKey & $itemValue
$this->getKeyValueListFromSqlEnumSpec($formElement, $itemKey, $itemValue);
$attributeBase = $this->getAttributeFeMode($formElement[FE_MODE]);
$attributeBase .= $this->getAttributeFeMode($formElement[FE_MODE]);
$attributeBase .= $this->getAttributeList($formElement, [F_FE_DATA_PATTERN_ERROR, F_FE_DATA_REQUIRED_ERROR, F_FE_DATA_MATCH_ERROR, F_FE_DATA_ERROR]);
$attributeBase .= Support::doAttribute('id', $formElement[FE_HTML_ID]);
$attributeBase .= Support::doAttribute('name', $htmlFormElementName);
$attributeBase .= Support::doAttribute('type', $formElement[FE_TYPE]);
$attributeBase .= Support::doAttribute('data-load', ($formElement[FE_DYNAMIC_UPDATE] === 'yes') ? 'data-load' : '');
$jj = 0;
$orientation = ($formElement['maxLength'] > 1) ? ALIGN_HORIZONTAL : ALIGN_VERTICAL;
$orientation = ($formElement[FE_MAX_LENGTH] > 1) ? ALIGN_HORIZONTAL : ALIGN_VERTICAL;
$radioClass = ($orientation === ALIGN_HORIZONTAL) ? 'radio-inline' : 'radio';
$br = '';
......@@ -1675,9 +1679,9 @@ abstract class AbstractBuildForm {
$htmlElement = Support::wrapTag('<label>', $htmlElement);
}
if ($formElement['maxLength'] > 1) {
if ($formElement[FE_MAX_LENGTH] > 1) {
if ($jj == $formElement['maxLength']) {
if ($jj == $formElement[FE_MAX_LENGTH]) {
$jj = 0;
$br = '<br>';
} else {
......@@ -1712,11 +1716,13 @@ abstract class AbstractBuildForm {
public function buildSelect(array $formElement, $htmlFormElementName, $value, array &$json, $mode = FORM_LOAD) {
$itemKey = array();
$itemValue = array();
$attribute = '';
// Fill $itemKey & $itemValue
$this->getKeyValueListFromSqlEnumSpec($formElement, $itemKey, $itemValue);
$attribute = $this->getAttributeFeMode($formElement[FE_MODE]);
$attribute .= $this->getAttributeFeMode($formElement[FE_MODE]);
$attribute .= Support::doAttribute('id', $formElement[FE_HTML_ID]);
$attribute .= Support::doAttribute('name', $htmlFormElementName);
$attribute .= Support::doAttribute('class', 'form-control');
$attribute .= Support::doAttribute('title', $formElement['tooltip']);
......@@ -2188,6 +2194,7 @@ abstract class AbstractBuildForm {
$hiddenSipUpload = $this->buildNativeHidden($htmlFormElementName, $sipUpload);
$attribute .= Support::doAttribute('id', $formElement[FE_HTML_ID]);
$attribute .= Support::doAttribute('name', $htmlFormElementName);
// $attribute .= Support::doAttribute('class', 'form-control');
$attribute .= Support::doAttribute('type', 'file');
......@@ -2237,8 +2244,10 @@ abstract class AbstractBuildForm {
* @throws UserFormException
*/
public function buildDateTime(array $formElement, $htmlFormElementName, $value, array &$json, $mode = FORM_LOAD) {
$attribute = '';
$attribute = Support::doAttribute('name', $htmlFormElementName);
$attribute .= Support::doAttribute('id', $formElement[FE_HTML_ID]);
$attribute .= Support::doAttribute('name', $htmlFormElementName);
$attribute .= Support::doAttribute('class', 'form-control');
$arrMinMax = null;
......@@ -2271,8 +2280,8 @@ abstract class AbstractBuildForm {
}
// truncate if necessary
if ($value != '' && $formElement['maxLength'] > 0) {
$value = substr($value, 0, $formElement['maxLength']);
if ($value != '' && $formElement[FE_MAX_LENGTH] > 0) {
$value = substr($value, 0, $formElement[FE_MAX_LENGTH]);
}
$type = $formElement[FE_TYPE];
......@@ -2422,13 +2431,15 @@ abstract class AbstractBuildForm {
* @throws \qfq\UserFormException
*/
public function buildEditor(array $formElement, $htmlFormElementName, $value, array &$json, $mode = FORM_LOAD) {
$attribute = '';
//TODO plugin autoresize nutzen um Editorgroesse anzugeben
$this->adjustMaxLength($formElement);
$attribute = Support::doAttribute('name', $htmlFormElementName);
$attribute .= Support::doAttribute('id', $htmlFormElementName);
$attribute .= Support::doAttribute('id', $formElement[FE_HTML_ID]);
$attribute .= Support::doAttribute('name', $htmlFormElementName);
// $attribute .= Support::doAttribute('id', $htmlFormElementName);
$attribute .= Support::doAttribute('class', 'qfq-tinymce');
$attribute .= Support::doAttribute('data-control-name', "$htmlFormElementName");
......@@ -2601,6 +2612,7 @@ abstract class AbstractBuildForm {
// save parent processed FE's
$tmpStore = $this->feSpecNative;
$attribute .= Support::doAttribute('id', $formElement[FE_HTML_ID]);
$attribute .= Support::doAttribute('name', $htmlFormElementName);
$attribute .= Support::doAttribute('data-load', ($formElement[FE_DYNAMIC_UPDATE] === 'yes') ? 'data-load' : '');
......
......@@ -421,19 +421,19 @@ EOF;
}
$html .= $this->customWrap($formElement, $htmlLabel, FE_WRAP_LABEL, $formElement[FE_BS_LABEL_COLUMNS],
[$this->wrap[WRAP_SETUP_LABEL][WRAP_SETUP_START], $this->wrap[WRAP_SETUP_LABEL][WRAP_SETUP_END]]);
[$this->wrap[WRAP_SETUP_LABEL][WRAP_SETUP_START], $this->wrap[WRAP_SETUP_LABEL][WRAP_SETUP_END]], $formElement[FE_HTML_ID] . HTML_ID_EXTENSION_LABEL);
$html .= $this->customWrap($formElement, $htmlElement, FE_WRAP_INPUT, $formElement[FE_BS_INPUT_COLUMNS],
[$this->wrap[WRAP_SETUP_INPUT][WRAP_SETUP_START], $this->wrap[WRAP_SETUP_INPUT][WRAP_SETUP_END]]);
[$this->wrap[WRAP_SETUP_INPUT][WRAP_SETUP_START], $this->wrap[WRAP_SETUP_INPUT][WRAP_SETUP_END]], $formElement[FE_HTML_ID] . HTML_ID_EXTENSION_INPUT);
$note = Support::wrapTag("<div class='qfq-note'>", $formElement[FE_NOTE], true);
$html .= $this->customWrap($formElement, $note, FE_WRAP_NOTE, $formElement[FE_BS_NOTE_COLUMNS],
[$this->wrap[WRAP_SETUP_NOTE][WRAP_SETUP_START], $this->wrap[WRAP_SETUP_NOTE][WRAP_SETUP_END]]);
[$this->wrap[WRAP_SETUP_NOTE][WRAP_SETUP_START], $this->wrap[WRAP_SETUP_NOTE][WRAP_SETUP_END]], $formElement[FE_HTML_ID] . HTML_ID_EXTENSION_NOTE);
// ROW
$openTag = (Support::findInSet('row', $formElement[FE_WRAP_ROW_LABEL_INPUT_NOW])) ? $this->wrap[WRAP_SETUP_ELEMENT][WRAP_SETUP_START] : '';
$closeTag = (Support::findInSet('/row', $formElement[FE_WRAP_ROW_LABEL_INPUT_NOW])) ? $this->wrap[WRAP_SETUP_ELEMENT][WRAP_SETUP_END] : '';
$html = $this->customWrap($formElement, $html, FE_WRAP_ROW, 99, [$openTag, $closeTag]);
$html = $this->customWrap($formElement, $html, FE_WRAP_ROW, 99, [$openTag, $closeTag], $formElement[FE_HTML_ID] . HTML_ID_EXTENSION_ROW);
return $html;
}
......@@ -448,13 +448,15 @@ EOF;
* @return string Wrapped $htmlElement
* @throws \qfq\UserFormException
*/
private function customWrap(array $formElement, $htmlElement, $wrapName, $bsColumns, array $wrapArray) {
private function customWrap(array $formElement, $htmlElement, $wrapName, $bsColumns, array $wrapArray, $htmlId = '') {
// If $bsColumns==0: do not wrap with default.
if ($bsColumns == 0) {
$wrapArray[0] = '';
$wrapArray[1] = '';
}
// If there is a 'per FormElement'-wrap, take it.
if (isset($formElement[$wrapName])) {
$wrapArray = explode('|', $formElement[$wrapName], 2);
}
......@@ -463,6 +465,10 @@ EOF;
throw new UserFormException("Need open & close wrap token for FormElement.parameter" . $wrapName . " - E.g.: <div ...>|</div>", ERROR_MISSING_VALUE);
}
if ($wrapArray[0] != '') {
$wrapArray[0] = Support::insertAttribute($wrapArray[0], 'id', $htmlId);
}
return $wrapArray[0] . $htmlElement . $wrapArray[1];
}
......
......@@ -161,6 +161,7 @@ const ERROR_SENDMAIL_MISSING_VALUE = 1072;
const ERROR_OVERWRITE_RECORD_ID = 1073;
const ERROR_MISSING_SLAVE_ID_DEFINITION = 1074;
const ERROR_MISSING_INTL = 1075;
const ERROR_HTML_TOKEN_TOO_SHORT = 1076;
// Subrecord
const ERROR_SUBRECORD_MISSING_COLUMN_ID = 1100;
......@@ -574,6 +575,7 @@ const RETYPE_FE_NAME_EXTENSION = 'RETYPE';
const FE_HTML_ID = 'htmlId'; // Will be dynamically computed during runtime.
// FormElement Types
const FE_TYPE_UPLOAD = 'upload';
const FE_TYPE_EXTRA = 'extra';
......@@ -599,6 +601,12 @@ const ESCAPE_WITH_HTML_QUOTE = 'htmlquote';
const FLAG_ALL = 'flagAll';
const FLAG_DYNAMIC_UPDATE = 'flagDynamicUpdate';
const HTML_ID_EXTENSION_LABEL = '-l';
const HTML_ID_EXTENSION_INPUT = '-i';
const HTML_ID_EXTENSION_NOTE = '-n';
const HTML_ID_EXTENSION_TOOLTIP = '-t';
const HTML_ID_EXTENSION_ROW = '-r';
const QUERY_TYPE_SELECT = 'type: select,show,describe,explain';
const QUERY_TYPE_INSERT = 'type: insert';
const QUERY_TYPE_UPDATE = 'type: update,replace,delete';
......
......@@ -186,9 +186,8 @@ class QuickFormQuery {
$html = '';
if ($this->store->getVar(TYPO3_DEBUG_SHOW_BODY_TEXT, STORE_TYPO3) === 'yes') {
// TODO: hier den Tootltip mit eienr ID versehen
// $htmlId = HelperFormElement::buildFormElementId($this->)
$html .= Support::doTooltip('', $this->t3data['bodytext']);
$htmlId = HelperFormElement::buildFormElementId($this->formSpec[F_ID], 0, 0, 0);
$html .= Support::doTooltip($htmlId . HTML_ID_EXTENSION_TOOLTIP, $this->t3data['bodytext']);
}
$html .= $this->doForm(FORM_LOAD);
......
......@@ -100,11 +100,14 @@ class Support {
/**
* Format's an attribute: $type=$value. If $flagOmitEmpty==true && $value=='': return ''.
* Add's a space at the end.
*
* @param string $type
* @param string|array $value
* @param bool $flagOmitEmpty
* @return string
* @param string $modeEscape
* @return string correctly fomratted attribute. Space at the end.
* @throws CodeException
*/
public static function doAttribute($type, $value, $flagOmitEmpty = true, $modeEscape = ESCAPE_WITH_BACKSLASH) {
......@@ -120,7 +123,7 @@ class Support {
switch (strtolower($type)) {
case 'size':
case 'maxlength':
// empty or '0' for attributes of type 'size' or 'maxlenght' result in unsuable input elements: skip this.
// empty or '0' for attributes of type 'size' or 'maxlength' result in unsuable input elements: skip this.
if ($value === '' || $value == 0) {
return '';
}
......@@ -137,7 +140,6 @@ class Support {
$value = self::escapeDoubleTick(trim($value), $modeEscape);
return $type . '="' . $value . '" ';
}
/**
......@@ -175,6 +177,37 @@ class Support {
return $newStr;
}
/**
* Format's an attribute and inserts them at the beginning of the $htmlTag:
* If $flagOmitEmpty==true && $value=='': insert nothing
*
* @param string $htmlTag with open and closing angle.
* @param string $type
* @param string|array $value
* @param bool $flagOmitEmpty
* @param string $modeEscape
* @return string correctly fomratted attribute. Space at the end.
* @throws CodeException
*/
public static function insertAttribute($htmlTag, $type, $value, $flagOmitEmpty = true, $modeEscape = ESCAPE_WITH_BACKSLASH) {
$htmlTag = trim($htmlTag);
// e.g. '<div class=...' will be exploded to '<div' and 'class=...'
$parts = explode(' ', $htmlTag, 2);
if (count($parts) < 2) {
if (strlen($htmlTag) < 3) {
throw new CodeException('HTML Token too short (<3 chars):' . $htmlTag, ERROR_HTML_TOKEN_TOO_SHORT);
} else {
$parts[0] = substr($htmlTag, 0, -1);
$parts[1] = '>';
}
}
$attr = self::doAttribute($type, $value, $flagOmitEmpty, $modeEscape);
return $parts[0] . ' ' . $attr . $parts[1];
}
/**
* Search for the parameter $needle in $haystack. The arguments has to be seperated by ','.
*
......
......@@ -404,6 +404,31 @@ class SupportTest extends \PHPUnit_Framework_TestCase {
$this->assertEquals('\\"\\"\\"', $new);
}
public function testInsertAttribute() {
$new = Support::insertAttribute('<i>', 'class', 'qfq');
$this->assertEquals('<i class="qfq" >', $new);
$new = Support::insertAttribute('<div>', 'class', 'qfq');
$this->assertEquals('<div class="qfq" >', $new);
$new = Support::insertAttribute(' <div> ', 'class', 'qfq');
$this->assertEquals('<div class="qfq" >', $new);
$new = Support::insertAttribute('<div >', 'class', 'qfq');
$this->assertEquals('<div class="qfq" >', $new);
$new = Support::insertAttribute('<div class="123">', 'class', 'qfq');
$this->assertEquals('<div class="qfq" class="123">', $new);
}
/**
* @expectedException \qfq\CodeException
*/
public function testInsertAttributeException1() {
Support::insertAttribute('<>', 'class', 'qfq');
}
protected function setUp() {
parent::setUp();
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment