Commit 7be64978 authored by Rafael Ostertag's avatar Rafael Ostertag
Browse files

Merge remote-tracking branch 'origin/crose_work' into raos_work

parents 83dfdcde bd991dba
...@@ -258,9 +258,10 @@ Server Response ...@@ -258,9 +258,10 @@ Server Response
: The response contains a [Minimal Response]. : The response contains a [Minimal Response].
### Record delete ### Record(s) delete
Request the deletion of the record identified by the SIP. Request the deletion of the record identified by the SIP. The SIP might contain a SIP_TABLE and/or a SIP_FORM.
If both are specified, SIP_FORM will be taken. With SIP_FORM, the tableName is derived from the form.
Request Request
: api/delete.php : api/delete.php
...@@ -273,6 +274,7 @@ URL Parameters ...@@ -273,6 +274,7 @@ URL Parameters
Server Response Server Response
: The response contains a [Minimal Response]. : The response contains a [Minimal Response].
[Redirection Response] may be included.
## Glossary ## Glossary
......
...@@ -36,12 +36,14 @@ Setup ...@@ -36,12 +36,14 @@ Setup
* Install the extension via the Extensionmanager. * Install the extension via the Extensionmanager.
* If you install the extension by manual download/upload and get an error message * If you install the extension by manual download/upload and get an error message
"can't activate extension": rename the downloaded zip file to `qfq.zip`. "can't activate extension": rename the downloaded zip file to `qfq.zip` or `qfq_<version>.zip` (e.g. version: 0.9.1).
* If the Extensionmanager stops after importing: check your memory limit in php.ini. * If the Extensionmanager stops after importing: check your memory limit in php.ini.
* Enable the online Documentation_. * Enable the online Documentation_.
* Copy/rename the file *<ext_dir>/config.example.qfq.ini* to *typo3conf/config.qfq.ini* and configure the necessary values: `config.qfq.ini`_ * Copy/rename the file *<Documentroot>/typo3conf/ext/<ext_dir>/config.example.qfq.ini* to
*<Documentroot>/typo3conf/config.qfq.ini* and configure the necessary values: `config.qfq.ini`_
The configuration file is outside the extension directory to not loose it during updates.
* Play the SQL File *<ext_dir>/qfq/sql/formEditor.sql* to fill the database with the *FormEditor* records. * Play the SQL File *<ext_dir>/qfq/sql/formEditor.sql* to fill the database with the *FormEditor* records.
* Configure Typoscript to include Bootstrap, jQuery, QFQ javascript and CSS files. * Configure Typoscript to include Bootstrap, jQuery, QFQ javascript and CSS files.
...@@ -88,35 +90,42 @@ Setup a *report* to manage all *forms*: Create a Typo3 page and insert a content ...@@ -88,35 +90,42 @@ Setup a *report* to manage all *forms*: Create a Typo3 page and insert a content
config.qfq.ini config.qfq.ini
-------------- --------------
+------------------------+----------------------------------+----------------------------------------------------------------------------+ +-------------------------+-----------------------------------------+----------------------------------------------------------------------------+
| Keyword | Example | Description | | Keyword | Example | Description |
+========================+==================================+============================================================================+ +=========================+=========================================+============================================================================+
| DB_USER | DB_USER=qfqUser | Credentials configured in MySQL | | DB_USER | DB_USER=qfqUser | Credentials configured in MySQL |
+------------------------+----------------------------------+----------------------------------------------------------------------------+ +-------------------------+-----------------------------------------+----------------------------------------------------------------------------+
| DB_PASSWORD | DB_PASSWORD=12345678 | Credentials configured in MySQL | | DB_PASSWORD | DB_PASSWORD=12345678 | Credentials configured in MySQL |
+------------------------+----------------------------------+----------------------------------------------------------------------------+ +-------------------------+-----------------------------------------+----------------------------------------------------------------------------+
| DB_SERVER | DB_SERVER=localhost | Hostname of MySQL Server | | DB_SERVER | DB_SERVER=localhost | Hostname of MySQL Server |
+------------------------+----------------------------------+----------------------------------------------------------------------------+ +-------------------------+-----------------------------------------+----------------------------------------------------------------------------+
| DB_NAME | DB_NAME=qfq_db | Database name | | DB_NAME | DB_NAME=qfq_db | Database name |
+------------------------+----------------------------------+----------------------------------------------------------------------------+ +-------------------------+-----------------------------------------+----------------------------------------------------------------------------+
| DB_NAME_TEST | DB_NAME_TEST=qfq_db_test | Used during development of QFQ | | DB_NAME_TEST | DB_NAME_TEST=qfq_db_test | Used during development of QFQ |
+------------------------+----------------------------------+----------------------------------------------------------------------------+ +-------------------------+-----------------------------------------+----------------------------------------------------------------------------+
| DB_INIT | DB_INIT=set names utf8 | Global init for using the database. | | DB_INIT | DB_INIT=set names utf8 | Global init for using the database. |
+------------------------+----------------------------------+----------------------------------------------------------------------------+ +-------------------------+-----------------------------------------+----------------------------------------------------------------------------+
| SQL_LOG | SQL_LOG=sql.log | Filename to log SQL commands: relative to <ext_dir> or absolute. | | SQL_LOG | SQL_LOG=sql.log | Filename to log SQL commands: relative to <ext_dir> or absolute. |
+------------------------+----------------------------------+----------------------------------------------------------------------------+ +-------------------------+-----------------------------------------+----------------------------------------------------------------------------+
| SQL_LOG_MODE | SQL_LOG_MODE=modify | *all*: every statement will be logged - this is a lot | | SQL_LOG_MODE | SQL_LOG_MODE=modify | *all*: every statement will be logged - this is a lot |
| | | *modify*: log only statements who change data | | | | *modify*: log only statements who change data |
+------------------------+----------------------------------+----------------------------------------------------------------------------+ +-------------------------+-----------------------------------------+----------------------------------------------------------------------------+
| SHOW_DEBUG_INFO | SHOW_DEBUG_INFO=auto | Possible values: auto|yes|no. For 'auto': If a BE User is logged in, | | SHOW_DEBUG_INFO | SHOW_DEBUG_INFO=auto | Possible values: auto|yes|no. For 'auto': If a BE User is logged in, |
| | | debug information will be shown on the fronend. | | | | debug information will be shown on the fronend. |
+------------------------+----------------------------------+----------------------------------------------------------------------------+ +-------------------------+-----------------------------------------+----------------------------------------------------------------------------+
| CSS_LINK_CLASS_INTERNAL| CSS_LINK_CLASS_INTERNAL=internal | CSS class name of links which points to internal tagets | | CSS_LINK_CLASS_INTERNAL | CSS_LINK_CLASS_INTERNAL=internal | CSS class name of links which points to internal tagets |
+------------------------+----------------------------------+----------------------------------------------------------------------------+ +-------------------------+-----------------------------------------+----------------------------------------------------------------------------+
| CSS_LINK_CLASS_EXTERNAL| CSS_LINK_CLASS_EXTERNAL=external | CSS class name of links which points to internal tagets | | CSS_LINK_CLASS_EXTERNAL | CSS_LINK_CLASS_EXTERNAL=external | CSS class name of links which points to internal tagets |
+------------------------+----------------------------------+----------------------------------------------------------------------------+ +-------------------------+-----------------------------------------+----------------------------------------------------------------------------+
| DATE_FORMAT | DATE_FORMAT= yyyy-mm-dd | Possible options: yyyy-mm-dd, dd.mm.yyyy | | CSS_CLASS_QFQ_CONTAINER |CSS_CLASS_QFQ_CONTAINER=container | QFQ with own Bootstrap: 'container'. |
+------------------------+----------------------------------+----------------------------------------------------------------------------+ | | | QFQ already nested in Bootstrap of mainpage: <empty> |
+-------------------------+-----------------------------------------+----------------------------------------------------------------------------+
| CSS_CLASS_QFQ_FORM_PILL |CSS_CLASS_QFQ_FORM_PILL=qfq-color-grey-1 | Wrap around title bar for pills: CSS Class, typically a background color |
+-------------------------+-----------------------------------------+----------------------------------------------------------------------------+
| CSS_CLASS_QFQ_FORM_BODY |CSS_CLASS_QFQ_FORM_BODY=qfq-color-grey-2 | Wrap around formelements: CSS Class, typically a background color |
+-------------------------+-----------------------------------------+----------------------------------------------------------------------------+
| DATE_FORMAT | DATE_FORMAT= yyyy-mm-dd | Possible options: yyyy-mm-dd, dd.mm.yyyy |
+-------------------------+-----------------------------------------+----------------------------------------------------------------------------+
Example: *typo3conf/config.qfq.ini* Example: *typo3conf/config.qfq.ini*
...@@ -132,13 +141,16 @@ Example: *typo3conf/config.qfq.ini* ...@@ -132,13 +141,16 @@ Example: *typo3conf/config.qfq.ini*
SHOW_DEBUG_INFO = auto SHOW_DEBUG_INFO = auto
CSS_LINK_CLASS_INTERNAL = internal CSS_LINK_CLASS_INTERNAL = internal
CSS_LINK_CLASS_EXT = external CSS_LINK_CLASS_EXT = external
CSS_CLASS_QFQ_CONTAINER =
CSS_CLASS_QFQ_FORM_PILL = qfq-color-grey-1
CSS_CLASS_QFQ_FORM_BODY = qfq-color-grey-2
Documentation Documentation
------------- -------------
To render the QFQ reST documentation: To render the QFQ reST documentation:
* Take care to have 'unzip' and 'Python setuptools' installed (necessary to run ). * Take care to have 'unzip' and 'Python setuptools' installed (necessary to run).
Preparation for Ubuntu 16.04:: Preparation for Ubuntu 16.04::
......
...@@ -32,7 +32,7 @@ QFQ Extension ...@@ -32,7 +32,7 @@ QFQ Extension
Quick Form Query, Form, Report, SQL, Query, Generator. Quick Form Query, Form, Report, SQL, Query, Generator.
:Copyright: :Copyright:
2016 2017
:Author: :Author:
Carsten Rose, Rafael Ostertag Carsten Rose, Rafael Ostertag
......
; comment ; QFQ configuration
;
; Save this file as: <Documentroot>/typo3conf/config.qfq.ini
DB_USER = <DBUSER> DB_USER = <DBUSER>
DB_SERVER = <DBSERVER> DB_SERVER = <DBSERVER>
DB_PASSWORD = <DBPW> DB_PASSWORD = <DBPW>
...@@ -12,7 +15,7 @@ SQL_LOG = sql.log ...@@ -12,7 +15,7 @@ SQL_LOG = sql.log
; all, modify ; all, modify
SQL_LOG_MODE = modify SQL_LOG_MODE = modify
; auto|yes|no. 'auto': if BE User is loggend in 'true', else 'false' ; auto|yes|no. 'auto': if BE User is logged in the value will be 'true', else 'false'
SHOW_DEBUG_INFO = auto SHOW_DEBUG_INFO = auto
CSS_LINK_CLASS_INTERNAL = internal CSS_LINK_CLASS_INTERNAL = internal
...@@ -21,5 +24,9 @@ CSS_LINK_CLASS_EXTERNAL = external ...@@ -21,5 +24,9 @@ CSS_LINK_CLASS_EXTERNAL = external
; QFQ with own Bootstrap: 'container'. QFQ already nested in Bootstrap of mainpage: <empty> ; QFQ with own Bootstrap: 'container'. QFQ already nested in Bootstrap of mainpage: <empty>
CSS_CLASS_QFQ_CONTAINER = CSS_CLASS_QFQ_CONTAINER =
; Default background color, specified via CSS class
CSS_CLASS_QFQ_FORM_PILL = qfq-color-grey-1
CSS_CLASS_QFQ_FORM_BODY = qfq-color-grey-2
; yyyy-mm-dd, dd.mm.yyyy ; yyyy-mm-dd, dd.mm.yyyy
DATE_FORMAT = yyyy-mm-dd DATE_FORMAT = yyyy-mm-dd
...@@ -11,12 +11,28 @@ namespace qfq; ...@@ -11,12 +11,28 @@ namespace qfq;
use qfq; use qfq;
require_once(__DIR__ . '/../qfq/QuickFormQuery.php'); require_once(__DIR__ . '/../qfq/QuickFormQuery.php');
//require_once(__DIR__ . '/../qfq/store/Store.php'); require_once(__DIR__ . '/../qfq/store/Store.php');
require_once(__DIR__ . '/../qfq/Constants.php'); require_once(__DIR__ . '/../qfq/Constants.php');
require_once(__DIR__ . '/../qfq/exceptions/CodeException.php');
/** /**
* Return JSON encoded answer * delete: success
* SIP_MODE_ANSWER: MODE_HTML
* Send header 'location' to targetUrl
*
* SUP_MODE_ANSWER: MODE_JSON
* Send AJAX answer with Status 'success'
*
* delete: failed
* SIP_MODE_ANSWER: MODE_HTML
* No forward, print error message.
*
* SUP_MODE_ANSWER: MODE_JSON
* Send AJAX answer with Status 'error' and 'error message' as JSON encoded
*
*
* JSON Format:
* *
* status: success|error * status: success|error
* message: <message> * message: <message>
...@@ -47,17 +63,58 @@ require_once(__DIR__ . '/../qfq/Constants.php'); ...@@ -47,17 +63,58 @@ require_once(__DIR__ . '/../qfq/Constants.php');
$answer = array(); $answer = array();
$answer[API_REDIRECT] = API_ANSWER_REDIRECT_NO; $answer[API_REDIRECT] = API_ANSWER_REDIRECT_NO;
$answer[API_MESSAGE] = 'Something failed'; $answer[API_MESSAGE] = '';
$answer[API_STATUS] = API_ANSWER_STATUS_ERROR; $answer[API_STATUS] = API_ANSWER_STATUS_ERROR;
$result[MSG_HEADER] = '';
$result[MSG_CONTENT] = '';
$modeAnswer = false;
$flagSuccess = false;
try { try {
$qfq = new \qfq\QuickFormQuery(['bodytext' => '']); $qfq = new \qfq\QuickFormQuery(['bodytext' => '']);
$result = $qfq->delete(); $flagSuccess = $qfq->delete();
$targetUrl = Store::getVar(SIP_TARGET_URL, STORE_SIP);
$modeAnswer = Store::getVar(SIP_MODE_ANSWER, STORE_SIP);
switch ($modeAnswer) {
case MODE_JSON:
$answer[API_MESSAGE] = 'delete: success';
$answer[API_REDIRECT] = API_ANSWER_REDIRECT_CLIENT;
$answer[API_STATUS] = API_ANSWER_STATUS_SUCCESS;
break;
case MODE_HTML:
if ($targetUrl === false || $targetUrl === '') {
throw new CodeException('Missing target URL', ERROR_MISSING_VALUE);
}
$result[MSG_HEADER] = "Location: $targetUrl";
break;
default:
throw new CodeException('Unknown mode: ' . $modeAnswer, ERROR_UNKNOWN_MODE);
break;
}
} catch (qfq\UserFormException $e) { } catch (qfq\UserFormException $e) {
$answer[API_MESSAGE] = $e->formatMessage(); $answer[API_MESSAGE] = $e->formatMessage();
$val = Store::getVar(SYSTEM_FORM_ELEMENT, STORE_SYSTEM);
if ($val !== false) {
$answer[API_FIELD_NAME] = $val;
}
$val = Store::getVar(SYSTEM_FORM_ELEMENT_MESSAGE, STORE_SYSTEM);
if ($val !== false) {
$answer[API_FIELD_MESSAGE] = $val;
}
} catch (qfq\CodeException $e) { } catch (qfq\CodeException $e) {
$answer[API_MESSAGE] = $e->formatMessage(); $answer[API_MESSAGE] = $e->formatMessage();
} catch (qfq\DbException $e) { } catch (qfq\DbException $e) {
...@@ -66,17 +123,28 @@ try { ...@@ -66,17 +123,28 @@ try {
$answer[API_MESSAGE] = "Generic Exception: " . $e->getMessage(); $answer[API_MESSAGE] = "Generic Exception: " . $e->getMessage();
} }
// Fallbak. in case an exception has been thrown and $result is not filled. // In case $modeAnswer is still missing: try to get it again - maybe the SIP store has been initialized before the exception has been thrown.
if (!isset($result[MSG_HEADER]) && !isset($result[MSG_CONTENT])) { if ($modeAnswer === false) {
$modeAnswer = Store::getVar(SIP_MODE_ANSWER, STORE_SIP);
}
if ($modeAnswer === MODE_JSON) {
// JSON
$result[MSG_HEADER] = "Content-Type: application/json"; $result[MSG_HEADER] = "Content-Type: application/json";
$result[MSG_CONTENT] = json_encode($answer); $result[MSG_CONTENT] = json_encode($answer);
} else {
// HTML
if (!$flagSuccess) {
$result[MSG_CONTENT] = "<p>" . $answer[API_MESSAGE] . "</p>";
if (isset($answer[API_FIELD_NAME])) {
$result[MSG_CONTENT] .= "<p>" . $answer[API_FIELD_NAME] . " : " . $answer[API_FIELD_MESSAGE] . "</p>";
}
}
} }
if (isset($result[MSG_HEADER]) && $result[MSG_HEADER] !== '') { // Send header, if given.
if ($result[MSG_HEADER] !== '') {
header($result[MSG_HEADER]); header($result[MSG_HEADER]);
} }
echo $result[MSG_CONTENT]; echo $result[MSG_CONTENT];
\ No newline at end of file
...@@ -861,6 +861,8 @@ abstract class AbstractBuildForm { ...@@ -861,6 +861,8 @@ abstract class AbstractBuildForm {
* @return string * @return string
*/ */
private function getHelpBlock() { private function getHelpBlock() {
//TODO: #3066 Class 'hidden' einbauen
// return '<div class="help-block with-errors hidden"></div>';
return '<div class="help-block with-errors"></div>'; return '<div class="help-block with-errors"></div>';
} }
...@@ -1444,8 +1446,20 @@ abstract class AbstractBuildForm { ...@@ -1444,8 +1446,20 @@ abstract class AbstractBuildForm {
} }
if ($flagDelete) { if ($flagDelete) {
$s = $this->createDeleteUrl($targetTableName, $row[$nameColumnId], RETURN_SIP); $toolTip = 'Delete';
$rowHtml .= Support::wrapTag('<td>', Support::wrapTag("<button type='button' class='record-delete btn btn-default' data-sip='$s'>", '<span class="glyphicon ' . GLYPH_ICON_DELETE . '"></span>'));
if ($this->showDebugInfo) {
$toolTip .= PHP_EOL . "form = '" . $this->formSpec[F_NAME] . "'" . PHP_EOL . "table = '" . $this->formSpec[F_TABLE_NAME] . "'" . PHP_EOL . "r = '" . $row[$nameColumnId] . "'";
}
// $buttonDelete = $this->buildButtonCode('delete-button', $toolTip, GLYPH_ICON_DELETE, $disabled);
$s = $this->createDeleteUrl($formElement[SUBRECORD_PARAMETER_FORM], $targetTableName, $row[$nameColumnId], RETURN_SIP);
// $rowHtml .= Support::wrapTag('<td>', Support::wrapTag("<button type='button' class='record-delete btn btn-default' data-sip='$s'>", '<span class="glyphicon ' . GLYPH_ICON_DELETE . '"></span>'));
$rowHtml .= Support::wrapTag('<td>', Support::wrapTag("<button type='button' class='record-delete btn btn-default' data-sip='$s' " . Support::doAttribute('title', $toolTip) . ">", '<span class="glyphicon ' . GLYPH_ICON_DELETE . '"></span>'));
} }
Support::setIfNotSet($row, FE_SUBRECORD_ROW_CLASS); Support::setIfNotSet($row, FE_SUBRECORD_ROW_CLASS);
...@@ -1727,14 +1741,23 @@ abstract class AbstractBuildForm { ...@@ -1727,14 +1741,23 @@ abstract class AbstractBuildForm {
/** /**
* Create a link (incl. SIP) to delete the current record. * Create a link (incl. SIP) to delete the current record.
* *
* @param string $formName if there is a form, specify that
* @param string $tableName if there is no form , specify the table from where to delete the record.
* @param int $recordId record to delete
* @param string $mode
* * mode=RETURN_URL: return complete URL
* * mode=RETURN_SIP: returns only the sip
* * mode=RETURN_ARRAY: returns array with url ('_url') and all decoded and created parameters.
* @return string String: "API_DIR/delete.php?sip=...." * @return string String: "API_DIR/delete.php?sip=...."
* @throws CodeException
*/ */
public function createDeleteUrl($table, $recordId, $mode = RETURN_URL) { public function createDeleteUrl($formName, $tableName, $recordId, $mode = RETURN_URL) {
//TODO: Umstellen auf Benutzung der Link Klasse. //TODO: Umstellen auf Benutzung der Link Klasse.
$queryStringArray = [ $queryStringArray = [
SIP_TABLE => $table, SIP_FORM => $formName,
SIP_TABLE => $tableName,
SIP_RECORD_ID => $recordId, SIP_RECORD_ID => $recordId,
SIP_MODE_ANSWER => MODE_JSON SIP_MODE_ANSWER => MODE_JSON
]; ];
...@@ -1743,7 +1766,7 @@ abstract class AbstractBuildForm { ...@@ -1743,7 +1766,7 @@ abstract class AbstractBuildForm {
$sip = $this->store->getSipInstance(); $sip = $this->store->getSipInstance();
return $sip->queryStringToSip($queryString, $mode, API_DIR . '/delete.php'); return $sip->queryStringToSip($queryString, $mode, API_DIR . '/' . API_DELETE_PHP);
} }
/** /**
...@@ -2226,16 +2249,16 @@ abstract class AbstractBuildForm { ...@@ -2226,16 +2249,16 @@ abstract class AbstractBuildForm {
* @param $toolTip * @param $toolTip
* @return string * @return string
*/ */
private function createDeleteLink($table, $recordId, $symbol, $toolTip) { // private function createDeleteLink($table, $recordId, $symbol, $toolTip) {
//
if ($this->showDebugInfo) { // if ($this->showDebugInfo) {
$toolTip .= PHP_EOL . "table = '$table'" . PHP_EOL . "id = '$recordId'"; // $toolTip .= PHP_EOL . "table = '$table'" . PHP_EOL . "id = '$recordId'";
} // }
//
$url = $this->createDeleteUrl($table, $recordId); // $url = $this->createDeleteUrl('', $table, $recordId);
//
return Support::wrapTag('<a ' . Support::doAttribute('href', $url) . ' title="' . $toolTip . '">', $symbol); // return Support::wrapTag('<a ' . Support::doAttribute('href', $url) . ' title="' . $toolTip . '">', $symbol);
//
} // }
} }
\ No newline at end of file
...@@ -72,7 +72,7 @@ class BuildFormBootstrap extends AbstractBuildForm { ...@@ -72,7 +72,7 @@ class BuildFormBootstrap extends AbstractBuildForm {
* @param $note * @param $note
*/ */
public function fillWrapLabelInputNote($label, $input, $note) { public function fillWrapLabelInputNote($label, $input, $note) {
$this->wrap[WRAP_SETUP_LABEL][WRAP_SETUP_START] = "<div class='col-md-$label'>"; $this->wrap[WRAP_SETUP_LABEL][WRAP_SETUP_START] = "<div class='col-md-$label qfq-label'>";
$this->wrap[WRAP_SETUP_LABEL][WRAP_SETUP_END] = "</div>"; $this->wrap[WRAP_SETUP_LABEL][WRAP_SETUP_END] = "</div>";
$this->wrap[WRAP_SETUP_INPUT][WRAP_SETUP_START] = "<div class='col-md-$input'>"; $this->wrap[WRAP_SETUP_INPUT][WRAP_SETUP_START] = "<div class='col-md-$input'>";
$this->wrap[WRAP_SETUP_INPUT][WRAP_SETUP_END] = "</div>"; $this->wrap[WRAP_SETUP_INPUT][WRAP_SETUP_END] = "</div>";
...@@ -113,7 +113,9 @@ class BuildFormBootstrap extends AbstractBuildForm { ...@@ -113,7 +113,9 @@ class BuildFormBootstrap extends AbstractBuildForm {
$html .= $this->getFormTag(); $html .= $this->getFormTag();
$html .= '<div class="tab-content">'; //TODO: Problem fuer Forms ohne Pils
$html .= '<div class="tab-content ' . $this->formSpec[F_CLASS_BODY] . '">';
// $html .= '<div class="col-md-12 ' . $this->formSpec[F_CLASS_BODY] . '">';
return $html; return $html;
} }
...@@ -168,7 +170,7 @@ class BuildFormBootstrap extends AbstractBuildForm { ...@@ -168,7 +170,7 @@ class BuildFormBootstrap extends AbstractBuildForm {
$toolTip = 'Delete'; $toolTip = 'Delete';
if ($this->showDebugInfo && $recordId > 0) { if ($this->showDebugInfo && $recordId > 0) {
$toolTip .= PHP_EOL . "table = '" . $this->formSpec[F_TABLE_NAME] . "'" . PHP_EOL . "r = '" . $recordId . "'"; $toolTip .= PHP_EOL . "form = '" . $this->formSpec[F_NAME] . "'" . PHP_EOL . "table = '" . $this->formSpec[F_TABLE_NAME] . "'" . PHP_EOL . "r = '" . $recordId . "'";
} }
$disabled = ($recordId > 0) ? '' : 'disabled'; $disabled = ($recordId > 0) ? '' : 'disabled';
...@@ -183,10 +185,13 @@ class BuildFormBootstrap extends AbstractBuildForm { ...@@ -183,10 +185,13 @@ class BuildFormBootstrap extends AbstractBuildForm {
$buttonNew = $this->buildButtonAnchor('form-new-button', $url, $toolTip, GLYPH_ICON_NEW); $buttonNew = $this->buildButtonAnchor('form-new-button', $url, $toolTip, GLYPH_ICON_NEW);
} }
$html = Support::wrapTag('<div class="btn-group" role="group">', $buttonEditForm); // Arrangement: Edit Form / Save / Close / Delete / New
$html .= Support::wrapTag('<div class="btn-group" role="group">', $buttonSave . $buttonClose); // Specified in reverse order cause 'pull-right' inverts the order. http://getbootstrap.com/css/#helper-classes-floats
$html .= Support::wrapTag('<div class="btn-group" role="group">', $buttonDelete); $html = '';
$html .= Support::wrapTag('<div class="btn-group" role="group">', $buttonNew); $html .= Support::wrapTag('<div class="btn-group pull-right" role="group">', $buttonNew);
$html .= Support::wrapTag('<div class="btn-group pull-right" role="group">', $buttonDelete);
$html .= Support::wrapTag('<div class="btn-group pull-right" role="group">', $buttonSave . $buttonClose);
$html .= Support::wrapTag('<div class="btn-group pull-right" role="group">', $buttonEditForm);
$html = Support::wrapTag('<div class="btn-toolbar" role="toolbar">', $html); $html = Support::wrapTag('<div class="btn-toolbar" role="toolbar">', $html);
...@@ -267,12 +272,12 @@ class BuildFormBootstrap extends AbstractBuildForm { ...@@ -267,12 +272,12 @@ class BuildFormBootstrap extends AbstractBuildForm {
// Pill Dropdown necessary? // Pill Dropdown necessary?
if ($ii > $maxVisiblePill) { if ($ii > $maxVisiblePill) {
$htmlDropdown = Support::wrapTag('<ul class="dropdown-menu">', $pillDropdown, true); $htmlDropdown = Support::wrapTag('<ul class="dropdown-menu qfq-form-pill ' . $this->formSpec[F_CLASS_PILL] . '">', $pillDropdown, true);
$htmlDropdown = '<a class="dropdown-toggle" data-toggle="dropdown" href="#" role="button">more <span class="caret"></span></a>' . $htmlDropdown; $htmlDropdown = '<a class="dropdown-toggle" data-toggle="dropdown" href="#" role="button">more <span class="caret"></span></a>' . $htmlDropdown;
$htmlDropdown = Support::wrapTag('<li role="presentation" class="dropdown">', $htmlDropdown, false); $htmlDropdown = Support::wrapTag('<li role="presentation" class="dropdown">', $htmlDropdown, false);
} }
$htmlDropdown = Support::wrapTag('<ul id="' . $this->getTabId() . '" class="nav nav-pills" role="tablist">', $pillButton . $htmlDropdown); $htmlDropdown = Support::wrapTag('<ul id="' . $this->getTabId() . '" class="nav nav-pills qfq-form-pill ' . $this->formSpec[F_CLASS_PILL] . '" role="tablist">', $pillButton . $htmlDropdown);
$htmlDropdown = Support::wrapTag('<div class="col-md-12">', $htmlDropdown); $htmlDropdown = Support::wrapTag('<div class="col-md-12">', $htmlDropdown);
return $htmlDropdown; return $htmlDropdown;
...@@ -340,12 +345,15 @@ class BuildFormBootstrap extends AbstractBuildForm { ...@@ -340,12 +345,15 @@ class BuildFormBootstrap extends AbstractBuildForm {
$tabId = $this->getTabId(); $tabId = $this->getTabId();
if (0 < ($recordId = $this->store->getVar(SIP_RECORD_ID, STORE_SIP))) { if (0 < ($recordId = $this->store->getVar(SIP_RECORD_ID, STORE_SIP))) {
$deleteUrl = $this->createDeleteUrl($this->formSpec[F_TABLE_NAME], $recordId); $deleteUrl = $this->createDeleteUrl($this->formSpec[F_NAME], $this->formSpec[F_TABLE_NAME], $recordId);
} }
$actionUpload = FILE_ACTION . '=' . FILE_ACTION_UPLOAD; $actionUpload = FILE_ACTION . '=' . FILE_ACTION_UPLOAD;
$actionDelete = FILE_ACTION . '=' . FILE_ACTION_DELETE; $actionDelete = FILE_ACTION . '=' . FILE_ACTION_DELETE;
$apiDir = API_DIR;
$apiDeletePhp = API_DIR . '/' . API_DELETE_PHP;
$html .= '</form>'; // <form class="form-horizontal" ... $html .= '</form>'; // <form class="form-horizontal" ...
$html .= <<<EOF $html .= <<<EOF
<script type="text/javascript"> <script type="text/javascript">
...@@ -356,14 +364,14 @@ class BuildFormBootstrap extends AbstractBuildForm { ...@@ -356,14 +364,14 @@ class BuildFormBootstrap extends AbstractBuildForm {
var qfqPage = new QfqNS.QfqPage({ var qfqPage = new QfqNS.QfqPage({
tabsId: '$tabId', tabsId: '$tabId',
formId: '$formId', formId: '$formId',
submitTo: 'typo3conf/ext/qfq/qfq/api/save.php', submitTo: '$apiDir/save.php',
deleteUrl: '$deleteUrl', deleteUrl: '$deleteUrl',
refreshUrl: "typo3conf/ext/qfq/qfq/api/load.php", refreshUrl: '$apiDir/load.php',
fileUploadTo: 'typo3conf/ext/qfq/qfq/api/file.php?$actionUpload', fileUploadTo: '$apiDir/file.php?$actionUpload',
fileDeleteUrl: 'typo3conf/ext/qfq/qfq/api/file.php?$actionDelete'