Completed
Push — master ( 401bbc...02c732 )
by Grant
05:46 queued 02:35
created

SkillSampleAPI.SkillSample   B

Complexity

Conditions 6
Paths 32

Size

Total Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 6
nc 32
nop 0
dl 0
loc 1
rs 8.6666
c 1
b 0
f 0
1
var SkillSampleAPI = {};
2
3
SkillSampleAPI.wrapperClass = "applicant-evidence__skill-attribute--sample";
4
5
SkillSampleAPI.SkillSample = function (criteria_id) {
6
    this.criteria_id = criteria_id;
7
    this.name = null;
8
    this.type = null;
9
    this.date_created = null;
10
    this.http_link = null;
11
    this.story = null;
12
13
    this.isComplete = function () {
14
        //!= instead of !== is on purpose; want to check that none are empty strings or null
15
        return (this.criteria_id &&
16
                this.name &&
17
                this.type &&
18
                this.date_created &&
19
                this.http_link &&
20
                this.story);
21
    };
22
    
23
    /**
24
     * Return true if this object is ready to be saved to server
25
     * @return {Boolean}
26
     */
27
    this.isValid = function () {
28
        return this.criteria_id != false;
0 ignored issues
show
Best Practice introduced by
Comparing this.criteria_id to false using the != operator is not safe. Consider using !== instead.
Loading history...
Coding Style introduced by
It is recommended to use !== to compare with false.

Generally, it is recommended to use strict comparison whenever possible and not to rely on the weaker type-juggling comparison operator.

Read more about comparison operations.

Loading history...
29
    };
30
    
31
    this.isEmpty = function() {
32
        return (this.name == null &&
0 ignored issues
show
Best Practice introduced by
Comparing this.name to null using the == operator is not safe. Consider using === instead.
Loading history...
Coding Style introduced by
It is recommended to use === to compare with null.

Generally, it is recommended to use strict comparison whenever possible and not to rely on the weaker type-juggling comparison operator.

Read more about comparison operations.

Loading history...
33
                this.type == null &&
0 ignored issues
show
Best Practice introduced by
Comparing this.type to null using the == operator is not safe. Consider using === instead.
Loading history...
Coding Style introduced by
It is recommended to use === to compare with null.

Generally, it is recommended to use strict comparison whenever possible and not to rely on the weaker type-juggling comparison operator.

Read more about comparison operations.

Loading history...
34
                this.date_created == null &&
0 ignored issues
show
Best Practice introduced by
Comparing this.date_created to null using the == operator is not safe. Consider using === instead.
Loading history...
Coding Style introduced by
It is recommended to use === to compare with null.

Generally, it is recommended to use strict comparison whenever possible and not to rely on the weaker type-juggling comparison operator.

Read more about comparison operations.

Loading history...
35
                this.http_link == null &&
0 ignored issues
show
Best Practice introduced by
Comparing this.http_link to null using the == operator is not safe. Consider using === instead.
Loading history...
Coding Style introduced by
It is recommended to use === to compare with null.

Generally, it is recommended to use strict comparison whenever possible and not to rely on the weaker type-juggling comparison operator.

Read more about comparison operations.

Loading history...
36
                this.story == null);
0 ignored issues
show
Best Practice introduced by
Comparing this.story to null using the == operator is not safe. Consider using === instead.
Loading history...
Coding Style introduced by
It is recommended to use === to compare with null.

Generally, it is recommended to use strict comparison whenever possible and not to rely on the weaker type-juggling comparison operator.

Read more about comparison operations.

Loading history...
37
    };
38
    
39
    this.nullifyEmptyFields = function() {
40
        this.name = this.name ? this.name : null;
41
        this.type = this.type ? this.type : null;
42
        this.date_created = this.date_created ? this.date_created : null;
43
        this.http_link = this.http_link ? this.http_link : null;
44
        this.story = this.story ? this.story : null;
45
    };
46
};
47
48
    SkillSampleAPI.parseApplicationSkillSampleResponse = function(responseJson) {
49
        var samples = [];
50
        for (var i=0; i<responseJson.length; i++) {
51
            var applicationItem = responseJson[i];
52
            var item = applicationItem.work_sample;
53
54
            var criteria_id = applicationItem.criteria_id;
55
            var name = item.work_sample_name;
56
            var type = item.file_type;
57
            var date_created = item.work_sample_date_created;
58
            var http_link = item.work_sample_url;
59
            var story = item.work_sample_story;
60
61
            var sample = new SkillSampleAPI.SkillSample(criteria_id);
62
            sample.name = name;
63
            sample.type = type;
64
            sample.date_created = date_created;
65
            sample.http_link = http_link;
66
            sample.story = story;
67
            
68
            samples.push(sample);
69
        }
70
        return samples;
71
    };
