PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.3.8
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.3.8
4.4.8 4.4.7 4.4.6 4.4.5 4.4.4 4.4.3 4.4.2 4.4.1 4.4.0 4.3.9.1 4.3.9 4.3.8 4.3.7 4.1.6.9 4.1.6.9.1 4.1.6.9.2 4.1.6.9.3 4.1.6.9.4 4.1.7 4.1.7.1 4.1.7.2 4.1.7.3 4.1.7.3.1 4.1.7.3.2 4.2.0 All 139 releases
learnpress / inc / admin / views / quiz / question-fib-editor.php

question-fib-editor.php in LearnPress – WordPress LMS Plugin for Create and Sell Online Courses 4.3.8, at inc/admin/views/quiz/question-fib-editor.php

345 lines 9.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Admin quiz editor: fib question answer template.
4 *
5 * @since 3.0.0
6 */
7
8 ?>
9
10 <script type="text/x-template" id="tmpl-lp-quiz-fib-question-answer">
11 <div class="admin-quiz-fib-question-editor">
12 <?php learn_press_admin_view( 'question/fib-answer-editor' ); ?>
13 </div>
14 </script>
15
16 <script type="text/javascript">
17 jQuery(document).ready(function ($) {
18 var $Vue = window.$Vue || Vue;
19 var $store = window.LP_Quiz_Store;
20
21 Vue.component('lp-quiz-fib-question-answer', {
22 template: '#tmpl-lp-quiz-fib-question-answer',
23 props: ['question'],
24 data: function () {
25 return {
26 valid: true,
27 canInsertNewBlank: false,
28 blanks: []
29 }
30 },
31 computed: {
32 answer: function () {
33 return {
34 order: 1,
35 is_true: '',
36 question_answer_id: this.question.answers[0].question_answer_id,
37 title: this.question.answers[0].title,
38 value: '',
39 blanks: this.answers[ 0 ].blanks,
40 };
41 },
42 answers: function () {
43 return this.question.answers
44 }
45 },
46 mounted: function () {
47 var that = this,
48 content = this.getContent();
49 this.blanks = this.answers[0].blanks;
50 this.$editor = $(this.$el).find('.content-editable');
51 this.$editor.html(content);
52 this.parseBlanks(content);
53
54 this.$editor[0].addEventListener("DOMCharacterDataModified", function (e) {
55 var $target = $(e.target).parent(), id = $target.data('id');
56
57 for (var i in that.blanks) {
58 if (that.blanks[i].id == id) {
59 that.blanks[i].fill = $target.html().trim();
60 that.$activeBlank = $target;
61 break;
62 }
63 }
64 }, false);
65
66 this.interval = setInterval(function (a) {
67 a.parseBlanks(a.getContent());
68 }, 1000, this);
69 },
70 methods: {
71 updateAnswer: function () {
72 var answer = JSON.parse(JSON.stringify(this.answer));
73 answer.title = this.getShortcode();
74 answer.blanks = this.getBlanksForDB();
75
76 $store.dispatch('lqs/updateQuestionAnswerTitle', {
77 question_id: this.question.id,
78 answer: answer
79 });
80 },
81
82 updateAnswerBlank: function (e, blank) {
83 blank['comparison'] = e.target.value || '';
84 this.updateAnswer();
85 },
86 updateAnswerMatchCase( e, blank ) {
87 blank['match_case'] = e.target.checked ? true : false;
88 this.updateAnswer();
89 },
90 getContent: function () {
91 var content = this.answers[0].title,
92 shortcodes = content.match(/\[fib.*?\]/g),
93 uids = {};
94
95 if (shortcodes) {
96 for (var i = 0; i < shortcodes.length; i++) {
97 var uid,
98 fill,
99 replaceText,
100 props = shortcodes[i].match(/([a-z_]+)="(.*?)"/g),
101 data = [];
102
103 for (var j in props) {
104 var prop = props[j].match(/([a-z_]+)="(.*?)"/);
105
106 if (!prop) {
107 continue;
108 }
109
110 switch (prop[1]) {
111 case 'uid':
112 case 'id':
113 uid = prop[2];
114 break;
115 case 'fill':
116 fill = prop[2];
117 break;
118 default:
119 data.push('data-' + prop[1] + '="' + prop[2] + '"')
120 }
121 }
122
123 uid = uid ? uid : LP.uniqueId();
124
125 if (uids[uid]) {
126 uid = LP.uniqueId();
127 }
128
129 replaceText = FIB.outerHTML(this.createBlank(fill, uid).attr('data-index', i + 1));// '<span class="fib-blank" id="fib-blank-' + uid + '" data-id="' + uid + '" data-index="' + (i + 1) + '">' + fill + '</span>';
130 uids[uid] = true;
131
132 content = content.replace(shortcodes[i], replaceText);
133 }
134 }
135 return content;
136 },
137 activeBlank: function (e) {
138 this.$activeBlank = $(e.target).closest('.fib-blank');
139 },
140
141
142 findBlank: function (id) {
143 for (var i in this.blanks) {
144 if (this.blanks[i].id == id) {
145 return this.blanks[i];
146 }
147 }
148
149 return false;
150 },
151 parseBlanks: function (content) {
152 var $container = this.$editor,
153 $inputs = $container.find('.fib-blank'),
154 $input,
155 data,
156 blanks = [], uids = [],
157 i = 0, n = 0;
158
159
160 for (i = 0; i < $inputs.length; i++) {
161 $input = $inputs.eq(i).attr('data-index', i + 1);
162 data = $input.data();
163
164 if (-1 !== $.inArray(data.id, uids)) {
165 data.id = LP.uniqueId();
166 }
167
168 var oldBlank = this.findBlank(data.id) || {};
169
170 blanks.push({
171 fill: $input.html().trim(),
172 id: data.id,
173 comparison: data.comparison || oldBlank.comparison || '',
174 match_case: data.match_case || oldBlank.match_case || 0,
175 index: i + 1,
176 open: !!oldBlank.open,
177 });
178 uids.push(data.id);
179 }
180 this.blanks = blanks;
181 },
182 updateBlanks: function (content) {
183 this.parseBlanks(content !== undefined ? content : this.$editor.html());
184 return this.getShortcode();
185 },
186 getShortcode: function () {
187 var that = this,
188 $container = this.$editor.clone(),
189 $blanks = $container.find('.fib-blank');
190
191 $blanks.each(function () {
192 var $blank = $(this),
193 id = $blank.attr('id'),
194 uid = id.replace('fib-blank-', ''),
195 blank = that.getBlankById(uid),
196 code = 'fib';
197
198 if (blank) {
199 if (!blank.id) {
200 return;
201 }
202 for (var i in blank) {
203 if ($.inArray(i, ['index']) !== -1) {
204 continue;
205 }
206
207 if (!blank[i]) {
208 continue;
209 }
210
211 code += ' ' + i + '="' + blank[i] + '"';
212 }
213 $blank.replaceWith('[' + code + ']');
214 } else {
215 console.log('Not found: ' + uid)
216 $blank.replaceWith('')
217 }
218 });
219 return $container.html();
220 },
221 getBlankById: function (id) {
222 var blank = false;
223 $.each(this.blanks, function () {
224 if (id == this.id) {
225 blank = this;
226 return true;
227 }
228 });
229 return blank;
230 },
231 updateBlank: function (e) {
232 var $el = $(e.target),
233 id = $el.attr('id'),
234 $blank = this.$editor.find('#' + id);
235 $blank.html(e.target.value);
236 this.updateAnswer();
237 },
238 removeBlank: function (e, id) {
239 e.preventDefault();
240 this.removeBlankById(id);
241 this.updateAll();
242 },
243 removeBlankById: function (id) {
244 var $blank = this.$editor.find('.fib-blank#fib-blank-' + id);
245 $blank.replaceWith($blank.html());
246 },
247 updateAll: function () {
248 this.answer.title = this.updateBlanks();
249 this.updateAnswer();
250 },
251 insertBlank: function () {
252 if (!this.canInsertNewBlank) {
253 return;
254 }
255
256 var $content = $(this.$el).find('.content-editable'),
257 content = $content.html(),
258 selectedText = FIB.getSelectedText(),
259 selectionRange = FIB.getSelectionRange(),
260 $blank = this.createBlank(selectedText),
261 nodeValue = selectionRange.anchorNode.nodeValue,
262 x = selectionRange.anchorOffset,
263 y = selectionRange.focusOffset;
264 startRange = x < y ? x : y;
265 endRange = startRange == x ? y: x;
266
267 selectionRange.anchorNode.nodeValue = nodeValue.substr(0, startRange);
268 $($blank).insertAfter(selectionRange.anchorNode);
269 $(FIB.createTextNode(nodeValue.substr(endRange))).insertAfter($blank);
270
271 var $blanks = $content.find('.fib-blank');
272 $blanks.each(function (i, el) {
273 var $blank = $(this);
274 $blank.attr('data-index', i + 1)
275 });
276
277 this.parseBlanks($content.html());
278 this.updateAnswer();
279 },
280 createBlank: function (content, id) {
281 if (!id) {
282 id = LP.uniqueId();
283 }
284 return $('<b class="fib-blank" id="fib-blank-' + id + '" data-id="' + id + '"> ' + content + '</b>');
285 },
286 clearBlanks: function () {
287 if (!confirm($store.getters['i18n/all'].confirm_remove_blanks)) {
288 return;
289 }
290
291 for (var i in this.blanks) {
292 this.removeBlankById(this.blanks[i].id);
293 }
294 this.updateAll();
295 },
296 clearContent: function () {
297 this.$editor.html('');
298 this.updateAnswer();
299 },
300 canInsertBlank: function () {
301 var $content = $(this.$el).find('.content-editable'),
302 content = $content.html(),
303 selectedText = FIB.getSelectedText(),
304 selectionRange = FIB.getSelectionRange();
305
306 this.canInsertNewBlank = selectedText.length && !FIB.isContainHtml(selectionRange.anchorNode);
307 },
308 getBlanksForDB: function () {
309 var blanks = {};
310 for (var i = 0, n = this.blanks.length; i < n; i++) {
311 var id = this.blanks[i].id.replace('fib-blank-', '');
312 blanks[id] = JSON.parse(JSON.stringify(this.blanks[i]));
313 blanks[id].id = id;
314 }
315 return blanks;
316 },
317 toggleOptions: function (e, id) {
318 e.preventDefault();
319 var that = this;
320 $(e.target).closest('.fib-blank').find('.blank-options ul').slideToggle(function () {
321 that.setBlankProp(id, 'open', !$(this).is(':hidden'))
322 })
323 },
324 setBlankProp: function (id, prop, value) {
325 for (var i in this.blanks) {
326 if (this.blanks[i].id == id) {
327 if ($.isPlainObject(prop)) {
328 for (var p in prop) {
329 this.$set(this.blanks[i], p, prop[p]);
330 }
331 } else {
332 this.$set(this.blanks[i], prop, value);
333 }
334
335 break;
336 }
337 }
338 this.updateAnswer();
339 }
340 },
341 })
342 });
343
344 </script>
345