BuildFormBootstrap.php 12.1 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
<?php
/**
 * Created by PhpStorm.
 * User: crose
 * Date: 1/25/16
 * Time: 10:00 PM
 */

namespace qfq;

use qfq;
12
use qfq\UserException;
13
14

require_once(__DIR__ . '/../qfq/Constants.php');
15
require_once(__DIR__ . '/../qfq/helper/OnArray.php');
16
require_once(__DIR__ . '/../qfq/AbstractBuildForm.php');
17
require_once(__DIR__ . '/../qfq/exceptions/UserException.php');
18

Carsten  Rose's avatar
Carsten Rose committed
19
20
21
22
/**
 * Class BuildFormBootstrap
 * @package qfq
 */
23
24
class BuildFormBootstrap extends AbstractBuildForm {

25
26
27
28
29
30
31
32
33
34
    private $isFirstPill;

    /**
     * @param array $formSpec
     * @param array $feSpecAction
     * @param array $feSpecNative
     */
    public function __construct(array $formSpec, array $feSpecAction, array $feSpecNative) {
        parent::__construct($formSpec, $feSpecAction, $feSpecNative);
        $this->isFirstPill = true;
35
36

        // Set some defaults
37
        if (!isset($this->formSpec['class'])) {
38
39
            $this->formSpec['class'] = 'container';
        }
40
41
    }

Carsten  Rose's avatar
Carsten Rose committed
42
43
44
    /**
     *
     */
45
    public function fillWrap() {
46
47
48
49
50


//        $this->wrap[WRAP_SETUP_OUTER][WRAP_SETUP_START] = '<div class="tab-content">';
//        $this->wrap[WRAP_SETUP_OUTER][WRAP_SETUP_END] = '</div>';

51
52
        $this->wrap[WRAP_SETUP_TITLE][WRAP_SETUP_START] = '<div class="row hidden-xs"><div class="col-md-12"><h1>';
        $this->wrap[WRAP_SETUP_TITLE][WRAP_SETUP_END] = '</h1></div></div>';
53

54
        // Element: Label + Input + Note
55
56
        $this->wrap[WRAP_SETUP_ELEMENT][WRAP_SETUP_START] = '<div class="form-group">';
        $this->wrap[WRAP_SETUP_ELEMENT][WRAP_SETUP_END] = '</div>';
57

58
59
60
61
62
63
64
65
66
        $this->wrap[WRAP_SETUP_LABEL][WRAP_SETUP_START] = '<div class="col-md-2">';
        $this->wrap[WRAP_SETUP_LABEL][WRAP_SETUP_END] = '</div>';
        $this->wrap[WRAP_SETUP_INPUT][WRAP_SETUP_START] = '<div class="col-md-6">';
        $this->wrap[WRAP_SETUP_INPUT][WRAP_SETUP_END] = '</div>';
        $this->wrap[WRAP_SETUP_NOTE][WRAP_SETUP_START] = '<div class="col-md-4">';
        $this->wrap[WRAP_SETUP_NOTE][WRAP_SETUP_END] = '</div>';

        $this->wrap[WRAP_SETUP_SUBRECORD][WRAP_SETUP_START] = '<div class="col-md-12">';
        $this->wrap[WRAP_SETUP_SUBRECORD][WRAP_SETUP_END] = '</div>';
67
68
69
70

        $this->wrap[WRAP_SETUP_IN_FIELDSET][WRAP_SETUP_START] = '<p>';
        $this->wrap[WRAP_SETUP_IN_FIELDSET][WRAP_SETUP_END] = '</p>';

71
72
//        $this->feDivClass['radio'] = 'radio';
//        $this->feDivClass['checkbox'] = 'checkbox';
73
74
    }

Carsten  Rose's avatar
Carsten Rose committed
75
76
77
    /**
     * @return string
     */
78
79
80
81
    public function getProcessFilter() {
        return FORM_ELEMENTS_NATIVE_SUBRECORD;
    }

Carsten  Rose's avatar
Carsten Rose committed
82
83
84
    /**
     * @return string
     */
85
86
87
88
89
90
91
92
    public function doSubrecords() {
        return '';
    }

