Passed
Branch master (c2f34b)
by greg
02:22
created

EditorSave.js ➔ ???   B

Complexity

Conditions 5
Paths 4

Size

Total Lines 28

Duplication

Lines 0
Ratio 0 %

Importance

Changes 7
Bugs 7 Features 0
Metric Value
c 7
b 7
f 0
nc 4
nop 0
dl 0
loc 28
cc 5
rs 8.439

1 Function

Rating   Name   Duplication   Size   Complexity  
A EditorSave.js ➔ ... ➔ ??? 0 3 1
1
/*global document, window, json, alert */
2
3
import {IframeNode} from '../utils/iframe'
4
import EditorUtils from './EditorUtils'
5
import Json from '../modules/EditorJson'
6
import on from 'on'
7
8
export default class EditorSave {
9
  constructor() {
10
    this._json = Json.instance
11
    this._saveType = 'draft'
12
13
    this.onFileSaved = on(this)
14
15
    this._abeForm = document.querySelector('#abeForm')
16
    this._abeDisplayStatus = document.querySelector('[data-display-status]')
17
    this._abeFormSubmit = document.querySelector('#abeForm button[type=submit]')
18
19
    this._handleSubmitClick = this._submitClick.bind(this)
20
21
    this._btnSaves = document.querySelectorAll('.btn-save')
22
    Array.prototype.forEach.call(this._btnSaves, (btnSave) => {
23
      btnSave.addEventListener('click', this._handleSubmitClick)
24
    })
25
26
    var pageTpl = document.querySelector('#page-template')
27
    if(typeof pageTpl !== 'undefined' && pageTpl !== null) {
28
      document.querySelector('#page-template').addEventListener('load', () => {
29
        EditorUtils.checkAttribute()
30
      })
31
    }
32
33
    if(typeof this._abeForm !== 'undefined' && this._abeForm !== null) {
34
      this._formSubmit()
35
    }
36
  }
37
38
  /**
39
   * return abe form to json
40
   * @return {Object} json
41
   */
42
  serializeForm() {
43
    var abeForm = document.getElementById('abeForm')
44
    if (abeForm == null) return
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
45
      
46
    var inputs = [].slice.call(abeForm.querySelectorAll('input'))
47
    var selects = [].slice.call(abeForm.querySelectorAll('select'))
48
    inputs = inputs.concat(selects)
49
    var textareas = [].slice.call(abeForm.querySelectorAll('textarea'))
50
    inputs = inputs.concat(textareas)
51
52
    this._json.data = json
53
54
    Array.prototype.forEach.call(inputs, (input) => {
55
      var dataId = input.getAttribute('data-id')
56
      if(input.type === 'file') return
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
57
      if(typeof dataId !== 'undefined' && dataId !== null) {
58
        if(dataId.indexOf('[') > -1){
59
          var obj = dataId.split('[')[0]
60
          var index = dataId.match(/[^\[]+?(?=\])/)[0]
61
          var key = dataId.replace(/[^\.]+?-/, '')
62
          if(typeof this._json.data[obj] === 'undefined' || this._json.data[obj] === null) this._json.data[obj] = []
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
63
          if(typeof this._json.data[obj][index] === 'undefined' || this._json.data[obj][index] === null) this._json.data[obj][index] = {}
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
64
          this._json.data[obj][index][key] = input.value
65
          var emptyObject = 0
66
          for(var prop in this._json.data[obj][index]) {
0 ignored issues
show
Complexity introduced by
A for in loop automatically includes the property of any prototype object, consider checking the key using hasOwnProperty.

When iterating over the keys of an object, this includes not only the keys of the object, but also keys contained in the prototype of that object. It is generally a best practice to check for these keys specifically:

var someObject;
for (var key in someObject) {
    if ( ! someObject.hasOwnProperty(key)) {
        continue; // Skip keys from the prototype.
    }

    doSomethingWith(key);
}
Loading history...
67
            if(this._json.data[obj][index][prop].trim() !== '') emptyObject++
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
68
          }
69
          if(emptyObject === 0) {
70
            delete this._json.data[obj][index]
71
          }
72
        }else {
73
          var value
74
75
          if (input.nodeName === 'SELECT') {
76
            var checked = input.querySelectorAll('option:checked')
77
            value = []
78
            Array.prototype.forEach.call(checked, (check) => {
79
              if(check.value !== '') {
80
                if(check.value.indexOf('{') > -1 || check.value.indexOf('[') > -1) {
81
                  value.push(JSON.parse(check.value))
82
                }else {
83
                  value.push(check.value)
84
                }
85
              }
86
            })
87
          }else if (input.getAttribute('data-autocomplete') === 'true') {
88
            var results = input.parentNode.querySelectorAll('.autocomplete-result-wrapper .autocomplete-result')
89
            value = []
90
            Array.prototype.forEach.call(results, (result) => {
91
              var val = result.getAttribute('value')
92
              if(val !== '') {
93
                if(val.indexOf('{') > -1 || val.indexOf('[') > -1) {
94
                  value.push(JSON.parse(val))
95
                }else {
96
                  value.push(val)
97
                }
98
              }
99
            })
100
          }else {
101
            value = input.value.replace(/\"/g, '\"') + ''
102
          }
103
          this._json.data[dataId] = value
104
        }
105
      }
106
    })
107
  }
108
109
  savePage(type) {
110
    var target = document.querySelector(`[data-action="${type}"]`)
111
    this.serializeForm()
112
    target.classList.add('loading')
113
    target.setAttribute('disabled', 'disabled')
114
    var url = target.getAttribute('data-url')
115
116
    this._json.save(this._saveType, url)
117
        .then((result) => {
118
          target.classList.add('done')
119
          // this._populateFromJson(this._json.data)
120
121
          target.classList.remove('loading')
122
          target.classList.remove('done')
123
          target.removeAttribute('disabled')
124
125
          if(result.success === 1) {
126
            this._abeDisplayStatus.innerHTML = result.json.abe_meta.status
127
            window.json = result.json
128
          }
129
          var formWrapper = document.querySelector('#abeForm')
130
          Array.prototype.forEach.call(formWrapper.classList, (classStr) => {
131
            if(classStr.indexOf('status-') > -1) formWrapper.classList.remove(classStr)
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
132
          })
133
          formWrapper.classList.add('status-' + result.json.abe_meta.status)
134
          this.onFileSaved._fire()
135
        }).catch(function(e) {
136
          console.error(e)
137
        })
138
  }
139
140
  /**
141
   * Listen form submit and save page template 
142
   * @return {void}
143
   */
144
  _formSubmit() {
145
    this._abeForm.addEventListener('submit', (e) => {
146
      e.preventDefault()
147
      this.savePage(this._saveType)
148
    })
149
  }
150
151
  _submitClick(e) {
152
    this._saveType = e.currentTarget.getAttribute('data-action')
153
    if (this._saveType !== 'draft' && this._saveType !== 'reject') {
154
      this._abeFormRequired()
155
    }else {
156
      this.savePage(this._saveType)
157
      // this._abeFormSubmit.click()
158
    }
159
  }
160
161
  _abeFormRequired() {
162
    var formGroups = [].slice.call(document.getElementById('abeForm').querySelectorAll('.form-group'))
163
    var valid = true
164
165
    Array.prototype.forEach.call(formGroups, (formGroup) => {
166
      var input = formGroup.querySelector('[data-required=true]')
167
      if(typeof input !== 'undefined' && input !== null) {
168
        var required = input.getAttribute('data-required')
169
170
        var precontrib = formGroup.getAttribute('data-precontrib-templates')
171
172
        if (precontrib != null && precontrib != '') {
173
          if (precontrib != 'json.abe_meta.template') {
174
            return
175
          }
176
        }
177
178
        var autocomplete = input.getAttribute('data-autocomplete')
179
        if(typeof autocomplete !== 'undefined' && autocomplete !== null && (autocomplete === 'true' || autocomplete === true)) {
180
          var countValue = input.parentNode.querySelectorAll('.autocomplete-result')
181
          if (countValue.length <= 0) {
182
            formGroup.classList.add('has-error')
183
            valid = false
184
          }else {
185
            formGroup.classList.remove('has-error')
186
          }
187
        }else if(typeof required !== 'undefined' && required !== null && (required === 'true' || required === true)) {
188
          if (input.value === '') {
189
            formGroup.classList.add('has-error')
190
            valid = false
191
          }else {
192
            formGroup.classList.remove('has-error')
193
          }
194
        }
195
      }
196
    })
197
198
    if (valid) {
199
      this.savePage(this._saveType)
200
      // this._abeFormSubmit.click()
201
    }else {
202
      alert('Required fields are missing')
203
    }
204
  }
205
206
  /**
207
   * populate all form and iframe html with json
208
   * @param  {Object} json object with all values
209
   * @return {null}
210
   */
211
  _populateFromJson(json) {
212
    this._json.data = json
213
    var forms = document.querySelectorAll('.form-abe')
214
    Array.prototype.forEach.call(forms, (form) => {
215
      var id = form.getAttribute('data-id')
216
      if(typeof id != 'undefined' && id !== null && typeof json[id] != 'undefined' && json[id] !== null) {
217
        var value = json[id]
218
        if(typeof value === 'object' && Object.prototype.toString.call(value) === '[object Array]') {
219
          value = JSON.stringify(value)
220
        }else if(typeof value === 'object' && Object.prototype.toString.call(value) === '[object Object]') {
221
          value = JSON.stringify(value)
222
        }
223
        form.value = value
224
225
        var node = IframeNode('#page-template', '[data-abe-' + id.replace(/\[([0-9]*)\]/g, '$1') + ']')[0]
226
        EditorUtils.formToHtml(node, form)
227
      }
228
    })
229
  }
230
}