index.js 11.3 KB
Newer Older
1
// Object which stores all the user selected/entered values
2
let inputObj = {
3
4
    textChoice: 'manual',           // choice of text entry initially set as manual. Can have values manual, calculated
    text: '',                       // User entered text in case of manual  
5
    numberOfCharacters: '',         // number of characters in text. Either from user entered text or user entered number
6
7
    schoolLevel: '',                // Value of school level selected from dropdown
    category: ''                    // Value of category selected from dropdown
8
};
9

10
11

// function handleTextRadioClick: responsible for showing or hiding text input / text length input based on selected option
12
function handleTextRadioClick() {
13
14
    let textChoice = document.querySelector('input[name="text-input-option"]:checked').value;
    inputObj.textChoice = textChoice;
15
16
17
18
19
20
21
22
    if (textChoice === 'manual') {
        let value = removeSpecialCharacters(inputObj.text);
        let characters = value.length;
        setCharacterLength(characters);
    } else {
        let value = document.getElementById("inputTextCharacters").value;
        setCharacterLength(value);
    }
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

    // show or hide validation messages
    if (inputObj.textChoice === 'manual' && inputObj.text === '') {
        //document.getElementById('textarea-validation').style.display = 'block';
    } else {
        document.getElementById('textarea-validation').style.display = 'none';
    }

    if (inputObj.textChoice === 'calculated' &&
        (inputObj.numberOfCharacters === '' || inputObj.numberOfCharacters === 0)) {

        //document.getElementById('textCharacters-validation').style.display = 'block';
    } else {
        document.getElementById('textCharacters-validation').style.display = 'none';
    }

39
40
41
    document.getElementById('min-count-100-validation').style.display = 'none';
    document.getElementById('min-count-400-validation').style.display = 'none';

42
43
44
45
    toggleElement('character-calculation-wrapper');
    toggleElement('manual-character-input');
}

46
47
48

// function toggleElement: hides/shows the html element based on current visibility. 
// accepts value of id attribute of element as parameter
49
function toggleElement(id) {
50
51
52
    let element = document.getElementById(id);
    if (element.style.display === "none") {
        element.style.display = "block";
53
    } else {
54
        element.style.display = "none";
55
56
57
    }
}

58
59

// function handleTextAreaChange: captures the changes as user enters the text and gets the length
60
// and sets number of characters to property numberOfCharacters on inputObj
61
62
function handleTextAreaChange() {
    let value = document.getElementById("manual-text-entry").value;
63
    inputObj.text = value;
64
65
    value = removeSpecialCharacters(value);
    let characters = value.length;
66
    setCharacterLength(characters);
67
68
69
70
71
72
73
74
    document.getElementById("calculatedTextCharacters").setAttribute('value', characters);
}

// function removeSpecialCharacters: removes punctuation marks and other special characters
// but allows numbers and alphabets along with language specific characters German: äöüÄÖÜß and French: ùûüÿàâæéèêëïîôœÙÛÜŸÀÂÆÉÈÊËÏÎÔŒ
function removeSpecialCharacters(str) {
    return str.replace(/(?!\w|||||||||||\ÿ|||||||||||||||||||||||||\Œ)./g, '')  // regex to remove special characters 
        .replace(/^(\s*)([\W\w]*)(\b\s*$)/g, '$2');   // regex to trim the string to remove any whitespace at the beginning or the end
75
76
}

77
78

// function handleCharacterInputChange: captures changes in number of characters input field
79
// and sets number of characters to property numberOfCharacters on inputObj
80
81
82
83
84
function handleCharacterInputChange() {
    let value = document.getElementById("inputTextCharacters").value;
    setCharacterLength(value);
}

85
// function setCharacterLength: sets number of characters to property numberOfCharacters on inputObj
86
function setCharacterLength(characters) {
87
88
89
90
91
    if (characters === '') {
        inputObj.numberOfCharacters = 0;
    } else {
        inputObj.numberOfCharacters = parseInt(characters);
    }
92
93
94
}


95
96
97
// function isFormValid: checks for mandatory input fields and validates te form 
// returns true if all values are filled else returns false
// also shows error messages for respective inputs fields
98
function isFormValid() {
99
100
101
102
103
104
105
106
    let invalidFields = 0;
    if (inputObj.textChoice === 'manual' && inputObj.text === '') {
        invalidFields++;
        document.getElementById('textarea-validation').style.display = 'block';
    } else {
        document.getElementById('textarea-validation').style.display = 'none';
    }

107
    if (inputObj.textChoice === 'calculated' &&
108
        (inputObj.numberOfCharacters === '' || inputObj.numberOfCharacters === 0)) {
109

110
111
112
113
114
115
        invalidFields++;
        document.getElementById('textCharacters-validation').style.display = 'block';
    } else {
        document.getElementById('textCharacters-validation').style.display = 'none';
    }

116
    if (inputObj.schoolLevel === '' || inputObj.schoolLevel === 0) {
117
        invalidFields++;
118
        document.getElementById('schoolLevel-validation').style.display = 'block';
119
    } else {
120
        document.getElementById('schoolLevel-validation').style.display = 'none';
121
122
    }

Ratnadeep Rajendra Kharade's avatar
Ratnadeep Rajendra Kharade committed
123
    if (inputObj.category === '' || inputObj.category === 0) {
124
        invalidFields++;
125
        document.getElementById('category-validation').style.display = 'block';
126
    } else {
127
        document.getElementById('category-validation').style.display = 'none';
128
    }
129

130
131
    if ((inputObj.numberOfCharacters < 100 && (inputObj.schoolLevel === '1' || inputObj.schoolLevel === '2'))) {
        invalidFields++;
132
133
134
135
136
137
138
139
        document.getElementById('min-count-100-validation').style.display = 'block';
    } else {
        document.getElementById('min-count-100-validation').style.display = 'none';
    }

    if ((inputObj.numberOfCharacters < 400 && (inputObj.schoolLevel === '3' || inputObj.schoolLevel === '4'))) {
        invalidFields++;
        document.getElementById('min-count-400-validation').style.display = 'block';
140
    } else {
141
        document.getElementById('min-count-400-validation').style.display = 'none';
142
143
    }

144
    return invalidFields < 1
145
146
}