    /**
     * @return string
     */
    public function head() {
93
        $html = '';
94

95
        $html .= '<div ' . $this->getAttribute('class', $this->formSpec['class'], TRUE) . '>'; // main <div class=...> around everything, Whole FORM; class="container" or class="container-fluid"
96
97
98
99
100
101

        $html .= '<div class="row hidden-xs"><div class="col-md-12"><h2>' . $this->formSpec['title'] . '</h2></div></div>'; // Form Title

        $pill = $this->buildPillNavigation(OnArray::filter($this->feSpecNative, 'type', 'pill'));
        $button = $this->buildButtons();

102
        $html .= Support::wrapTag('<div class="row">', $pill . $button);
103

104
105
        $html .= $this->getFormTag();

106
        $html .= '<div class="tab-content">';
107
108
109
110

        return $html;
    }

Carsten  Rose's avatar
Carsten Rose committed
111
    /**
112
     * @param $pillArray
Carsten  Rose's avatar
Carsten Rose committed
113
     * @return string
114
     * @throws UserException
Carsten  Rose's avatar
Carsten Rose committed
115
     */
116
    private function buildPillNavigation($pillArray) {
117
        $htmlDropdown = '';
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
        $pillButton = '';
        $pillDropdown = '';

        if ($pillArray == null)
            return '';

        $maxVisiblePill = (isset($this->formSpec['maxVisiblePill']) && $this->formSpec['maxVisiblePill'] !== '') ? $this->formSpec['maxVisiblePill'] : 1000;

        // Iterate over all 'pill'
        $ii = 0;
        $active = 'class="active"';
        foreach ($pillArray as $formElement) {
            $ii++;

            if ($formElement['name'] === '' || $formElement['label'] === '') {
                $this->store->setVar(SYSTEM_FORM_ELEMENT, $formElement['name'] . ' / ' . $formElement['id'], STORE_SYSTEM);
                $this->store->setVar(SYSTEM_FORM_ELEMENT_COLUMN, 'name, label', STORE_SYSTEM);
                throw new UserException("Field 'name' and/or 'label' are empty", ERROR_NAME_LABEL_EMPTY);
            }

138
            $a = '<a href="#' . $this->createAnker($formElement['id']) . '" data-toggle="tab">' . $formElement['label'] . '</a>';
139

140
141
142
143
144
145
146
            if ($ii <= $maxVisiblePill) {
                $pillButton .= '<li role="presentation" ' . $active . '>' . $a . '</li>';
            } else {
                $pillDropdown .= '<li>' . $a . '</li>';
            }
            $active = '';
        }
147

148
149
        // Pill Dropdown necessary?
        if ($ii > $maxVisiblePill) {
150
151
            $htmlDropdown = Support::wrapTag('<ul class="dropdown-menu">', $pillDropdown, true);
            $htmlDropdown = '<a class="dropdown-toggle" data-toggle="dropdown" href="#" role="button">more <span class="caret"></span></a>' . $htmlDropdown;
152
            $htmlDropdown = Support::wrapTag('<li role="presentation" class="dropdown">', $htmlDropdown, false);
153
        }
154

155
156
        $htmlDropdown = Support::wrapTag('<ul id="' . $this->getTabId() . '" class="nav nav-pills" role="tablist">', $pillButton . $htmlDropdown);
        $htmlDropdown = Support::wrapTag('<div class="col-md-9">', $htmlDropdown);
157

158
        return $htmlDropdown;
159
160
161
162
163
164
165
166
167
168
169
170
    }