72
73
        SkillSampleAPI.loadSavedSkillSamplesForJobApplication = function (jobApplicationId) {
74
            DataAPI.getSkillSamplesForApplication(jobApplicationId, function (request) {
0 ignored issues
show
Bug introduced by
The variable DataAPI seems to be never declared. If this is a global, consider adding a /** global: DataAPI */ 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...
75
                //Check that request returned a valid response
76
                if (request.status === 200 && request.response) {
77
                    var samples = SkillSampleAPI.parseApplicationSkillSampleResponse(JSON.parse(request.response));
78
                    SkillSampleAPI.populateApplicationUiSkillSamples(samples);
79
                }
80
            });
81
        };
82
83
        SkillSampleAPI.populateApplicationUiSkillSamples = function (samples) {
84
            for (var i=0; i<samples.length; i++) {
85
                var sample = samples[i];
86
87
                //find appropriate Evidence Panel
88
                var panel = document.querySelector('.applicant-evidence__skill[data-criteria-id="' + sample.criteria_id + '"]');
89
                //if panel exists, set saved values
90
                if (panel) {
91
                    var name = panel.querySelector('input[name=\"sample_name\"]');
92
                    if (name) {
93
                        name.value = sample.name;
94
                    }
95
                    var type = panel.querySelector('select[name=\"sample_type\"]');
96
                    if (type) {
97
                        type.value = sample.type;
98
                    }
99
                    var date_created = panel.querySelector('input[name=\"sample_date_created\"]');
100
                    if (date_created) {
101
                        date_created.value = sample.date_created;
102
                    }
103
                    var http_link = panel.querySelector('input[name=\"sample_http_link\"]');
104
                    if (http_link) {
105
                        http_link.value = sample.http_link;
106
                    }
107
                    var story = panel.querySelector('textarea[name=\"sample_story\"]');
108
                    if (story) {
109
                        story.value = sample.story;
110
                    }
111
112
                    //Run status change handler, because declartion may now be complete
113
                    SkillSampleAPI.onStatusChange(sample.criteria_id);
114
                    
115
                    //if new sample is not empty, make sure it appears in ui
116
                    //And show status as currently saved
117
                    if (!sample.isEmpty()) {
118
                        var showButton = panel.querySelector(".applicant-evidence__optional-button--sample");
119
                        EvidenceAPI.addWorkSample(showButton);
0 ignored issues
show
Bug introduced by
The variable EvidenceAPI seems to be never declared. If this is a global, consider adding a /** global: EvidenceAPI */ 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...
120
                        
121
                        EvidenceAPI.setUiSaved(sample.criteria_id, SkillSampleAPI, true);
122
                    }
123
                }
124
            }
125
        };
126
127
        SkillSampleAPI.populateApplicationPreviewUiSkillSamples = function (samples) {
128
            for (var i=0; i<samples.length; i++) {
129
                var sample = samples[i];
130
131
                //find appropriate Evidence Panel
132
                var panel = document.querySelector('.applicant-evidence-preview__accordion-wrapper[data-criteria-id="' + sample.criteria_id + '"]');
133
                //if panel exists, set saved values
134
                if (panel) {
135
                    var name = panel.querySelector('.applicant-evidence-preview__evidence-name');
136
                    if (name) {
137
                        name.innerHTML = sample.name;
138
                    }
139
                    /*
140
                    var type = panel.querySelector('select[name=\"sample_type\"]');
141
                    if (type) {
142
                    type.innerHTML = ref.type;
143
                }
144
                */
145
                var date_created = panel.querySelector('.applicant-evidence-preview__evidence-date');
146
                if (date_created) {
147
                    date_created.innerHTML = sample.date_created;
148
                }
149
                var http_link = panel.querySelector('.applicant-evidence-preview__evidence-link');
150
                if (http_link) {
151
                    http_link.href = sample.http_link;
152
                }
153
                var story = panel.querySelector('.applicant-evidence-preview__evidence-story');
154
                if (story) {
155
                    story.innerHTML = sample.story;
156
                }
157
158
                //Hide null-response, and show data
159
                var refContent = panel.querySelector('.applicant-evidence-preview__evidence-content');
160
                refContent.classList.remove("hidden");
161
                var nullResponse = panel.querySelector('.applicant-evidence-preview__evidence-null');
162
                nullResponse.classList.add("hidden");
163
            }
164
        }
165
    };
