Completed
Push — master ( d0f3cd...eb99f6 )
by Bui Quang
10s
created

form.js ➔ ... ➔ this._assignExistDFIs   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
c 0
b 0
f 0
nc 1
nop 0
dl 0
loc 13
rs 9.4285
1
import DFI from './dfi.js';
2
import Layout from './layout.js';
3
import Sortable from 'sortablejs';
4
5
var Form = function(id) {
6
7
    /**
8
     * form variable is created to represent Form instance.
9
     */
10
    var form = this;
11
12
    /**
13
     * element variable is created to be a master element of the Form, all the variables will be found via element variable
14
     * Eg: element.find('.btn-add')
15
     */
16
    var element = $(id);
17
18
    /**
19
     * addButton variable is created to represent Add DFI Button of the Form.
20
     */
21
    var addButton = element.find('#add_dfi_button');
22
23
    /**
24
     * saveButton variable is created to represent Save Button of the Form.
25
     */
26
    var saveButton = element.find('#save_form_button');
27
28
    /**
29
     * dfis variable is created to represent all dfis exist on the Form.
30
     */
31
    var dfis = [];
32
33
    /**
34
     * dfiWrapper variable is created to represent wrapper element of all dfis exist on Form.
35
     */
36
    var dfiWrapper = element.find('#dfi_wrapper');
37
38
    /**
39
     * errorWrapper variable is created to represent wrapper element of errors all exist on Form.
40
     */
41
    var errorWrapper = element.find('#error_wrapper');
42
43
    /**
44
     * errors variable is created to temporary store all the errors of the Form.
45
     */
46
    var errors = [];
47
48
    /**
49
     * dfiClass variable is created to represent dfi class, for better readable.
50
     */
51
    var dfiClass = '.item-option';
52
53
    /** 
54
     * layout variable is created to handle all rendering layout stuff for the Form.
55
     */
56
    var layout = new Layout();
57
58
    /**
59
     * Initialize actions when create a single instance of Form.
60
     */
61
    this.init = function() {
62
        /* Reindex all the dfis (if needed). */
63
        form._reindexDFIs();
64
        /* Assign all exist dfis to dfis variable. */
65
        form._assignExistDFIs();
66
        /* Initialize Sortable JS to reorder form's dfis. */
67
        form._initilizeSortable();
68
        /* Initialize Tooltip. */
69
        form._initilizeTooltip();
70
        /* Validate all the data when submit the Form. */
71
        form._validate();
72
        /* Bind add new dfi feature when click on Add DFI Button. */
73
        form._addNewDFI();
74
    }
75
76
    /**
77
     * Add new dfi actions when user click on Add DFI Button.
78
     */
79
    this._addNewDFI = function() {
80
81
        addButton.click(function(e) {
82
            e.preventDefault();
83
            /* First: count total dfis, assign it to a temporary variable totalDFI. */
84
            var totalDFI = form._countTotalDFIs();
85
            /* Second: disable add button, don't let user click multiple times. */
86
            form._disableAddButton();
87
            /* Third: 
88
             *    Call an AJAX to get a default layout of a dfi .
89
             *    Display the default layout we just received in the bottom of the dfi wrapper.
90
             *    Initialize new dfi.
91
             *    Update Form's dfi variable.
92
             *    Enable add button.
93
             */
94
            layout.getDefaultDFILayout(totalDFI + 1).done(function(html){
95
96
                form._addNewLayout(html);
97
98
                var dfi = new DFI(totalDFI+1, form);
99
                dfi.init();
100
101
                form._updateDFIVariable(dfi);
102
103
                form._enableAddButton();
104
105
                form._initilizeTooltip();
106
107
            });
108
            
109
110
        });
111
112
    }
113
114
    /**
115
     * Validate all the data when submit the Form
116
     */
117
    this._validate = function() {
118
119
        saveButton.click(function(e){
120
            e.preventDefault();
121
            
122
            /* Check if form input is valid or not. */
123
            if(form._validateDFIs()) {
124
                /* If yes: submit the form. */
125
                form._submit();
126
            } else {
127
                /**
128
                 * If no:
129
                 *    Remove all exist errors on FE.
130
                 *    Add new errors on FE.
131
                 *    Truncate errors variable after display error on FE.
132
                 */
133
                form._removeExistErrors();
134
                form._addNewErrors();
135
                form._truncateErrorsVariable();
136
            }
137
            
138
        });
139
    }
140
141
    /**
142
     * Validate data from all the dfis
143
     */
144
    this._validateDFIs = function() {
145
        /**
146
         * Create a loop to loop through all exist dfis.
147
         * Validate the dfis, return false if any dfi is invalid.
148
         * Store all errors of all dfis.
149
         * Truncate the current errors of all dfis
150
         */
151
        var flag = true;
152
        dfis.forEach(function(dfi){
153
            if(!dfi.validate())  {
154
                flag = false;
155
                form._updateErrors(dfi.getErrors());
156
                dfi.truncateErrors();
157
            }   
158
        });
159
160
        return flag;
161
    }
162
163
    /**
164
     * Remove all current exits errors on FE.
165
     */
166
    this._removeExistErrors = function() {
167
168
        errorWrapper.empty();
169
    
170
    }
171
172
    /**
173
     * Truncate errors variables
174
     */
175
    this._truncateErrorsVariable = function() {
176
        errors = [];
177
    }
178
179
    /**
180
     * Add new error on FE
181
     */
182
    this._addNewErrors = function() {
183
        /**
184
         * Create a loop to loop through all exist errors.
185
         * For each error, create a list item to display the error.
186
         * Display the new errors in error wrapper on FE.
187
         */
188
        /* Get error listing wrapper */
189
        var errorListingWrapper = layout.getErrorListingWrapperLayout();
190
        var errorListing = '';
191
        /* Get error listing */
192
        errors.forEach(function(error){
193
            errorListing += layout.getErrorSingleListingLayout(error);
194
        });
195
        /* Get errors layout by replace markup in error listing wrapper with error listing */
196
        var errorsLayout = errorListingWrapper.replace('%error-list-markup%', errorListing);
197
        /* Display errors layout */
198
        errorWrapper.append(errorsLayout);
199
    }
200
201
    /**
202
     * Update value for errors variable of the Form.
203
     */
204
    this._updateErrors = function(error) {
205
        error.forEach(function(err){
206
207
            errors.push(err);
208
209
        });
210
211
    }
212
213
    /**
214
     * Add new layout to the Form
215
     */
216
    this._addNewLayout = function(html) {
217
        /* Display the layout passed via parameter to the bottom of dfi wrapper. */
218
        $(JSON.parse(html)).appendTo(dfiWrapper);
219
220
    }
221
222
    /**
223
     * Assign all exist dfi to dfi variable
224
     */
225
    this._assignExistDFIs = function() {
226
227
        element.find(dfiClass).each(function() {
228
229
            var dfiIndex = $(this).attr('data-index');
230
            var dfi = new DFI(dfiIndex, form);
231
            dfi.init();
232
233
            form._updateDFIVariable(dfi);
234
235
        });
236
237
    }
238
239
    /**
240
     * Initialize Sortable to reorder form's dfis.
241
     */
242
    this._initilizeSortable = function() {
243
        var sortableWrapper = dfi_wrapper;
0 ignored issues
show
Bug introduced by
The variable dfi_wrapper seems to be never declared. If this is a global, consider adding a /** global: dfi_wrapper */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
244
        Sortable.create(sortableWrapper, { 
245
246
            animation: 150,
247
            // Element dragging ended
248
            onEnd: function (evt) {
249
                var droppedIndex = evt.oldIndex;
250
                var draggedIndex = evt.newIndex;
251
                var indexDifferent = (droppedIndex != draggedIndex);
252
                /* Check if old index is not the same as old index. */
253
                if(indexDifferent) {
254
                    /* Swap two element. */
255
                    form._sortDFIsVariable();
256
                    form._reindexDFIs();
257
258
                    /** 
259
                     * Check if the draggedIndex or droppedIndex equal to 0.
260
                     * It mean that draggedDFIElement or droppedDFIElement is the first dfi. 
261
                     * Add delete button on the new first dfi and remove delete button on the opposite dfi.
262
                     * Bind delete event on the new first dfi.
263
                     */
264
                    var draggElFirst = (draggedIndex == 0);
265
                    var droppElFirst = (droppedIndex == 0);
266
267
                    if(draggElFirst || droppElFirst) {
268
269
                        if(draggElFirst) {
270
                            /**
271
                             * 0 - 1 - 2
272
                             * swap 2 with 0.
273
                             * 0 -> 1, 2 -> 0
274
                             * Remove delete button on 0, add delete button on 1.
275
                             */
276
                            dfis[0].removeDeleteButton();
277
                            dfis[1].addDeleteButton();
278
                            dfis[1].onDelete();
279
280
                        } else if (droppElFirst) {
281
                            /**
282
                             * 0 - 1 - 2
283
                             * swap 0 with 2.
284
                             * 1 -> 0, 0 -> 2
285
                             * Remove delete button on 0, add delete button on 2.
286
                             */
287
                            dfis[0].removeDeleteButton();
288
                            dfis[draggedIndex].addDeleteButton();
289
                            dfis[draggedIndex].onDelete();
290
291
                        }
292
293
                    } 
294
                
295
                }
296
            
297
            },
298
299
        });
300
301
    }
302
303
    this._initilizeTooltip = function() {
304
        $('[data-toggle="tooltip"]').tooltip();
305
    }
306
307
    /**
308
     * Count total number of dfis.
309
     */
310
    this._countTotalDFIs = function() {
311
312
        return dfis.length;
313
314
    }
315
316
    /**
317
     * Update value for dfis variable of the Form.
318
     */
319
    this._updateDFIVariable = function(dfi) {
320
321
        dfis.push(dfi);
322
323
    }
324
325
    /**
326
     * Submit the Form.
327
     */
328
    this._submit = function() {
329
330
        element.submit();
331
332
    }
333
334
    /**
335
     * Remove a dfi from the Form.
336
     */
337
    this.removeDFI = function(dfiIndex) {
338
339
        /**
340
         * First: we need to remove the dfi from dfis variable.
341
         * Second: we need to reindex all the dfis element of the Form (Html).
342
         * Third: we need to reindex all the dfis object of the Form (Javascript Object).
343
         */
344
        form._rmDFIInDFIsVar(dfiIndex);
345
        form._reindexDFIs();
346
347
    }
348
349
    /**
350
     * Remove a dfi from dfis variable.
351
     */
352
    this._rmDFIInDFIsVar = function(dfiIndex) {
353
354
        dfis.splice(dfiIndex, 1);
355
356
    }
357
358
    /**
359
     * Check and reindex all dfis.
360
     */
361
    this._reindexDFIs = function() {
362
363
        /**
364
         * Loop through all exist dfi element.
365
         * Reindex the dfi via index of the element.
366
         */
367
        dfis.forEach(function(dfi, index){
368
            
369
            var dfiIndex = index + 1;
370
            var indexDifferent = (dfiIndex != dfi.getIndex());
371
            if(indexDifferent) {
372
                dfi.reindex(dfiIndex);
373
            }
374
375
        })
376
377
    }
378
379
    /**
380
     * Disable add button.
381
     */
382
    this._disableAddButton = function() {
383
384
        addButton.css('pointer-events', 'none');
385
386
    }
387
388
    /**
389
     * Enable add button.
390
     */
391
    this._enableAddButton = function() {
392
393
        addButton.css('pointer-events', 'visible');
394
395
    }
396
397
    /**
398
     * Sort dfi variable after drag and drop.
399
     */
400
    this._sortDFIsVariable = function() {
401
402
        var tempDFI = [];
403
        element.find(dfiClass).each(function(elementIndex){
404
405
            var dfiElement = $(this);
406
            var oldIndex = dfiElement.attr('data-index') - 1;
407
            var newIndex = elementIndex;
408
            var indexDifferent = (oldIndex != newIndex);
409
            if(indexDifferent) {
410
                tempDFI[newIndex] = dfis[newIndex];
411
                if(typeof tempDFI[oldIndex] == 'undefined') {
412
                    dfis[newIndex] = dfis[oldIndex];
413
                } else {
414
                    dfis[newIndex] = tempDFI[oldIndex];
415
                }
416
            }
417
418
        });
419
420
    }
421
422
}
423
424
export default Form;