|
| 1 | +/** |
| 2 | + * Gravity Perks // Nested Forms // Duplicate Child Entry Multiple Times |
| 3 | + * https://gravitywiz.com/documentation/gravity-forms-nested-forms/ |
| 4 | + * |
| 5 | + * Prompts for a quantity and runs the duplication that many times. |
| 6 | + * |
| 7 | + * Instructions: |
| 8 | + * |
| 9 | + * 1. Install this snippet with our free Custom JavaScript plugin. |
| 10 | + * https://gravitywiz.com/gravity-forms-code-chest/ |
| 11 | + * |
| 12 | + * 2. Configure the snippet's fieldId, maxCopies and prompt |
| 13 | + */ |
| 14 | +(function( $ ) { |
| 15 | + |
| 16 | + // Configuration |
| 17 | + var CONFIG = { |
| 18 | + targets: [ |
| 19 | + { |
| 20 | + fieldId: 1, // Nested Form Field ID. |
| 21 | + // maxCopies: 5, // Optional cap per duplicate action. |
| 22 | + // prompt: '', // Override the default prompt. |
| 23 | + }, |
| 24 | + ], |
| 25 | + }; |
| 26 | + |
| 27 | + function init( gpnf ) { |
| 28 | + var config; |
| 29 | + |
| 30 | + // Match the active GPNestedForms instance to the configured targets. |
| 31 | + for ( var i = 0; i < CONFIG.targets.length; i++ ) { |
| 32 | + if ( CONFIG.targets[ i ].fieldId === gpnf.fieldId && matchesForm( gpnf ) ) { |
| 33 | + config = CONFIG.targets[ i ]; |
| 34 | + break; |
| 35 | + } |
| 36 | + } |
| 37 | + |
| 38 | + if ( ! config || gpnf._multiDuplicateReady ) { |
| 39 | + return; |
| 40 | + } |
| 41 | + |
| 42 | + gpnf._multiDuplicateReady = true; |
| 43 | + |
| 44 | + // Wrap GPNF's duplicate endpoint in a promise so we can queue requests sequentially. |
| 45 | + var duplicateOnce = (function() { |
| 46 | + var nonce = window.GPNFData && window.GPNFData.nonces ? window.GPNFData.nonces.duplicateEntry : ''; |
| 47 | + |
| 48 | + return function( entryId ) { |
| 49 | + return $.post( gpnf.ajaxUrl, { |
| 50 | + action: 'gpnf_duplicate_entry', |
| 51 | + nonce: nonce, |
| 52 | + gpnf_entry_id: entryId, |
| 53 | + gpnf_parent_form_id: gpnf.formId, |
| 54 | + gpnf_nested_form_field_id: gpnf.fieldId, |
| 55 | + gpnf_context: gpnf.ajaxContext |
| 56 | + } ).then( function( response ) { |
| 57 | + if ( ! response || ! response.success ) { |
| 58 | + return $.Deferred().reject( response && response.data ? response.data : 'Unable to duplicate entry.' ); |
| 59 | + } |
| 60 | + |
| 61 | + if ( window.GPNestedForms && typeof window.GPNestedForms.loadEntry === 'function' ) { |
| 62 | + window.GPNestedForms.loadEntry( response.data ); |
| 63 | + } |
| 64 | + |
| 65 | + if ( window.gform && typeof window.gform.doAction === 'function' ) { |
| 66 | + window.gform.doAction( 'gpnf_post_duplicate_entry', response.data.entry, response ); |
| 67 | + } |
| 68 | + |
| 69 | + return response; |
| 70 | + } ); |
| 71 | + }; |
| 72 | + })(); |
| 73 | + |
| 74 | + gpnf.duplicateEntry = function( entryId, $trigger ) { |
| 75 | + |
| 76 | + var message = config.prompt || 'How many times should this entry be duplicated?'; |
| 77 | + var input = window.prompt( message, '1' ); |
| 78 | + |
| 79 | + if ( input === null ) { |
| 80 | + return; |
| 81 | + } |
| 82 | + |
| 83 | + var copies = parseInt( input, 10 ); |
| 84 | + |
| 85 | + if ( isNaN( copies ) || copies < 1 ) { |
| 86 | + copies = 1; |
| 87 | + } |
| 88 | + |
| 89 | + if ( typeof config.maxCopies === 'number' ) { |
| 90 | + copies = Math.min( copies, config.maxCopies ); |
| 91 | + } |
| 92 | + |
| 93 | + var max = gpnf.entryLimitMax; |
| 94 | + |
| 95 | + if ( window.gform && gform.applyFilters ) { |
| 96 | + max = gform.applyFilters( 'gpnf_entry_limit_max', max, gpnf.formId, gpnf.fieldId, gpnf ); |
| 97 | + } |
| 98 | + |
| 99 | + if ( max !== '' && max != null ) { |
| 100 | + max = parseInt( max, 10 ); |
| 101 | + |
| 102 | + if ( ! isNaN( max ) ) { |
| 103 | + var current = gpnf.viewModel && gpnf.viewModel.entries ? gpnf.viewModel.entries().length : 0; |
| 104 | + copies = Math.min( copies, Math.max( max - current, 0 ) ); |
| 105 | + } |
| 106 | + } |
| 107 | + |
| 108 | + if ( copies < 1 ) { |
| 109 | + return; |
| 110 | + } |
| 111 | + |
| 112 | + var disableTarget = $trigger && typeof $trigger.prop === 'function' ? $trigger : null; |
| 113 | + |
| 114 | + if ( disableTarget ) { |
| 115 | + disableTarget.prop( 'disabled', true ); |
| 116 | + } |
| 117 | + |
| 118 | + var chain = $.Deferred().resolve(); |
| 119 | + for ( var i = 0; i < copies; i++ ) { |
| 120 | + chain = chain.then( function() { |
| 121 | + return duplicateOnce( entryId ); |
| 122 | + } ); |
| 123 | + } |
| 124 | + |
| 125 | + chain.fail( function( message ) { |
| 126 | + if ( message ) { |
| 127 | + window.alert( message ); |
| 128 | + } |
| 129 | + } ).always( function() { |
| 130 | + if ( disableTarget ) { |
| 131 | + disableTarget.prop( 'disabled', false ); |
| 132 | + } |
| 133 | + } ); |
| 134 | + }; |
| 135 | + } |
| 136 | + |
| 137 | + function matchesForm( gpnf ) { |
| 138 | + if ( typeof gpnf.formId !== 'number' ) { |
| 139 | + return false; |
| 140 | + } |
| 141 | + |
| 142 | + if ( typeof GFFORMID !== 'undefined' ) { |
| 143 | + var currentFormId = parseInt( GFFORMID, 10 ); |
| 144 | + |
| 145 | + if ( ! isNaN( currentFormId ) ) { |
| 146 | + return gpnf.formId === currentFormId; |
| 147 | + } |
| 148 | + } |
| 149 | + |
| 150 | + return true; |
| 151 | + } |
| 152 | + |
| 153 | + if ( window.gform && gform.addAction ) { |
| 154 | + gform.addAction( 'gpnf_session_initialized', init ); |
| 155 | + } |
| 156 | + |
| 157 | + for ( var key in window ) { |
| 158 | + if ( key.indexOf( 'GPNestedForms_' ) === 0 ) { |
| 159 | + init( window[ key ] ); |
| 160 | + } |
| 161 | + } |
| 162 | + |
| 163 | +})( window.jQuery ); |
0 commit comments