166
167
168
169
    /**
170
    * Saves all completed samples for criteria of given type,
171
    * while Deleteing all incomplete samples of the given type.
172
    *
173
    * If criteriaType is undefined, it saves/deletes ALL completed skill declarations.
174
    *
175
    * Call onSuccess if all SkillSamples are saved/deleted successfully
176
    * Call onFailure if some/all requests returned with unexpected status
177
    *
178
    * @param {string} criteriaType
179
    * @param {function} onSuccess
180
    * @return {undefined}
181
    */
182
    SkillSampleAPI.saveSkillSamples = function (criteriaType, onSuccess, onFailure) {
183
        if (criteriaType) {
184
            var evidencePanels = document.querySelectorAll(".applicant-evidence__skill[data-criteria-type=\"" + criteriaType + "\"]:not(.template)");
185
        } else if (criteriaType === undefined) {
186
            var evidencePanels = document.querySelectorAll(".applicant-evidence__skill:not(.template)");
0 ignored issues
show
Comprehensibility Naming Best Practice introduced by
The variable evidencePanels already seems to be declared on line 184. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
Bug introduced by
It seems like evidencePanels was already defined.
Loading history...
187
        } else {
188
            Utilities.debug ? console.log("Cannot save Skill Samples with given type.") : null;
0 ignored issues
show
Bug introduced by
The variable Utilities seems to be never declared. If this is a global, consider adding a /** global: Utilities */ 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...
Debugging Code introduced by
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
Bug introduced by
Did you forget to assign or call a function?

This error message can for example pop up if you forget to assign the result of a function call to a variable or pass it to another function:

function someFunction(x) {
    (x > 0) ? callFoo() : callBar();
}

// JSHint expects you to assign the result to a variable:
function someFunction(x) {
    var rs = (x > 0) ? callFoo() : callBar();
}

// If you do not use the result, you could also use if statements in the
// case above.
function someFunction(x) {
    if (x > 0) {
        callFoo();
    } else {
        callBar();
    }
}
Loading history...
189
            return;
190
        }
191
192
        var submittedRequests = 0; //to keep track of number of HTTP calls in progress
193
        var requestsSuccessful = true;
194
195
        var applicationId = document.getElementById("jobApplicationJobApplicationId").value;
196
197
        if (!applicationId) {
198
            Utilities.debug ? console.log("Cannot save Skill Samples without an Application Id") : null;
0 ignored issues
show
Bug introduced by
Did you forget to assign or call a function?

This error message can for example pop up if you forget to assign the result of a function call to a variable or pass it to another function:

function someFunction(x) {
    (x > 0) ? callFoo() : callBar();
}

// JSHint expects you to assign the result to a variable:
function someFunction(x) {
    var rs = (x > 0) ? callFoo() : callBar();
}

// If you do not use the result, you could also use if statements in the
// case above.
function someFunction(x) {
    if (x > 0) {
        callFoo();
    } else {
        callBar();
    }
}
Loading history...
199
            return;
200
        }
201
202
        for (var i=0; i<evidencePanels.length; i++) {
0 ignored issues
show
Bug introduced by
The variable evidencePanels seems to be used out of scope.

This error can usually be fixed by declaring the variable in the scope where it is used:

function someFunction() {
    (function() {
        var i = 0;
    })();

    // i is not defined.
    alert(i);
}

// This can be fixed by moving the var statement to the outer scope.

function someFunction() {
    var i;
    (function() {
        i = 1;
    })();

    alert(i);
};
Loading history...
203
            var panel = evidencePanels[i];
0 ignored issues
show
Bug introduced by
The variable evidencePanels seems to be used out of scope.

This error can usually be fixed by declaring the variable in the scope where it is used:

function someFunction() {
    (function() {
        var i = 0;
    })();

    // i is not defined.
    alert(i);
}

// This can be fixed by moving the var statement to the outer scope.

function someFunction() {
    var i;
    (function() {
        i = 1;
    })();

    alert(i);
};
Loading history...
204
            var sample = SkillSampleAPI.getSkillSampleFromEvidencePanel(panel);
205
206
            //Only save if this sample is complete
207
            if (sample.isValid()) {
208
                submittedRequests = submittedRequests + 1;
209
                DataAPI.saveSkillSample(sample, sample.criteria_id, applicationId, function (response) {
0 ignored issues
show
Bug introduced by
The variable DataAPI seems to be never declared. If this is a global, consider adding a /** global: DataAPI */ 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...
Bug introduced by
It is generally not recommended to make functions within a loop.

While making functions in a loop will not lead to any runtime error, the code might not behave as you expect as the variables in the scope are not imported by value, but by reference. Let’s take a look at an example:

var funcs = [];
for (var i=0; i<10; i++) {
    funcs.push(function() {
        alert(i);
    });
}

funcs[0](); // alert(10);
funcs[1](); // alert(10);
/// ...
funcs[9](); // alert(10);

If you would instead like to bind the function inside the loop to the value of the variable during that specific iteration, you can create the function from another function:

var createFunc = function(i) {
    return function() {
        alert(i);
    };
};

var funcs = [];
for (var i=0; i<10; i++) {
    funcs.push(createFunc(i));
}

funcs[0](); // alert(0)
funcs[1](); // alert(1)
// ...
funcs[9](); // alert(9)
Loading history...
210
                    if (response.status !== 200) {
211
                        requestsSuccessful = false;
212
                    }
213
                    submittedRequests = submittedRequests - 1;
0 ignored issues
show
Bug introduced by
The variable submittedRequests is changed as part of the for loop for example by submittedRequests + 1 on line 208. Only the value of the last iteration will be visible in this function if it is called after the loop.
Loading history...
214
                    if (submittedRequests === 0) {
215
                        if (onSuccess && requestsSuccessful) {
0 ignored issues
show
Bug introduced by
The variable requestsSuccessful is changed as part of the for loop for example by false on line 211. Only the value of the last iteration will be visible in this function if it is called after the loop.
Loading history...
216
                            //Only call onSuccess if all requests have been successful
217
                            onSuccess();
218
                        } else if (onFailure && !requestsSuccessful) {
219
                            onFailure();
220
                        }
221
                    }
222
                });
223
            } else {
0 ignored issues
show
Comprehensibility Documentation Best Practice introduced by
This code block is empty. Consider removing it or adding a comment to explain.
Loading history...
224
                //If sample is not valid (ie not complete), do nothing
225
            }
226
        }
227
228
        if (onSuccess && submittedRequests === 0) {
229
            //If no requests were made, call onSuccess
230
            onSuccess();
231
        }
232
    };
