PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / trunk
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses vtrunk
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 4.2.1 All 138 releases
learnpress / assets / src / js / admin / course-material.js

course-material.js in LearnPress – WordPress LMS Plugin for Create and Sell Online Courses trunk, at assets/src/js/admin/course-material.js

302 lines 10.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 document.addEventListener( 'DOMContentLoaded', function() {
2 const $ = window.jQuery;
3 const postID = document.getElementById( 'current-material-post-id' ).value,
4 max_file_size = document.getElementById( 'material-max-file-size' ).value,
5 accept_file = document.querySelector( '.lp-material--field-upload' ).getAttribute( 'accept' ).split( ',' ),
6 can_upload = document.getElementById( 'available-to-upload' ),
7 add_btn = document.getElementById( 'btn-lp--add-material' ),
8 group_template = document.getElementById( 'lp-material--add-material-template' ),
9 material__group_container = document.getElementById( 'lp-material--group-container' ),
10 material_tab = document.getElementById( 'lp-material-container' ),
11 material_save_btn = document.getElementById( 'btn-lp--save-material' );
12 const getResponse = async ( ele, postID ) => {
13 const elementMaterial = document.querySelector( '.lp-material--table tbody' );
14 try {
15 const url = `${ lpDataAdmin.lp_rest_url }lp/v1/material/item-materials/${ postID }`;
16 fetch( url, {
17 method: 'GET',
18 headers: {
19 'X-WP-Nonce': lpGlobalSettings.nonce,
20 'Content-Type': 'application/json',
21 },
22 } )
23 .then( ( response ) => response.json() )
24 .then( ( response ) => {
25 const { data, status } = response;
26 if ( status !== 'success' ) {
27 console.error( response.message );
28 return;
29 }
30
31 if ( data && data.items && data.items.length > 0 ) {
32 const materials = data.items;
33 if ( ele.querySelector( '.lp-skeleton-animation' ) ) {
34 ele.querySelector( '.lp-skeleton-animation' ).remove();
35 }
36 for ( let i = 0; i < materials.length; i++ ) {
37 insertRow( elementMaterial, materials[ i ] );
38 }
39 }
40 } )
41 .catch( ( err ) => console.log( err ) );
42 } catch ( error ) {
43 console.log( error.message );
44 }
45 };
46 const insertRow = ( parent, data ) => {
47 if ( ! parent ) {
48 return;
49 }
50 const delete_btn_text = document.getElementById( 'delete-material-row-text' ).value;
51 parent.insertAdjacentHTML(
52 'beforeend',
53 `<tr data-id="${ data.file_id }" data-sort="${ data.orders }" >
54 <td class="sort"><span class="dashicons dashicons-menu"></span> ${ data.file_name }</td>
55 <td>${ capitalizeFirstChar( data.method ) }</td>
56 <td><a href="javascript:void(0)" class="delete-material-row" data-id="${ data.file_id }">${ delete_btn_text }</a></td>
57 </tr>`
58 );
59 };
60 const capitalizeFirstChar = ( str ) => str.charAt( 0 ).toUpperCase() + str.substring( 1 );
61 //load material data from API
62 getResponse( material_tab, postID );
63
64 //add material group field
65 add_btn.addEventListener( 'click', function( e ) {
66 const can_upload_data = ~~this.getAttribute( 'can-upload' );
67 const groups = material__group_container.querySelectorAll( '.lp-material--group' ).length;
68 if ( groups >= can_upload_data ) {
69 return false;
70 }
71 material__group_container.insertAdjacentHTML( 'afterbegin', group_template.innerHTML );
72 } );
73 //switch input when change method between "upload" and "external"
74 material_tab.addEventListener( 'change', function( event ) {
75 const target = event.target;
76 if ( target.classList.contains( 'lp-material--field-method' ) ) {
77 const method = target.value;
78 const upload_field_template = document.getElementById( 'lp-material--upload-field-template' ).innerHTML,
79 external_field_template = document.getElementById( 'lp-material--external-field-template' ).innerHTML;
80 switch ( method ) {
81 case 'upload' :
82 target.parentNode.insertAdjacentHTML( 'afterend', upload_field_template );
83 target.closest( '.lp-material--group' ).querySelector( '.lp-material--external-wrap' ).remove();
84 break;
85 case 'external' :
86 target.parentNode.insertAdjacentHTML( 'afterend', external_field_template );
87 target.closest( '.lp-material--group' ).querySelector( '.lp-material--upload-wrap' ).remove();
88 break;
89 }
90 }
91 if ( target.classList.contains( 'lp-material--field-upload' ) ) {
92 if ( target.value && target.files.length > 0 ) {
93 if ( ! accept_file.includes( target.files[ 0 ].type ) ) {
94 alert( 'This file is not allowed! Please choose another file!' );
95 target.value = '';
96 } else if ( target.files[ 0 ].size > max_file_size * 1024 * 1024 ) {
97 alert( `This file size is greater than ${ max_file_size }MB! Please choose another file!` );
98 target.value = '';
99 }
100 }
101 }
102 } );
103 // Dynamic click action ...
104 material_tab.addEventListener( 'click', function( event ) {
105 const target = event.target;
106 if ( target.classList.contains( 'lp-material--delete' ) && target.nodeName == 'BUTTON' ) {
107 target.closest( '.lp-material--group' ).remove();
108 } else if ( target.classList.contains( 'lp-material-save-field' ) ) {
109 // save a file
110 let material = target.closest( '.lp-material--group' );
111 material = singleNode( material );
112 // target.classList.add( 'loading' );
113 lpSaveMaterial( material, true, target );
114 // target.classList.remove( 'loading' );
115 }
116 return false;
117 } );
118
119 //save all material files
120 material_save_btn.addEventListener( 'click', function( event ) {
121 const materials = material__group_container.querySelectorAll( '.lp-material--group' );
122 if ( materials.length > 0 ) {
123 // material_save_btn.classList.add( 'loading' );
124 lpSaveMaterial( materials, false, material_save_btn );
125 // material_save_btn.classList.remove( 'loading' );
126 }
127 } );
128 function lpSaveMaterial( materials, is_single = false, target ) {
129 if ( materials.length > 0 ) {
130 let material_data = [];
131 let formData = new FormData(),
132 send_request = true;
133
134 materials.forEach( function( ele, index ) {
135 const label = ele.querySelector( '.lp-material--field-title' ).value,
136 method = ele.querySelector( '.lp-material--field-method' ).value,
137 external_field = ele.querySelector( '.lp-material--field-external-link' ),
138 upload_field = ele.querySelector( '.lp-material--field-upload' );
139 let file, link;
140 if ( ! label ) {
141 send_request = false;
142 }
143 switch ( method ) {
144 case 'upload' :
145 if ( upload_field.value ) {
146 file = upload_field.files[ 0 ].name;
147 link = '';
148 formData.append( 'file[]', upload_field.files[ 0 ] );
149 } else {
150 send_request = false;
151 }
152 break;
153 case 'external' :
154 link = external_field.value;
155 file = '';
156 if ( ! link ) {
157 send_request = false;
158 }
159 break;
160 }
161 material_data.push( { label, method, file, link } );
162 } );
163
164 if ( ! send_request ) {
165 alert( 'Enter file title, choose file or enter file link!' );
166 } else {
167 // console.log(material_data);
168 material_data = JSON.stringify( material_data );
169 const url = `${ lpGlobalSettings.rest }lp/v1/material/item-materials/${ postID }`;
170 formData.append( 'data', material_data );
171 target.classList.add( 'loading' );
172
173 fetch( url, {
174 method: 'POST',
175 headers: {
176 'X-WP-Nonce': lpGlobalSettings.nonce,
177 },
178 body: formData,
179 } ) // wrapped
180 .then( ( res ) => res.text() )
181 .then( ( resString ) => {
182 // console.log( data );
183 if ( ! is_single ) {
184 material__group_container.innerHTML = '';
185 } else {
186 materials[ 0 ].remove();
187 }
188 const res = JSON.parse( resString );
189 const { message, data, status } = res;
190 alert( message );
191
192 if ( status === 'success' ) {
193 if ( data.length > 0 ) {
194 const material_table = document.querySelector( '.lp-material--table' );
195 const thead = material_table.querySelector( 'thead' );
196 const tbody = material_table.querySelector( 'tbody' );
197
198 thead.classList.remove( 'hidden' );
199 for ( let i = 0; i < data.length; i++ ) {
200 const row = data[ i ];
201 insertRow( tbody, row );
202 }
203 can_upload.innerText = parseInt( can_upload.innerText ) - data.length;
204 add_btn.setAttribute( 'can-upload', can_upload.innerText );
205 }
206 }
207 } )
208 .finally( () => {
209 target.classList.remove( 'loading' );
210 } )
211 .catch( ( err ) => console.log( err ) );
212 }
213 }
214 }
215 //delete material
216 document.addEventListener( 'click', function( e ) {
217 const target = e.target;
218 if ( target.classList.contains( 'delete-material-row' ) && target.nodeName == 'A' ) {
219 const rowID = target.getAttribute( 'data-id' ), //material file ID
220 message = document.getElementById( 'delete-material-message' ).value;//Delete message content
221 if ( confirm( message ) ) {
222 wp.apiFetch( {
223 path: `lp/v1/material/${ rowID }`,
224 method: 'DELETE',
225 data: {
226 item_id: postID,
227 },
228 } ).then( ( res ) => {
229 // console.log( res );
230 if ( res.status !== 200 || ! res.delete ) {
231 alert( res.message );
232 } else {
233 target.closest( 'tr' ).remove();
234 can_upload.innerText = ~~can_upload.innerText + 1;
235 add_btn.setAttribute( 'can-upload', ~~can_upload.innerText );
236 }
237 } ).catch( ( err ) => {
238 console.log( err );
239 } ).finally( () => {
240
241 } );
242 }
243 }
244 } );
245 const singleNode = ( ( nodeList ) => ( node ) => {
246 const layer = { // define our specific case
247 0: { value: node, enumerable: true },
248 length: { value: 1 },
249 item: {
250 value( i ) {
251 return this[ +i || 0 ];
252 },
253 enumerable: true,
254 },
255 };
256 return Object.create( nodeList, layer ); // put our case on top of true NodeList
257 } )( document.createDocumentFragment().childNodes ); // scope a true NodeList
258 $( '.lp-material--table tbody' ).sortable( {
259 items: 'tr',
260 cursor: 'move',
261 axis: 'y',
262 handle: 'td.sort',
263 scrollSensitivity: 40,
264 forcePlaceholderSize: true,
265 helper: 'clone',
266 opacity: 0.65,
267 update( event, ui ) {
268 $( this ).sortable( 'option', 'disabled', true );
269 updateSort();
270 $( this ).sortable( 'option', 'disabled', false );
271 },
272 } );
273 function updateSort() {
274 const items = $( '.lp-material--table tbody tr' ),
275 data = [];
276 // $( ".lp-material--table tbody tr" ).sortable( "option", "disabled", true );
277 items.each( function( i, item ) {
278 $( this ).attr( 'data-sort', i + 1 );
279 data.push( { file_id: ~~$( this ).attr( 'data-id' ), orders: i + 1 } );
280 } );
281 wp.apiFetch( {
282 path: `lp/v1/material/item-materials/${ postID }`,
283 method: 'PUT',
284 data: {
285 sort_arr: JSON.stringify( data ),
286 },
287 } ).then( ( res ) => {
288 if ( res.status == 200 ) {
289 //
290 } else {
291 alert( 'Sort table fail.' );
292 }
293 } ).catch( ( err ) => {
294 console.log( err );
295 } ).finally( () => {
296
297 } );
298 // $( ".lp-material--table tbody tr" ).sortable( "option", "disabled", false );
299 // console.log( data );
300 }
301 } );
302