BuildFormBootstrap.php 12.8 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';
        }
Carsten  Rose's avatar
Carsten Rose committed
40

41
//        $this->formSpec['class'] = 'none';
42
43
    }

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


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

53
54
        $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>';
55

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

60
61
62
63
64
65
66
67
68
        $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>';
69
70
71
72

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

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

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

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

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

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

99
100
101
102
        $title = Support::wrapTag('<div class="hidden-xs col-sm-6 col-md-8">', Support::wrapTag('<h3>', $this->formSpec['title']));
        $button = Support::wrapTag('<div class="col-xs-12 col-sm-6 col-md-4">', $this->buildButtons());
//        '<div class="row hidden-xs">
        $html .= Support::wrapTag('<div class="row">', $title . $button);
103
104


105
106
        $pill = $this->buildPillNavigation(OnArray::filter($this->feSpecNative, 'type', 'pill'));
        $html .= Support::wrapTag('<div class="row">', $pill);
107

108
109
        $html .= $this->getFormTag();

110
        $html .= '<div class="tab-content">';
111
112
113
114

        return $html;
    }

115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
    /**
     * Simlute Submit Button: http://www.javascript-coder.com/javascript-form/javascript-form-submit.phtml
     *
     * @return string
     */
    private function buildButtons() {
        $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) . "'";
        }

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

        $buttonDebug = <<<BUTTON
        <div class="btn-group" role="group">
            <button id="debug-button" type="button" class="btn btn-default navbar-btn" title="$sipParamString"><span class="glyphicon glyphicon-eye-open"></span></button>
            <a href="$formEditUrl" id="form-edit-button" class="btn btn-default navbar-btn" title="Edit form"><span class="glyphicon glyphicon-wrench"></span></a>
        </div>
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;
        }

        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;
        }

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


//        <div class="btn-toolbar pull-right" role="toolbar">
        $html = <<<BUTTON
        <div class="btn-toolbar" role="toolbar">
            $buttonFormEdit
            <div class="btn-group" role="group">
                <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>
            </div>
            $buttonDelete
            $buttonNew
        </div>
BUTTON;
        return $html;
    }

Carsten  Rose's avatar
Carsten Rose committed
176
    /**
177
     * @param $pillArray
Carsten  Rose's avatar
Carsten Rose committed
178
     * @return string
179
     * @throws UserException
Carsten  Rose's avatar
Carsten Rose committed
180
     */
181
182
183
    private function buildPillNavigation($pillArray) {
        $pillButton = '';
        $pillDropdown = '';
184
        $htmlDropdown = '';
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202

        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);
            }

203
            // Anker for pill navigation
204
            $a = '<a href="#' . $this->createAnker($formElement['id']) . '" data-toggle="tab">' . $formElement['label'] . '</a>';
205

206
207
208
209
210
211
212
            if ($ii <= $maxVisiblePill) {
                $pillButton .= '<li role="presentation" ' . $active . '>' . $a . '</li>';
            } else {
                $pillDropdown .= '<li>' . $a . '</li>';
            }
            $active = '';
        }
213

214
215
        // Pill Dropdown necessary?
        if ($ii > $maxVisiblePill) {
216
217
            $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;
218
            $htmlDropdown = Support::wrapTag('<li role="presentation" class="dropdown">', $htmlDropdown, false);
219
        }
220

221
        $htmlDropdown = Support::wrapTag('<ul id="' . $this->getTabId() . '" class="nav nav-pills" role="tablist">', $pillButton . $htmlDropdown);
222
        $htmlDropdown = Support::wrapTag('<div class="col-md-12">', $htmlDropdown);
223

224
        return $htmlDropdown;
225
226
227
228
229
230
231
232
233
234
235
236
    }

    /**
     * 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
237
238
239
240
241
242
243
    /**
     * @return string
     */
    private function getTabId() {
        return 'qfqTabs';
    }

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

        $attribute = $this->getFormTagAtrributes();

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

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

258
259
260
261
262
    /**
     * @return string
     */
    public function tail() {
        $html = '';
263
        $html .= $this->buildNewSip();
264

265
266
        $formId = $this->getFormId();

267
268
        // TODO: bootstrap. See BuildFormTable.tail()

269
        $html .= '</div> <!--class="tab-content" -->';  //  <div class="tab-content">
270
//        $html .= '<input type="submit" value="Submit">';
271

Carsten  Rose's avatar
Carsten Rose committed
272
273
274
        $formId = $this->getFormId();
        $tabId = $this->getTabId();

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

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

Carsten  Rose's avatar
Carsten Rose committed
284

Carsten  Rose's avatar
Carsten Rose committed
285
286
287
288
289
290
291
292
                var qfqPage = new QfqNS.QfqPage({
                    tabsId: '$tabId',
                    formId: '$formId',
                    submitTo: 'typo3conf/ext/qfq/qfq/api/save.php',
                    deleteUrl: '$deleteUrl'
                });

                var qfqRecordList = new QfqNS.QfqRecordList('typo3conf/ext/qfq/qfq/api/delete.php');
Carsten  Rose's avatar
Carsten Rose committed
293
            })
294
295
         </script>
EOF;
296
        $html .= '</div>';  //  <div class="container-fluid"> === main <div class=...> around everything
297

298
299
300
301
302
303
304
305
306
307
        return $html;
    }

    /**
     * @param array $formElement
     * @param $htmlFormElementId
     * @param $value
     * @return mixed
     */
    public function buildPill(array $formElement, $htmlFormElementId, $value) {
308
        $html = '';
309
310
311
312
        // save parent processed FE's
        $tmpStore = $this->feSpecNative;

        // child FE's
313
        $sql = SQL_FORM_ELEMENT_SPECIFIC_CONTAINER;
314
        $this->feSpecNative = $this->db->sql($sql, ROW_REGULAR, ['yes', $this->formSpec["id"], 'native,container', $formElement['id']]);
315
        HelperFormElement::explodeParameterInArrayElements($this->feSpecNative);
316
317
318
319
320
        $html = $this->elements($this->store->getVar(SIP_RECORD_ID, STORE_SIP), FORM_ELEMENTS_NATIVE_SUBRECORD);

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

321
322
323
        return $html;
    }

324
325
326
327
328
    /**
     * @param $formElement
     * @param $elementHtml
     * @return string
     */
329
330
331
332
333
334
335
336
337
338
339
340
    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;
    }

341
342
343
344
345
    /**
     * @param $formElement
     * @param $elementHtml
     * @return string
     */
346
347
348
349
350
351
352
    public function buildRowPill($formElement, $elementHtml) {
        $html = '';

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

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

353
        $html = Support::wrapTag('<div role="tabpanel" class="tab-pane' . $active . '" id="' . $this->createAnker($formElement['id']) . '">', $html);
354
355
356
357
358
359

        $this->isFirstPill = false;

        return $html;
    }

360
361
362
363
    /**
     * @param $formElement
     * @param $elementHtml
     */
364
365
366
    public function buildRowFieldset($formElement, $elementHtml) {
    }

367
368
369
370
371
    /**
     * @param $formElement
     * @param $elementHtml
     * @return string
     */
372
373
374
375
376
    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']));
377
378
379

        return $html;
    }
380
}