233
234
    /**
235
    * @param {string} criteriaId
236
    * @param {function} onSuccess
237
    * @return {undefined}
238
    */
239
    SkillSampleAPI.saveSingleSkillSample = function (criteriaId, onSuccess, onFailure) {
240
241
        var panel = document.querySelector(".applicant-evidence__skill[data-criteria-id=\"" + criteriaId + "\"]:not(.template)");
242
243
        var applicationId = document.getElementById("jobApplicationJobApplicationId").value;
244
245
        if (!applicationId) {
246
            Utilities.debug ? console.log("Cannot save Skill Samples without an Application Id") : null;
0 ignored issues
show
Debugging Code introduced by
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
Bug introduced by
The variable Utilities seems to be never declared. If this is a global, consider adding a /** global: Utilities */ 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...
Bug introduced by
Did you forget to assign or call a function?

This error message can for example pop up if you forget to assign the result of a function call to a variable or pass it to another function:

function someFunction(x) {
    (x > 0) ? callFoo() : callBar();
}

// JSHint expects you to assign the result to a variable:
function someFunction(x) {
    var rs = (x > 0) ? callFoo() : callBar();
}

// If you do not use the result, you could also use if statements in the
// case above.
function someFunction(x) {
    if (x > 0) {
        callFoo();
    } else {
        callBar();
    }
}
Loading history...
247
            return;
248
        }
249
        var sample = SkillSampleAPI.getSkillSampleFromEvidencePanel(panel);
250
251
        //Only save if this sample is complete
252
        if (sample.isValid()) {
253
            DataAPI.saveSkillSample(sample, sample.criteria_id, applicationId, function (response) {
0 ignored issues
show
Bug introduced by
The variable DataAPI seems to be never declared. If this is a global, consider adding a /** global: DataAPI */ 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...
254
                if (response.status === 200) {
255
                    if (onSuccess)
256
                    onSuccess();
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...
257
                } else {
258
                    if (onFailure) {
259
                        window.alert(response.response.message);
260
                        onFailure();
261
                    }
262
                }
263
264
            });
265
        } else {
266
            window.alert("Skill sample invalid, cannot save");
267
            //If sample is not valid (ie not complete), do nothing
268
        }
269
    };