    /**
     * Create an identifier for the pill navigation menu
     *
     * @param $id
     * @return string
     */
    private function createAnker($id) {
        return $this->formSpec['name'] . '_' . $id;
    }

Carsten  Rose's avatar
Carsten Rose committed
171
172
173
174
175
176
177
    /**
     * @return string
     */
    private function getTabId() {
        return 'qfqTabs';
    }

178
179
180
181
182
    /**
     * Simlute Submit Button: http://www.javascript-coder.com/javascript-form/javascript-form-submit.phtml
     *
     * @return string
     */
183
    private function buildButtons() {
184
185
186
187
188
189
190
191
192
193
        $toolTipNew = 'New';
        $toolTipDelete = 'Delete';
        $buttonDelete = '';
        $buttonNew = '';


        if ($this->store->getVar(SYSTEM_SHOW_DEBUG_INFO, STORE_SYSTEM) === 'yes') {
            $toolTipNew .= PHP_EOL . "form = '" . $this->formSpec['name'] . "'" . PHP_EOL . "r = 0";
            $toolTipDelete .= PHP_EOL . "table = '" . $this->formSpec['tableName'] . "'" . PHP_EOL . "r = '" . $this->store->getVar(SIP_RECORD_ID, STORE_SIP) . "'";
        }
194

195
        $sipParamString = OnArray::toString($this->store->getStore(STORE_SIP), ' = ', PHP_EOL, "'");
196
197
        $formEditUrl = $this->createFormEditUrl();

198
        $buttonDebug = <<<BUTTON
199
        <div class="btn-group" role="group">
200
            <button id="debug-button" type="button" class="btn btn-default navbar-btn" title="$sipParamString"><span class="glyphicon glyphicon-eye-open"></span></button>
201
            <a href="$formEditUrl" id="form-edit-button" class="btn btn-default navbar-btn" title="Edit form"><span class="glyphicon glyphicon-wrench"></span></a>
202
        </div>
203
204
205
206
207
208
209
210
211
BUTTON;

        if (Support::findInSet(FORM_BUTTON_DELETE, $this->formSpec['showButton'])) {
            $buttonDelete = <<<BUTTON
            <div class="btn-group" role="group">
                        <button id="delete-button" type="button" class="btn btn-default navbar-btn" title="$toolTipDelete"><span class="glyphicon glyphicon-trash"></span></button>
            </div>
BUTTON;
        }
212

213
214
215
216
217
218
219
        if (Support::findInSet(FORM_BUTTON_NEW, $this->formSpec['showButton'])) {
            $buttonNew = <<<BUTTON
            <div class="btn-group" role="group">
                        <button id="delete-button" type="button" class="btn btn-default navbar-btn" title="$toolTipNew"><span class="glyphicon glyphicon-plus"></span></button>
            </div>
BUTTON;
        }
220

221
        $buttonFormEdit = ($this->store->getVar(SYSTEM_SHOW_DEBUG_INFO, STORE_SYSTEM) === 'yes') ? $buttonDebug : '';
222

223
224

        $html = <<<BUTTON
225
        <div class="col-md-3 ">
226
            <div class="btn-toolbar pull-right" role="toolbar">
227
                $buttonFormEdit
228
                <div class="btn-group" role="group">
229
230
                    <button id="save-button" type="button" class="btn btn-default navbar-btn" title="Save"><span class="glyphicon glyphicon-ok"></span></button>
                    <button id="close-button" type="button" class="btn btn-default navbar-btn" title="Close"><span class="glyphicon glyphicon-remove"></span></button>
231
                </div>
232
233
                $buttonDelete
                $buttonNew
234
235
            </div>
        </div>
236
BUTTON;
237
238
239
        return $html;
    }

240
241
242
243
244
    /**
     * Builds the complete HTML '<form ...>'-tag
     *
     * @return string
     */
245
    public function getFormTag() {
246
247
248
249
250
251
252
253

        $attribute = $this->getFormTagAtrributes();

        $attribute['class'] = 'form-horizontal';

        return '<form ' . OnArray::toString($attribute, '=', ' ', "'") . '>';
    }

254
255
256
257
258
    /**
     * @return string
     */
    public function tail() {
        $html = '';
259
        $html .= $this->buildNewSip();
260

261
262
        $formId = $this->getFormId();

263
264
        // TODO: bootstrap. See BuildFormTable.tail()

265
        $html .= '</div> <!--class="tab-content" -->';  //  <div class="tab-content">
266
//        $html .= '<input type="submit" value="Submit">';
267

Carsten  Rose's avatar
Carsten Rose committed
268
269
270
        $formId = $this->getFormId();
        $tabId = $this->getTabId();

271
272
        $deleteUrl = $this->createDeleteUrl($this->formSpec['tableName'], $this->store->getVar(SIP_RECORD_ID, STORE_SIP));

273
        $html .= '</form>';  //  <form class="form-horizontal" ...
274
275
276
277
278
279
        $html .= <<<EOF
        <script type="text/javascript">
            $(function () {
                'use strict';
                QfqNS.Log.level = 0;

Carsten  Rose's avatar
Carsten Rose committed
280

Carsten  Rose's avatar
Carsten Rose committed
281
282
283
284
            var qfqPage = new QfqNS.QfqPage({
                tabsId: '$tabId',
                formId: '$formId',
                submitTo: 'typo3conf/ext/qfq/qfq/api/save.php',
285
                deleteUrl: '$deleteUrl'
286
            });
Carsten  Rose's avatar
Carsten Rose committed
287
            })
288
289
         </script>
EOF;
290
        $html .= '</div>';  //  <div class="container-fluid"> === main <div class=...> around everything
291

292
293
294
295
296
297
298
299
300
301
        return $html;
    }

