first commit

This commit is contained in:
salam committed 2026-10-19 08:18:39 +02:00
commit 1218dd1517
12716 files changed
+989233

No files matched your search

@@ -0,0 +1,37 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<f:be.pageRenderer includeCssFiles="{stylesheets}" addInlineSettings="{addInlineSettings}" includeJsFiles="{0: 'EXT:backend/Resources/Public/JavaScript/jsfunc.tbe_editor.js'}" />
<div data-identifier="moduleLoadingIndicator" class="form-editor-loading-spinner">
<core:icon identifier="spinner-circle-dark" size="default" />
<div class="form-editor-loading-spinner-label"><f:translate key="LLL:EXT:form/Resources/Private/Language/Database.xlf:formEditor.loading" /></div>
</div>
<div data-identifier="moduleWrapper" class="hidden">
<f:format.raw>{formEditorTemplates}</f:format.raw>
<section id="t3-form-navigation-component" class="t3-form-x-component" data-identifier="structureSection">
<div id="t3-form-structure-panel">
<f:render section="ElementSidebarTree" />
</div>
</section>
<section id="t3-form-stage-container" data-identifier="stageContainer">
<div id="t3-form-stage-inner-container" data-identifier="stageContainerInner">
<header id="t3-form-stage-header">
<f:render section="Header" />
</header>
<div id="t3-form-stage-content">
<f:render section="Stage" />
</div>
</div>
</section>
<section id="t3-form-inspector-panels-container" class="t3-form-x-component" data-identifier="inspectorSection">
<f:render section="Inspector" />
</section>
</div>
<script type="text/javascript">
require(['{dynamicRequireJsModules.app}', '{dynamicRequireJsModules.mediator}', '{dynamicRequireJsModules.viewModel}'], function (formEditorApp, mediator, viewModel) {
window.TYPO3.FORMEDITOR_APP = formEditorApp.getInstance(
<f:format.htmlentitiesDecode>{formEditorAppInitialData}</f:format.htmlentitiesDecode>,
mediator,
viewModel
).run();
});
</script>
</html>
@@ -0,0 +1,5 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<f:be.pageRenderer includeCssFiles="{stylesheets}" />
<f:flashMessages />
<f:render section="MainContent" />
</html>
@@ -0,0 +1,12 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<div class="form-editor">
<div class="t3-form-control-group form-group">
<label data-random-id data-random-id-attribute="for" data-random-id-number="1">
<span data-template-property="label"></span>
<div class="t3-form-controls" data-identifier="inspectorEditorControlsWrapper">
<input data-random-id data-random-id-attribute="id" data-random-id-number="1" type="checkbox" />
</div>
</label>
</div>
</div>
</html>
@@ -0,0 +1,7 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<div class="t3-form-validator-editor">
<h4 data-template-property="header-label">
<span data-template-property="label"></span>
</h4>
</div>
</html>
@@ -0,0 +1,14 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<div class="form-editor">
<div class="t3-form-control-group form-group">
<label data-random-id data-random-id-attribute="for" data-random-id-number="1">
<span data-template-property="label"></span>
</label>
<div id="t3-form-add-finisher" class="t3-form-add-collection-element">
<select data-random-id data-random-id-attribute="id" data-random-id-number="1" data-template-property="selectOptions" class="form-control"></select>
</div>
</div>
</div>
<div id="t3-form-inspector-finishers" class="t3-form-collection-container" data-identifier="inspectorFinishers">
</div>
</html>
@@ -0,0 +1,5 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<div class="form-editor">
<h2 class="t3-form-inspector-formelement-header-editor" data-template-property="header-label" data-identifier="inspectorFormElementHeaderEditor"></h2>
</div>
</html>
@@ -0,0 +1,17 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<div class="form-editor">
<div class="t3-form-control-group form-group" data-identifier="editorWrapper">
<label data-random-id data-random-id-attribute="for" data-random-id-number="1"><span data-template-property="label"></span></label><br>
<div class="t3-form-controls btn-group" data-identifier="inspectorEditorControlsWrapper">
<button type="button" class="btn btn-default" data-identifier="viewportButton"></button>
</div>
</div>
<div class="t3-form-control-group form-group" data-template-property="numbersOfColumnsToUse">
<label data-random-id data-random-id-attribute="for" data-random-id-number="1"><span data-template-property="numbersOfColumnsToUse-label"></span></label>
<div class="t3-form-controls" data-identifier="numbersOfColumnsToUse-inspectorEditorControlsWrapper">
<input data-random-id data-random-id-attribute="id" data-random-id-number="1" type="number" value="" data-template-property="numbersOfColumnsToUse-propertyPath" class="form-control">
</div>
<span data-template-property="numbersOfColumnsToUse-fieldExplanationText"></span>
</div>
</div>
</html>
@@ -0,0 +1,8 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<div class="t3-form-control-group form-group">
<label data-random-id data-random-id-attribute="for" data-random-id-number="1"><span data-template-property="label"></span></label>
<div class="t3-form-controls" data-identifier="inspectorEditorControlsWrapper">
<select data-random-id data-random-id-attribute="id" data-random-id-number="1" data-template-property="selectOptions" class="form-control" multiple="multiple"></select>
</div>
</div>
</html>
@@ -0,0 +1,45 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<div class="form-editor">
<div class="t3-form-control-group form-group property-grid">
<label data-random-id data-random-id-attribute="for" data-random-id-number="1"><span data-template-property="label"></span></label>
<div data-editor="new-property-grid" data-template-property="newPropertyPath">
<table class="table table-hover" data-identifier="propertyGridContainer">
<thead>
<tr>
<th></th>
<th>Label</th>
<th>Value</th>
<th>Selected</th>
<th></th>
</tr>
</thead>
<tbody>
<tr data-identifier="rowItem">
<td><span class="sort-row-field" data-identifier="sortRow"><core:icon identifier="actions-move-move" /></span></td>
<td><input type="text" class="form-control" value="" data-identifier="label" /></td>
<td><input type="text" class="form-control" value="" data-identifier="value" /></td>
<td><input type="checkbox" data-identifier="selectValue" /></td>
<td>
<div class="btn-group btn-group-sm" role="group">
<button class="btn btn-default" title="Remove this row" data-identifier="deleteRow"><core:icon identifier="actions-delete" /></button>
</div>
</td>
</tr>
<tr data-identifier="addRowItem">
<td>
<div class="btn-group btn-group-sm" role="group">
<button data-random-id data-random-id-attribute="id" data-random-id-number="1" class="btn btn-default" title="Add a new row" data-identifier="addRow"><core:icon identifier="actions-add" /></button>
</div>
</td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
</div>
<div data-editor="property-grid" data-template-property="propertyPath" class="t3-form-grid"></div>
</div>
</div>
</html>
@@ -0,0 +1,5 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<div class="t3-form-control-group form-group btn-group-sm">
<button class="btn btn-default" title="Remove this Element"><core:icon identifier="actions-delete" alternativeMarkupIdentifier="inline" /></button>
</div>
</html>
@@ -0,0 +1,19 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<div class="form-editor">
<div class="t3-form-control-group form-group" data-identifier="editorWrapper">
<label data-random-id data-random-id-attribute="for" data-random-id-number="1">
<span data-template-property="label"></span>
<div class="t3-form-controls" data-identifier="inspectorEditorControlsWrapper">
<input data-random-id data-random-id-attribute="id" data-random-id-number="1" type="checkbox" />
</div>
</label>
</div>
<div class="t3-form-control-group form-group" data-template-property="validationErrorMessage">
<label data-random-id data-random-id-attribute="for" data-random-id-number="2"><span data-template-property="validationErrorMessage-label"></span></label>
<div class="t3-form-controls" data-identifier="inspectorEditorControlsWrapper">
<input data-random-id data-random-id-attribute="id" data-random-id-number="2" type="text" value="" data-template-property="validationErrorMessage-propertyPath" class="form-control">
</div>
<span data-template-property="validationErrorMessage-fieldExplanationText" class="inspector-editor-hint"></span>
</div>
</div>
</html>
@@ -0,0 +1,8 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<div class="t3-form-control-group form-group">
<label data-random-id data-random-id-attribute="for" data-random-id-number="1"><span data-template-property="label"></span></label>
<div class="t3-form-controls" data-identifier="inspectorEditorControlsWrapper">
<select data-random-id data-random-id-attribute="id" data-random-id-number="1" data-template-property="selectOptions" class="form-control"></select>
</div>
</div>
</html>
@@ -0,0 +1,24 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<div class="form-editor">
<div class="t3-form-control-group form-group">
<label data-random-id data-random-id-attribute="for" data-random-id-number="1"><span data-template-property="label"></span></label>
<div class="input-group" data-identifier="inspectorEditorControlsGroup">
<div class="t3-form-controls" data-identifier="inspectorEditorControlsWrapper">
<input data-random-id data-random-id-attribute="id" data-random-id-number="1" type="text" value="" data-template-property="propertyPath" class="form-control">
</div>
<span class="input-group-btn" role="group" data-identifier="inspectorEditorFormElementSelectorControlsWrapper">
<span class="btn-group t3-form-dropdown-buttons" data-identifier="inspectorEditorFormElementSelectorSplitButtonContainer">
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-expanded="false" title="{f:translate(key: 'LLL:EXT:form/Resources/Private/Language/Database.xlf:formEditor.inspector.editor.formelement_selector.title')}">
<core:icon identifier="actions-variable-select" />
<span class="caret"></span>
<span class="sr-only">Toggle Dropdown</span>
</button>
<ul class="dropdown-menu dropdown-menu-right" data-identifier="inspectorEditorFormElementSelectorSplitButtonListContainer"></ul>
</span>
</span>
</div>
<span class="inspector-editor-hint" data-template-property="fieldExplanationText"></span>
<span data-template-property="validationErrors"></span>
</div>
</div>
</html>
@@ -0,0 +1,11 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<div class="form-editor">
<div class="t3-form-control-group form-group">
<label data-random-id data-random-id-attribute="for" data-random-id-number="1"><span data-template-property="label"></span></label>
<div class="t3-form-controls" data-identifier="inspectorEditorControlsWrapper">
<textarea data-random-id data-random-id-attribute="id" data-random-id-number="1" data-template-property="propertyPath" class="form-control"></textarea>
</div>
<span class="inspector-editor-hint" data-template-property="fieldExplanationText"></span>
</div>
</div>
</html>
@@ -0,0 +1,19 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<div class="form-editor">
<div class="t3-form-control-group form-group">
<label data-random-id data-random-id-attribute="for" data-random-id-number="1"><span data-template-property="label"></span></label>
<div class="t3-form-controls" data-identifier="inspectorEditorControlsWrapper">
<input data-random-id data-random-id-attribute="id" data-random-id-number="1" type="text" value="" data-template-property="propertyPath" class="form-control" data-insert-target="">
<div class="help-block">
<a href="#" data-template-property="onclick" class="btn btn-default">
<span class="t3js-icon icon icon-size-small icon-state-default icon-mimetypes-x-content-text" data-identifier="mimetypes-x-content-text">
<span class="icon-markup" data-template-property="image"></span>
</span> <span data-template-property="buttonLabel"></span>
</a>
</div>
<span class="inspector-editor-hint" data-template-property="fieldExplanationText"></span>
<span data-template-property="validationErrors"></span>
</div>
</div>
</div>
</html>
@@ -0,0 +1,13 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<div class="form-editor">
<div class="t3-form-control-group form-group">
<label data-random-id data-random-id-attribute="for" data-random-id-number="1"><span data-template-property="label"></span></label>
<div data-identifier="inspectorEditorControlsGroup">
<div class="t3-form-controls" data-identifier="inspectorEditorControlsWrapper">
<input data-random-id data-random-id-attribute="id" data-random-id-number="1" type="text" value="" data-template-property="propertyPath" class="form-control">
</div>
</div>
<span class="inspector-editor-hint" data-template-property="fieldExplanationText"></span>
</div>
</div>
</html>
@@ -0,0 +1,14 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<div class="form-editor">
<div class="t3-form-control-group form-group">
<label data-random-id data-random-id-attribute="for" data-random-id-number="1">
<span data-template-property="label"></span>
</label>
<div id="t3-form-add-validator" class="t3-form-add-collection-element" data-template-property="selectOptionsContainer">
<select data-random-id data-random-id-attribute="id" data-random-id-number="1" data-template-property="selectOptions" class="form-control"></select>
</div>
</div>
</div>
<div id="t3-form-inspector-validators" class="t3-form-collection-container" data-identifier="inspectorValidators">
</div>
</html>
@@ -0,0 +1,28 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<div id="t3-form-insert-elements-panel">
<div class="t3-form-x-component-inner-wrapper">
<f:for each="{insertRenderablesPanelConfiguration}" as="insertRenderablePanelConfiguration">
<f:if condition="{insertRenderablePanelConfiguration.key} != 'page'">
<div class="row media">
<div class="col-sm-12">
<h4 class="t3-form-group-{insertRenderablePanelConfiguration.key}">
<span>{insertRenderablePanelConfiguration.label}</span>
</h4>
</div>
<f:for each="{insertRenderablePanelConfiguration.elements}" as="element">
<div class="col-sm-4 form-group">
<a class="t3-form-group-{insertRenderablePanelConfiguration.key} t3-form-type-{element.cssKey} btn btn-default btn-block" title="{element.key}" data-element-type="{element.key}">
<span class="pull-left">
<core:icon identifier="{element.iconIdentifier}" alternativeMarkupIdentifier="inline" />
<span>{element.label}</span>
</span>
<span class="clearfix"></span>
</a>
</div>
</f:for>
</div>
</f:if>
</f:for>
</div>
</div>
</html>
@@ -0,0 +1,29 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<div id="t3-form-insert-pages-panel">
<div class="t3-form-x-component-inner-wrapper">
<f:for each="{insertRenderablesPanelConfiguration}" as="insertRenderablePanelConfiguration">
<f:if condition="{insertRenderablePanelConfiguration.key} == 'page'">
<div class="row">
<div class="col-sm-12">
<h3 class="t3-form-group-{insertRenderablePanelConfiguration.key}">
<span>{insertRenderablePanelConfiguration.label}</span>
</h3>
</div>
<f:for each="{insertRenderablePanelConfiguration.elements}" as="element">
<div class="col-sm-4 btn-group">
<a class="t3-form-group-{insertRenderablePanelConfiguration.key} t3-form-type-{element.cssKey} btn btn-default btn-block" title="{element.key}" data-element-type="{element.key}">
<span class="pull-left">
<core:icon identifier="{element.iconIdentifier}" alternativeMarkupIdentifier="inline" />
<span>{element.label}</span>
</span>
<span class="clearfix"></span>
</a>
<hr>
</div>
</f:for>
</div>
</f:if>
</f:for>
</div>
</div>
</html>
@@ -0,0 +1,18 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<div id="t3-form-validation-errors-panel">
<div class="t3-form-x-component-inner-wrapper">
<div class="row">
<div class="col-sm-12">
<p><f:translate key="LLL:EXT:form/Resources/Private/Language/Database.xlf:formEditor.modals.validationErrors.dialogMessage" /></p>
</div>
<div class="col-sm-12">
<dl class="t3-overview-list" data-identifier="rowsContainer">
<dt data-identifier="rowItem">
<i class="fa fa-exclamation-triangle text-danger" aria-hidden="true"></i>&nbsp;<a data-identifier="rowLink"></a>
</dt>
</dl>
</div>
</div>
</div>
</div>
</html>
@@ -0,0 +1,29 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<div class="meta-label">
<span data-template-property="_type"></span>: <span data-template-property="_identifier"></span>
</div>
<div class="t3-form-form-element-body">
<div class="t3-form-icon-container">
<span data-identifier="elementIcon"></span>
</div>
<div class="t3-form-element-info">
<div class="element-label-container">
<div class="element-label">
<span data-template-property="label"></span>
<span data-template-property="_required"></span>
</div>
</div>
<div class="element-content">
<div data-template-property="properties.contentElementUid"></div>
</div>
</div>
<div class="t3-form-validator-info" data-identifier="validators">
<span data-identifier="validatorIcon"></span>
<div class="t3-form-validator-list">
<div data-identifier="validatorsContainer">
<div class="validator-label" data-template-property="_label"></div>
</div>
</div>
</div>
</div>
</html>
@@ -0,0 +1,18 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<div class="meta-label">
<span data-template-property="_type"></span>: <span data-template-property="_identifier"></span>
</div>
<div class="t3-form-form-element-body">
<div class="t3-form-icon-container">
<span data-identifier="elementIcon"></span>
</div>
<div class="t3-form-element-info">
<div class="element-label-container">
<div class="element-label">
<span data-template-property="label"></span>
<span data-template-property="_required"></span>
</div>
</div>
</div>
</div>
</html>
@@ -0,0 +1,32 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<div class="meta-label">
<span data-template-property="_type"></span>: <span data-template-property="_identifier"></span>
</div>
<div class="t3-form-form-element-body">
<div class="t3-form-icon-container">
<span data-identifier="elementIcon"></span>
</div>
<div class="t3-form-element-info">
<div class="element-label-container">
<div class="element-label">
<span data-template-property="label"></span>
<span data-template-property="_required"></span>
</div>
</div>
<div class="element-content">
<div data-template-property="properties.saveToFileMount"></div>
<div data-identifier="multiValueContainer" data-template-property="properties.allowedMimeTypes">
<div data-template-property="_value"></div>
</div>
</div>
</div>
<div class="t3-form-validator-info" data-identifier="validators">
<span data-identifier="validatorIcon"></span>
<div class="t3-form-validator-list">
<div data-identifier="validatorsContainer">
<div class="validator-label" data-template-property="_label"></div>
</div>
</div>
</div>
</div>
</html>
@@ -0,0 +1,3 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<h2 class="t3-form-page-title" data-template-property="label"></h2>
</html>
@@ -0,0 +1,31 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<div class="meta-label">
<span data-template-property="_type"></span>: <span data-template-property="_identifier"></span>
</div>
<div class="t3-form-form-element-body">
<div class="t3-form-icon-container">
<span data-identifier="elementIcon"></span>
</div>
<div class="t3-form-element-info">
<div class="element-label-container">
<div class="element-label">
<span data-template-property="label"></span>
<span data-template-property="_required"></span>
</div>
</div>
<div class="element-content">
<div data-identifier="multiValueContainer" data-template-property="properties.options">
<div data-template-property="_label"></div>
</div>
</div>
</div>
<div class="t3-form-validator-info" data-identifier="validators">
<span data-identifier="validatorIcon"></span>
<div class="t3-form-validator-list">
<div data-identifier="validatorsContainer">
<div class="validator-label" data-template-property="_label"></div>
</div>
</div>
</div>
</div>
</html>
@@ -0,0 +1,26 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<div class="meta-label">
<span data-template-property="_type"></span>: <span data-template-property="_identifier"></span>
</div>
<div class="t3-form-form-element-body">
<div class="t3-form-icon-container">
<span data-identifier="elementIcon"></span>
</div>
<div class="t3-form-element-info">
<div class="element-label-container">
<div class="element-label">
<span data-template-property="label"></span>
<span data-template-property="_required"></span>
</div>
</div>
</div>
<div class="t3-form-validator-info" data-identifier="validators">
<span data-identifier="validatorIcon"></span>
<div class="t3-form-validator-list">
<div data-identifier="validatorsContainer">
<div class="validator-label" data-template-property="_label"></div>
</div>
</div>
</div>
</div>
</html>
@@ -0,0 +1,29 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<div class="meta-label">
<span data-template-property="_type"></span>: <span data-template-property="_identifier"></span>
</div>
<div class="t3-form-form-element-body">
<div class="t3-form-icon-container">
<span data-identifier="elementIcon"></span>
</div>
<div class="t3-form-element-info">
<div class="element-label-container">
<div class="element-label">
<span data-template-property="label"></span>
<span data-template-property="_required"></span>
</div>
</div>
<div class="element-content">
<div data-template-property="properties.text"></div>
</div>
</div>
<div class="t3-form-validator-info" data-identifier="validators">
<span data-identifier="validatorIcon"></span>
<div class="t3-form-validator-list">
<div data-identifier="validatorsContainer">
<div class="validator-label" data-template-property="_label"></div>
</div>
</div>
</div>
</div>
</html>
@@ -0,0 +1,3 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<h2 data-template-property="label"></h2>
</html>
@@ -0,0 +1,35 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<div class="btn-toolbar-container" data-identifier="elementToolbar">
<div class="btn-toolbar" data-identifier="elementToolbarButtons">
<div class="btn-group btn-group-sm" role="group">
<a class="btn btn-default" href="#" title="{f:translate(key: 'LLL:EXT:form/Resources/Private/Language/Database.xlf:formEditor.stage.toolbar.new_element')}" data-identifier="stageElementToolbarNewElement"><core:icon identifier="actions-document-new" alternativeMarkupIdentifier="inline" /></a>
</div>
<div class="btn-group btn-group-sm" role="group">
<div class="btn-group t3-form-dropdown-buttons" data-identifier="stageElementToolbarNewElementSplitButton">
<button type="button" class="btn btn-sm btn-default dropdown-toggle" data-toggle="dropdown" aria-expanded="false" title="{f:translate(key: 'LLL:EXT:form/Resources/Private/Language/Database.xlf:formEditor.stage.toolbar.new_element')}">
<core:icon identifier="actions-document-new" alternativeMarkupIdentifier="inline" />
<span class="caret"></span>
<span class="sr-only">Toggle Dropdown</span>
</button>
<ul class="dropdown-menu dropdown-menu-right">
<li data-no-sorting>
<a href="#" data-identifier="stageElementToolbarNewElementSplitButtonInside">
<core:icon identifier="actions-form-insert-in" alternativeMarkupIdentifier="inline" />
<f:translate key="LLL:EXT:form/Resources/Private/Language/Database.xlf:formEditor.stage.toolbar.new_element.inside" />
</a>
</li>
<li data-no-sorting>
<a href="#" data-identifier="stageElementToolbarNewElementSplitButtonAfter">
<core:icon identifier="actions-form-insert-after" alternativeMarkupIdentifier="inline" />
<f:translate key="LLL:EXT:form/Resources/Private/Language/Database.xlf:formEditor.stage.toolbar.new_element.after" />
</a>
</li>
</ul>
</div>
</div>
<div class="btn-group btn-group-sm" role="group">
<a class="btn btn-default" href="#" title="{f:translate(key: 'LLL:EXT:form/Resources/Private/Language/Database.xlf:formEditor.stage.toolbar.remove')}" data-identifier="stageElementToolbarRemoveElement"><core:icon identifier="actions-edit-delete" alternativeMarkupIdentifier="inline" /></a>
</div>
</div>
</div>
</html>
@@ -0,0 +1,3 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<span><f:translate key="LLL:EXT:form/Resources/Private/Language/Database.xlf:formEditor.elements.UnknownElement" /></span>
</html>
@@ -0,0 +1,68 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<f:layout name="FormEditor" />
<f:section name="ElementSidebarTree">
<div class="t3-form-x-component-inner-wrapper">
<div id="t3-form-navigation-component-tree-root-container" data-identifier="treeRootContainer">
<core:icon identifier="content-form" />
<span id="t3-form-navigation-component-tree-root" data-identifier="treeRootElement"></span>
</div>
<div class="tree" data-identifier="structure-element"></div>
<div class="form-group col-sm-12">
<div class="btn-group btn-group-sm" role="group">
<a class="btn btn-default t3-form-element-new-page-button" href="#" title="{f:translate(key: 'LLL:EXT:form/Resources/Private/Language/Database.xlf:formEditor.new_page_button')}" data-identifier="treeNewPageBottom"><core:icon identifier="actions-page-new" /> {f:translate(key: 'LLL:EXT:form/Resources/Private/Language/Database.xlf:formEditor.new_page_button')}</a>
</div>
</div>
</div>
</f:section>
<f:section name="Header">
<h1><span id="t3-form-form-definition-label" data-identifier="formDefinitionLabel"></span></h1>
</f:section>
<f:section name="Stage">
<div class="panel panel-default" data-identifier="stagePanel">
<div class="panel-heading" data-identifier="panelHeading">
<span data-identifier="stageHeaderToolbar">
<div class="btn-group">
<button class="btn btn-default" title="" data-identifier="buttonViewModePreview"><core:icon identifier="actions-document-view" alternativeMarkupIdentifier="inline" /></button>
<button class="btn btn-default" title="" data-identifier="buttonViewModeAbstract"><core:icon identifier="actions-document-open" alternativeMarkupIdentifier="inline" /></button>
</div>
<div class="pull-right">
<span class="paginiation-label" data-identifier="paginationTitle"></span>
<div class="btn-group">
<button class="btn btn-default" title="" data-identifier="buttonPaginationPrevious"><core:icon identifier="actions-view-paging-previous" alternativeMarkupIdentifier="inline" /></button>
<button class="btn btn-default" title="" data-identifier="buttonPaginationNext"><core:icon identifier="actions-view-paging-next" alternativeMarkupIdentifier="inline" /></button>
</div>
</div>
</span>
</div>
<div class="form-section" data-identifier="stageSection">
<div class="row">
<div id="t3-form-stage" class="form-group col-sm-12" data-identifier="stageArea"></div>
</div>
<div class="row" data-identifier="stageNewElementRow">
<div class="form-group col-sm-12">
<div class="t3-form-new-element-container">
<div class="btn-group btn-group-sm" role="group">
<a class="btn btn-default" href="#" title="{f:translate(key: 'LLL:EXT:form/Resources/Private/Language/Database.xlf:formEditor.stage.toolbar.new_element')}" data-identifier="stageNewElementBottom"><core:icon identifier="actions-document-new" /> {f:translate(key: 'LLL:EXT:form/Resources/Private/Language/Database.xlf:formEditor.stage.toolbar.new_element')}</a>
</div>
</div>
</div>
</div>
</div>
</div>
</f:section>
<f:section name="Inspector">
<div id="t3-form-inspector-panels">
<div class="t3-form-x-component-inner-wrapper">
<div id="t3-form-inspector" data-identifier="inspector"></div>
</div>
</div>
</f:section>
</html>
@@ -0,0 +1,7 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<f:for each="{formEditorPartials}" key="formEditorTemplateName" as="formEditorPartial">
<script type="text/x-formeditor-template" data-template-name="{formEditorTemplateName}">
<f:render partial="{formEditorPartial}" arguments="{insertRenderablesPanelConfiguration: insertRenderablesPanelConfiguration}" />
</script>
</f:for>
</html>
@@ -0,0 +1,8 @@
type: 'Form'
identifier: 'blankForm'
label: '[Blank Form]'
renderables:
-
type: 'Page'
identifier: 'page-1'
label: 'Step'
@@ -0,0 +1,79 @@
identifier: ext-form-simple-contact-form-example
label: 'Simple Contact Form'
type: Form
finishers:
-
identifier: EmailToReceiver
options:
subject: 'Your message: {subject}'
recipientAddress: 'your.company@example.com'
recipientName: 'Your Company name'
senderAddress: '{email}'
senderName: '{name}'
replyToAddress: ''
carbonCopyAddress: ''
blindCarbonCopyAddress: ''
format: 'html'
attachUploads: 'true'
translation:
language: ''
renderables:
-
identifier: page-1
label: 'Contact Form'
type: Page
renderables:
-
identifier: name
label: 'Name'
type: Text
properties:
fluidAdditionalAttributes:
placeholder: 'Name'
defaultValue: ''
validators:
-
identifier: NotEmpty
-
identifier: subject
label: 'Subject'
type: Text
properties:
fluidAdditionalAttributes:
placeholder: 'Subject'
defaultValue: ''
validators:
-
identifier: NotEmpty
-
identifier: email
label: 'Email'
type: Text
properties:
fluidAdditionalAttributes:
placeholder: 'Email address'
defaultValue: ''
validators:
-
identifier: NotEmpty
-
identifier: EmailAddress
-
identifier: message
label: 'Message'
type: Textarea
properties:
fluidAdditionalAttributes:
placeholder: ''
defaultValue: ''
validators:
-
identifier: NotEmpty
-
identifier: summarypage
label: 'Summary page'
type: SummaryPage
@@ -0,0 +1,130 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<f:layout name="FormManager" />
<f:section name="MainContent">
<script type="text/javascript">
require(['{dynamicRequireJsModules.app}', '{dynamicRequireJsModules.viewModel}'], function (formManagerApp, viewModel) {
var FORMMANAGER_APP = formManagerApp.getInstance(
<f:format.htmlentitiesDecode>{formManagerAppInitialData}</f:format.htmlentitiesDecode>,
viewModel
).run();
});
</script>
<h1><f:translate key="LLL:EXT:form/Resources/Private/Language/Database.xlf:formManager.headline" /></h1>
<f:if condition="{forms}">
<f:then>
<div class="panel panel-space panel-default recordlist">
<div class="panel-heading">
<span><f:translate key="LLL:EXT:form/Resources/Private/Language/Database.xlf:formManager.edit_existing_forms" /></span>
</div>
<div class="collapse in">
<div class="table-fit">
<table id="forms" class="table table-striped table-hover">
<thead>
<tr>
<th class="col-icon nowrap"><a class="btn btn-default" data-identifier="newForm" href="#"><core:icon identifier="actions-add" /></a></th>
<th class="col-title col-responsive nowrap"><f:translate key="LLL:EXT:form/Resources/Private/Language/Database.xlf:formManager.form_name" /></th>
<th class="col-control nowrap"></th>
<th class="nowrap"><f:translate key="LLL:EXT:form/Resources/Private/Language/Database.xlf:formManager.location" /></th>
<th class="nowrap"><f:translate key="LLL:EXT:form/Resources/Private/Language/Database.xlf:formManager.references" /></th>
</tr>
</thead>
<tbody>
<f:for each="{forms}" as="form">
<tr>
<td class="col-icon nowrap">
<f:if condition="{form.invalid}">
<f:then>
<span title="{f:translate(key: 'LLL:EXT:form/Resources/Private/Language/Database.xlf:formManager.invalid')}" data-toggle="tooltip" data-placement="top">
<core:icon identifier="overlay-missing" />
</span>
</f:then>
<f:else if="{form.duplicateIdentifier}">
<span title="{f:translate(key: 'LLL:EXT:form/Resources/Private/Language/Database.xlf:formManager.duplicate_identifier')} {form.identifier}" data-toggle="tooltip" data-placement="top">
<core:icon identifier="overlay-missing" />
</span>
</f:else>
<f:else>
<f:if condition="{form.deprecatedFileExtension}">
<f:then>
<span title="{f:translate(key: 'LLL:EXT:form/Resources/Private/Language/Database.xlf:formManager.deprecated_file_extension')} {form.identifier}" data-toggle="tooltip" data-placement="top">
<core:icon identifier="overlay-missing" />
</span>
</f:then>
<f:else>
<span title="id={form.identifier}" data-toggle="tooltip" data-placement="right">
<core:icon identifier="content-form" />
</span>
</f:else>
</f:if>
</f:else>
</f:if>
</td>
<td class="col-title col-responsive nowrap">
<f:if condition="{form.invalid} || {form.readOnly}">
<f:then>
<div title="{form.name}">{form.name}</div>
</f:then>
<f:else>
<f:link.action controller="FormEditor" action="index" arguments="{formPersistenceIdentifier: form.persistenceIdentifier}" title="{f:translate(key: 'LLL:EXT:form/Resources/Private/Language/Database.xlf:formManager.edit_form')}" data="{toggle: 'tooltip', placement: 'right'}">{form.name}</f:link.action>
</f:else>
</f:if>
</td>
<td class="col-control nowrap">
<div class="btn-group" role="group">
<f:if condition="{form.invalid} || {form.readOnly}">
<f:then>
<button class="btn btn-default form-record-readonly" disabled="disabled" title="{f:translate(key: 'LLL:EXT:form/Resources/Private/Language/Database.xlf:formManager.edit_form_not_allowed')}"><core:icon identifier="actions-open" /></button>
</f:then>
<f:else>
<f:link.action controller="FormEditor" action="index" arguments="{formPersistenceIdentifier: form.persistenceIdentifier}" title="{f:translate(key: 'LLL:EXT:form/Resources/Private/Language/Database.xlf:formManager.edit_form')}" class="btn btn-default form-record-open"><core:icon identifier="actions-open" /></f:link.action>
</f:else>
</f:if>
<f:if condition="{form.invalid}">
<f:then>
<button class="btn btn-default form-record-readonly" disabled="disabled" title="{f:translate(key: 'LLL:EXT:form/Resources/Private/Language/Database.xlf:formManager.duplicate_form_not_allowed')}"><core:icon identifier="actions-duplicate" /></button>
<button class="btn btn-default form-record-readonly" disabled="disabled" title="{f:translate(key: 'LLL:EXT:form/Resources/Private/Language/Database.xlf:formManager.delete_form_not_allowed')}"><core:icon identifier="actions-edit-delete" /></button>
</f:then>
<f:else>
<a href="#" data-identifier="duplicateForm" data-form-persistence-identifier="{form.persistenceIdentifier}" data-form-name="{form.name}" title="{f:translate(key: 'LLL:EXT:form/Resources/Private/Language/Database.xlf:formManager.duplicate_this_form')}" class="btn btn-default form-record-duplicate"><core:icon identifier="actions-duplicate" /></a>
<f:if condition="{form.removable}">
<f:then>
<a href="#" data-identifier="removeForm" data-form-persistence-identifier="{form.persistenceIdentifier}" title="{f:translate(key: 'LLL:EXT:form/Resources/Private/Language/Database.xlf:formManager.delete_form')}" class="btn btn-default form-record-delete"><core:icon identifier="actions-edit-delete" /></a>
</f:then>
<f:else>
<button class="btn btn-default form-record-delete" disabled="disabled" title="{f:translate(key: 'LLL:EXT:form/Resources/Private/Language/Database.xlf:formManager.delete_form_not_allowed')}"><core:icon identifier="actions-edit-delete" /></button>
</f:else>
</f:if>
</f:else>
</f:if>
</div>
</td>
<td class="nowrap">{form.persistenceIdentifier}</td>
<td class="nowrap">
<f:if condition="{form.referenceCount}">
<f:then>
<a href="#" data-identifier="showReferences" data-form-persistence-identifier="{form.persistenceIdentifier}" data-form-name="{form.name}">{form.referenceCount}</a>
</f:then>
<f:else>
{form.referenceCount}
</f:else>
</f:if>
</td>
</tr>
</f:for>
</tbody>
</table>
</div>
</div>
</div>
</f:then>
<f:else>
<f:be.infobox state="-1" title="{f:translate(key: 'LLL:EXT:form/Resources/Private/Language/Database.xlf:formManager.forms_not_found.title')}">
<p><f:translate key="LLL:EXT:form/Resources/Private/Language/Database.xlf:formManager.forms_not_found.message" /></p>
<a class="btn btn-primary" href="#" data-identifier="newForm"><f:translate key="LLL:EXT:form/Resources/Private/Language/Database.xlf:formManager.create_new_form" /></a>
</f:be.infobox>
</f:else>
</f:if>
</f:section>
</html>
@@ -0,0 +1,30 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<formvh:renderRenderable renderable="{element}">
<f:render partial="Field/Field" arguments="{element: element}" contentAs="elementContent">
<div class="form-group">
<f:form.password
property="{element.identifier}.password"
id="{element.uniqueIdentifier}"
class="{element.properties.elementClassAttribute} form-control"
errorClass="{element.properties.elementErrorClassAttribute}"
additionalAttributes="{formvh:translateElementProperty(element: element, property: 'fluidAdditionalAttributes')}"
/>
<f:if condition="{formvh:translateElementProperty(element: element, property: 'passwordDescription')}">
<span class="help-block">{formvh:translateElementProperty(element: element, property: 'passwordDescription')}</span>
</f:if>
</div>
<div class="form-group">
<f:if condition="{formvh:translateElementProperty(element: element, property: 'confirmationLabel')}">
<label for="{element.uniqueIdentifier}-confirmation">{formvh:translateElementProperty(element: element, property: 'confirmationLabel')}<f:if condition="{element.required}"><f:render partial="Field/Required" /></f:if></label>
</f:if>
<f:form.password
property="{element.identifier}.confirmation"
id="{element.uniqueIdentifier}-confirmation"
class="{element.properties.confirmationClassAttribute} form-control"
errorClass="{element.properties.elementErrorClassAttribute}"
additionalAttributes="{formvh:translateElementProperty(element: element, property: 'fluidAdditionalAttributes')}"
/>
</div>
</f:render>
</formvh:renderRenderable>
</html>
@@ -0,0 +1,19 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<formvh:renderRenderable renderable="{element}">
<f:render partial="Field/Field" arguments="{element: element, doNotShowLabel: 1}" contentAs="elementContent">
<div class="form-check">
<label class="{element.properties.elementClassAttribute} form-check-label" for="{element.uniqueIdentifier}">
<f:form.checkbox
property="{element.identifier}"
id="{element.uniqueIdentifier}"
class="{element.properties.elementClassAttribute}"
value="{element.properties.value}"
errorClass="{element.properties.elementErrorClassAttribute}"
additionalAttributes="{formvh:translateElementProperty(element: element, property: 'fluidAdditionalAttributes')}"
/>
<span>{formvh:translateElementProperty(element: element, property: 'label')}<f:if condition="{element.required}"><f:render partial="Field/Required" /></f:if></span>
</label>
</div>
</f:render>
</formvh:renderRenderable>
</html>
@@ -0,0 +1,25 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<formvh:renderRenderable renderable="{element}">
<f:if condition="{element.rootForm.renderingOptions.previewMode}">
<f:then>
<div class="clearfix">
<f:if condition="{element.properties.contentElementUid}">
<f:then>
<formvh:be.renderContentElementPreview contentElementUid="{element.properties.contentElementUid}" />
</f:then>
<f:else>
<f:translate key="LLL:EXT:form/Resources/Private/Language/Database.xlf:formEditor.elements.ContentElement.selectContentElement" />
</f:else>
</f:if>
</div>
</f:then>
<f:else>
<f:if condition="{element.properties.contentElementUid}">
<div class="clearfix{f:if(condition: element.properties.elementClassAttribute, then: ' {element.properties.elementClassAttribute}')}">
<f:cObject typoscriptObjectPath="lib.tx_form.contentElementRendering">{element.properties.contentElementUid}</f:cObject>
</div>
</f:if>
</f:else>
</f:if>
</formvh:renderRenderable>
</html>
@@ -0,0 +1,14 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<formvh:renderRenderable renderable="{element}">
<f:render partial="Field/Field" arguments="{element: element}" contentAs="elementContent">
<f:form.textfield
type="date"
property="{element.identifier}"
id="{element.uniqueIdentifier}"
class="{element.properties.elementClassAttribute} form-control"
errorClass="{element.properties.elementErrorClassAttribute}"
additionalAttributes="{formvh:translateElementProperty(element: element, property: 'fluidAdditionalAttributes')}"
/>
</f:render>
</formvh:renderRenderable>
</html>
@@ -0,0 +1,47 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<formvh:renderRenderable renderable="{element}">
<div class="form-inline">
<f:render partial="Field/Field" arguments="{element: element}" contentAs="elementContent">
<formvh:form.datePicker
id="{element.uniqueIdentifier}"
property="{element.identifier}"
dateFormat="{element.properties.dateFormat}"
initialDate="{element.properties.initialDate}"
enableDatePicker="{element.properties.enableDatePicker}"
class="{element.properties.elementClassAttribute}"
errorClass="{element.properties.elementErrorClassAttribute}"
additionalAttributes="{formvh:translateElementProperty(element: element, property: 'fluidAdditionalAttributes')}"
previewMode="{element.rootForm.renderingOptions.previewMode}"
/>
</f:render>
<f:if condition="{element.properties.displayTimeSelector}">
<div class="form-group{f:if(condition: '{validationResults.errors.0}', then: ' has-error')}">
<label class="control-label" for="{element.uniqueIdentifier}-time">{formvh:translateElementProperty(element: element, property: 'timeSelectorHourLabel')}</label>
<div class="{element.properties.containerClassAttribute}">
<formvh:form.timePicker
id="{element.uniqueIdentifier}-time"
property="{element.identifier}"
initialDate="{element.properties.initialDate}"
class="{element.properties.timeSelectorClassAttribute} form-control"
errorClass="{element.properties.elementErrorClassAttribute}"
timeType="hour"
/>
</div>
</div>
<div class="form-group{f:if(condition: '{validationResults.errors.0}', then: ' has-error')}">
<label class="control-label" for="{element.uniqueIdentifier}-time-minute">{formvh:translateElementProperty(element: element, property: 'timeSelectorMinuteLabel')}</label>
<div class="{element.properties.containerClassAttribute}">
<formvh:form.timePicker
id="{element.uniqueIdentifier}-time-minute"
property="{element.identifier}"
initialDate="{element.properties.initialDate}"
class="{element.properties.timeSelectorClassAttribute} form-control"
errorClass="{element.properties.elementErrorClassAttribute}"
timeType="minute"
/>
</div>
</div>
</f:if>
</div>
</formvh:renderRenderable>
</html>
@@ -0,0 +1,14 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<formvh:renderRenderable renderable="{element}">
<f:render partial="Field/Field" arguments="{element: element}" contentAs="elementContent">
<f:form.textfield
type="email"
property="{element.identifier}"
id="{element.uniqueIdentifier}"
class="{element.properties.elementClassAttribute} form-control"
errorClass="{element.properties.elementErrorClassAttribute}"
additionalAttributes="{formvh:translateElementProperty(element: element, property: 'fluidAdditionalAttributes')}"
/>
</f:render>
</formvh:renderRenderable>
</html>
@@ -0,0 +1,25 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<f:form.validationResults for="{element.rootForm.identifier}.{element.identifier}">
<div class="form-group{f:if(condition: '{validationResults.errors.0}', then: ' has-error')}">
<f:if condition="{doNotShowLabel} != 1">
<label class="control-label" for="{element.uniqueIdentifier}">{formvh:translateElementProperty(element: element, property: 'label')}<f:if condition="{element.required}"><f:render partial="Field/Required" /></f:if></label>
</f:if>
<div class="{element.properties.containerClassAttribute}">
<f:format.raw>
{elementContent}
<f:if condition="{validationResults.flattenedErrors}">
<span class="error help-block" role="alert">
<f:for each="{validationResults.errors}" as="error">
<f:format.htmlspecialchars>{formvh:translateElementError(element: element, error: error)}</f:format.htmlspecialchars>
<br />
</f:for>
</span>
</f:if>
</f:format.raw>
<f:if condition="{element.properties.elementDescription}">
<span class="help-block">{formvh:translateElementProperty(element: element, property: 'elementDescription')}</span>
</f:if>
</div>
</div>
</f:form.validationResults>
</html>
@@ -0,0 +1,3 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<span class="required">*</span>
</html>
@@ -0,0 +1,12 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<formvh:renderRenderable renderable="{element}">
<fieldset id="{element.uniqueIdentifier}" class="form-group{f:if(condition: element.properties.elementClassAttribute, then: ' {element.properties.elementClassAttribute}')}">
<f:if condition="{element.label}">
<legend>{formvh:translateElementProperty(element: element, property: 'label')}</legend>
</f:if>
<f:for each="{element.elements}" as="element">
<f:render partial="{element.templateName}" arguments="{element: element}" />
</f:for>
</fieldset>
</formvh:renderRenderable>
</html>
@@ -0,0 +1,21 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<formvh:renderRenderable renderable="{element}">
<f:render partial="Field/Field" arguments="{element: element}" contentAs="elementContent">
<formvh:form.uploadedResource
property="{element.identifier}"
as="resource"
id="{element.uniqueIdentifier}"
class="{element.properties.elementClassAttribute}"
errorClass="{element.properties.elementErrorClassAttribute}"
additionalAttributes="{formvh:translateElementProperty(element: element, property: 'fluidAdditionalAttributes')}"
accept="{element.properties.allowedMimeTypes}"
>
<f:if condition="{resource}">
<div id="{element.uniqueIdentifier}-preview">
{resource.originalResource.originalFile.name}
</div>
</f:if>
</formvh:form.uploadedResource>
</f:render>
</formvh:renderRenderable>
</html>
@@ -0,0 +1,28 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<nav class="form-navigation">
<div class="btn-toolbar" role="toolbar">
<div class="btn-group" role="group">
<f:if condition="{form.previousPage}">
<span class="btn-group previous">
<f:form.hidden property="__currentPage" value="{form.previousPage.index}" />
<f:form.button type="button" onclick="document.forms['{form.formDefinition.identifier}'].submit();" class="btn btn-cancel" formnovalidate="formnovalidate">{formvh:translateElementProperty(element: form.currentPage, renderingOptionProperty: 'previousButtonLabel')}</f:form.button>
</span>
</f:if>
<f:if condition="{form.nextPage}">
<f:then>
<span class="btn-group next">
<f:form.button property="__currentPage" value="{form.nextPage.index}" class="btn btn-primary">{formvh:translateElementProperty(element: form.currentPage, renderingOptionProperty: 'nextButtonLabel')}</f:form.button>
</span>
</f:then>
<f:else>
<span class="btn-group next submit">
<f:form.button property="__currentPage" value="{form.pages -> f:count()}" class="btn btn-primary">
{formvh:translateElementProperty(element: form, renderingOptionProperty: 'submitButtonLabel')}
</f:form.button>
</span>
</f:else>
</f:if>
</div>
</div>
</nav>
</html>
@@ -0,0 +1,9 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<formvh:renderRenderable renderable="{element}">
<div class="{f:if(condition: element.properties.elementClassAttribute, then: '{element.properties.elementClassAttribute}')}">
<f:for each="{element.elements}" as="element">
<f:render partial="{element.templateName}" arguments="{element: element}" />
</f:for>
</div>
</formvh:renderRenderable>
</html>
@@ -0,0 +1,11 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<formvh:renderRenderable renderable="{element}">
<div class="{f:if(condition: element.properties.elementClassAttribute, then: '{element.properties.elementClassAttribute}')}">
<f:for each="{element.elements}" as="element">
<div class="{formvh:gridColumnClassAutoConfiguration(element: element)}">
<f:render partial="{element.templateName}" arguments="{element: element}" />
</div>
</f:for>
</div>
</formvh:renderRenderable>
</html>
@@ -0,0 +1,9 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<formvh:renderRenderable renderable="{element}">
<f:form.hidden
property="{element.identifier}"
id="{element.uniqueIdentifier}"
additionalAttributes="{formvh:translateElementProperty(element: element, property: 'fluidAdditionalAttributes')}"
/>
</formvh:renderRenderable>
</html>
@@ -0,0 +1,10 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<f:if condition="{element.properties.renderAsHiddenField}">
<f:then>
<f:form.hidden property="{element.identifier}" id="{element.uniqueIdentifier}" additionalAttributes="{autocomplete: element.identifier}" />
</f:then>
<f:else>
<f:form.textfield property="{element.identifier}" id="{element.uniqueIdentifier}" class="{element.properties.elementClassAttribute}" additionalAttributes="{autocomplete: element.identifier, aria-hidden: 'true'}" tabindex="-1" style="{element.properties.styleAttribute}" />
</f:else>
</f:if>
</html>
@@ -0,0 +1,23 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<formvh:renderRenderable renderable="{element}">
<f:render partial="Field/Field" arguments="{element: element}" contentAs="elementContent">
<formvh:form.uploadedResource
property="{element.identifier}"
as="image"
id="{element.uniqueIdentifier}"
class="{element.properties.elementClassAttribute}"
errorClass="{element.properties.elementErrorClassAttribute}"
additionalAttributes="{formvh:translateElementProperty(element: element, property: 'fluidAdditionalAttributes')}"
accept="{element.properties.allowedMimeTypes}"
>
<f:if condition="{image}">
<div id="{element.uniqueIdentifier}-preview">
<a href="{f:uri.image(image: image, maxWidth: element.properties.imageLinkMaxWidth)}" class="{element.properties.elementClassAttribute}">
<f:image image="{image}" maxWidth="{element.properties.imageMaxWidth}" maxHeight="{element.properties.imageMaxHeight}" alt="{formvh:translateElementProperty(element: element, property: 'altText')}" />
</a>
</div>
</f:if>
</formvh:form.uploadedResource>
</f:render>
</formvh:renderRenderable>
</html>
@@ -0,0 +1,24 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<formvh:renderRenderable renderable="{element}">
<f:render partial="Field/Field" arguments="{element: element}" contentAs="elementContent">
<div id="{element.uniqueIdentifier}" class="inputs-list">
<f:for each="{element.properties.options}" as="label" key="value" iteration="idIterator">
<div class="form-check">
<label class="form-check-label" for="{element.uniqueIdentifier}-{idIterator.index}">
<f:form.checkbox
property="{element.identifier}"
multiple="1"
id="{element.uniqueIdentifier}-{idIterator.index}"
class="{element.properties.elementClassAttribute}"
value="{value}"
errorClass="{element.properties.elementErrorClassAttribute}"
additionalAttributes="{formvh:translateElementProperty(element: element, property: 'fluidAdditionalAttributes')}"
/>
<span>{formvh:translateElementProperty(element: element, property: '{0: \'options\', 1: value}')}</span>
</label>
</div>
</f:for>
</div>
</f:render>
</formvh:renderRenderable>
</html>
@@ -0,0 +1,33 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<formvh:renderRenderable renderable="{element}">
<f:render partial="Field/Field" arguments="{element: element}" contentAs="elementContent">
<f:if condition="{element.properties.prependOptionLabel}">
<f:then>
<f:form.select
property="{element.identifier}"
id="{element.uniqueIdentifier}"
class="{element.properties.elementClassAttribute} form-control"
options="{formvh:translateElementProperty(element: element, property: 'options')}"
multiple="multiple"
errorClass="{element.properties.elementErrorClassAttribute}"
additionalAttributes="{formvh:translateElementProperty(element: element, property: 'fluidAdditionalAttributes')}"
prependOptionLabel="{formvh:translateElementProperty(element: element, property: 'prependOptionLabel')}"
prependOptionValue="{formvh:translateElementProperty(element: element, property: 'prependOptionValue')}"
/>
</f:then>
<f:else>
<f:form.select
property="{element.identifier}"
id="{element.uniqueIdentifier}"
class="{element.properties.elementClassAttribute} form-control"
options="{formvh:translateElementProperty(element: element, property: 'options')}"
multiple="multiple"
errorClass="{element.properties.elementErrorClassAttribute}"
additionalAttributes="{formvh:translateElementProperty(element: element, property: 'fluidAdditionalAttributes')}"
/>
</f:else>
</f:if>
</f:render>
</formvh:renderRenderable>
</html>
@@ -0,0 +1,14 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<formvh:renderRenderable renderable="{element}">
<f:render partial="Field/Field" arguments="{element: element}" contentAs="elementContent">
<f:form.textfield
type="number"
property="{element.identifier}"
id="{element.uniqueIdentifier}"
class="{element.properties.elementClassAttribute} form-control"
errorClass="{element.properties.elementErrorClassAttribute}"
additionalAttributes="{formvh:translateElementProperty(element: element, property: 'fluidAdditionalAttributes')}"
/>
</f:render>
</formvh:renderRenderable>
</html>
@@ -0,0 +1,10 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<formvh:renderRenderable renderable="{page}">
<f:if condition="{page.label}">
<h2>{formvh:translateElementProperty(element: page, property: 'label')}</h2>
</f:if>
<f:for each="{page.elements}" as="element">
<f:render partial="{element.templateName}" arguments="{element: element}" />
</f:for>
</formvh:renderRenderable>
</html>
@@ -0,0 +1,13 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<formvh:renderRenderable renderable="{element}">
<f:render partial="Field/Field" arguments="{element: element}" contentAs="elementContent">
<f:form.password
property="{element.identifier}"
id="{element.uniqueIdentifier}"
class="{element.properties.elementClassAttribute} form-control"
additionalAttributes="{formvh:translateElementProperty(element: element, property: 'fluidAdditionalAttributes')}"
errorClass="{element.properties.elementErrorClassAttribute}"
/>
</f:render>
</formvh:renderRenderable>
</html>
@@ -0,0 +1,28 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<formvh:renderRenderable renderable="{element}">
<f:render partial="Field/Field" arguments="{element: element, doNotShowLabel: 1}" contentAs="elementContent">
<label class="control-label">{formvh:translateElementProperty(element: element, property: 'label')}<f:if condition="{element.required}"><f:render partial="Field/Required" /></f:if></label>
<div class="{element.properties.containerClassAttribute}">
<div id="{element.uniqueIdentifier}" class="inputs-list">
<div class="form-group">
<f:for each="{element.properties.options}" as="label" key="value" iteration="idIterator">
<div class="radio">
<label for="{element.uniqueIdentifier}-{idIterator.index}">
<f:form.radio
property="{element.identifier}"
id="{element.uniqueIdentifier}-{idIterator.index}"
class="{element.properties.elementClassAttribute} form-check-input"
value="{value}"
errorClass="{element.properties.elementErrorClassAttribute}"
additionalAttributes="{formvh:translateElementProperty(element: element, property: 'fluidAdditionalAttributes')}"
/>
<span>{formvh:translateElementProperty(element: element, property: '{0: \'options\', 1: value}')}</span>
</label>
</div>
</f:for>
</div>
</div>
</div>
</f:render>
</formvh:renderRenderable>
</html>
@@ -0,0 +1,30 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<formvh:renderRenderable renderable="{element}">
<f:render partial="Field/Field" arguments="{element: element}" contentAs="elementContent">
<f:if condition="{element.properties.prependOptionLabel}">
<f:then>
<f:form.select
property="{element.identifier}"
id="{element.uniqueIdentifier}"
options="{formvh:translateElementProperty(element: element, property: 'options')}"
class="{element.properties.elementClassAttribute} form-control"
errorClass="{element.properties.elementErrorClassAttribute}"
additionalAttributes="{formvh:translateElementProperty(element: element, property: 'fluidAdditionalAttributes')}"
prependOptionLabel="{formvh:translateElementProperty(element: element, property: 'prependOptionLabel')}"
prependOptionValue="{formvh:translateElementProperty(element: element, property: 'prependOptionValue')}"
/>
</f:then>
<f:else>
<f:form.select
property="{element.identifier}"
id="{element.uniqueIdentifier}"
options="{formvh:translateElementProperty(element: element, property: 'options')}"
class="{element.properties.elementClassAttribute} form-control"
errorClass="{element.properties.elementErrorClassAttribute}"
additionalAttributes="{formvh:translateElementProperty(element: element, property: 'fluidAdditionalAttributes')}"
/>
</f:else>
</f:if>
</f:render>
</formvh:renderRenderable>
</html>
@@ -0,0 +1,12 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<formvh:renderRenderable renderable="{element}">
<div class="clearfix">
<f:if condition="{element.label}">
<h2>{formvh:translateElementProperty(element: element, property: 'label')}</h2>
</f:if>
<f:if condition="{element.properties.text}">
<p{f:if(condition: element.properties.elementClassAttribute, then: ' class="{element.properties.elementClassAttribute}"')}>{formvh:translateElementProperty(element: element, property: 'text') -> f:format.nl2br()}</p>
</f:if>
</div>
</formvh:renderRenderable>
</html>
@@ -0,0 +1,46 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<formvh:renderRenderable renderable="{page}">
<fieldset class="form-group">
<f:if condition="{page.label}">
<legend>{formvh:translateElementProperty(element: page, property: 'label')}</legend>
</f:if>
<div class="table-responsive">
<table class="table">
<formvh:renderAllFormValues renderable="{page.rootForm}" as="formValue">
<tr>
<td class="summary-table-first-col">{formvh:translateElementProperty(element: formValue.element, property: 'label')}</td>
<td>
<f:if condition="{formValue.value}">
<f:then>
<f:if condition="{0: formValue.element.type} == {0: 'ImageUpload'}">
<f:then>
<f:image image="{formValue.value}" maxWidth="{formValue.element.properties.imageMaxWidth}" maxHeight="{formValue.element.properties.imageMaxHeight}" alt="{formvh:translateElementProperty(element: formValue.element, property: 'altText')}" />
</f:then>
<f:else>
<f:if condition="{formValue.isMultiValue}">
<f:then>
<ul>
<f:for each="{formValue.processedValue}" as="value">
<li>{value}</li>
</f:for>
</ul>
</f:then>
<f:else>
<f:format.nl2br>{formValue.processedValue}</f:format.nl2br>
</f:else>
</f:if>
</f:else>
</f:if>
</f:then>
<f:else>
-
</f:else>
</f:if>
</td>
</tr>
</formvh:renderAllFormValues>
</table>
</div>
</fieldset>
</formvh:renderRenderable>
</html>
@@ -0,0 +1,14 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<formvh:renderRenderable renderable="{element}">
<f:render partial="Field/Field" arguments="{element: element}" contentAs="elementContent">
<f:form.textfield
type="tel"
property="{element.identifier}"
id="{element.uniqueIdentifier}"
class="{element.properties.elementClassAttribute} form-control"
errorClass="{element.properties.elementErrorClassAttribute}"
additionalAttributes="{formvh:translateElementProperty(element: element, property: 'fluidAdditionalAttributes')}"
/>
</f:render>
</formvh:renderRenderable>
</html>
@@ -0,0 +1,13 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<formvh:renderRenderable renderable="{element}">
<f:render partial="Field/Field" arguments="{element: element}" contentAs="elementContent">
<f:form.textfield
property="{element.identifier}"
id="{element.uniqueIdentifier}"
class="{element.properties.elementClassAttribute} form-control"
errorClass="{element.properties.elementErrorClassAttribute}"
additionalAttributes="{formvh:translateElementProperty(element: element, property: 'fluidAdditionalAttributes')}"
/>
</f:render>
</formvh:renderRenderable>
</html>
@@ -0,0 +1,15 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<formvh:renderRenderable renderable="{element}">
<f:render partial="Field/Field" arguments="{element: element}" contentAs="elementContent">
<f:form.textarea
property="{element.identifier}"
id="{element.uniqueIdentifier}"
class="{element.properties.elementClassAttribute} form-control"
rows="{element.properties.rows}"
cols="{element.properties.cols}"
errorClass="{element.properties.elementErrorClassAttribute}"
additionalAttributes="{formvh:translateElementProperty(element: element, property: 'fluidAdditionalAttributes')}"
/>
</f:render>
</formvh:renderRenderable>
</html>
@@ -0,0 +1,3 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<formvh:renderRenderable renderable="{element}"> </formvh:renderRenderable>
</html>
@@ -0,0 +1,14 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<formvh:renderRenderable renderable="{element}">
<f:render partial="Field/Field" arguments="{element: element}" contentAs="elementContent">
<f:form.textfield
type="url"
property="{element.identifier}"
id="{element.uniqueIdentifier}"
class="{element.properties.elementClassAttribute} form-control"
errorClass="{element.properties.elementErrorClassAttribute}"
additionalAttributes="{formvh:translateElementProperty(element: element, property: 'fluidAdditionalAttributes')}"
/>
</f:render>
</formvh:renderRenderable>
</html>
@@ -0,0 +1,12 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<div id="{form.identifier}">
<f:if condition="{isPreparedMessage}">
<f:then>
{message -> f:format.raw()}
</f:then>
<f:else>
{message -> f:format.nl2br()}
</f:else>
</f:if>
</div>
</html>
@@ -0,0 +1,45 @@
{namespace formvh=TYPO3\CMS\Form\ViewHelpers}
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="format-detection" content="telephone=no">
</head>
<body>
<table width="600" cellpadding="0" cellspacing="0" border="0">
<formvh:renderAllFormValues renderable="{form.formDefinition}" as="formValue">
<tr>
<td width="600" valign="top" align="left">{formvh:translateElementProperty(element: formValue.element, property: 'label')}</td>
<td width="600" valign="top" align="left">
<f:if condition="{formValue.value}">
<f:then>
<f:if condition="{formValue.isMultiValue}">
<f:then>
<table cellspacing="0" border="0">
<f:for each="{formValue.processedValue}" as="value">
<tr>
<td>{value}</td>
</tr>
</f:for>
</table>
</f:then>
<f:else>
<table cellspacing="0" border="0">
<tr>
<td><f:format.nl2br>{formValue.processedValue}</f:format.nl2br></td>
</tr>
</table>
</f:else>
</f:if>
</f:then>
<f:else>
-
</f:else>
</f:if>
</td>
</tr>
</formvh:renderAllFormValues>
</table>
</body>
</html>
@@ -0,0 +1,15 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<formvh:renderAllFormValues renderable="{form.formDefinition}" as="formValue"><f:spaceless>
<f:if condition="{formValue.isMultiValue}">
<f:then>
<formvh:translateElementProperty element="{formValue.element}" property="label" />:
<f:for each="{formValue.processedValue}" as="singleValue">- {singleValue}
</f:for>
</f:then>
<f:else>
<formvh:translateElementProperty element="{formValue.element}" property="label" />: <f:if condition="{formValue.processedValue}"><f:then>{formValue.processedValue -> f:format.raw()}</f:then><f:else>-</f:else></f:if>
</f:else>
</f:if>
</f:spaceless>
</formvh:renderAllFormValues>
</html>
@@ -0,0 +1,20 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<formvh:renderRenderable renderable="{form}">
<formvh:form
object="{form}"
action="{form.renderingOptions.controllerAction}"
method="{form.renderingOptions.httpMethod}"
id="{form.identifier}"
section="{form.identifier}"
enctype="{form.renderingOptions.httpEnctype}"
addQueryString="{form.renderingOptions.addQueryString}"
argumentsToBeExcludedFromQueryString="{form.renderingOptions.argumentsToBeExcludedFromQueryString}"
additionalParams="{form.renderingOptions.additionalParams}"
>
<f:render partial="{form.currentPage.templateName}" arguments="{page: form.currentPage}" />
<div class="actions">
<f:render partial="Form/Navigation" arguments="{form: form}" />
</div>
</formvh:form>
</formvh:renderRenderable>
</html>
@@ -0,0 +1,6 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<f:if condition="{formConfiguration}">
<formvh:render overrideConfiguration="{formConfiguration}" />
<f:flashMessages />
</f:if>
</html>
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,126 @@
<?xml version="1.0" encoding="UTF-8"?>
<xliff version="1.0" xmlns:t3="http://typo3.org/schemas/xliff">
<file t3:id="1475977066" source-language="en" datatype="plaintext" original="EXT:form/Resources/Private/Language/locallang.xlf" date="2016-10-09T03:38:32Z" product-name="form">
<header/>
<body>
<trans-unit id="element.ImageUpload.properties.SummaryPage.altText" resname="element.ImageUpload.properties.SummaryPage.altText" xml:space="preserve">
<source>Uploaded image</source>
</trans-unit>
<trans-unit id="element.DatePicker.properties.timeSelectorHourLabel" resname="element.DatePicker.properties.timeSelectorHourLabel" xml:space="preserve">
<source>Hour</source>
</trans-unit>
<trans-unit id="element.DatePicker.properties.timeSelectorMinuteLabel" resname="element.DatePicker.properties.timeSelectorMinuteLabel" xml:space="preserve">
<source>Minute</source>
</trans-unit>
<trans-unit id="validation.error.1221560910" resname="validation.error.1221560910" xml:space="preserve">
<source>This field is mandatory.</source>
</trans-unit>
<trans-unit id="validation.error.1221560718" resname="validation.error.1221560718" xml:space="preserve">
<source>This field is mandatory.</source>
</trans-unit>
<trans-unit id="validation.error.1347992400" resname="validation.error.1347992400" xml:space="preserve">
<source>This field is mandatory.</source>
</trans-unit>
<trans-unit id="validation.error.1347992453" resname="validation.error.1347992453" xml:space="preserve">
<source>This field is mandatory.</source>
</trans-unit>
<trans-unit id="validation.error.1238087674" resname="validation.error.1238087674" xml:space="preserve">
<source>You must enter a valid date.</source>
</trans-unit>
<trans-unit id="validation.error.1221551320" resname="validation.error.1221551320" xml:space="preserve">
<source>You can only enter letters or digits.</source>
</trans-unit>
<trans-unit id="validation.error.1221565786" resname="validation.error.1221565786" xml:space="preserve">
<source>You can only enter non formatted text without any markup (e.g without XML tags).</source>
</trans-unit>
<trans-unit id="validation.error.1238110957" resname="validation.error.1238110957" xml:space="preserve">
<source>You can only enter non formatted text without any markup (e.g without XML tags).</source>
</trans-unit>
<trans-unit id="validation.error.1269883975" resname="validation.error.1269883975" xml:space="preserve">
<source>You can only enter non formatted text without any markup (e.g without XML tags).</source>
</trans-unit>
<trans-unit id="validation.error.1428504122" resname="validation.error.1428504122" xml:space="preserve">
<source>Your text must be a minimum of %s characters in length and no longer than %s.</source>
</trans-unit>
<trans-unit id="validation.error.1238108068" resname="validation.error.1238108068" xml:space="preserve">
<source>You must enter text which is longer than %s characters.</source>
</trans-unit>
<trans-unit id="validation.error.1238108069" resname="validation.error.1238108069" xml:space="preserve">
<source>You must enter text which is no longer than %s characters.</source>
</trans-unit>
<trans-unit id="validation.error.1221559976" resname="validation.error.1221559976" xml:space="preserve">
<source>You must enter a valid email address.</source>
</trans-unit>
<trans-unit id="validation.error.1221560494" resname="validation.error.1221560494" xml:space="preserve">
<source>You must enter a valid number.</source>
</trans-unit>
<trans-unit id="validation.error.1221560288" resname="validation.error.1221560288" xml:space="preserve">
<source>You must enter a valid floating point number.</source>
</trans-unit>
<trans-unit id="validation.error.1221563685" resname="validation.error.1221563685" xml:space="preserve">
<source>You must enter a valid number.</source>
</trans-unit>
<trans-unit id="validation.error.1221561046" resname="validation.error.1221561046" xml:space="preserve">
<source>You must enter a valid number between %s and %s.</source>
</trans-unit>
<trans-unit id="validation.error.1221565130" resname="validation.error.1221565130" xml:space="preserve">
<source>You must enter a valid value. Please refer to the description of this field.</source>
</trans-unit>
<trans-unit id="validation.error.1475002976" resname="validation.error.1475002976" xml:space="preserve">
<source>You must enter a countable subject.</source>
</trans-unit>
<trans-unit id="validation.error.1475002994" resname="validation.error.1475002994" xml:space="preserve">
<source>You must select between %s to %s elements.</source>
</trans-unit>
<trans-unit id="validation.error.1471708997" resname="validation.error.1471708997" xml:space="preserve">
<source>You must enter an instance of \TYPO3\CMS\Extbase\Domain\Model\FileReference or \TYPO3\CMS\Core\Resource\File.</source>
</trans-unit>
<trans-unit id="validation.error.1471708998" resname="validation.error.1471708998" xml:space="preserve">
<source>You entered an incorrect media type, "%s" is not allowed for this file. Please refer to the description of this field.</source>
</trans-unit>
<trans-unit id="validation.error.1613126216" resname="validation.error.1613126216" xml:space="preserve">
<source>The file extension provided "%s" does not match to expected media types. Please refer to the description of this field.</source>
</trans-unit>
<trans-unit id="validation.error.1476396435" resname="validation.error.1476396435" xml:space="preserve">
<source>You must NOT fill this field.</source>
</trans-unit>
<trans-unit id="validation.error.1505303626" resname="validation.error.1505303626" xml:space="preserve">
<source>You must enter an instance of \TYPO3\CMS\Extbase\Domain\Model\FileReference or \TYPO3\CMS\Core\Resource\File.</source>
</trans-unit>
<trans-unit id="validation.error.1505305752" resname="validation.error.1505305752" xml:space="preserve">
<source>You must select a file that is larger than %s in size.</source>
</trans-unit>
<trans-unit id="validation.error.1505305753" resname="validation.error.1505305753" xml:space="preserve">
<source>You must select a file that is no larger than %s.</source>
</trans-unit>
<trans-unit id="validation.error.1521293686" resname="validation.error.1521293686" xml:space="preserve">
<source>You must select a date before %s.</source>
</trans-unit>
<trans-unit id="validation.error.1521293687" resname="validation.error.1521293687" xml:space="preserve">
<source>You must select a date after %s.</source>
</trans-unit>
<trans-unit id="validation.error.1556283177" resname="validation.error.1556283177" xml:space="preserve">
<source>Password does not match confirmation</source>
</trans-unit>
<trans-unit id="form_new_wizard_title" resname="form_new_wizard_title" xml:space="preserve">
<source>Form</source>
</trans-unit>
<trans-unit id="form_new_wizard_description" resname="form_new_wizard_description" xml:space="preserve">
<source>A form that allows website users to submit messages.</source>
</trans-unit>
<trans-unit id="upload.error.150530345" resname="upload.error.150530345" xml:space="preserve">
<source>Maximum file size exceeded.</source>
</trans-unit>
<trans-unit id="upload.error.150530346" resname="upload.error.150530346" xml:space="preserve">
<source>Upload failed. The file was only partially uploaded, please try again.</source>
</trans-unit>
<trans-unit id="upload.error.150530347" resname="upload.error.150530347" xml:space="preserve">
<source>No file was uploaded.</source>
</trans-unit>
<trans-unit id="upload.error.150530348" resname="upload.error.150530348" xml:space="preserve">
<source>Upload failed.</source>
</trans-unit>
</body>
</file>
</xliff>
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<xliff version="1.0" xmlns:t3="http://typo3.org/schemas/xliff">
<file t3:id="1877653884" source-language="en" datatype="plaintext" original="EXT:form/Resources/Private/Language/locallang_formEditor_failSafeErrorHandling_javascript.xlf" date="2019-04-27T03:38:32Z" product-name="form">
<header/>
<body>
<trans-unit id="formEditor.error.headline" resname="formEditor.error.headline" xml:space="preserve">
<source>Oops! Something went wrong.</source>
</trans-unit>
<trans-unit id="formEditor.error.message" resname="formEditor.error.message" xml:space="preserve">
<source>Please contact your administrator.</source>
</trans-unit>
<trans-unit id="formEditor.error.technicalReason" resname="formEditor.error.technicalReason" xml:space="preserve">
<source>Technical Reason:</source>
</trans-unit>
</body>
</file>
</xliff>
@@ -0,0 +1,83 @@
<?xml version="1.0" encoding="UTF-8"?>
<xliff version="1.0" xmlns:t3="http://typo3.org/schemas/xliff">
<file t3:id="1477653834" source-language="en" datatype="plaintext" original="EXT:form/Resources/Private/Language/locallang_formManager_javascript.xlf" date="2016-10-09T03:38:32Z" product-name="form">
<header/>
<body>
<trans-unit id="formManager.form_name" resname="formManager.form_name" xml:space="preserve">
<source>Form name</source>
</trans-unit>
<trans-unit id="formManager.new_form_name" resname="formManager.new_form_name" xml:space="preserve">
<source>New form name</source>
</trans-unit>
<trans-unit id="formManager.form_save_path" resname="formManager.form_save_path" xml:space="preserve">
<source>Form storage</source>
</trans-unit>
<trans-unit id="formManager.form_prototype" resname="formManager.form_prototype" xml:space="preserve">
<source>Form prototype</source>
</trans-unit>
<trans-unit id="formManager.form_template" resname="formManager.form_template" xml:space="preserve">
<source>Start template</source>
</trans-unit>
<trans-unit id="formManager.cancel" resname="formManager.cancel" xml:space="preserve">
<source>Cancel</source>
</trans-unit>
<trans-unit id="formManager.remove_form" resname="formManager.remove_form" xml:space="preserve">
<source>Remove</source>
</trans-unit>
<trans-unit id="formManager.remove_form_title" resname="formManager.remove_form_title" xml:space="preserve">
<source>Remove form</source>
</trans-unit>
<trans-unit id="formManager.remove_form_message" resname="formManager.remove_form_message" xml:space="preserve">
<source>Are you sure that you want to remove this form?</source>
</trans-unit>
<trans-unit id="formManager.newFormWizard.step1.title" resname="formManager.newFormWizard.step1.title" xml:space="preserve">
<source>Create new form</source>
</trans-unit>
<trans-unit id="formManager.newFormWizard.step1.noStorages" resname="formManager.newFormWizard.step1.noStorages" xml:space="preserve">
<source>No accessible form storage folders</source>
</trans-unit>
<trans-unit id="formManager.newFormWizard.step1.advanced" resname="formManager.newFormWizard.step1.advanced" xml:space="preserve">
<source>Advanced settings</source>
</trans-unit>
<trans-unit id="formManager.newFormWizard.step2.title" resname="formManager.newFormWizard.step2.title" xml:space="preserve">
<source>Advanced settings</source>
</trans-unit>
<trans-unit id="formManager.newFormWizard.step3.title" resname="formManager.newFormWizard.step3.title" xml:space="preserve">
<source>Ready</source>
</trans-unit>
<trans-unit id="formManager.newFormWizard.step3.message" resname="formManager.newFormWizard.step3.message" xml:space="preserve">
<source>Now you are ready to create your new form.</source>
</trans-unit>
<trans-unit id="formManager.newFormWizard.step4.errorTitle" resname="formManager.newFormWizard.step4.errorTitle" xml:space="preserve">
<source>Create</source>
</trans-unit>
<trans-unit id="formManager.newFormWizard.step4.errorMessage" resname="formManager.newFormWizard.step4.errorMessage" xml:space="preserve">
<source>The form could not be saved</source>
</trans-unit>
<trans-unit id="formManager.duplicateFormWizard.step1.title" resname="formManager.duplicateFormWizard.step1.title" xml:space="preserve">
<source>Duplicate form "{0}"</source>
</trans-unit>
<trans-unit id="formManager.duplicateFormWizard.step2.errorTitle" resname="formManager.duplicateFormWizard.step2.errorTitle" xml:space="preserve">
<source>Duplicate</source>
</trans-unit>
<trans-unit id="formManager.duplicateFormWizard.step2.errorMessage" resname="formManager.duplicateFormWizard.step2.errorMessage" xml:space="preserve">
<source>The form could not be saved</source>
</trans-unit>
<trans-unit id="formManager.no_references" resname="formManager.no_references" xml:space="preserve">
<source>There are no references yet</source>
</trans-unit>
<trans-unit id="formManager.page" resname="formManager.page" xml:space="preserve">
<source>Page</source>
</trans-unit>
<trans-unit id="formManager.record" resname="formManager.record" xml:space="preserve">
<source>Record</source>
</trans-unit>
<trans-unit id="formManager.references.title" resname="formManager.references.title" xml:space="preserve">
<source>References</source>
</trans-unit>
<trans-unit id="formManager.references.headline" resname="formManager.references.headline" xml:space="preserve">
<source>References for "{0}"</source>
</trans-unit>
</body>
</file>
</xliff>
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<xliff version="1.0" xmlns:t3="http://typo3.org/schemas/xliff">
<file t3:id="1465049996" source-language="en" datatype="plaintext" original="EXT:form/Resources/Private/Language/locallang_module.xlf" date="2016-06-04T20:22:33Z" product-name="form">
<header/>
<body>
<trans-unit id="mlang_labels_tablabel" resname="mlang_labels_tablabel">
<source>Build custom forms</source>
</trans-unit>
<trans-unit id="mlang_labels_tabdescr" resname="mlang_labels_tabdescr">
<source>This module ships a flexible and user-friendly form editor. It allows you to build and create versatile forms for your frontend. Your forms can easily be added to any page by using the content element "Form". Within this element, finishers can be overridden.</source>
</trans-unit>
<trans-unit id="mlang_tabs_tab" resname="mlang_tabs_tab">
<source>Forms</source>
</trans-unit>
</body>
</file>
</xliff>
@@ -0,0 +1,13 @@
/*!
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/
body{overflow-y:scroll}.t3-form-x-component{position:absolute;top:0;height:100%;line-height:normal;background:#f5f5f5}.t3-form-x-component a{text-decoration:none}.t3-form-x-component ol,.t3-form-x-component ul:not(.dropdown-menu){list-style:none;padding:0}.t3-form-x-component .ui-sortable-placeholder{outline-offset:-1px!important}.t3-form-x-component-inner-wrapper{position:relative;padding:1.5em}#t3-form-navigation-component{overflow:hidden;left:0}#t3-form-structure-panel{overflow:auto;padding-top:65px;height:100%}#t3-form-structure-panel .icon{z-index:1}#t3-form-structure-panel #t3-form-navigation-component-tree-root-container,#t3-form-structure-panel .tree li>div{border:1px solid transparent;cursor:pointer}#t3-form-structure-panel .tree .svg-wrapper svg{overflow:visible;position:relative;top:-.8em;left:.6em}#t3-form-structure-panel .tree .svg-wrapper path{fill:none;shape-rendering:crispEdges;stroke:#ddd;stroke-width:1}#t3-form-structure-panel .tree li{white-space:nowrap}#t3-form-structure-panel .tree li .icon-actions-pagetree-collapse{margin-right:.3em}#t3-form-structure-panel .tree li .icon-actions-pagetree-collapse img{-webkit-transform:rotate(90deg);transform:rotate(90deg);-webkit-transition:-webkit-transform .2s;transition:-webkit-transform .2s;transition:transform .2s;transition:transform .2s,-webkit-transform .2s}#t3-form-structure-panel .tree li.mjs-nestedSortable-collapsed>ol{display:none}#t3-form-structure-panel .tree li.mjs-nestedSortable-collapsed .icon-actions-pagetree-collapse img{-webkit-transform:rotate(0);transform:rotate(0);-webkit-transition:-webkit-transform .2s;transition:-webkit-transform .2s;transition:transform .2s;transition:transform .2s,-webkit-transform .2s}#t3-form-structure-panel .tree li small{padding-left:.5em;font-size:80%}#t3-form-structure-panel .tree .t3-form-icon{margin-right:.5em;margin-left:.5em}#t3-form-structure-panel .tree .t3-form-element-has-children>div .t3-form-icon{margin-left:.1em}#t3-form-structure-panel .tree .sortable-hover{outline:1px solid #aaa}#t3-form-structure-panel .icon{margin-top:1px}#t3-form-structure-panel #t3-form-navigation-component-tree-root-container,#t3-form-structure-panel .tree li>div{height:20px}#t3-form-structure-panel #t3-form-navigation-component-tree-root-container>span,#t3-form-structure-panel .tree li>div>span{display:inline-block;vertical-align:top;line-height:20px}#t3-form-structure-panel #t3-form-navigation-component-tree-root{width:90%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}#t3-form-structure-panel #t3-form-navigation-component-tree-root-container:hover,#t3-form-structure-panel .t3-form-form-element-selected,#t3-form-structure-panel .t3-form-root-element-selected,#t3-form-structure-panel .tree li>div:hover{background-color:#f2f2f2;border-color:#dcdbdb;border-radius:2px;margin-left:-20px;padding-left:20px;margin-right:-1.3em}#t3-form-structure-panel #t3-form-navigation-component-tree-root-container.t3-form-root-element-selected,#t3-form-structure-panel #t3-form-navigation-component-tree-root-container.t3-form-root-element-selected:hover,#t3-form-structure-panel .tree li>.t3-form-form-element-selected,#t3-form-structure-panel .tree li>.t3-form-form-element-selected:hover{background-color:#fff;border-color:#dcdbdb}#t3-form-structure-panel .t3-form-x-component-inner-wrapper{padding-top:2.5em}#t3-form-structure-panel .ui-sortable-helper #t3-form-navigation-component-tree-root-container:hover,#t3-form-structure-panel .ui-sortable-helper .t3-form-form-element-selected,#t3-form-structure-panel .ui-sortable-helper .t3-form-root-element-selected,#t3-form-structure-panel .ui-sortable-helper>div:hover{background-color:transparent!important;border-color:transparent!important}#t3-form-structure-panel .ui-sortable-helper svg{opacity:0}#t3-form-structure-panel .mjs-nestedSortable-branch span[data-identifier=treeExpander]{margin-left:-1.7em}#t3-form-structure-panel .mjs-nestedSortable-leaf span.t3-form-icon{margin-left:initial}.form-group.t3-form-collection-element-remove-button,.form-group.t3-form-inspector-validators-editor-removeButton,.t3-form-inspector-finishers-editor-removeButton{margin:0!important;font-size:0}#t3-form-inspector-panels-container{overflow:hidden;right:0;padding-top:65px}#t3-form-inspector-panels{overflow:auto;height:100%}#t3-form-inspector{padding:1em .5em}#t3-form-inspector h2,#t3-form-inspector h3,#t3-form-inspector h4{margin:0;padding:.1em .2em .2em .5em;border-top:1px solid #c3c3c3;clear:both;font:inherit;font-weight:700}#t3-form-inspector h2{padding-bottom:1em;border:none;border-bottom:1px solid #c3c3c3}#t3-form-inspector>h2:first-child{border-top:none}#t3-form-inspector h3{color:#000;padding-top:.3em;border:none}#t3-form-inspector h4{padding:.8em 3em .8em 4em;font-weight:500;background-color:#ddd}#t3-form-inspector h4 span[data-template-property=label]{vertical-align:top}#t3-form-inspector .icon-size-small{line-height:1.5}#t3-form-inspector .input-group-btn{position:static}#t3-form-inspector .t3-Line truncated
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><path fill="#3B7EB0" d="M0 0h64v64H0z"/><path fill="#FFF" d="M14 14h32v36H14z"/><path fill="#3B7EB0" d="M22 42h8v4h-8z"/><path opacity=".5" fill="#3B7EB0" d="M32 42h8v4h-8z"/><path fill="#3B7EB0" d="M22 18h14v2H22zM22 32h2v2h-2zM22 36h2v2h-2z"/><path opacity=".5" fill="#3B7EB0" d="M26 32h16v2H26zM26 36h16v2H26zM22 22h20v8H22z"/><path fill="#3B7EB0" d="M14 14h4v4h-4z"/><path opacity=".5" fill="#3B7EB0" d="M16 14h2v36h-2z"/></svg>

After

Width:  |  Height:  |  Size: 492 B

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><path fill="#3B7EB0" d="M0 0h64v64H0z"/><path fill="#FFF" d="M14 14h32v36H14z"/><path fill="#3B7EB0" d="M22 42h8v4h-8z"/><path opacity=".5" fill="#3B7EB0" d="M32 42h8v4h-8z"/><path fill="#3B7EB0" d="M22 18h14v2H22zM22 32h2v2h-2zM22 36h2v2h-2z"/><path opacity=".5" fill="#3B7EB0" d="M26 32h16v2H26zM26 36h16v2H26zM22 22h20v8H22z"/><path fill="#3B7EB0" d="M14 14h4v4h-4z"/><path opacity=".5" fill="#3B7EB0" d="M16 14h2v36h-2z"/></svg>

After

Width:  |  Height:  |  Size: 492 B

@@ -0,0 +1,911 @@
/*
* jQuery UI Nested Sortable
* v 2.1a / 2016-02-04
* https://github.com/ilikenwf/nestedSortable
*
* Depends on:
* jquery.ui.sortable.js 1.10+
*
* Copyright (c) 2010-2016 Manuele J Sarfatti and contributors
* Licensed under the MIT License
* http://www.opensource.org/licenses/mit-license.php
*/
(function(factory) {
"use strict";
if (typeof define === "function" && define.amd) {
// AMD. Register as an anonymous module.
define([
"jquery",
"jquery-ui/sortable"
], factory);
} else {
// Browser globals
factory(window.jQuery);
}
}(function($) {
"use strict";
function isOverAxis(x, reference, size) {
return (x > reference) && (x < (reference + size));
}
$.widget("mjs.nestedSortable", $.extend({}, $.ui.sortable.prototype, {
options: {
disableParentChange: false,
doNotClear: false,
expandOnHover: 700,
isAllowed: function() {
return true;
},
isTree: false,
listType: "ol",
maxLevels: 0,
protectRoot: false,
rootID: null,
rtl: false,
startCollapsed: false,
tabSize: 20,
branchClass: "mjs-nestedSortable-branch",
collapsedClass: "mjs-nestedSortable-collapsed",
disableNestingClass: "mjs-nestedSortable-no-nesting",
errorClass: "mjs-nestedSortable-error",
expandedClass: "mjs-nestedSortable-expanded",
hoveringClass: "mjs-nestedSortable-hovering",
leafClass: "mjs-nestedSortable-leaf",
disabledClass: "mjs-nestedSortable-disabled"
},
_create: function() {
var self = this,
err;
this.element.data("ui-sortable", this.element.data("mjs-nestedSortable"));
// mjs - prevent browser from freezing if the HTML is not correct
if (!this.element.is(this.options.listType)) {
err = "nestedSortable: " +
"Please check that the listType option is set to your actual list type";
throw new Error(err);
}
// if we have a tree with expanding/collapsing functionality,
// force 'intersect' tolerance method
if (this.options.isTree && this.options.expandOnHover) {
this.options.tolerance = "intersect";
}
$.ui.sortable.prototype._create.apply(this, arguments);
// prepare the tree by applying the right classes
// (the CSS is responsible for actual hide/show functionality)
if (this.options.isTree) {
$(this.items).each(function() {
var $li = this.item,
hasCollapsedClass = $li.hasClass(self.options.collapsedClass),
hasExpandedClass = $li.hasClass(self.options.expandedClass);
if ($li.children(self.options.listType).length) {
$li.addClass(self.options.branchClass);
// expand/collapse class only if they have children
if (!hasCollapsedClass && !hasExpandedClass) {
if (self.options.startCollapsed) {
$li.addClass(self.options.collapsedClass);
} else {
$li.addClass(self.options.expandedClass);
}
}
} else {
$li.addClass(self.options.leafClass);
}
});
}
},
_destroy: function() {
this.element
.removeData("mjs-nestedSortable")
.removeData("ui-sortable");
return $.ui.sortable.prototype._destroy.apply(this, arguments);
},
_mouseDrag: function(event) {
var i,
item,
itemElement,
intersection,
self = this,
o = this.options,
scrolled = false,
$document = $(document),
previousTopOffset,
parentItem,
level,
childLevels,
itemAfter,
itemBefore,
newList,
method,
a,
previousItem,
nextItem,
helperIsNotSibling;
//Compute the helpers position
this.position = this._generatePosition(event);
this.positionAbs = this._convertPositionTo("absolute");
if (!this.lastPositionAbs) {
this.lastPositionAbs = this.positionAbs;
}
//Do scrolling
if (this.options.scroll) {
if (this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") {
if (
(
this.overflowOffset.top +
this.scrollParent[0].offsetHeight
) -
event.pageY <
o.scrollSensitivity
) {
scrolled = this.scrollParent.scrollTop() + o.scrollSpeed;
this.scrollParent.scrollTop(scrolled);
} else if (
event.pageY -
this.overflowOffset.top <
o.scrollSensitivity
) {
scrolled = this.scrollParent.scrollTop() - o.scrollSpeed;
this.scrollParent.scrollTop(scrolled);
}
if (
(
this.overflowOffset.left +
this.scrollParent[0].offsetWidth
) -
event.pageX <
o.scrollSensitivity
) {
scrolled = this.scrollParent.scrollLeft() + o.scrollSpeed;
this.scrollParent.scrollLeft(scrolled);
} else if (
event.pageX -
this.overflowOffset.left <
o.scrollSensitivity
) {
scrolled = this.scrollParent.scrollLeft() - o.scrollSpeed;
this.scrollParent.scrollLeft(scrolled);
}
} else {
if (
event.pageY -
$document.scrollTop() <
o.scrollSensitivity
) {
scrolled = $document.scrollTop() - o.scrollSpeed;
$document.scrollTop(scrolled);
} else if (
$(window).height() -
(
event.pageY -
$document.scrollTop()
) <
o.scrollSensitivity
) {
scrolled = $document.scrollTop() + o.scrollSpeed;
$document.scrollTop(scrolled);
}
if (
event.pageX -
$document.scrollLeft() <
o.scrollSensitivity
) {
scrolled = $document.scrollLeft() - o.scrollSpeed;
$document.scrollLeft(scrolled);
} else if (
$(window).width() -
(
event.pageX -
$document.scrollLeft()
) <
o.scrollSensitivity
) {
scrolled = $document.scrollLeft() + o.scrollSpeed;
$document.scrollLeft(scrolled);
}
}
if (scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
$.ui.ddmanager.prepareOffsets(this, event);
}
}
//Regenerate the absolute position used for position checks
this.positionAbs = this._convertPositionTo("absolute");
// mjs - find the top offset before rearrangement,
previousTopOffset = this.placeholder.offset().top;
//Set the helper position
if (!this.options.axis || this.options.axis !== "y") {
this.helper[0].style.left = this.position.left + "px";
}
if (!this.options.axis || this.options.axis !== "x") {
this.helper[0].style.top = (this.position.top) + "px";
}
// mjs - check and reset hovering state at each cycle
this.hovering = this.hovering ? this.hovering : null;
this.mouseentered = this.mouseentered ? this.mouseentered : false;
// mjs - let's start caching some variables
(function() {
var _parentItem = this.placeholder.parent().parent();
if (_parentItem && _parentItem.closest(".ui-sortable").length) {
parentItem = _parentItem;
}
}.call(this));
level = this._getLevel(this.placeholder);
childLevels = this._getChildLevels(this.helper);
newList = document.createElement(o.listType);
//Rearrange
for (i = this.items.length - 1; i >= 0; i--) {
//Cache variables and intersection, continue if no intersection
item = this.items[i];
itemElement = item.item[0];
intersection = this._intersectsWithPointer(item);
if (!intersection) {
continue;
}
// Only put the placeholder inside the current Container, skip all
// items form other containers. This works because when moving
// an item from one container to another the
// currentContainer is switched before the placeholder is moved.
//
// Without this moving items in "sub-sortables" can cause the placeholder to jitter
// beetween the outer and inner container.
if (item.instance !== this.currentContainer) {
continue;
}
// No action if intersected item is disabled
// and the element above or below in the direction we're going is also disabled
if (itemElement.className.indexOf(o.disabledClass) !== -1) {
// Note: intersection hardcoded direction values from
// jquery.ui.sortable.js:_intersectsWithPointer
if (intersection === 2) {
// Going down
itemAfter = this.items[i + 1];
if (itemAfter && itemAfter.item.hasClass(o.disabledClass)) {
continue;
}
} else if (intersection === 1) {
// Going up
itemBefore = this.items[i - 1];
if (itemBefore && itemBefore.item.hasClass(o.disabledClass)) {
continue;
}
}
}
method = intersection === 1 ? "next" : "prev";
// cannot intersect with itself
// no useless actions that have been done before
// no action if the item moved is the parent of the item checked
if (itemElement !== this.currentItem[0] &&
this.placeholder[method]()[0] !== itemElement &&
!$.contains(this.placeholder[0], itemElement) &&
(
this.options.type === "semi-dynamic" ?
!$.contains(this.element[0], itemElement) :
true
)
) {
// mjs - we are intersecting an element:
// trigger the mouseenter event and store this state
if (!this.mouseentered) {
$(itemElement).mouseenter();
this.mouseentered = true;
}
// mjs - if the element has children and they are hidden,
// show them after a delay (CSS responsible)
if (o.isTree && $(itemElement).hasClass(o.collapsedClass) && o.expandOnHover) {
if (!this.hovering) {
$(itemElement).addClass(o.hoveringClass);
this.hovering = window.setTimeout(function() {
$(itemElement)
.removeClass(o.collapsedClass)
.addClass(o.expandedClass);
self.refreshPositions();
self._trigger("expand", event, self._uiHash());
}, o.expandOnHover);
}
}
this.direction = intersection === 1 ? "down" : "up";
// mjs - rearrange the elements and reset timeouts and hovering state
if (this.options.tolerance === "pointer" || this._intersectsWithSides(item)) {
$(itemElement).mouseleave();
this.mouseentered = false;
$(itemElement).removeClass(o.hoveringClass);
if (this.hovering) {
window.clearTimeout(this.hovering);
}
this.hovering = null;
// mjs - do not switch container if
// it's a root item and 'protectRoot' is true
// or if it's not a root item but we are trying to make it root
if (o.protectRoot &&
!(
this.currentItem[0].parentNode === this.element[0] &&
// it's a root item
itemElement.parentNode !== this.element[0]
// it's intersecting a non-root item
)
) {
if (this.currentItem[0].parentNode !== this.element[0] &&
itemElement.parentNode === this.element[0]
) {
if (!$(itemElement).children(o.listType).length) {
itemElement.appendChild(newList);
if (o.isTree) {
$(itemElement)
.removeClass(o.leafClass)
.addClass(o.branchClass + " " + o.expandedClass);
}
}
if (this.direction === "down") {
a = $(itemElement).prev().children(o.listType);
} else {
a = $(itemElement).children(o.listType);
}
if (a[0] !== undefined) {
this._rearrange(event, null, a);
}
} else {
this._rearrange(event, item);
}
} else if (!o.protectRoot) {
this._rearrange(event, item);
}
} else {
break;
}
// Clear emtpy ul's/ol's
this._clearEmpty(itemElement);
this._trigger("change", event, this._uiHash());
break;
}
}
// mjs - to find the previous sibling in the list,
// keep backtracking until we hit a valid list item.
(function() {
var _previousItem = this.placeholder.prev();
if (_previousItem.length) {
previousItem = _previousItem;
} else {
previousItem = null;
}
}.call(this));
if (previousItem != null) {
while (
previousItem[0].nodeName.toLowerCase() !== "li" ||
previousItem[0].className.indexOf(o.disabledClass) !== -1 ||
previousItem[0] === this.currentItem[0] ||
previousItem[0] === this.helper[0]
) {
if (previousItem[0].previousSibling) {
previousItem = $(previousItem[0].previousSibling);
} else {
previousItem = null;
break;
}
}
}
// mjs - to find the next sibling in the list,
// keep stepping forward until we hit a valid list item.
(function() {
var _nextItem = this.placeholder.next();
if (_nextItem.length) {
nextItem = _nextItem;
} else {
nextItem = null;
}
}.call(this));
if (nextItem != null) {
while (
nextItem[0].nodeName.toLowerCase() !== "li" ||
nextItem[0].className.indexOf(o.disabledClass) !== -1 ||
nextItem[0] === this.currentItem[0] ||
nextItem[0] === this.helper[0]
) {
if (nextItem[0].nextSibling) {
nextItem = $(nextItem[0].nextSibling);
} else {
nextItem = null;
break;
}
}
}
this.beyondMaxLevels = 0;
// mjs - if the item is moved to the left, send it one level up
// but only if it's at the bottom of the list
if (parentItem != null &&
nextItem == null &&
!(o.protectRoot && parentItem[0].parentNode == this.element[0]) &&
(
o.rtl &&
(
this.positionAbs.left +
this.helper.outerWidth() > parentItem.offset().left +
parentItem.outerWidth()
) ||
!o.rtl && (this.positionAbs.left < parentItem.offset().left)
)
) {
parentItem.after(this.placeholder[0]);
helperIsNotSibling = !parentItem
.children(o.listItem)
.children("li:visible:not(.ui-sortable-helper)")
.length;
if (o.isTree && helperIsNotSibling) {
parentItem
.removeClass(this.options.branchClass + " " + this.options.expandedClass)
.addClass(this.options.leafClass);
}
if (typeof parentItem !== 'undefined')
this._clearEmpty(parentItem[0]);
this._trigger("change", event, this._uiHash());
// mjs - if the item is below a sibling and is moved to the right,
// make it a child of that sibling
} else if (previousItem != null &&
!previousItem.hasClass(o.disableNestingClass) &&
(
previousItem.children(o.listType).length &&
previousItem.children(o.listType).is(":visible") ||
!previousItem.children(o.listType).length
) &&
!(o.protectRoot && this.currentItem[0].parentNode === this.element[0]) &&
(
o.rtl &&
(
this.positionAbs.left +
this.helper.outerWidth() <
previousItem.offset().left +
previousItem.outerWidth() -
o.tabSize
) ||
!o.rtl &&
(this.positionAbs.left > previousItem.offset().left + o.tabSize)
)
) {
this._isAllowed(previousItem, level, level + childLevels + 1);
if (!previousItem.children(o.listType).length) {
previousItem[0].appendChild(newList);
if (o.isTree) {
previousItem
.removeClass(o.leafClass)
.addClass(o.branchClass + " " + o.expandedClass);
}
}
// mjs - if this item is being moved from the top, add it to the top of the list.
if (previousTopOffset && (previousTopOffset <= previousItem.offset().top)) {
previousItem.children(o.listType).prepend(this.placeholder);
} else {
// mjs - otherwise, add it to the bottom of the list.
previousItem.children(o.listType)[0].appendChild(this.placeholder[0]);
}
if (typeof parentItem !== 'undefined')
this._clearEmpty(parentItem[0]);
this._trigger("change", event, this._uiHash());
} else {
this._isAllowed(parentItem, level, level + childLevels);
}
//Post events to containers
this._contactContainers(event);
//Interconnect with droppables
if ($.ui.ddmanager) {
$.ui.ddmanager.drag(this, event);
}
//Call callbacks
this._trigger("sort", event, this._uiHash());
this.lastPositionAbs = this.positionAbs;
return false;
},
_mouseStop: function(event) {
// mjs - if the item is in a position not allowed, send it back
if (this.beyondMaxLevels) {
this.placeholder.removeClass(this.options.errorClass);
if (this.domPosition.prev) {
$(this.domPosition.prev).after(this.placeholder);
} else {
$(this.domPosition.parent).prepend(this.placeholder);
}
this._trigger("revert", event, this._uiHash());
}
// mjs - clear the hovering timeout, just to be sure
$("." + this.options.hoveringClass)
.mouseleave()
.removeClass(this.options.hoveringClass);
this.mouseentered = false;
if (this.hovering) {
window.clearTimeout(this.hovering);
}
this.hovering = null;
this._relocate_event = event;
this._pid_current = $(this.domPosition.parent).parent().attr("id");
this._sort_current = this.domPosition.prev ? $(this.domPosition.prev).next().index() : 0;
$.ui.sortable.prototype._mouseStop.apply(this, arguments); //asybnchronous execution, @see _clear for the relocate event.
},
// mjs - this function is slightly modified
// to make it easier to hover over a collapsed element and have it expand
_intersectsWithSides: function(item) {
var half = this.options.isTree ? .8 : .5,
isOverBottomHalf = isOverAxis(
this.positionAbs.top + this.offset.click.top,
item.top + (item.height * half),
item.height
),
isOverTopHalf = isOverAxis(
this.positionAbs.top + this.offset.click.top,
item.top - (item.height * half),
item.height
),
isOverRightHalf = isOverAxis(
this.positionAbs.left + this.offset.click.left,
item.left + (item.width / 2),
item.width
),
verticalDirection = this._getDragVerticalDirection(),
horizontalDirection = this._getDragHorizontalDirection();
if (this.floating && horizontalDirection) {
return (
(horizontalDirection === "right" && isOverRightHalf) ||
(horizontalDirection === "left" && !isOverRightHalf)
);
} else {
return verticalDirection && (
(verticalDirection === "down" && isOverBottomHalf) ||
(verticalDirection === "up" && isOverTopHalf)
);
}
},
_contactContainers: function() {
if (this.options.protectRoot && this.currentItem[0].parentNode === this.element[0]) {
return;
}
$.ui.sortable.prototype._contactContainers.apply(this, arguments);
},
_clear: function() {
var i,
item;
$.ui.sortable.prototype._clear.apply(this, arguments);
//relocate event
if (!(this._pid_current === this._uiHash().item.parent().parent().attr("id") &&
this._sort_current === this._uiHash().item.index())) {
this._trigger("relocate", this._relocate_event, this._uiHash());
}
// mjs - clean last empty ul/ol
for (i = this.items.length - 1; i >= 0; i--) {
item = this.items[i].item[0];
this._clearEmpty(item);
}
},
serialize: function(options) {
var o = $.extend({}, this.options, options),
items = this._getItemsAsjQuery(o && o.connected),
str = [];
$(items).each(function() {
var res = ($(o.item || this).attr(o.attribute || "id") || "")
.match(o.expression || (/(.+)[-=_](.+)/)),
pid = ($(o.item || this).parent(o.listType)
.parent(o.items)
.attr(o.attribute || "id") || "")
.match(o.expression || (/(.+)[-=_](.+)/));
if (res) {
str.push(
(
(o.key || res[1]) +
"[" +
(o.key && o.expression ? res[1] : res[2]) + "]"
) +
"=" +
(pid ? (o.key && o.expression ? pid[1] : pid[2]) : o.rootID));
}
});
if (!str.length && o.key) {
str.push(o.key + "=");
}
return str.join("&");
},
toHierarchy: function(options) {
var o = $.extend({}, this.options, options),
ret = [];
$(this.element).children(o.items).each(function() {
var level = _recursiveItems(this);
ret.push(level);
});
return ret;
function _recursiveItems(item) {
var id = ($(item).attr(o.attribute || "id") || "").match(o.expression || (/(.+)[-=_](.+)/)),
currentItem;
var data = $(item).data();
if (data.nestedSortableItem) {
delete data.nestedSortableItem; // Remove the nestedSortableItem object from the data
}
if (id) {
currentItem = {
"id": id[2]
};
currentItem = $.extend({}, currentItem, data); // Combine the two objects
if ($(item).children(o.listType).children(o.items).length > 0) {
currentItem.children = [];
$(item).children(o.listType).children(o.items).each(function() {
var level = _recursiveItems(this);
currentItem.children.push(level);
});
}
return currentItem;
}
}
},
toArray: function(options) {
var o = $.extend({}, this.options, options),
sDepth = o.startDepthCount || 0,
ret = [],
left = 1;
if (!o.excludeRoot) {
ret.push({
"item_id": o.rootID,
"parent_id": null,
"depth": sDepth,
"left": left,
"right": ($(o.items, this.element).length + 1) * 2
});
left++;
}
$(this.element).children(o.items).each(function() {
left = _recursiveArray(this, sDepth, left);
});
ret = ret.sort(function(a, b) {
return (a.left - b.left);
});
return ret;
function _recursiveArray(item, depth, _left) {
var right = _left + 1,
id,
pid,
parentItem;
if ($(item).children(o.listType).children(o.items).length > 0) {
depth++;
$(item).children(o.listType).children(o.items).each(function() {
right = _recursiveArray($(this), depth, right);
});
depth--;
}
id = ($(item).attr(o.attribute || "id") || "").match(o.expression || (/(.+)[-=_](.+)/));
if (depth === sDepth) {
pid = o.rootID;
} else {
parentItem = ($(item).parent(o.listType)
.parent(o.items)
.attr(o.attribute || "id"))
.match(o.expression || (/(.+)[-=_](.+)/));
pid = parentItem[2];
}
if (id) {
var data = $(item).children('div').data();
var itemObj = $.extend(data, {
"id": id[2],
"parent_id": pid,
"depth": depth,
"left": _left,
"right": right
});
ret.push(itemObj);
}
_left = right + 1;
return _left;
}
},
_clearEmpty: function(item) {
function replaceClass(elem, search, replace, swap) {
if (swap) {
search = [replace, replace = search][0];
}
$(elem).removeClass(search).addClass(replace);
}
var o = this.options,
childrenList = $(item).children(o.listType),
hasChildren = childrenList.has('li').length;
var doNotClear =
o.doNotClear ||
hasChildren ||
o.protectRoot && $(item)[0] === this.element[0];
if (o.isTree) {
replaceClass(item, o.branchClass, o.leafClass, doNotClear);
}
if (!doNotClear) {
childrenList.parent().removeClass(o.expandedClass);
childrenList.remove();
}
},
_getLevel: function(item) {
var level = 1,
list;
if (this.options.listType) {
list = item.closest(this.options.listType);
while (list && list.length > 0 && !list.is(".ui-sortable")) {
level++;
list = list.parent().closest(this.options.listType);
}
}
return level;
},
_getChildLevels: function(parent, depth) {
var self = this,
o = this.options,
result = 0;
depth = depth || 0;
$(parent).children(o.listType).children(o.items).each(function(index, child) {
result = Math.max(self._getChildLevels(child, depth + 1), result);
});
return depth ? result + 1 : result;
},
_isAllowed: function(parentItem, level, levels) {
var o = this.options,
// this takes into account the maxLevels set to the recipient list
maxLevels = this
.placeholder
.closest(".ui-sortable")
.nestedSortable("option", "maxLevels"),
// Check if the parent has changed to prevent it, when o.disableParentChange is true
oldParent = this.currentItem.parent().parent(),
disabledByParentchange = o.disableParentChange && (
//From somewhere to somewhere else, except the root
typeof parentItem !== 'undefined' && !oldParent.is(parentItem) ||
typeof parentItem === 'undefined' && oldParent.is("li") //From somewhere to the root
);
// mjs - is the root protected?
// mjs - are we nesting too deep?
if (
disabledByParentchange ||
!o.isAllowed(this.placeholder, parentItem, this.currentItem)
) {
this.placeholder.addClass(o.errorClass);
if (maxLevels < levels && maxLevels !== 0) {
this.beyondMaxLevels = levels - maxLevels;
} else {
this.beyondMaxLevels = 1;
}
} else {
if (maxLevels < levels && maxLevels !== 0) {
this.placeholder.addClass(o.errorClass);
this.beyondMaxLevels = levels - maxLevels;
} else {
this.placeholder.removeClass(o.errorClass);
this.beyondMaxLevels = 0;
}
}
}
}));
$.mjs.nestedSortable.prototype.options = $.extend(
{},
$.ui.sortable.prototype.options,
$.mjs.nestedSortable.prototype.options
);
}));
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,314 @@
/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/
/**
* Module: TYPO3/CMS/Form/Backend/FormEditor/Helper
*/
define(['jquery'], function($) {
'use strict';
return (function($) {
/**
* @private
*
* @var object
*/
var _formEditorApp = null;
/**
* @private
*
* @var object
*/
var _configuration = {};
/**
* @private
*
* @var object
*/
var _defaultConfiguration = {
domElementClassNames: {
active: 'active',
buttonCollectionElementRemove: 't3-form-collection-element-remove-button',
buttonFormEditor: 't3-form-button',
disabled: 'disabled',
hidden: 'hidden',
icon: 't3-form-icon',
jQueryUiStateDisabled: 'ui-state-disabled',
sortableHover: 'sortable-hover'
},
domElementDataAttributeNames: {
elementIdentifier: 'data-element-identifier-path',
identifier: 'data-identifier',
template: 'data-template-name',
templateProperty: 'data-template-property'
},
domElementSelectorPattern: {
bracesWithKey: '[{0}]',
bracesWithKeyValue: '[{0}="{1}"]',
class: '.{0}',
id: '#{0}',
keyValue: '{0}="{1}"'
}
};
/* *************************************************************
* Private Methodes
* ************************************************************/
/**
* @private
*
* @return object
*/
function getFormEditorApp() {
return _formEditorApp;
};
/**
* @private
*
* @return object
*/
function getUtility() {
return getFormEditorApp().getUtility();
};
/**
* @private
*
* @param mixed test
* @param string message
* @param int messageCode
* @return void
*/
function assert(test, message, messageCode) {
return getFormEditorApp().assert(test, message, messageCode);
};
/* *************************************************************
* Public Methodes
* ************************************************************/
/**
* @public
*
* @param object
* @return this
* @throws 1478950623
*/
function setConfiguration(configuration) {
assert('object' === $.type(configuration), 'Invalid parameter "configuration"', 1478950623);
_configuration = $.extend(true, _defaultConfiguration, configuration);
return this;
};
/**
* @public
*
* @param string
* @param array
* @return string
* @throws 1478801251
* @throws 1478801252
*/
function buildDomElementSelectorHelper(patternIdentifier, replacements) {
var newString;
assert(
!getUtility().isUndefinedOrNull(_configuration['domElementSelectorPattern'][patternIdentifier]),
'Invalid parameter "patternIdentifier" (' + patternIdentifier + ')',
1478801251
);
assert('array' === $.type(replacements), 'Invalid parameter "replacements"', 1478801252);
newString = _configuration['domElementSelectorPattern'][patternIdentifier];
for (var i = 0, len = replacements.length; i < len; ++i) {
newString = newString.replace('{' + i + '}', replacements[i]);
}
return newString;
};
/**
* @public
*
* @param string
* @param array
* @return string
* @throws 1478372374
*/
function getDomElementSelector(selectorIdentifier, args) {
assert(
!getUtility().isUndefinedOrNull(_configuration['domElementSelectorPattern'][selectorIdentifier]),
'Invalid parameter "selectorIdentifier" (' + selectorIdentifier + ')',
1478372374
);
return buildDomElementSelectorHelper(selectorIdentifier, args);
};
/**
* @public
*
* @param string
* @param bool
* @return string
* @throws 1478803906
*/
function getDomElementClassName(classNameIdentifier, asSelector) {
var className;
assert(
!getUtility().isUndefinedOrNull(_configuration['domElementClassNames'][classNameIdentifier]),
'Invalid parameter "classNameIdentifier" (' + classNameIdentifier + ')',
1478803906
);
className = _configuration['domElementClassNames'][classNameIdentifier];
if (!!asSelector) {
className = getDomElementSelector('class', [className]);
}
return className;
};
/**
* @public
*
* @param string
* @param bool
* @return string
* @throws 1479251518
*/
function getDomElementIdName(idNameIdentifier, asSelector) {
var idName;
assert(
!getUtility().isUndefinedOrNull(_configuration['domElementIdNames'][idNameIdentifier]),
'Invalid parameter "domElementIdNames" (' + idNameIdentifier + ')',
1479251518
);
idName = _configuration['domElementIdNames'][idNameIdentifier];
if (!!asSelector) {
idName = getDomElementSelector('id', [idName]);
}
return idName;
};
/**
* @public
*
* @param string
* @param bool
* @return string
* @throws 1478806884
*/
function getDomElementDataAttributeValue(dataAttributeValueIdentifier) {
assert(
!getUtility().isUndefinedOrNull(_configuration['domElementDataAttributeValues'][dataAttributeValueIdentifier]),
'Invalid parameter "dataAttributeValueIdentifier" (' + dataAttributeValueIdentifier + ')',
1478806884
);
return _configuration['domElementDataAttributeValues'][dataAttributeValueIdentifier];
};
/**
* @public
*
* @param string
* @param string
* @param array
* @return string
* @throws 1478808035
*/
function getDomElementDataAttribute(dataAttributeIdentifier, selectorIdentifier, additionalSelectorArgs) {
assert(
!getUtility().isUndefinedOrNull(_configuration['domElementDataAttributeNames'][dataAttributeIdentifier]),
'Invalid parameter "dataAttributeIdentifier" (' + dataAttributeIdentifier + ')',
1478808035
);
if (getUtility().isUndefinedOrNull(selectorIdentifier)) {
return _configuration['domElementDataAttributeNames'][dataAttributeIdentifier];
}
additionalSelectorArgs = additionalSelectorArgs || [];
return getDomElementSelector(
selectorIdentifier,
[_configuration['domElementDataAttributeNames'][dataAttributeIdentifier]].concat(additionalSelectorArgs)
);
};
/**
* @public
*
* Return a string like [data-identifier="someValue"]
*
* @return string
*/
function getDomElementDataIdentifierSelector(dataAttributeValueIdentifier) {
return getDomElementDataAttribute('identifier', 'bracesWithKeyValue', [getDomElementDataAttributeValue(dataAttributeValueIdentifier)]);
};
/**
* @public
*
* @param string
* @return object
*/
function getTemplate(templateName) {
if (!getUtility().isUndefinedOrNull(_configuration['domElementDataAttributeValues'][templateName])) {
templateName = getDomElementDataAttributeValue(templateName);
}
return $(getDomElementDataAttribute('template', 'bracesWithKeyValue', [templateName]));
};
/**
* @public
*
* @param string
* @param object
* @return object
*/
function getTemplatePropertyDomElement(templatePropertyName, templateDomElement) {
return $(getDomElementDataAttribute('templateProperty', 'bracesWithKeyValue', [templatePropertyName]), $(templateDomElement));
};
/**
* @public
*
* @param object formEditorApp
* @return void
*/
function bootstrap(formEditorApp) {
_formEditorApp = formEditorApp;
};
/**
* Publish the public methods.
* Implements the "Revealing Module Pattern".
*/
return {
bootstrap: bootstrap,
buildDomElementSelectorHelper: buildDomElementSelectorHelper,
getDomElementClassName: getDomElementClassName,
getDomElementIdName: getDomElementIdName,
getDomElementDataAttribute: getDomElementDataAttribute,
getDomElementDataAttributeValue: getDomElementDataAttributeValue,
getDomElementDataIdentifierSelector: getDomElementDataIdentifierSelector,
getDomElementSelector: getDomElementSelector,
getTemplate: getTemplate,
getTemplatePropertyDomElement: getTemplatePropertyDomElement,
setConfiguration: setConfiguration
};
})($);
});
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,538 @@
/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/
/**
* Module: TYPO3/CMS/Form/Backend/FormEditor/ModalsComponent
*/
define(['jquery',
'TYPO3/CMS/Form/Backend/FormEditor/Helper',
'TYPO3/CMS/Backend/Modal',
'TYPO3/CMS/Backend/Severity',
'TYPO3/CMS/Backend/Icons'
], function($, Helper, Modal, Severity, Icons) {
'use strict';
return (function($, Helper, Modal, Severity, Icons) {
/**
* @private
*
* @var object
*/
var _configuration = null;
/**
* @private
*
* @var object
*/
var _defaultConfiguration = {
domElementClassNames: {
buttonDefault: 'btn-default',
buttonInfo: 'btn-info',
buttonWarning: 'btn-warning'
},
domElementDataAttributeNames: {
elementType: 'element-type',
fullElementType: 'data-element-type'
},
domElementDataAttributeValues: {
rowItem: 'rowItem',
rowLink: 'rowLink',
rowsContainer: 'rowsContainer',
templateInsertElements: 'Modal-InsertElements',
templateInsertPages: 'Modal-InsertPages',
templateValidationErrors: 'Modal-ValidationErrors'
}
};
/**
* @private
*
* @var object
*/
var _formEditorApp = null;
/* *************************************************************
* Private Methodes
* ************************************************************/
/**
* @private
*
* @return void
* @throws 1478268638
*/
function _helperSetup() {
assert('function' === $.type(Helper.bootstrap),
'The view model helper does not implement the method "bootstrap"',
1478268638
);
Helper.bootstrap(getFormEditorApp());
};
/**
* @private
*
* @return object
*/
function getFormEditorApp() {
return _formEditorApp;
};
/**
* @public
*
* @param object
* @return object
*/
function getHelper(configuration) {
if (getUtility().isUndefinedOrNull(configuration)) {
return Helper.setConfiguration(_configuration);
}
return Helper.setConfiguration(configuration);
};
/**
* @private
*
* @return object
*/
function getUtility() {
return getFormEditorApp().getUtility();
};
/**
* @private
*
* @param mixed test
* @param string message
* @param int messageCode
* @return void
*/
function assert(test, message, messageCode) {
return getFormEditorApp().assert(test, message, messageCode);
};
/**
* @private
*
* @return object
*/
function getRootFormElement() {
return getFormEditorApp().getRootFormElement();
};
/**
* @private
*
* @return object
*/
function getPublisherSubscriber() {
return getFormEditorApp().getPublisherSubscriber();
};
/**
* @private
*
* @param object
* @param string
* @return mixed
*/
function getFormElementDefinition(formElement, formElementDefinitionKey) {
return getFormEditorApp().getFormElementDefinition(formElement, formElementDefinitionKey);
};
/**
* @public
*
* @param string publisherTopicName
* @param object publisherTopicArguments
* @return void
* @throws 1478889044
* @throws 1478889049
*/
function _showRemoveElementModal(publisherTopicName, publisherTopicArguments) {
var modalButtons = [];
assert(
getUtility().isNonEmptyString(publisherTopicName),
'Invalid parameter "publisherTopicName"',
1478889049
);
assert(
'array' === $.type(publisherTopicArguments),
'Invalid parameter "formElement"',
1478889044
);
modalButtons.push({
text: getFormElementDefinition(getRootFormElement(), 'modalRemoveElementCancleButton'),
active: true,
btnClass: getHelper().getDomElementClassName('buttonDefault'),
name: 'cancel',
trigger: function() {
Modal.currentModal.trigger('modal-dismiss');
}
});
modalButtons.push({
text: getFormElementDefinition(getRootFormElement(), 'modalRemoveElementConfirmButton'),
active: true,
btnClass: getHelper().getDomElementClassName('buttonWarning'),
name: 'confirm',
trigger: function() {
getPublisherSubscriber().publish(publisherTopicName, publisherTopicArguments);
Modal.currentModal.trigger('modal-dismiss');
}
});
Modal.show(
getFormElementDefinition(getRootFormElement(), 'modalRemoveElementDialogTitle'),
getFormElementDefinition(getRootFormElement(), 'modalRemoveElementDialogMessage'),
Severity.warning,
modalButtons
);
};
/**
* @private
*
* @param object modalContent
* @param string publisherTopicName
* @param object configuration
* @return void
* @publish mixed
* @throws 1478910954
*/
function _insertElementsModalSetup(modalContent, publisherTopicName, configuration) {
var formElementItems;
assert(
getUtility().isNonEmptyString(publisherTopicName),
'Invalid parameter "publisherTopicName"',
1478910954
);
if ('object' === $.type(configuration)) {
for (var key in configuration) {
if (!configuration.hasOwnProperty(key)) {
continue;
}
if (
key === 'disableElementTypes'
&& 'array' === $.type(configuration[key])
) {
for (var i = 0, len = configuration[key].length; i < len; ++i) {
$(
getHelper().getDomElementDataAttribute(
'fullElementType',
'bracesWithKeyValue', [configuration[key][i]]
),
modalContent
).addClass(getHelper().getDomElementClassName('disabled'));
}
}
if (
key === 'onlyEnableElementTypes'
&& 'array' === $.type(configuration[key])
) {
$(
getHelper().getDomElementDataAttribute(
'fullElementType',
'bracesWithKey'
),
modalContent
).each(function(i, element) {
for (var i = 0, len = configuration[key].length; i < len; ++i) {
var that = $(this);
if (that.data(getHelper().getDomElementDataAttribute('elementType')) !== configuration[key][i]) {
that.addClass(getHelper().getDomElementClassName('disabled'));
}
}
});
}
}
}
$('a', modalContent).on("click", function(e) {
getPublisherSubscriber().publish(publisherTopicName, [$(this).data(getHelper().getDomElementDataAttribute('elementType'))]);
$('a', modalContent).off();
Modal.currentModal.trigger('modal-dismiss');
});
};
/**
* @private
*
* @param object modalContent
* @param object validationResults
* @return void
* @publish view/modal/validationErrors/element/clicked
* @throws 1479161268
*/
function _validationErrorsModalSetup(modalContent, validationResults) {
var formElement, newRowItem, rowItemTemplate;
assert(
'array' === $.type(validationResults),
'Invalid parameter "validationResults"',
1479161268
);
rowItemTemplate = $(
getHelper().getDomElementDataIdentifierSelector('rowItem'),
modalContent
).clone();
$(getHelper().getDomElementDataIdentifierSelector('rowItem'), modalContent).remove();
for (var i = 0, len = validationResults.length; i < len; ++i) {
var hasError = false, validationElement;
for (var j = 0, len2 = validationResults[i]['validationResults'].length; j < len2; ++j) {
if (
validationResults[i]['validationResults'][j]['validationResults']
&& validationResults[i]['validationResults'][j]['validationResults'].length > 0
) {
hasError = true;
break;
}
}
if (hasError) {
formElement = getFormEditorApp()
.getFormElementByIdentifierPath(validationResults[i]['formElementIdentifierPath']);
newRowItem = rowItemTemplate.clone();
$(getHelper().getDomElementDataIdentifierSelector('rowLink'), newRowItem)
.attr(
getHelper().getDomElementDataAttribute('elementIdentifier'),
validationResults[i]['formElementIdentifierPath']
)
.html(_buildTitleByFormElement(formElement));
$(getHelper().getDomElementDataIdentifierSelector('rowsContainer'), modalContent)
.append(newRowItem);
}
}
$('a', modalContent).on("click", function(e) {
getPublisherSubscriber().publish('view/modal/validationErrors/element/clicked', [
$(this).attr(getHelper().getDomElementDataAttribute('elementIdentifier'))
]);
$('a', modalContent).off();
Modal.currentModal.trigger('modal-dismiss');
});
};
/**
* @private
*
* @param object
* @return object
* @throws 1479162557
*/
function _buildTitleByFormElement(formElement) {
var label;
assert('object' === $.type(formElement), 'Invalid parameter "formElement"', 1479162557);
return $('<span></span>').text((formElement.get('label')
? formElement.get('label')
: formElement.get('identifier')));
};
/* *************************************************************
* Public Methodes
* ************************************************************/
/**
* @public
*
* @param object formElement
* @return void
* @publish view/modal/removeFormElement/perform
*/
function showRemoveFormElementModal(formElement) {
_showRemoveElementModal('view/modal/removeFormElement/perform', [formElement]);
};
/**
* @public
*
* @param string collectionElementIdentifier
* @param string collectionName
* @param object formElement
* @return void
* @publish view/modal/removeCollectionElement/perform
* @throws 1478894420
* @throws 1478894421
*/
function showRemoveCollectionElementModal(collectionElementIdentifier, collectionName, formElement) {
assert(
getUtility().isNonEmptyString(collectionElementIdentifier),
'Invalid parameter "collectionElementIdentifier"',
1478894420
);
assert(
getUtility().isNonEmptyString(collectionName),
'Invalid parameter "collectionName"',
1478894421
);
_showRemoveElementModal('view/modal/removeCollectionElement/perform', [collectionElementIdentifier, collectionName, formElement]);
};
/**
* @public
*
* @return void
* @publish view/modal/close/perform
*/
function showCloseConfirmationModal() {
var modalButtons = [];
modalButtons.push({
text: getFormElementDefinition(getRootFormElement(), 'modalCloseCancleButton'),
active: true,
btnClass: getHelper().getDomElementClassName('buttonDefault'),
name: 'cancel',
trigger: function() {
Modal.currentModal.trigger('modal-dismiss');
}
});
modalButtons.push({
text: getFormElementDefinition(getRootFormElement(), 'modalCloseConfirmButton'),
active: true,
btnClass: getHelper().getDomElementClassName('buttonWarning'),
name: 'confirm',
trigger: function() {
getPublisherSubscriber().publish('view/modal/close/perform', []);
Modal.currentModal.trigger('modal-dismiss');
}
});
Modal.show(
getFormElementDefinition(getRootFormElement(), 'modalCloseDialogTitle'),
getFormElementDefinition(getRootFormElement(), 'modalCloseDialogMessage'),
Severity.warning,
modalButtons
);
};
/**
* @public
*
* @param string
* @param object
* @return void
*/
function showInsertElementsModal(publisherTopicName, configuration) {
var html, template;
template = getHelper().getTemplate('templateInsertElements');
if (template.length > 0) {
html = $(template.html());
_insertElementsModalSetup(html, publisherTopicName, configuration);
Modal.show(
getFormElementDefinition(getRootFormElement(), 'modalInsertElementsDialogTitle'),
$(html),
Severity.info
);
}
};
/**
* @public
*
* @param string
* @return void
*/
function showInsertPagesModal(publisherTopicName) {
var html, template;
template = getHelper().getTemplate('templateInsertPages');
if (template.length > 0) {
html = $(template.html());
_insertElementsModalSetup(html, publisherTopicName);
Modal.show(
getFormElementDefinition(getRootFormElement(), 'modalInsertPagesDialogTitle'),
$(html),
Severity.info
);
}
};
/**
* @public
*
* @param object
* @return void
*/
function showValidationErrorsModal(validationResults) {
var html, template, modalButtons = [];
modalButtons.push({
text: getFormElementDefinition(getRootFormElement(), 'modalValidationErrorsConfirmButton'),
active: true,
btnClass: getHelper().getDomElementClassName('buttonDefault'),
name: 'confirm',
trigger: function() {
Modal.currentModal.trigger('modal-dismiss');
}
});
template = getHelper().getTemplate('templateValidationErrors');
if (template.length > 0) {
html = $(template.html()).clone();
_validationErrorsModalSetup(html, validationResults);
Modal.show(
getFormElementDefinition(getRootFormElement(), 'modalValidationErrorsDialogTitle'),
html,
Severity.error,
modalButtons
);
}
}
/**
* @public
*
* @param object
* @param object
* @return this
*/
function bootstrap(formEditorApp, configuration) {
_formEditorApp = formEditorApp;
_configuration = $.extend(true, _defaultConfiguration, configuration || {});
_helperSetup();
return this;
};
/**
* Publish the public methods.
* Implements the "Revealing Module Pattern".
*/
return {
bootstrap: bootstrap,
showCloseConfirmationModal: showCloseConfirmationModal,
showInsertElementsModal: showInsertElementsModal,
showInsertPagesModal: showInsertPagesModal,
showRemoveCollectionElementModal: showRemoveCollectionElementModal,
showRemoveFormElementModal: showRemoveFormElementModal,
showValidationErrorsModal: showValidationErrorsModal
};
})($, Helper, Modal, Severity, Icons);
});
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,691 @@
/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/
/**
* Module: TYPO3/CMS/Form/Backend/FormEditor/TreeComponent
*/
define(['jquery',
'TYPO3/CMS/Form/Backend/FormEditor/Helper',
'TYPO3/CMS/Backend/Icons',
'TYPO3/CMS/Form/Backend/Contrib/jquery.mjs.nestedSortable'
], function($, Helper, Icons) {
'use strict';
return (function($, Helper, Icons) {
/**
* @private
*
* @var object
*/
var _configuration = null;
/**
* @private
*
* @var object
*/
var _expanderStates = {};
/**
* @private
*
* @var object
*/
var _defaultConfiguration = {
domElementClassNames: {
collapsed: 'mjs-nestedSortable-collapsed',
expanded: 'mjs-nestedSortable-expanded',
hasChildren: 't3-form-element-has-children',
sortable: 'sortable',
svgLinkWrapper: 'svg-wrapper',
noNesting: 'mjs-nestedSortable-no-nesting'
},
domElementDataAttributeNames: {
abstractType: 'data-element-abstract-type'
},
domElementDataAttributeValues: {
collapse: 'actions-pagetree-collapse',
expander: 'treeExpander',
title: 'treeTitle'
},
isSortable: true,
svgLink: {
height: 15,
paths: {
angle: 'M0 0 V20 H15',
vertical: 'M0 0 V20 H0',
hidden: 'M0 0 V0 H0'
},
width: 20
}
};
/**
* @private
*
* @var object
*/
var _formEditorApp = null;
/**
* @private
*
* @var object
*/
var _treeDomElement = null;
/* *************************************************************
* Private Methodes
* ************************************************************/
/**
* @private
*
* @return void
* @throws 1478268638
*/
function _helperSetup() {
assert('function' === $.type(Helper.bootstrap),
'The view model helper does not implement the method "bootstrap"',
1478268638
);
Helper.bootstrap(getFormEditorApp());
};
/**
* @private
*
* @return object
*/
function getFormEditorApp() {
return _formEditorApp;
};
/**
* @public
*
* @param object
* @return object
*/
function getHelper(configuration) {
if (getUtility().isUndefinedOrNull(configuration)) {
return Helper.setConfiguration(_configuration);
}
return Helper.setConfiguration(configuration);
};
/**
* @private
*
* @return object
*/
function getUtility() {
return getFormEditorApp().getUtility();
};
/**
* @private
*
* @param mixed test
* @param string message
* @param int messageCode
* @return void
*/
function assert(test, message, messageCode) {
return getFormEditorApp().assert(test, message, messageCode);
};
/**
* @private
*
* @return object
*/
function getRootFormElement() {
return getFormEditorApp().getRootFormElement();
};
/**
* @private
*
* @return object
*/
function getCurrentlySelectedFormElement() {
return getFormEditorApp().getCurrentlySelectedFormElement();
};
/**
* @private
*
* @return object
*/
function getPublisherSubscriber() {
return getFormEditorApp().getPublisherSubscriber();
};
/**
* @private
*
* @param object
* @param string
* @return mixed
*/
function getFormElementDefinition(formElement, formElementDefinitionKey) {
return getFormEditorApp().getFormElementDefinition(formElement, formElementDefinitionKey);
};
/**
* @private
*
* @return object
*/
function _getLinkSvg(type) {
return $('<span class="' + getHelper().getDomElementClassName('svgLinkWrapper') + '">'
+ '<svg version="1.1" width="' + _configuration['svgLink']['width'] + '" height="' + _configuration['svgLink']['height'] + '">'
+ '<path class="link" d="' + _configuration['svgLink']['paths'][type] + '">'
+ '</svg>'
+ '</span>');
};
/**
* @private
*
* @param object
* @return object
* @publish view/tree/render/listItemAdded
* @throws 1478715704
*/
function _renderNestedSortableListItem(formElement) {
var childFormElements, childList, expanderItem, isLastFormElementWithinParentFormElement,
listItem, listItemContent, searchElement;
assert('object' === $.type(formElement), 'Invalid parameter "formElement"', 1478715704);
isLastFormElementWithinParentFormElement = false;
if (formElement.get('__identifierPath') === getFormEditorApp().getLastFormElementWithinParentFormElement(formElement).get('__identifierPath')) {
isLastFormElementWithinParentFormElement = true;
}
listItem = $('<li></li>');
if (!getFormElementDefinition(formElement, '_isCompositeFormElement')) {
listItem.addClass(getHelper().getDomElementClassName('noNesting'));
}
listItemContent = $('<div></div>')
.attr(getHelper().getDomElementDataAttribute('elementIdentifier'), formElement.get('__identifierPath'))
.append(
$('<span></span>')
.attr(getHelper().getDomElementDataAttribute('identifier'), getHelper().getDomElementDataAttributeValue('title'))
.html(buildTitleByFormElement(formElement))
);
if (getFormElementDefinition(formElement, '_isCompositeFormElement')) {
listItemContent.attr(getHelper().getDomElementDataAttribute('abstractType'), 'isCompositeFormElement');
}
if (getFormElementDefinition(formElement, '_isTopLevelFormElement')) {
listItemContent.attr(getHelper().getDomElementDataAttribute('abstractType'), 'isTopLevelFormElement');
}
expanderItem = $('<span></span>').attr('data-identifier', getHelper().getDomElementDataAttributeValue('expander'));
listItemContent.prepend(expanderItem);
Icons.getIcon(getFormElementDefinition(formElement, 'iconIdentifier'), Icons.sizes.small, null, Icons.states.default).done(function(icon) {
expanderItem.after(
$(icon).addClass(getHelper().getDomElementClassName('icon'))
.tooltip({
title: 'id = ' + formElement.get('identifier'),
placement: 'right'
})
);
if (getFormElementDefinition(formElement, '_isCompositeFormElement')) {
if (formElement.get('renderables') && formElement.get('renderables').length > 0) {
Icons.getIcon(getHelper().getDomElementDataAttributeValue('collapse'), Icons.sizes.small).done(function(icon) {
expanderItem.before(_getLinkSvg('angle')).html($(icon));
listItem.addClass(getHelper().getDomElementClassName('hasChildren'));
});
} else {
expanderItem.before(_getLinkSvg('angle')).remove();
}
} else {
listItemContent.prepend(_getLinkSvg('angle'));
expanderItem.remove();
}
searchElement = formElement.get('__parentRenderable');
while (searchElement) {
if (searchElement.get('__identifierPath') === getRootFormElement().get('__identifierPath')) {
break;
}
if (searchElement.get('__identifierPath') === getFormEditorApp().getLastFormElementWithinParentFormElement(searchElement).get('__identifierPath')) {
listItemContent.prepend(_getLinkSvg('hidden'));
} else {
listItemContent.prepend(_getLinkSvg('vertical'));
}
searchElement = searchElement.get('__parentRenderable');
}
});
listItem.append(listItemContent);
getPublisherSubscriber().publish('view/tree/render/listItemAdded', [listItem, formElement]);
childFormElements = formElement.get('renderables');
childList = null;
if ('array' === $.type(childFormElements)) {
childList = $('<ol></ol>');
for (var i = 0, len = childFormElements.length; i < len; ++i) {
childList.append(_renderNestedSortableListItem(childFormElements[i]));
}
}
if (childList) {
listItem.append(childList);
}
return listItem;
};
/**
* @private
*
* @return void
* @publish view/tree/dnd/stop
* @publish view/tree/dnd/change
* @publish view/tree/dnd/update
*/
function _addSortableEvents() {
$('ol.' + getHelper().getDomElementClassName('sortable'), _treeDomElement).nestedSortable({
forcePlaceholderSize: true,
protectRoot: true,
isTree: true,
handle: 'div' + getHelper().getDomElementDataAttribute('elementIdentifier', 'bracesWithKey'),
helper: 'clone',
items: 'li',
opacity: .6,
revert: 250,
delay: 200,
tolerance: 'pointer',
toleranceElement: '> div',
isAllowed: function(placeholder, placeholderParent, currentItem) {
var formElementIdentifierPath, formElementTypeDefinition, targetFormElementIdentifierPath,
targetFormElementTypeDefinition;
if (typeof placeholderParent === 'undefined') {
return true;
}
formElementIdentifierPath = getTreeNodeIdentifierPathWithinDomElement($(currentItem));
targetFormElementIdentifierPath = getTreeNodeIdentifierPathWithinDomElement($(placeholderParent));
formElementTypeDefinition = getFormElementDefinition(formElementIdentifierPath);
targetFormElementTypeDefinition = getFormElementDefinition(targetFormElementIdentifierPath);
if (
targetFormElementTypeDefinition['_isTopLevelFormElement']
&& !targetFormElementTypeDefinition['_isCompositeFormElement']
) {
return false;
}
if (
formElementTypeDefinition['_isGridContainerFormElement']
&& (
getFormEditorApp().findEnclosingGridContainerFormElement(targetFormElementIdentifierPath)
|| getFormEditorApp().findEnclosingGridRowFormElement(targetFormElementIdentifierPath)
)
) {
return false;
}
if (
!formElementTypeDefinition['_isGridContainerFormElement']
&& !formElementTypeDefinition['_isGridRowFormElement']
&& targetFormElementTypeDefinition['_isGridContainerFormElement']
) {
return false;
}
return true;
},
stop: function(e, o) {
getPublisherSubscriber().publish('view/tree/dnd/stop', [getTreeNodeIdentifierPathWithinDomElement($(o.item))]);
},
change: function(e, o) {
var enclosingCompositeFormElement, parentFormElementIdentifierPath;
parentFormElementIdentifierPath = getParentTreeNodeIdentifierPathWithinDomElement($(o.placeholder));
if (parentFormElementIdentifierPath) {
enclosingCompositeFormElement = getFormEditorApp().findEnclosingCompositeFormElementWhichIsNotOnTopLevel(parentFormElementIdentifierPath);
}
getPublisherSubscriber().publish('view/tree/dnd/change', [$(o.placeholder), parentFormElementIdentifierPath, enclosingCompositeFormElement]);
},
update: function(e, o) {
var nextFormElementIdentifierPath, movedFormElementIdentifierPath,
previousFormElementIdentifierPath;
movedFormElementIdentifierPath = getTreeNodeIdentifierPathWithinDomElement($(o.item));
previousFormElementIdentifierPath = getSiblingTreeNodeIdentifierPathWithinDomElement($(o.item), 'prev');
nextFormElementIdentifierPath = getSiblingTreeNodeIdentifierPathWithinDomElement($(o.item), 'next');
getPublisherSubscriber().publish('view/tree/dnd/update', [$(o.item), movedFormElementIdentifierPath, previousFormElementIdentifierPath, nextFormElementIdentifierPath]);
}
});
};
/**
* @private
*
* @return void
*/
function _saveExpanderStates() {
var addStates;
addStates = function(formElement) {
var childFormElements, treeNode;
if (getFormElementDefinition(formElement, '_isCompositeFormElement')) {
treeNode = getTreeNode(formElement);
if (treeNode.length) {
if (treeNode.closest('li').hasClass(getHelper().getDomElementClassName('expanded'))) {
_expanderStates[formElement.get('__identifierPath')] = true;
} else {
_expanderStates[formElement.get('__identifierPath')] = false;
}
}
if (getUtility().isUndefinedOrNull(_expanderStates[formElement.get('__identifierPath')])) {
_expanderStates[formElement.get('__identifierPath')] = true;
}
}
childFormElements = formElement.get('renderables');
if ('array' === $.type(childFormElements)) {
for (var i = 0, len = childFormElements.length; i < len; ++i) {
addStates(childFormElements[i]);
}
}
};
addStates(getRootFormElement());
for (var identifierPath in _expanderStates) {
if (!_expanderStates.hasOwnProperty(identifierPath)) {
continue;
}
try {
getFormEditorApp().getFormElementByIdentifierPath(identifierPath);
} catch (error) {
delete _expanderStates[identifierPath];
}
}
};
/**
* @private
*
* @return void
*/
function _loadExpanderStates() {
for (var identifierPath in _expanderStates) {
var treeNode;
if (!_expanderStates.hasOwnProperty(identifierPath)) {
continue;
}
treeNode = getTreeNode(identifierPath);
if (treeNode.length) {
if (_expanderStates[identifierPath]) {
treeNode.closest('li')
.removeClass(getHelper().getDomElementClassName('collapsed'))
.addClass(getHelper().getDomElementClassName('expanded'));
} else {
treeNode.closest('li')
.addClass(getHelper().getDomElementClassName('collapsed'))
.removeClass(getHelper().getDomElementClassName('expanded'));
}
}
}
};
/* *************************************************************
* Public Methodes
* ************************************************************/
/**
* @public
*
* @param object
* @return object
* @throws 1478721208
*/
function renderCompositeFormElementChildsAsSortableList(formElement) {
var elementList;
assert('object' === $.type(formElement), 'Invalid parameter "formElement"', 1478721208);
elementList = $('<ol></ol>').addClass(getHelper().getDomElementClassName('sortable'));
if ('array' === $.type(formElement.get('renderables'))) {
for (var i = 0, len = formElement.get('renderables').length; i < len; ++i) {
elementList.append(_renderNestedSortableListItem(formElement.get('renderables')[i]));
}
}
return elementList;
};
/**
* @public
*
* @return void
* @param object
* @publish view/tree/node/clicked
*/
function renew(formElement) {
if (getFormEditorApp().getUtility().isUndefinedOrNull(formElement)) {
formElement = getRootFormElement();
}
_saveExpanderStates();
_treeDomElement.off().empty().append(renderCompositeFormElementChildsAsSortableList(formElement));
_treeDomElement.on("click", function(e) {
var formElementIdentifierPath;
formElementIdentifierPath = $(e.target)
.closest(getHelper().getDomElementDataAttribute('elementIdentifier', 'bracesWithKey'))
.attr(getHelper().getDomElementDataAttribute('elementIdentifier'));
if (getUtility().isUndefinedOrNull(formElementIdentifierPath) || !getUtility().isNonEmptyString(formElementIdentifierPath)) {
return;
}
getPublisherSubscriber().publish('view/tree/node/clicked', [formElementIdentifierPath]);
});
$(getHelper().getDomElementDataIdentifierSelector('expander'), _treeDomElement).on('click', function() {
$(this).closest('li').toggleClass(getHelper().getDomElementClassName('collapsed')).toggleClass(getHelper().getDomElementClassName('expanded'));
});
if (_configuration['isSortable']) {
_addSortableEvents();
}
_loadExpanderStates();
};
/**
* @public
*
* @param object
* @return string
*/
function getAllTreeNodes() {
return $(getHelper().getDomElementDataAttribute('elementIdentifier', 'bracesWithKey'), _treeDomElement);
};
/**
* @public
*
* @param object
* @return string
*/
function getTreeNodeWithinDomElement(element) {
return $(element).find(getHelper().getDomElementDataAttribute('elementIdentifier', 'bracesWithKey')).first();
};
/**
* @public
*
* @param object
* @return string
*/
function getTreeNodeIdentifierPathWithinDomElement(element) {
return getTreeNodeWithinDomElement($(element)).attr(getHelper().getDomElementDataAttribute('elementIdentifier'));
};
/**
* @public
*
* @param object
* @return string
*/
function getParentTreeNodeWithinDomElement(element) {
return $(element).parent().closest('li').find(getHelper().getDomElementDataAttribute('elementIdentifier', 'bracesWithKey')).first();
};
/**
* @public
*
* @param object
* @return string
*/
function getParentTreeNodeIdentifierPathWithinDomElement(element) {
return getParentTreeNodeWithinDomElement(element).attr(getHelper().getDomElementDataAttribute('elementIdentifier'));
};
/**
* @private
*
* @param object
* @param string
* @return string
*/
function getSiblingTreeNodeIdentifierPathWithinDomElement(element, position) {
var formElementIdentifierPath;
if (getUtility().isUndefinedOrNull(position)) {
position = 'prev';
}
formElementIdentifierPath = getTreeNodeIdentifierPathWithinDomElement(element);
element = (position === 'prev') ? $(element).prev('li') : $(element).next('li');
return element.find(getHelper().getDomElementDataAttribute('elementIdentifier', 'bracesWithKey'))
.not(getHelper().getDomElementDataAttribute('elementIdentifier', 'bracesWithKeyValue', [formElementIdentifierPath]))
.first()
.attr(getHelper().getDomElementDataAttribute('elementIdentifier'));
};
/**
* @public
*
* @param string
* @param object
* @return void
*/
function setTreeNodeTitle(title, formElement) {
if (getUtility().isUndefinedOrNull(title)) {
title = buildTitleByFormElement(formElement);
}
$(getHelper().getDomElementDataIdentifierSelector('title'), getTreeNode(formElement)).html(title);
};
/**
* @public
*
* @param string|object
* @return object
*/
function getTreeNode(formElement) {
var formElementIdentifierPath;
if ('string' === $.type(formElement)) {
formElementIdentifierPath = formElement;
} else {
if (getUtility().isUndefinedOrNull(formElement)) {
formElementIdentifierPath = getCurrentlySelectedFormElement().get('__identifierPath');
} else {
formElementIdentifierPath = formElement.get('__identifierPath');
}
}
return $(getHelper().getDomElementDataAttribute('elementIdentifier', 'bracesWithKeyValue', [formElementIdentifierPath]), _treeDomElement);
};
/**
* @public
*
* @param object
* @return object
* @throws 1478719287
*/
function buildTitleByFormElement(formElement) {
if (getUtility().isUndefinedOrNull(formElement)) {
formElement = getCurrentlySelectedFormElement();
}
assert('object' === $.type(formElement), 'Invalid parameter "formElement"', 1478719287);
return $('<span></span>')
.text((formElement.get('label') ? formElement.get('label') : formElement.get('identifier')))
.append($('<small></small>').text("(" + getFormElementDefinition(formElement, 'label') + ")"));
};
/**
* @public
*
* @return object
*/
function getTreeDomElement() {
return _treeDomElement;
};
/**
* @public
*
* @param object
* @param object
* @param object
* @return this
* @throws 1478714814
*/
function bootstrap(formEditorApp, appendToDomElement, configuration) {
_formEditorApp = formEditorApp;
assert('object' === $.type(appendToDomElement), 'Invalid parameter "appendToDomElement"', 1478714814);
_treeDomElement = $(appendToDomElement);
_configuration = $.extend(true, _defaultConfiguration, configuration || {});
_helperSetup();
return this;
};
/**
* Publish the public methods.
* Implements the "Revealing Module Pattern".
*/
return {
bootstrap: bootstrap,
buildTitleByFormElement: buildTitleByFormElement,
getAllTreeNodes: getAllTreeNodes,
getParentTreeNodeWithinDomElement: getParentTreeNodeWithinDomElement,
getParentTreeNodeIdentifierPathWithinDomElement: getParentTreeNodeIdentifierPathWithinDomElement,
getSiblingTreeNodeIdentifierPathWithinDomElement: getSiblingTreeNodeIdentifierPathWithinDomElement,
getTreeDomElement: getTreeDomElement,
getTreeNode: getTreeNode,
getTreeNodeWithinDomElement: getTreeNodeWithinDomElement,
getTreeNodeIdentifierPathWithinDomElement: getTreeNodeIdentifierPathWithinDomElement,
renderCompositeFormElementChildsAsSortableList: renderCompositeFormElementChildsAsSortableList,
renew: renew,
setTreeNodeTitle: setTreeNodeTitle
};
})($, Helper, Icons);
});
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,240 @@
/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/
/**
* Module: TYPO3/CMS/Form/Backend/FormManager
*/
define(['jquery'], function($) {
'use strict';
/**
* Return a static method named "getInstance".
* Use this method to create the formmanager app.
*/
return (function() {
/**
* @private
*
* Hold the instance (Singleton Pattern)
*/
var _formManagerInstance = null;
/**
* @public
*
* @param object _configuration
* @param object _viewModel
* @return object
*/
function FormManager(_configuration, _viewModel) {
/**
* @private
*
* @var bool
*/
var _isRunning = false;
/**
* @public
*
* @param mixed test
* @param string message
* @param int messageCode
* @return void
*/
function assert(test, message, messageCode) {
if ('function' === $.type(test)) {
test = (test() !== false);
}
if (!test) {
message = message || "Assertion failed";
if (messageCode) {
message = message + ' (' + messageCode + ')';
}
if ('undefined' !== typeof Error) {
throw new Error(message);
}
throw message;
}
};
/**
* @private
*
* @var bool
*/
var _isRunning = false;
/**
* @public
*
* @return object
*/
function getPrototypes() {
var prototypes = [];
if ('array' === $.type(_configuration['selectablePrototypesConfiguration'])) {
for (var i = 0, len = _configuration['selectablePrototypesConfiguration'].length; i < len; ++i) {
prototypes.push({
label: _configuration['selectablePrototypesConfiguration'][i]['label'],
value: _configuration['selectablePrototypesConfiguration'][i]['identifier']
});
}
}
return prototypes;
};
/**
* @public
*
* @param string prototypeName
* @return object
*/
function getTemplatesForPrototype(prototypeName) {
var templates = [];
assert('string' === $.type(prototypeName), 'Invalid parameter "prototypeName"', 1475945286);
if ('array' === $.type(_configuration['selectablePrototypesConfiguration'])) {
for (var i = 0, len1 = _configuration['selectablePrototypesConfiguration'].length; i < len1; ++i) {
if (_configuration['selectablePrototypesConfiguration'][i]['identifier'] !== prototypeName) {
continue;
}
if ('array' === $.type(_configuration['selectablePrototypesConfiguration'][i]['newFormTemplates'])) {
for (var j = 0, len2 = _configuration['selectablePrototypesConfiguration'][i]['newFormTemplates'].length; j < len2; ++j) {
templates.push({
label: _configuration['selectablePrototypesConfiguration'][i]['newFormTemplates'][j]['label'],
value: _configuration['selectablePrototypesConfiguration'][i]['newFormTemplates'][j]['templatePath']
});
}
}
}
}
return templates;
};
/**
* @public
*
* @param string prototypeName
* @return object
*/
function getAccessibleFormStorageFolders() {
var folders = [];
if ('array' === $.type(_configuration['accessibleFormStorageFolders'])) {
for (var i = 0, len1 = _configuration['accessibleFormStorageFolders'].length; i < len1; ++i) {
folders.push({
label: _configuration['accessibleFormStorageFolders'][i]['label'] + ' (' + _configuration['accessibleFormStorageFolders'][i]['value'] + ')',
value: _configuration['accessibleFormStorageFolders'][i]['value']
});
}
}
return folders;
};
/**
* @public
*
* @param string prototypeName
* @return object
* @throws 1477506508
*/
function getAjaxEndpoint(endpointName) {
var templates = [];
assert(typeof _configuration['endpoints'][endpointName] !== 'undefined', 'Endpoint ' + endpointName + ' does not exist', 1477506508);
return _configuration['endpoints'][endpointName];
};
/**
* @private
*
* @return void
* @throws 1475942906
*/
function _viewSetup() {
assert('function' === $.type(_viewModel.bootstrap), 'The view model does not implement the method "bootstrap"', 1475942906);
_viewModel.bootstrap(_formManagerInstance);
};
/**
* @private
*
* @return void
* @throws 1477506504
*/
function _bootstrap() {
_configuration = _configuration || {};
assert('object' === $.type(_configuration['endpoints']), 'Invalid parameter "endpoints"', 1477506504);
_viewSetup();
};
/**
* @public
*
* @return TYPO3/CMS/Form/Backend/FormManager
* @throws 1475942618
*/
function run() {
if (_isRunning) {
throw 'You can not run the app twice (1475942618)';
}
_bootstrap();
_isRunning = true;
return this;
};
/**
* Publish the public methods.
* Implements the "Revealing Module Pattern".
*/
return {
getPrototypes: getPrototypes,
getTemplatesForPrototype: getTemplatesForPrototype,
getAccessibleFormStorageFolders: getAccessibleFormStorageFolders,
getAjaxEndpoint: getAjaxEndpoint,
assert: assert,
run: run
};
};
/**
* Emulation of static methods
*/
return {
/**
* @public
* @static
*
* Implement the "Singleton Pattern".
*
* Return a singleton instance of a
* "FormManager" object.
*
* @param object configuration
* @param object viewModel
* @return object
*/
getInstance: function(configuration, viewModel) {
if (_formManagerInstance === null) {
_formManagerInstance = new FormManager(configuration, viewModel);
}
return _formManagerInstance;
}
};
})();
});
@@ -0,0 +1,575 @@
/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/
/**
* Module: TYPO3/CMS/Form/Backend/FormManager/ViewModel
*/
define(['jquery',
'TYPO3/CMS/Backend/Modal',
'TYPO3/CMS/Backend/Severity',
'TYPO3/CMS/Backend/Wizard',
'TYPO3/CMS/Backend/Icons',
'TYPO3/CMS/Backend/Notification'
], function($, Modal, Severity, Wizard, Icons, Notification) {
'use strict';
return (function($, Modal, Severity, Wizard, Icons, Notification) {
/**
* @private
*
* @var object
*/
var _formManagerApp = null;
/**
* @private
*
* @var object
*/
var _domElementIdentifierCache = {};
/**
* @private
*
* @return void
*/
function _domElementIdentifierCacheSetup() {
_domElementIdentifierCache = {
newFormModalTrigger: {identifier: '[data-identifier="newForm"]'},
duplicateFormModalTrigger: {identifier: '[data-identifier="duplicateForm"]'},
removeFormModalTrigger: {identifier: '[data-identifier="removeForm"]'},
newFormName: {identifier: '[data-identifier="newFormName"]'},
newFormSavePath: {identifier: '[data-identifier="newFormSavePath"]'},
advancedWizard: {identifier: '[data-identifier="advancedWizard"]'},
newFormPrototypeName: {identifier: '[data-identifier="newFormPrototypeName"]'},
newFormTemplate: {identifier: '[data-identifier="newFormTemplate"]'},
duplicateFormName: {identifier: '[data-identifier="duplicateFormName"]'},
duplicateFormSavePath: {identifier: '[data-identifier="duplicateFormSavePath"]'},
showReferences: {identifier: '[data-identifier="showReferences"]'},
referenceLink: {identifier: '[data-identifier="referenceLink"]'},
tooltip: {identifier: '[data-toggle="tooltip"]'},
moduleBody: {class: '.module-body.t3js-module-body'},
t3Logo: {class: '.t3-message-page-logo'},
t3Footer: {id: '#t3-footer'}
}
};
/**
* @private
*
* @return void
* @throws 1477506500
* @throws 1477506501
* @throws 1477506502
*/
function _newFormSetup() {
$(getDomElementIdentifier('newFormModalTrigger')).on('click', function(e) {
e.preventDefault();
/**
* Wizard step 1
*/
Wizard.addSlide('new-form-step-1', TYPO3.lang['formManager.newFormWizard.step1.title'], '', Severity.info, function(slide) {
var advandecWizardHasOptions, folders, html, modal, nextButton, prototypes,
savePathSelect, templates;
modal = Wizard.setup.$carousel.closest('.modal');
nextButton = modal.find('.modal-footer').find('button[name="next"]');
folders = _formManagerApp.getAccessibleFormStorageFolders();
if (folders.length === 0) {
html = '<div class="new-form-modal">'
+ '<div class="form-horizontal">'
+ '<div>'
+ '<label class="control-label">' + TYPO3.lang['formManager.newFormWizard.step1.noStorages'] + '</label>'
+ '</div>'
+ '</div>'
+ '</div>';
slide.html(html);
_formManagerApp.assert(false, 'No accessible form storage folders', 1477506500);
}
Wizard.set('savePath', folders[0]['value']);
if (folders.length > 1) {
savePathSelect = $('<select class="new-form-save-path form-control" id="new-form-save-path" data-identifier="newFormSavePath" />');
for (var i = 0, len = folders.length; i < len; ++i) {
var option = new Option(folders[i]['label'], folders[i]['value']);
$(savePathSelect).append(option);
}
}
prototypes = _formManagerApp.getPrototypes();
_formManagerApp.assert(prototypes.length > 0, 'No prototypes available', 1477506501);
Wizard.set('prototypeName', prototypes[0]['value']);
templates = _formManagerApp.getTemplatesForPrototype(prototypes[0]['value']);
_formManagerApp.assert(templates.length > 0, 'No templates available', 1477506502);
Wizard.set('templatePath', templates[0]['value']);
html = '<div class="new-form-modal">'
+ '<div class="form-horizontal">'
+ '<div>'
+ '<label class="control-label" for="new-form-name">' + TYPO3.lang['formManager.form_name'] + '</label>'
+ '<input class="new-form-name form-control has-error" id="new-form-name" data-identifier="newFormName" />';
if (savePathSelect) {
html += '<label class="control-label" for="new-form-save-path">' + TYPO3.lang['formManager.form_save_path'] + '</label>' + $(savePathSelect)[0].outerHTML;
}
if (prototypes.length > 1 || templates.length > 1) {
html += '<label class="control-label" for="new-form-advance-wizard">' + TYPO3.lang['formManager.newFormWizard.step1.advanced'] + '</label>'
+ '<div class="t3-form-controls"><input type="checkbox" class="new-form-advance-wizard" id="new-form-advance-wizard" data-identifier="advancedWizard" /></div>';
}
html += '</div>'
+ '</div>'
+ '</div>';
slide.html(html);
$(getDomElementIdentifier('newFormName'), modal).focus();
$(getDomElementIdentifier('newFormName'), modal).on('keyup paste', function(e) {
if ($(this).val().length > 0) {
$(this).removeClass('has-error');
Wizard.unlockNextStep();
Wizard.set('formName', $(this).val());
} else {
$(this).addClass('has-error');
Wizard.lockNextStep();
}
});
$(getDomElementIdentifier('newFormSavePath'), modal).on('change', function(e) {
Wizard.set('savePath', $(getDomElementIdentifier('newFormSavePath') + ' option:selected', modal).val());
});
$(getDomElementIdentifier('advancedWizard'), modal).on('change', function(e) {
if ($(this).is(':checked')) {
Wizard.set('advancedWizard', true);
} else {
Wizard.set('advancedWizard', false);
}
});
nextButton.on('click', function() {
Wizard.setup.forceSelection = false;
Icons.getIcon('spinner-circle-dark', Icons.sizes.large, null, null).done(function(markup) {
slide.html($('<div />', {class: 'text-center'}).append(markup));
});
});
});
/**
* Wizard step 2
*/
Wizard.addSlide('new-form-step-2', TYPO3.lang['formManager.newFormWizard.step2.title'], '', Severity.info, function(slide, settings) {
var addOnTemplateChangeEvents, html, modal, nextButton, prototypes, prototypeNameSelect,
templates, templateSelect;
if (settings['advancedWizard'] !== true) {
Wizard.unlockNextStep().trigger('click');
return;
}
modal = Wizard.setup.$carousel.closest('.modal');
nextButton = modal.find('.modal-footer').find('button[name="next"]');
prototypeNameSelect = $('<select class="new-form-prototype-name form-control" id="new-form-prototype-name" data-identifier="newFormPrototypeName" />');
templateSelect = $('<select class="new-form-template form-control" id="new-form-template" data-identifier="newFormTemplate" />');
prototypes = _formManagerApp.getPrototypes();
templates = {};
if (prototypes.length > 0) {
for (var i = 0, len = prototypes.length; i < len; ++i) {
var option = new Option(prototypes[i]['label'], prototypes[i]['value']);
$(prototypeNameSelect).append(option);
}
templates = _formManagerApp.getTemplatesForPrototype(prototypes[0]['value']);
for (var i = 0, len = templates.length; i < len; ++i) {
var option = new Option(templates[i]['label'], templates[i]['value']);
$(templateSelect).append(option);
}
}
html = '<div class="new-form-modal">'
+ '<div class="form-horizontal">'
+ '<div>';
if (prototypes.length > 1) {
html += '<label class="control-label" for="new-form-prototype-name">' + TYPO3.lang['formManager.form_prototype'] + '</label>' + $(prototypeNameSelect)[0].outerHTML;
}
if (templates.length > 1) {
html += '<label class="control-label" for="new-form-template">' + TYPO3.lang['formManager.form_template'] + '</label>' + $(templateSelect)[0].outerHTML;
}
html += '</div>'
+ '</div>'
+ '</div>';
slide.html(html);
if (prototypes.length > 1) {
$(getDomElementIdentifier('newFormPrototypeName'), modal).focus();
} else if (templates.length > 1) {
$(getDomElementIdentifier('newFormTemplate'), modal).focus();
}
addOnTemplateChangeEvents = function() {
$(getDomElementIdentifier('newFormTemplate'), modal).on('change', function(e) {
Wizard.set('templatePath', $(getDomElementIdentifier('newFormTemplate') + ' option:selected', modal).val());
});
};
$(getDomElementIdentifier('newFormPrototypeName'), modal).on('change', function(e) {
Wizard.set('prototypeName', $(this).val());
templates = _formManagerApp.getTemplatesForPrototype($(this).val());
$(getDomElementIdentifier('newFormTemplate'), modal).off().empty();
for (var i = 0, len = templates.length; i < len; ++i) {
var option = new Option(templates[i]['label'], templates[i]['value']);
$(getDomElementIdentifier('newFormTemplate'), modal).append(option);
Wizard.set('templatePath', templates[0]['value']);
}
addOnTemplateChangeEvents();
});
addOnTemplateChangeEvents();
nextButton.on('click', function() {
Icons.getIcon('spinner-circle-dark', Icons.sizes.large, null, null).done(function(markup) {
slide.html($('<div />', {class: 'text-center'}).append(markup));
});
});
});
/**
* Wizard step 3
*/
Wizard.addSlide('new-form-step-3', TYPO3.lang['formManager.newFormWizard.step3.title'], TYPO3.lang['formManager.newFormWizard.step3.message'], Severity.info);
/**
* Wizard step 4
*/
Wizard.addFinalProcessingSlide(function() {
$.post(_formManagerApp.getAjaxEndpoint('create'), {
tx_form_web_formformbuilder: {
formName: Wizard.setup.settings['formName'],
templatePath: Wizard.setup.settings['templatePath'],
prototypeName: Wizard.setup.settings['prototypeName'],
savePath: Wizard.setup.settings['savePath']
}
}, function(data, textStatus, jqXHR) {
if (data['status'] === 'success') {
document.location = data.url;
} else {
Notification.error(TYPO3.lang['formManager.newFormWizard.step4.errorTitle'], TYPO3.lang['formManager.newFormWizard.step4.errorMessage'] + " " + data['message']);
}
Wizard.dismiss();
}).fail(function(jqXHR, textStatus, errorThrown) {
var parser = new DOMParser(),
responseDocument = parser.parseFromString(jqXHR.responseText, "text/html"),
responseBody = $(responseDocument.body);
Notification.error(textStatus, errorThrown, 2);
Wizard.dismiss();
$(getDomElementIdentifier('t3Logo', 'class'), responseBody).remove();
$(getDomElementIdentifier('t3Footer', 'id'), responseBody).remove();
$(getDomElementIdentifier('moduleBody', 'class')).html(responseBody.html());
});
}).done(function() {
Wizard.show();
});
});
};
/**
* @private
*
* @return void
*/
function _removeFormSetup() {
$(getDomElementIdentifier('removeFormModalTrigger')).on('click', function(e) {
var modalButtons = [], that;
e.preventDefault();
that = $(this)
modalButtons.push({
text: TYPO3.lang['formManager.cancel'],
active: true,
btnClass: 'btn-default',
name: 'cancel',
trigger: function() {
Modal.currentModal.trigger('modal-dismiss');
}
});
modalButtons.push({
text: TYPO3.lang['formManager.remove_form'],
active: true,
btnClass: 'btn-warning',
name: 'createform',
trigger: function() {
document.location = _formManagerApp.getAjaxEndpoint('delete') + '&tx_form_web_formformbuilder[formPersistenceIdentifier]=' + that.data('formPersistenceIdentifier');
Modal.currentModal.trigger('modal-dismiss');
}
});
Modal.show(
TYPO3.lang['formManager.remove_form_title'],
TYPO3.lang['formManager.remove_form_message'],
Severity.warning,
modalButtons
);
});
};
/**
* @private
*
* @return void
* @throws 1477649539
*/
function _duplicateFormSetup() {
$(getDomElementIdentifier('duplicateFormModalTrigger')).on('click', function(e) {
var that;
e.preventDefault();
that = $(this);
/**
* Wizard step 1
*/
Wizard.addSlide('duplicate-form-step-1', TYPO3.lang['formManager.duplicateFormWizard.step1.title'].replace('{0}', that.data('formName')), '', Severity.info, function(slide) {
var folders, html, modal, nextButton, savePathSelect;
modal = Wizard.setup.$carousel.closest('.modal');
nextButton = modal.find('.modal-footer').find('button[name="next"]');
folders = _formManagerApp.getAccessibleFormStorageFolders();
_formManagerApp.assert(folders.length > 0, 'No accessible form storage folders', 1477649539);
Wizard.set('formPersistenceIdentifier', that.data('formPersistenceIdentifier'));
Wizard.set('savePath', folders[0]['value']);
if (folders.length > 1) {
savePathSelect = $('<select class="duplicate-form-save-path form-control" data-identifier="duplicateFormSavePath" />');
for (var i = 0, len = folders.length; i < len; ++i) {
var option = new Option(folders[i]['label'], folders[i]['value']);
$(savePathSelect).append(option);
}
}
html = '<div class="duplicate-form-modal">'
+ '<div class="form-horizontal">'
+ '<div>'
+ '<label class="control-label">' + TYPO3.lang['formManager.new_form_name'] + '</label>'
+ '<input class="duplicate-form-name form-control has-error" data-identifier="duplicateFormName" />';
if (savePathSelect) {
html += '<label class="control-label">' + TYPO3.lang['formManager.form_save_path'] + '</label>' + $(savePathSelect)[0].outerHTML;
}
html += '</div>'
+ '</div>'
+ '</div>';
slide.html(html);
$(getDomElementIdentifier('duplicateFormName'), modal).focus();
$(getDomElementIdentifier('duplicateFormName'), modal).on('keyup paste', function(e) {
if ($(this).val().length > 0) {
$(this).removeClass('has-error');
Wizard.unlockNextStep();
Wizard.set('formName', $(this).val());
} else {
$(this).addClass('has-error');
Wizard.lockNextStep();
}
});
$(getDomElementIdentifier('duplicateFormSavePath'), modal).on('change', function(e) {
Wizard.set('savePath', $(getDomElementIdentifier('duplicateFormSavePath') + ' option:selected', modal).val());
});
});
/**
* Wizard step 2
*/
Wizard.addFinalProcessingSlide(function() {
$.post(_formManagerApp.getAjaxEndpoint('duplicate'), {
tx_form_web_formformbuilder: {
formName: Wizard.setup.settings['formName'],
formPersistenceIdentifier: Wizard.setup.settings['formPersistenceIdentifier'],
savePath: Wizard.setup.settings['savePath']
}
}, function(data, textStatus, jqXHR) {
if (data['status'] === 'success') {
document.location = data.url;
} else {
Notification.error(TYPO3.lang['formManager.duplicateFormWizard.step2.errorTitle'], TYPO3.lang['formManager.duplicateFormWizard.step2.errorMessage'] + " " + data['message']);
}
Wizard.dismiss();
}).fail(function(jqXHR, textStatus, errorThrown) {
var parser = new DOMParser(),
responseDocument = parser.parseFromString(jqXHR.responseText, "text/html"),
responseBody = $(responseDocument.body);
Notification.error(textStatus, errorThrown, 2);
Wizard.dismiss();
$(getDomElementIdentifier('t3Logo', 'class'), responseBody).remove();
$(getDomElementIdentifier('t3Footer', 'id'), responseBody).remove();
$(getDomElementIdentifier('moduleBody', 'class')).html(responseBody.html());
});
}).done(function() {
Wizard.show();
});
});
};
/**
* @private
*
* @return void
*/
function _showReferencesSetup() {
$(getDomElementIdentifier('showReferences')).on('click', function(e) {
var that, url;
e.preventDefault();
that = this;
url = _formManagerApp.getAjaxEndpoint('references') + '&tx_form_web_formformbuilder[formPersistenceIdentifier]=' + $(this).data('formPersistenceIdentifier');
$.get(url, function(data, textStatus, jqXHR) {
var html, modalButtons = [], referencesLength;
modalButtons.push({
text: TYPO3.lang['formManager.cancel'],
active: true,
btnClass: 'btn-default',
name: 'cancel',
trigger: function() {
Modal.currentModal.trigger('modal-dismiss');
}
});
referencesLength = data['references'].length;
if (referencesLength > 0) {
html = '<div>'
+ '<h3>' + TYPO3.lang['formManager.references.headline'].replace('{0}', $(that).data('formName')) + '</h3>'
+ '</div>'
+ '<div class="table-fit">'
+ '<table id="forms" class="table table-striped table-condensed">'
+ '<thead>'
+ '<tr>'
+ '<th>' + TYPO3.lang['formManager.page'] + '</th>'
+ '<th>' + TYPO3.lang['formManager.record'] + '</th>'
+ '</tr>'
+ '</thead>'
+ '<tbody>';
for (var i = 0, len = data['references'].length; i < len; ++i) {
html += '<tr>'
+ '<td>' + data['references'][i]['recordPageTitle'] + '</td>'
+ '<td>'
+ data['references'][i]['recordIcon']
+ '<a href="' + data['references'][i]['recordEditUrl'] + '" data-identifier="referenceLink">'
+ data['references'][i]['recordTitle'] + ' (uid: ' + data['references'][i]['recordUid'] + ')'
+ '</a>'
+ '</td>'
+ '</tr>';
}
html += '</tbody>'
+ '</table>'
+ '</div>';
} else {
html = '<div>'
+ '<h1>' + TYPO3.lang['formManager.references.title'].replace('{0}', data['formPersistenceIdentifier']) + '</h1>'
+ '</div>'
+ '<div>' + TYPO3.lang['formManager.no_references'] + '</div>';
}
html = $(html);
$(getDomElementIdentifier('referenceLink'), html).on('click', function(e) {
e.preventDefault();
Modal.currentModal.trigger('modal-dismiss');
document.location = $(this).prop('href');
});
Modal.show(
TYPO3.lang['formManager.references.title'],
html,
Severity.info,
modalButtons
);
}).fail(function(jqXHR, textStatus, errorThrown) {
if (jqXHR.status !== 0) {
Notification.error(textStatus, errorThrown, 2);
}
});
});
};
/**
* @public
*
* @param string elementIdentifier
* @param string type
* @return mixed|undefined
* @throws 1477506413
* @throws 1477506414
*/
function getDomElementIdentifier(elementIdentifier, type) {
_formManagerApp.assert(elementIdentifier.length > 0, 'Invalid parameter "elementIdentifier"', 1477506413);
_formManagerApp.assert(typeof _domElementIdentifierCache[elementIdentifier] !== "undefined", 'elementIdentifier "' + elementIdentifier + '" does not exist', 1477506414);
if (typeof type === "undefined") {
type = 'identifier';
}
return _domElementIdentifierCache[elementIdentifier][type] || undefined;
};
/**
* @public
*
* @param object formManagerApp
* @return void
*/
function bootstrap(formManagerApp) {
_formManagerApp = formManagerApp;
_domElementIdentifierCacheSetup();
_removeFormSetup();
_newFormSetup();
_duplicateFormSetup();
_showReferencesSetup();
$(getDomElementIdentifier('tooltip')).tooltip();
};
/**
* Publish the public methods.
* Implements the "Revealing Module Pattern".
*/
return {
bootstrap: bootstrap
};
})($, Modal, Severity, Wizard, Icons, Notification);
});