270
    
271
    SkillSampleAPI.deleteSkillSample = function(criteriaId) {
272
        var panel = document.querySelector(".applicant-evidence__skill[data-criteria-id=\"" + criteriaId + "\"]:not(.template)");
273
        panel.querySelector('input[name=\"sample_name\"]').value = "";
274
        panel.querySelector('select[name=\"sample_type\"]').value = "";
275
        panel.querySelector('input[name=\"sample_date_created\"]').value = "";
276
        panel.querySelector('input[name=\"sample_http_link\"]').value = "";
277
        panel.querySelector('textarea[name=\"sample_story\"]').value = "";
278
        
279
        var applicationId = document.getElementById("jobApplicationJobApplicationId").value;
280
        
281
        if (applicationId) {
282
            DataAPI.deleteSkillSample(criteriaId, applicationId, function(request) {
0 ignored issues
show
Bug introduced by
The variable DataAPI seems to be never declared. If this is a global, consider adding a /** global: DataAPI */ 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...
Unused Code introduced by
The parameter request is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
283
                //TODO: deal with delete response?
284
            });
285
        }
286
        
287
        SkillSampleAPI.onStatusChange(criteriaId);
288
    };
289
290
    SkillSampleAPI.getSkillSampleFromEvidencePanel = function (panel) {
291
        var criteria_id = panel.getAttribute("data-criteria-id");
292
        var sample = new SkillSampleAPI.SkillSample(criteria_id);
293
294
        var name = panel.querySelector('input[name=\"sample_name\"]');
295
        if (name) {
296
            sample.name = name.value;
297
        }
298
        var type = panel.querySelector('select[name=\"sample_type\"]');
299
        if (type) {
300
            sample.type = type.value;
301
        }
302
        var date_created = panel.querySelector('input[name=\"sample_date_created\"]');
303
        if (date_created) {
304
            sample.date_created = date_created.value;
305
        }
306
        var http_link = panel.querySelector('input[name=\"sample_http_link\"]');
307
        if (http_link) {
308
            sample.http_link = http_link.value;
309
        }
310
        var story = panel.querySelector('textarea[name=\"sample_story\"]');
311
        if (story) {
312
            sample.story = story.value;
313
        }
314
        
315
        sample.nullifyEmptyFields();
316
        return sample;
317
    };
318
319
    SkillSampleAPI.onStatusChange = function (criteriaId) {
320
        //If status changes, this can no longer be in a saved state
321
        EvidenceAPI.setUiSaved(criteriaId, SkillSampleAPI, false);
0 ignored issues
show
Bug introduced by
The variable EvidenceAPI seems to be never declared. If this is a global, consider adding a /** global: EvidenceAPI */ 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...
322
323
        var panel = document.querySelector(".applicant-evidence__skill[data-criteria-id=\"" + criteriaId + "\"]:not(.template)");
324
325
        var sample = SkillSampleAPI.getSkillSampleFromEvidencePanel(panel);
326
327
        //Use validity to determine Completeness status
328
        EvidenceAPI.setUiComplete(criteriaId, SkillSampleAPI, sample.isComplete());
329
        
330
        EvidenceAPI.onStatusUpdate();
331
    };
332