PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / trunk
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More vtrunk
6.35 6.34 6.33.1 6.33 6.32.1 6.32 6.31 6.25 6.25.1 6.26 6.26.1 6.27 6.28 6.29 6.3 6.3.1 6.3.2 6.30 6.4 6.4.1 6.4.2 6.5 6.5.1 6.5.2 6.5.3 All 141 releases
← All changes | js/admin/applications.js +137 -105 6.5 → trunk View file →
@@ -4,9 +4,9 @@
4 4 if ( 'undefined' === typeof ajaxurl || 'undefined' === typeof wp || 'undefined' === typeof frmDom ) {
5 5 return;
6 6 }
7 7
8 - const __ = wp.i18n.__;
8 + const { __, sprintf } = wp.i18n;
9 9 const { tag, div, span, a, svg, img } = frmDom;
10 10 const { maybeCreateModal, footerButton } = frmDom.modal;
11 11 const { newSearchInput } = frmDom.search;
12 12 const { doJsonFetch } = frmDom.ajax;
@@ -38,10 +38,10 @@
38 38 wp.hooks.addAction( 'frm_application_render_templates', 'formidable', getUrlParamsAndMaybeOpenTemplateModal );
39 39 getApplicationDataAndLoadPage();
40 40 }
41 41
42 - function getUrlParamsAndMaybeOpenTemplateModal( _, { data } = {}) {
43 - const url = new URL( window.location.href );
42 + function getUrlParamsAndMaybeOpenTemplateModal( _, { data } = {} ) {
43 + const url = new URL( window.location.href );
44 44 const urlParams = url.searchParams;
45 45 if ( ! urlParams.get( 'triggerViewApplicationModal' ) ) {
46 46 return;
47 47 }
@@ -66,14 +66,14 @@
66 66 state.templates = data.templates;
67 67
68 68 container.innerHTML = '';
69 69
70 - const contentWrapper = div({ className: 'frm-applications-index-content' });
71 - container.appendChild( contentWrapper );
70 + const contentWrapper = div( { className: 'frm-applications-index-content' } );
71 + container.append( contentWrapper );
72 72
73 73 const customTemplatesNav = getCustomTemplatesNav();
74 74
75 - contentWrapper.appendChild( customTemplatesNav );
75 + contentWrapper.append( customTemplatesNav );
76 76 renderFormidableTemplates( contentWrapper, data.templates );
77 77
78 78 const hookName = 'frm_application_render_templates';
79 79 const args = { data, customTemplatesNav };
@@ -84,64 +84,68 @@
84 84 }
85 85 }
86 86
87 87 function getCustomTemplatesNav() {
88 - return div({
88 + return div( {
89 89 className: 'frm-application-templates-nav wrap',
90 90 children: [
91 91 tag(
92 92 'h2',
93 93 {
94 - child: span( __( 'My Applications', 'formidable-pro' ) ),
94 + child: span( __( 'My Applications', 'formidable' ) ),
95 95 className: 'frm-h2'
96 96 }
97 97 )
98 98 ]
99 - });
99 + } );
100 100 }
101 101
102 102 function addCustomApplicationsPlaceholder( customTemplatesNav ) {
103 - const placeholder = div({
103 + const placeholder = div( {
104 104 id: 'frm_custom_applications_placeholder',
105 105 className: 'frm_placeholder_block',
106 - child: div({
107 - child: img({ src: getUrlToApplicationsImages() + 'custom-applications.svg' })
108 - })
109 - });
110 - placeholder.appendChild(
111 - div({
106 + child: div( {
107 + className: 'frm_grid_container',
112 108 children: [
113 - img({ src: getUrlToApplicationsImages() + 'folder.svg' }),
114 - tag( 'h3', __( 'Improve your workflow with applications', 'formidable' ) ),
115 - div( __( 'Applications help to organize your workspace by combining forms, Views, and pages into a full solution.', 'formidable' ) ),
116 - a({
117 - className: 'button button-primary frm-button-primary',
118 - text: __( 'Upgrade to Pro', 'formidable' ),
119 - href: frmApplicationsVars.proUpgradeUrl
120 - })
109 + div( {
110 + className: 'frm10 frm_clearfix',
111 + children: [
112 + img( { src: `${ getUrlToApplicationsImages() }folder.svg` } ),
113 + tag( 'h3', __( 'Improve your workflow with applications', 'formidable' ) ),
114 + div( __( 'Applications help to organize your workspace by combining forms, Views, and pages into a full solution.', 'formidable' ) ),
115 + ]
116 + } ),
117 + div( {
118 + className: 'frm2',
119 + child: a( {
120 + className: 'frm-button-primary frm-gradient',
121 + text: __( 'Upgrade to Pro', 'formidable' ),
122 + href: frmApplicationsVars.proUpgradeUrl
123 + } )
124 + } )
121 125 ]
122 - })
123 - );
126 + } )
127 + } );
124 128 customTemplatesNav.parentNode.insertBefore( placeholder, customTemplatesNav.nextElementSibling );
125 129 }
126 130
127 131 function getUrlToApplicationsImages() {
128 - return frmGlobal.url + '/images/applications/';
132 + return `${ frmGlobal.url }/images/applications/`;
129 133 }
130 134
131 135 function renderFormidableTemplates( contentWrapper, templates ) {
132 - elements.templatesGrid = div({
136 + elements.templatesGrid = div( {
133 137 id: 'frm_application_templates_grid',
134 138 className: 'frm_grid_container frm-application-cards-grid'
135 - });
139 + } );
136 140 addTemplatesToGrid( templates );
137 - contentWrapper.appendChild( getTemplatesNav() );
138 - contentWrapper.appendChild( elements.templatesGrid );
141 + contentWrapper.append( getTemplatesNav() );
142 + contentWrapper.append( elements.templatesGrid );
139 143 }
140 144
141 145 function addTemplatesToGrid( templates ) {
142 146 templates.forEach(
143 - application => elements.templatesGrid.appendChild( createApplicationCard( application ) )
147 + application => elements.templatesGrid.append( createApplicationCard( application ) )
144 148 );
145 149 maybeTriggerSearch();
146 150 }
147 151
@@ -154,9 +158,9 @@
154 158 }
155 159 }
156 160
157 161 function getTemplatesNav() {
158 - return div({
162 + return div( {
159 163 className: 'frm-application-templates-nav wrap',
160 164 children: [
161 165 tag(
162 166 'h2',
@@ -167,9 +171,9 @@
167 171 ),
168 172 getCategoryOptions(),
169 173 getTemplateSearch()
170 174 ]
171 - });
175 + } );
172 176 }
173 177
174 178 function getCategoryOptions() {
175 179 if ( state.templates.length < 8 ) {
@@ -177,14 +181,14 @@
177 181 return document.createTextNode( '' );
178 182 }
179 183
180 184 const categories = [ getAllItemsCategory() ].concat( state.categories );
181 - const wrapper = div({ id: 'frm_application_category_filter', className: 'subsubsub' });
185 + const wrapper = div( { id: 'frm_application_category_filter', className: 'subsubsub' } );
182 186
183 187 categories.forEach( addCategoryToWrapper );
184 188 function addCategoryToWrapper( category, index ) {
185 189 if ( 0 !== index ) {
186 - wrapper.appendChild( document.createTextNode( '|' ) );
190 + wrapper.append( document.createTextNode( '|' ) );
187 191 }
188 192 const anchor = a( category );
189 193 if ( 0 === index ) {
190 194 anchor.classList.add( 'current' );
@@ -201,9 +205,9 @@
201 205 anchor.classList.add( 'current' );
202 206 elements.activeCategoryAnchor = anchor;
203 207 }
204 208 );
205 - wrapper.appendChild( anchor );
209 + wrapper.append( anchor );
206 210 }
207 211
208 212 return wrapper;
209 213 }
@@ -209,9 +213,9 @@
209 213 }
210 214
211 215 function getAllItemsCategory() {
212 216 /* translators: %d: Number of application templates. */
213 - return __( 'All Items (%d)', 'formidable' ).replace( '%d', state.templates.length );
217 + return sprintf( __( 'All Items (%d)', 'formidable' ), state.templates.length );
214 218 }
215 219
216 220 function handleCategorySelect( category ) {
217 221 state.filteredCategory = category;
@@ -226,9 +230,9 @@
226 230 }
227 231
228 232 addTemplatesToGrid(
229 233 state.templates.filter(
230 - template => -1 !== template.categories.indexOf( category )
234 + template => template.categories.includes( category )
231 235 )
232 236 );
233 237 }
234 238
@@ -236,16 +240,15 @@
236 240 const id = 'frm-application-search';
237 241 const placeholder = __( 'Search Templates', 'formidable' );
238 242 const targetClassName = 'frm-application-template-card';
239 243 const args = { handleSearchResult: handleTemplateSearch };
240 - const wrappedInput = newSearchInput( id, placeholder, targetClassName, args );
241 - return wrappedInput;
244 + return newSearchInput( id, placeholder, targetClassName, args );
242 245 }
243 246
244 - function handleTemplateSearch({ foundSomething, notEmptySearchText }) {
247 + function handleTemplateSearch( { foundSomething, notEmptySearchText } ) {
245 248 if ( false === elements.noTemplateSearchResultsPlaceholder ) {
246 249 elements.noTemplateSearchResultsPlaceholder = getNoResultsPlaceholder();
247 - elements.templatesGrid.appendChild( elements.noTemplateSearchResultsPlaceholder );
250 + elements.templatesGrid.append( elements.noTemplateSearchResultsPlaceholder );
248 251 }
249 252 elements.noTemplateSearchResultsPlaceholder.classList.toggle( 'frm_hidden', ! notEmptySearchText || foundSomething );
250 253 }
251 254
@@ -258,21 +261,21 @@
258 261 }
259 262
260 263 function createApplicationCard( data ) {
261 264 const isTemplate = ! data.termId;
262 - const card = div({
263 - className: 'frm-application-card',
265 + const card = div( {
266 + className: 'frm-application-card frm-card-item',
264 267 children: [
265 268 getCardHeader(),
266 - div({ className: 'frm-flex' })
269 + div( { className: 'frm-flex' } )
267 270 ]
268 - });
271 + } );
269 272
270 273 if ( isTemplate ) {
271 274 card.classList.add( 'frm-application-template-card' );
272 275 card.classList.add( 'frm-locked-application-template' );
273 - card.appendChild( tag( 'hr' ) );
274 - card.appendChild( getCardContent() );
276 + card.append( tag( 'hr' ) );
277 + card.append( getCardContent() );
275 278
276 279 card.addEventListener(
277 280 'click',
278 281 event => 'a' !== event.target.nodeName.toLowerCase() && card.querySelector( 'a' ).click()
@@ -279,35 +282,40 @@
279 282 );
280 283 }
281 284
282 285 const hookName = 'frm_application_index_card';
283 - const args = { data };
286 + const args = { data };
284 287 wp.hooks.doAction( hookName, card, args );
285 288
286 289 function getCardHeader() {
287 290 const titleWrapper = tag(
288 - 'h4',
291 + 'h3',
289 292 {
290 293 children: [
291 - svg({ href: '#frm_lock_icon' }),
292 - document.createTextNode( data.name )
294 + svg( { href: '#frm_lock_icon' } ),
295 + span( { className: 'frm-inner-text', text: data.name } )
293 296 ]
294 297 }
295 298 );
296 - const header = div({
299 + const header = div( {
297 300 children: [
298 - titleWrapper,
299 - getUseThisTemplateControl( data )
301 + titleWrapper
300 302 ]
301 - });
303 + } );
302 304
305 + const templateControl = getUseThisTemplateControl( data );
306 + if ( templateControl.classList.contains( 'frm-delete-application-trigger' ) ) {
307 + header.append( templateControl );
308 + } else {
309 + titleWrapper.append( templateControl );
310 + }
303 311 if ( data.isNew ) {
304 - titleWrapper.appendChild( span({ className: 'frm-new-pill', text: __( 'NEW', 'formidable' ) }) );
312 + titleWrapper.append( span( { className: 'frm-new-pill frm-meta-tag frm-fadein', text: __( 'NEW', 'formidable' ) } ) );
305 313 }
306 314
307 315 const counter = getItemCounter();
308 316 if ( false !== counter ) {
309 - header.appendChild( counter );
317 + header.append( counter );
310 318 }
311 319
312 320 return header;
313 321 }
@@ -318,29 +326,29 @@
318 326 return wp.hooks.applyFilters( hookName, false, args );
319 327 }
320 328
321 329 function getCardContent() {
322 - const thumbnailFolderUrl = getUrlToApplicationsImages() + 'thumbnails/';
323 - const filenameToUse = data.hasLiteThumbnail ? data.key + '.png' : 'placeholder.svg';
324 - return div({
330 + const thumbnailFolderUrl = `${ getUrlToApplicationsImages() }thumbnails/`;
331 + const filenameToUse = data.hasLiteThumbnail ? data.key + ( data.isWebp ? '.webp' : '.png' ) : 'placeholder.svg';
332 + return div( {
325 333 className: 'frm-application-card-image-wrapper',
326 - child: img({ src: thumbnailFolderUrl + filenameToUse })
327 - });
334 + child: img( { src: thumbnailFolderUrl + filenameToUse } )
335 + } );
328 336 }
329 337
330 338 return card;
331 339 }
332 340
333 - function filterItemCount( counter, { data }) {
334 - const hasForms = 'undefined' !== typeof data.formCount && '0' !== data.formCount;
335 - const hasViews = 'undefined' !== typeof data.viewCount && '0' !== data.viewCount;
336 - const hasPages = 'undefined' !== typeof data.pageCount && '0' !== data.pageCount;
341 + function filterItemCount( counter, { data } ) {
342 + const hasForms = data.formCount !== undefined && '0' !== data.formCount;
343 + const hasViews = data.viewCount !== undefined && '0' !== data.viewCount;
344 + const hasPages = data.pageCount !== undefined && '0' !== data.pageCount;
337 345
338 346 if ( ! hasForms && ! hasViews && ! hasPages ) {
339 347 return counter;
340 348 }
341 349
342 - counter = div({ className: 'frm-application-item-count' });
350 + counter = div( { className: 'frm-application-item-count' } );
343 351
344 352 if ( hasForms ) {
345 353 addCount( data.formCount, __( 'Forms', 'formidable' ), __( 'Form', 'formidable' ) );
346 354 }
@@ -354,14 +362,14 @@
354 362 }
355 363
356 364 function addCount( countValue, pluralDescriptor, singularDescriptor ) {
357 365 if ( counter.children.length ) {
358 - counter.appendChild( document.createTextNode( ' | ' ) );
366 + counter.append( document.createTextNode( ' | ' ) );
359 367 }
360 368
361 369 const descriptor = '1' === countValue ? singularDescriptor : pluralDescriptor;
362 - counter.appendChild(
363 - span( countValue + ' ' + descriptor )
370 + counter.append(
371 + span( `${ countValue } ${ descriptor }` )
364 372 );
365 373 }
366 374
367 375 return counter;
@@ -367,15 +375,15 @@
367 375 return counter;
368 376 }
369 377
370 378 function getUseThisTemplateControl( data ) {
371 - let control = a({
372 - className: 'button frm-button-secondary frm-button-sm',
379 + let control = a( {
380 + className: 'button frm-button-secondary frm-button-sm frm-fadein',
373 381 text: __( 'Learn More', 'formidable' )
374 - });
382 + } );
375 383 control.setAttribute( 'role', 'button' );
376 384 /* translators: %s: Application Template Name */
377 - const ariaDescription = __( '%s Template' ).replace( '%s', data.name );
385 + const ariaDescription = sprintf( __( '%s Template', 'formidable' ), data.name );
378 386 control.setAttribute( 'aria-description', ariaDescription );
379 387 control.addEventListener(
380 388 'click',
381 389 event => {
@@ -413,26 +421,26 @@
413 421 const children = [];
414 422
415 423 if ( data.upgradeUrl ) {
416 424 children.push(
417 - div({
418 - className: 'frm_warning_style',
425 + div( {
426 + className: 'frm_note_style2',
419 427 children: [
420 428 span(
421 429 /* translators: %s: The required license type (ie. Plus, Business, or Elite) */
422 - __( 'Access to this application requires the %s plan.', 'formidable' )
423 - .replace( '%s', data.requires )
430 + sprintf( __( 'Access to this application requires the %s plan.', 'formidable' ), data.requires )
424 431 ),
425 - a({
432 + a( {
433 + className: 'frm-gradient frm-button-primary frm-button-sm',
426 434 text: getUpgradeNowText(),
427 435 href: data.upgradeUrl
428 - })
436 + } )
429 437 ]
430 - })
438 + } )
431 439 );
432 440 }
433 441
434 - const placeholderImage = img({ src: getUrlToApplicationsImages() + 'placeholder.png' });
442 + const placeholderImage = img( { src: `${ getUrlToApplicationsImages() }placeholder.png` } );
435 443 if ( placeholderImage.complete ) {
436 444 setTimeout( maybeCenterViewApplicationModal, 0 );
437 445 } else {
438 446 placeholderImage.addEventListener( 'load', maybeCenterViewApplicationModal );
@@ -437,34 +445,56 @@
437 445 } else {
438 446 placeholderImage.addEventListener( 'load', maybeCenterViewApplicationModal );
439 447 }
440 448
449 + const detailsChildren = [
450 + div( {
451 + className: 'frm-application-modal-label',
452 + text: __( 'Description', 'formidable' )
453 + } ),
454 + div( data.description )
455 + ];
456 +
457 + if ( data.usedAddons?.length ) {
458 + detailsChildren.push(
459 + div( {
460 + className: 'frm-application-modal-label',
461 + text: __( 'Required Add-ons', 'formidable-pro' )
462 + } ),
463 + getBasicList( data.usedAddons )
464 + );
465 + }
466 +
441 467 children.push(
442 - div({
468 + div( {
443 469 className: 'frm-application-image-wrapper',
444 470 child: placeholderImage
445 - }),
446 - div({
471 + } ),
472 + div( {
447 473 className: 'frm-application-modal-details',
448 - children: [
449 - div({
450 - className: 'frm-application-modal-label',
451 - text: __( 'Description', 'formidable' )
452 - }),
453 - div( data.description )
454 - ]
455 - })
474 + children: detailsChildren
475 + } )
456 476 );
457 477
458 - const output = div({ children });
478 + const output = div( { children } );
459 479
460 480 const hookName = 'frm_view_application_modal_content';
461 - const args = { data };
481 + const args = { data };
462 482 wp.hooks.doAction( hookName, output, args );
463 483
464 484 return output;
465 485 }
466 486
487 + function getBasicList( data ) {
488 + return tag(
489 + 'ul',
490 + {
491 + className: 'frm-application-item-list',
492 + children: data.map( text => tag( 'li', text ) )
493 + }
494 + );
495 + }
496 +
467 497 function maybeCenterViewApplicationModal() {
468 498 if ( false !== elements.viewApplicationModal ) {
469 499 centerModal( elements.viewApplicationModal );
470 500 }
@@ -475,34 +505,36 @@
475 505 my: 'center',
476 506 at: 'center',
477 507 of: window
478 508 };
479 - jQuery( modal ).dialog({ position });
509 + jQuery( modal ).dialog( { position } );
480 510 }
481 511
482 512 function getViewApplicationModalFooter( data ) {
483 - const viewDemoSiteButton = footerButton({
513 + const viewDemoSiteButton = footerButton( {
484 514 text: __( 'Learn More', 'formidable' ),
485 515 buttonType: 'secondary'
486 - });
516 + } );
487 517 viewDemoSiteButton.href = data.link;
488 518 viewDemoSiteButton.target = '_blank';
489 519
490 - let primaryActionButton = footerButton({
520 + let primaryActionButton = footerButton( {
491 521 text: getUpgradeNowText(),
492 522 buttonType: 'primary'
493 - });
523 + } );
494 524
495 525 if ( data.upgradeUrl ) {
496 526 primaryActionButton.classList.remove( 'dismiss' );
497 527 primaryActionButton.setAttribute( 'href', data.upgradeUrl );
528 + primaryActionButton.target = '_blank';
529 + primaryActionButton.rel = 'noopener';
498 530 }
499 531
500 532 const hookName = 'frm_view_application_modal_primary_action_button';
501 - const args = { data };
533 + const args = { data };
502 534 primaryActionButton = wp.hooks.applyFilters( hookName, primaryActionButton, args );
503 535
504 - return div({
536 + return div( {
505 537 children: [ viewDemoSiteButton, primaryActionButton ]
506 - });
538 + } );
507 539 }
508 540 }() );