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