    /**
     * @param array $formElement
     * @param $htmlFormElementId
     * @param $value
     * @return mixed
     */
    public function buildPill(array $formElement, $htmlFormElementId, $value) {
302
        $html = '';
303
304
305
306
        // save parent processed FE's
        $tmpStore = $this->feSpecNative;

        // child FE's
307
        $sql = SQL_FORM_ELEMENT_SPECIFIC_CONTAINER;
308
        $this->feSpecNative = $this->db->sql($sql, ROW_REGULAR, ['yes', $this->formSpec["id"], 'native,container', $formElement['id']]);
309
        HelperFormElement::explodeParameterInArrayElements($this->feSpecNative);
310
311
312
313
314
        $html = $this->elements($this->store->getVar(SIP_RECORD_ID, STORE_SIP), FORM_ELEMENTS_NATIVE_SUBRECORD);

        // restore parent processed FE's
        $this->feSpecNative = $tmpStore;

315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
        return $html;
    }


    public function buildRowNative($formElement, $elementHtml) {
        $html = '';

        $html .= $this->wrapItem(WRAP_SETUP_LABEL, $formElement['label']);
        $html .= $this->wrapItem(WRAP_SETUP_INPUT, $elementHtml);
        $html .= $this->wrapItem(WRAP_SETUP_NOTE, $formElement['note'], true);

        $html = $this->wrapItem(WRAP_SETUP_ELEMENT, $html);

        return $html;
    }

    public function buildRowPill($formElement, $elementHtml) {
        $html = '';

        $html .= $this->wrapItem(WRAP_SETUP_INPUT, $elementHtml);

        $active = $this->isFirstPill ? ' active' : '';

338
        $html = Support::wrapTag('<div role="tabpanel" class="tab-pane' . $active . '" id="' . $this->createAnker($formElement['id']) . '">', $html);
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353

        $this->isFirstPill = false;

        return $html;
    }

    public function buildRowFieldset($formElement, $elementHtml) {
    }


    public function buildRowSubrecord($formElement, $elementHtml) {
        $html = '';
        $html .= $this->wrapItem(WRAP_SETUP_ELEMENT, $this->wrapItem(WRAP_SETUP_SUBRECORD, $formElement['label']));
        $html .= $this->wrapItem(WRAP_SETUP_ELEMENT, $this->wrapItem(WRAP_SETUP_SUBRECORD, $elementHtml));
        $html .= $this->wrapItem(WRAP_SETUP_ELEMENT, $this->wrapItem(WRAP_SETUP_SUBRECORD, $formElement['note']));
354
355
356

        return $html;
    }
357
}