147
148

// function showFeedbackForm: displays feedback form when calculation is done
149
function showFeedbackForm() {
150
151
    let element = document.getElementById('feedback-form');
    element.style.display = "block";
152
}
153

154

155
156
157
// function schoolLevelChangeEvent: listens for change in school level dropdown
// and sets selected value to property schoolLevel on inputObj
function schoolLevelChangeEvent(event) {
158
    inputObj.schoolLevel = event.target.value;
159
160
}

161
162
163
// function categoryChangeEvent: listens for change in category dropdown
// and sets selected value to property category on inputObj
function categoryChangeEvent(event) {
164
    inputObj.category = event.target.value;
165
}
166
167
168
169
170
171
172
173
174
175
176


// function calculateReadingTime: This function is responsible for calculating reading time
// reading time can be calculated if all inputs are valid
function calculateReadingTime() {

    if (isFormValid()) {

        //variable x which holds final reading time in minutes
        let x = 0;

177
        // logic or algorithm for calculating reading time goes here
178
        // inputObj.numberOfCharacters has number of characters (number data type)
179
180
        // inputObj.schoolLevel has level of school (string data type)
        // inputObj.category has category of reader (string data type)
181

182

183
        // example calculation
184
185
186
        //x = (inputObj.numberOfCharacters * inputObj.schoolLevel * inputObj.category);

        let combination = inputObj.schoolLevel + '' + inputObj.category;
187

188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
        let C = inputObj.numberOfCharacters;

        switch (combination) {
            case '11':
                x = (0.7165 * C) + (172.8332 * 0.690) - 125.9143;
                break;
            case '12':
                x = (0.3463 * C) + (185.4177 * 0.249) - 62.0577;
                break;
            case '13':
                x = (0.4967 * C) + (223.3422 * 0.386) - 101.3559;
                break;
            case '14':
                x = (0.6489 * C) + (195.7637 * 0.528) - 120.8358;
                break;
            case '15':
                x = (0.7165 * C) + (172.8332 * 0.690) - 125.9143;
                break;
            case '21':
                x = (0.5007 * C) + (703.686 * 0.505) - 358.5641;
                break;
            case '22':
                x = (0.3135 * C) + (902.8845 * 0.30) - 285.855;
                break;
            case '23':
                x = (0.3396 * C) + (956.5228 * 0.329) - 326.4739;
                break;
            case '24':
                x = (0.3797 * C) + (857.5144 * 0.378) - 328.6899;
                break;
            case '25':
                x = (0.5007 * C) + (703.686 * 0.505) - 358.5641;
                break;
            case '31':
                x = (0.3524 * C) + (563.8412 * 0.42) - 196.8003;
                break;
            case '32':
                x = (0.1941 * C) + (671.9616 * 0.204) - 131.0749;
                break;
            case '33':
                x = (0.2432 * C) + (712.2978 * 0.263) - 177.29;
                break;
            case '34':
                x = (0.2965 * C) + (628.5916 * 0.34) - 189.2485;
                break;
            case '35':
                x = (0.3524 * C) + (563.8412 * 0.42) - 196.8003;
                break;
            case '41':
                x = (0.3445 * C) + (1315.1448 * 0.357) - 459.0464;
                break;
            case '42':
240
                x = (0.2003 * C) + (1421.0975 * 0.206) - 290.0477;
241
242
243
244
245
246
247
248
249
250
251
252
253
254
                break;
            case '43':
                x = (0.2289 * C) + (1389.9964 * 0.24) - 325.0492;
                break;
            case '44':
                x = (0.2842 * C) + (1471.1005 * 0.298) - 431.9652;
                break;
            case '45':
                x = (0.3445 * C) + (1315.1448 * 0.357) - 459.0464;
                break;
            default:
                x = 'error';
                break;
        }
255

256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
        // get modulo division of x for rounding off till 30 seconds
        let xMod60 = x % 60;
        if (xMod60 <= 15) {
            roundOff = 0;
        }
        if (xMod60 > 15 && xMod60 <= 30) {
            roundOff = 30;
        }
        if (xMod60 > 30 && xMod60 <= 45) {
            roundOff = 30;
        }
        if (xMod60 > 45) {
            roundOff = 60;
        }

        // subtract mod seconds and add rounded off seconds
        let roundedOffSeconds = x - xMod60 + roundOff;

        // get formatted time in hh:mm:ss format
        let formattedTime = getFormattedTime(roundedOffSeconds)

        // set time value to html element
278
        var s = document.getElementById('reading-time-element');
279
        s.innerHTML = formattedTime;
280
281
282
283
284
        // display html element which shows time
        let element = document.getElementById('calculate-time-element');
        element.style.display = "block";
    }
}
285

286
// function getFormattedTime
287
288
289
290
291
292
293
294
295
296
297
298
299
// accepts seconds value and returns in hh:mm:ss format
function getFormattedTime(totalSeconds) {
    let hours = Math.floor(totalSeconds / 3600);
    totalSeconds %= 3600;
    let minutes = Math.floor(totalSeconds / 60);
    let seconds = totalSeconds % 60;

    minutes = String(minutes).padStart(2, "0");
    hours = String(hours).padStart(2, "0");
    seconds = String(seconds).padStart(2, "0");

    return hours + ":" + minutes + ":" + seconds;
}