Commit 04bdb19b authored by Elias Villiger's avatar Elias Villiger
Browse files

Feature #6249 - DragAndDrop for subrecords is working

parent aadd22b6
......@@ -2410,6 +2410,31 @@ abstract class AbstractBuildForm {
$linkNew = $flagNew ? Support::wrapTag('<th>', $this->createFormLink($formElement, 0, $primaryRecord, $this->symbol[SYMBOL_NEW], 'New')) : '<th></th>';
}
// Determine if DragAndDrop is active
$hasDragAndDrop = false;
$orderColumn = $formElement[FE_ORDER_COLUMN] ?? DND_COLUMN_ORD;
$dndTable = '';
if (isset($formElement[FE_DND_TABLE])) {
// Table is specified in parameter field
$dndTable = $formElement[FE_DND_TABLE];
} else {
// Read table from form specified in subrecord
$formName = $formElement[SUBRECORD_PARAMETER_FORM];
$form = $this->dbArray[$this->dbIndexQfq]->sql("SELECT * FROM Form AS f WHERE f." . F_NAME . " LIKE ? AND f.deleted='no'",
ROW_REGULAR, [$formName]);
if (count($form) > 0) { $dndTable = $form[0][F_TABLE_NAME]; }
}
if ($dndTable) {
$columns = $this->dbArray[$this->dbIndexQfq]->sql("SHOW COLUMNS FROM $dndTable");
foreach ($columns as $column) {
if ($column['Field'] === $orderColumn) {
// DragAndDrop is active if the dndTable has the orderColumn
$hasDragAndDrop = true;
break;
}
}
}
$firstRow = isset($formElement[FE_SQL1][0]) ? $formElement[FE_SQL1][0] : array();
$htmlHead = $this->subrecordHead($linkNew, $flagDelete, $firstRow, $control);
$htmlBody = '';
......@@ -2456,19 +2481,37 @@ abstract class AbstractBuildForm {
}
$rowAttribute = Support::doAttribute('class', $rowClass);
$rowAttribute .= Support::doAttribute('title', $rowTooltip);
$rowAttribute .= Support::doAttribute('id', 'any-tag-'.$row[$nameColumnId]);
if ($hasDragAndDrop) {
$rowAttribute .= Support::doAttribute('id', $formElement[FE_HTML_ID] . '-' . $row[$nameColumnId]);
$rowAttribute .= Support::doAttribute('data-dnd-id', $row[$nameColumnId]);
}
$htmlBody .= Support::wrapTag("<tr $rowAttribute>", $rowHtml, true);
}
// TODO EV: Replace with generic, only if DND is ON
$subrecordId = $formElement[FE_ID];
$apiAttribute = $this->evaluate->parse( "{{ '".DND_SUBRECORD_ID."=$subrecordId' AS _data-dnd-api }}");
// Handle DragAndDrop
$dndAttributes = '';
if ($hasDragAndDrop) {
$orderInterval = 10;
$numColumns = 0;
if (count($formElement[FE_SQL1]) > 0) {
$numColumns = count($formElement[FE_SQL1][0]) + (int)$flagDelete + (int)($flagNew || $flagEdit);
}
$dataDndApi = DND_SUBRECORD_ID . '=' . $formElement[FE_ID];
$dataDndApi .= '&' . DND_SUBRECORD_FORM_ID . '=' . $this->store->getVar('id', STORE_RECORD);
$dataDndApi .= '&' . FE_ORDER_INTERVAL . '=' . $orderInterval;
$dataDndApi .= '&' . FE_ORDER_COLUMN . '=' . $orderColumn;
$dataDndApi .= '&' . FE_DND_TABLE . '=' . $dndTable;
$dndAttributes = Support::doAttribute('class', 'qfq-dnd-sort');
$dndAttributes .= $this->evaluate->parse( "{{ '$dataDndApi' AS _data-dnd-api }}").' ';
$dndAttributes .= Support::doAttribute('data-columns', $numColumns);
}
$attribute = Support::doAttribute('class', $formElement[FE_SUBRECORD_TABLE_CLASS]);
return Support::wrapTag("<table $attribute>",
$htmlHead . Support::wrapTag("<tbody class=\"qfq-dnd-sort\" $apiAttribute data-columns=\"5\">", $htmlBody), true);
$htmlHead . Support::wrapTag("<tbody $dndAttributes>", $htmlBody), true);
}
/**
......
......@@ -55,6 +55,7 @@ const RETURN_URL = 'return_url';
const RETURN_SIP = 'return_sip';
const RETURN_ARRAY = 'return_array';
const SQL_FORM_ELEMENT_BY_ID = "SELECT * FROM FormElement AS fe WHERE fe.id = ?";
const SQL_FORM_ELEMENT_RAW = "SELECT * FROM FormElement AS fe WHERE fe.formId = ? AND fe.deleted = 'no' AND fe.enabled='yes' ORDER BY fe.ord, fe.id";
const SQL_FORM_ELEMENT_SPECIFIC_CONTAINER = "SELECT *, ? AS 'nestedInFieldSet' FROM FormElement AS fe WHERE fe.formId = ? AND fe.deleted = 'no' AND FIND_IN_SET(fe.class, ? ) AND fe.feIdContainer = ? AND fe.enabled='yes' ORDER BY fe.ord, fe.id";
const SQL_FORM_ELEMENT_ALL_CONTAINER = "SELECT *, ? AS 'nestedInFieldSet' FROM FormElement AS fe WHERE fe.formId = ? AND fe.deleted = 'no' AND FIND_IN_SET(fe.class, ? ) AND fe.enabled='yes' ORDER BY fe.ord, fe.id";
......@@ -1094,6 +1095,10 @@ const FE_TYPE_PILL = 'pill';
const FE_HTML_ID = 'htmlId'; // Will be dynamically computed during runtime.
const FE_ORDER_INTERVAL = 'orderInterval';
const FE_ORDER_COLUMN = 'orderColumn';
const FE_DND_TABLE = 'dndTable';
const MODE_ENCODE = 'encode';
const MODE_DECODE = 'decode';
const MODE_NONE = 'none';
......@@ -1544,5 +1549,6 @@ const DND_COLUMN_ID = 'id';
const DND_COLUMN_ORD = 'ord';
const DND_COLUMN_ORD_NEW = 'ordNew';
const DND_DATA_DND_API = 'data-dnd-api';
const DND_SUBRECORD_ID = 'dnd-subrecord-id'; // Internal qualifier used to communicate with dnd api
const DND_SUBRECORD_ID = 'dnd-subrecord-id'; // Internal qualifier used to communicate with dnd api for subrecord dnd
const DND_SUBRECORD_FORM_ID = 'dnd-subrecord-form-id';
......@@ -1383,19 +1383,32 @@ class QuickFormQuery {
$fillStoreForm->process(FORM_DRAG_AND_DROP);
$json = "";
$dndSubrecordId = $this->store->getVar(DND_SUBRECORD_ID, STORE_SIP . STORE_TYPO3 . STORE_CLIENT . STORE_ZERO);
if ($dndSubrecordId > 0) { // Subrecord dragndrop
// TODO EV: Fill in formSpec based on dndSubrecordId
$dndSubrecordId = $this->store->getVar(DND_SUBRECORD_ID, STORE_SIP . STORE_CLIENT . STORE_ZERO);
if ($dndSubrecordId > 0) {
// Subrecord DragAndDrop
$subrecord = $this->dbArray[$this->dbIndexQfq]->sql(SQL_FORM_ELEMENT_BY_ID, ROW_REGULAR, [$dndSubrecordId]);
$recordId = $this->store->getVar(DND_SUBRECORD_FORM_ID, STORE_SIP . STORE_ZERO);
$this->fillStoreWithRecord('Form', $recordId);
$dndOrderSql = $this->eval->parse($subrecord[0][FE_SQL1]);
foreach ($dndOrderSql as $i => $row) {
foreach ($row as $key => $value) {
if (substr($key, 0, 1) === '_') {
$dndOrderSql[$i][substr($key, 1)] = $value;
}
}
}
$dummyFormSpec= [
F_ORDER_INTERVAL => "1",
F_ORDER_COLUMN => "xId",
F_DRAG_AND_DROP_ORDER_SQL => $this->eval->parse("{{!SELECT gm.id AS id, gm.xId AS ord FROM gGroupMember AS gm WHERE gm.grId=8 ORDER BY gm.xId}}"),
F_TABLE_NAME => "gGroupMember"
F_ORDER_INTERVAL => $this->store->getVar(FE_ORDER_INTERVAL, STORE_SIP . STORE_ZERO),
F_ORDER_COLUMN => $this->store->getVar(FE_ORDER_COLUMN, STORE_SIP . STORE_ZERO),
F_DRAG_AND_DROP_ORDER_SQL => $dndOrderSql,
F_TABLE_NAME => $this->store->getVar(FE_DND_TABLE, STORE_SIP . STORE_ZERO)
];
$dragAndDrop = new DragAndDrop($dummyFormSpec);
$dragAndDrop->process();
} else { // User-defined dragndrop
} else {
// User-defined DragAndDrop
$json = $this->doForm(FORM_DRAG_AND_DROP);
}
......
......@@ -182,7 +182,7 @@ class Database {
$result = array();
$this->closeMysqliStmt();
// CR often forgets to specify the $mode and use prepared statement with parameter instead.
// CR (& EV) often forgets to specify the $mode and use prepared statement with parameter instead.
if (is_array($mode)) {
throw new CodeException("Probably a parameter forgotten: \$mode ?");
}
......
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