1/** 2 * Contact Form 7 add confirm â front-end controller. 3 * 4 * æµã: 5 * step1: 確èªãã¿ã³ï¼type=submitï¼â CF7 ã REST éä¿¡ï¼ãµã¼ãå´ãã«æ¤è¨¼ã»ã¡ã¼ã«ã¯ã¹ãããï¼ 6 * â å¿ç status "cscf7_confirmed" â ãã®ã¹ã¯ãªããã確èªè¡¨ç¤ºã¸åæ¿ 7 * step2: éä¿¡ãã¿ã³ â CF7 ã®é常éä¿¡ â "mail_sent" â å ¥å表示ã¸å¾©å¸° 8 * 9 * CF7 6.x ã®ä»æ§ã«ä¾åãã¦ããç¹: 10 * - wpcf7submit / wpcf7mailsent ã¯ãã©ã¼ã è¦ç´ ãã bubbles:true ã§ dispatch ããã 11 * - å¿ç status ãæªç¥ã®å¤ã§ããã©ã¼ã ã® data-status ã custom-* ã«ãªãã ãã§å£ããªã 12 * - FormData ã¯ãã©ã¼ã è¦ç´ ããæ§ç¯ãããï¼disabled ã¯è¼ããªãã»readonly ã¯è¼ãï¼ 13 */ 14(() => { 15 'use strict'; 16 17 const HIDE = 'wpcf7c-force-hide'; 18 19 const setup = ( form ) => { 20 if ( form.cscf7 ) { 21 return; 22 } 23 24 if ( ! form.querySelector( '.wpcf7c-btn-confirm' ) ) { 25 return; 26 } 27 28 let marker = form.querySelector( 'input[name="_cscf7"]' ); 29 30 if ( ! marker ) { 31 marker = document.createElement( 'input' ); 32 marker.type = 'hidden'; 33 marker.name = '_cscf7'; 34 form.appendChild( marker ); 35 } 36 37 form.cscf7 = { step: 1, marker }; 38 39 // é常ã®éä¿¡ãã¿ã³ã¯ç¢ºèªã¹ãããï¼step2ï¼ã®è¦ç´ ã¨ãã¦æ±ãã 40 form.querySelectorAll( '.wpcf7-submit' ).forEach( ( el ) => { 41 if ( ! el.classList.contains( 'wpcf7c-btn-confirm' ) ) { 42 el.classList.add( 'wpcf7c-elm-step2' ); 43 } 44 } ); 45 46 form.addEventListener( 'click', ( e ) => { 47 const back = e.target.closest( '.wpcf7c-btn-back' ); 48 49 if ( back && ! back.disabled ) { 50 e.preventDefault(); 51 toStep1( form, true ); 52 } 53 } ); 54 55 show( form, 1 ); 56 }; 57 58 const show = ( form, step ) => { 59 form.querySelectorAll( '.wpcf7c-elm-step1' ).forEach( ( el ) => { 60 el.classList.toggle( HIDE, 1 !== step ); 61 } ); 62 63 form.querySelectorAll( '.wpcf7c-elm-step2' ).forEach( ( el ) => { 64 el.classList.toggle( HIDE, 2 !== step ); 65 } ); 66 67 form.classList.toggle( 'wpcf7c-confirming', 2 === step ); 68 form.cscf7.step = step; 69 form.cscf7.marker.value = 'step' + step; 70 }; 71 72 const addClone = ( el, name, value ) => { 73 const clone = document.createElement( 'input' ); 74 clone.type = 'hidden'; 75 clone.name = name; 76 clone.value = value; 77 clone.className = 'wpcf7c-conf-hidden'; 78 el.after( clone ); 79 }; 80 81 /** 82 * å ¥åã確èªè¡¨ç¤ºï¼ç·¨éä¸å¯ï¼ã¸ã 83 * disabled ã«ããè¦ç´ 㯠FormData ã«è¼ããªãããã鏿å¤ã hidden ã§è¤è£½ã㦠84 * step2 ã®æ¬éä¿¡ã«åãå¤ã渡ãããã«ãããå ã«æ»ãããã®ç¶æ 㯠85 * data-cscf7-locked ã«è¨é²ããï¼å ãã readonly/disabled ã®è¦ç´ ã¯è§¦ããªãï¼ã 86 */ 87 const lock = ( form ) => { 88 form.querySelectorAll( 'input, textarea, select' ).forEach( ( el ) => { 89 const tag = el.tagName.toLowerCase(); 90 const type = ( el.getAttribute( 'type' ) || 'text' ).toLowerCase(); 91 92 if ( 'input' === tag 93 && [ 'submit', 'button', 'hidden', 'image', 'reset' ].includes( type ) ) { 94 return; 95 } 96 97 if ( el.dataset.cscf7Locked ) { 98 return; 99 } 100 101 if ( 'textarea' === tag ) { 102 if ( ! el.readOnly ) { 103 el.dataset.cscf7Locked = 'readonly'; 104 el.readOnly = true; 105 } 106 el.classList.add( 'wpcf7c-conf' ); 107 } else if ( 'select' === tag ) { 108 if ( ! el.disabled ) { 109 el.dataset.cscf7Locked = 'disabled'; 110 Array.from( el.selectedOptions ).forEach( ( opt ) => { 111 addClone( el, el.name, opt.value ); 112 } ); 113 el.disabled = true; 114 } 115 el.classList.add( 'wpcf7c-conf' ); 116 } else if ( 'radio' === type || 'checkbox' === type ) { 117 if ( ! el.disabled ) { 118 el.dataset.cscf7Locked = 'disabled'; 119 if ( el.checked ) { 120 addClone( el, el.name, el.value ); 121 } 122 el.disabled = true; 123 } 124 el.classList.add( 'wpcf7c-conf' ); 125 } else if ( 'file' === type ) { 126 el.dataset.cscf7Locked = 'file'; 127 el.classList.add( HIDE ); 128 129 const stand = document.createElement( 'input' ); 130 stand.type = 'text'; 131 stand.readOnly = true; 132 stand.disabled = true; 133 stand.className = 'wpcf7c-conf wpcf7c-conf-hidden'; 134 stand.value = Array.from( el.files || [] ) 135 .map( ( f ) => f.name ) 136 .join( ', ' ); 137 el.after( stand ); 138 } else { 139 if ( ! el.readOnly ) {
140 el.dataset.cscf7Locked = 'readonly'; 141 el.readOnly = true; 142 } 143 el.classList.add( 'wpcf7c-conf' ); 144 } 145 } ); 146 }; 147 148 const unlock = ( form ) => { 149 form.querySelectorAll( '.wpcf7c-conf-hidden' ).forEach( ( el ) => { 150 el.remove(); 151 } ); 152 153 form.querySelectorAll( '[data-cscf7-locked]' ).forEach( ( el ) => { 154 const mode = el.dataset.cscf7Locked; 155 delete el.dataset.cscf7Locked; 156 157 el.classList.remove( 'wpcf7c-conf' ); 158 159 if ( 'readonly' === mode ) { 160 el.readOnly = false; 161 } else if ( 'disabled' === mode ) { 162 el.disabled = false; 163 } else if ( 'file' === mode ) { 164 el.classList.remove( HIDE ); 165 } 166 } ); 167 168 // å ãã readonly/disabled ã§ locked ãä»ããªãã£ãè¦ç´ ã®è¡¨ç¤ºã¯ã©ã¹ãæé¤ã 169 form.querySelectorAll( '.wpcf7c-conf' ).forEach( ( el ) => { 170 el.classList.remove( 'wpcf7c-conf' ); 171 } ); 172 }; 173 174 const toStep2 = ( form ) => { 175 lock( form ); 176 show( form, 2 ); 177 scrollToForm( form ); 178 }; 179 180 const toStep1 = ( form, scroll ) => { 181 unlock( form ); 182 show( form, 1 ); 183 184 if ( scroll ) { 185 scrollToForm( form ); 186 } 187 }; 188 189 const scrollToForm = ( form ) => { 190 const anchor = form.querySelector( '.wpcf7c-anchor' ) || form; 191 anchor.scrollIntoView( { behavior: 'smooth', block: 'start' } ); 192 }; 193 194 document.addEventListener( 'wpcf7submit', ( e ) => { 195 const form = e.target; 196 197 if ( ! form || ! form.cscf7 ) { 198 return; 199 } 200 201 if ( e.detail && 'cscf7_confirmed' === e.detail.status ) { 202 toStep2( form ); 203 } 204 } ); 205 206 document.addEventListener( 'wpcf7mailsent', ( e ) => { 207 const form = e.target; 208 209 if ( ! form || ! form.cscf7 ) { 210 return; 211 } 212 213 // CF7 æ¬ä½ããã®å¾ form.reset() ããã表示ã ãå ¥åã¹ãããã¸æ»ãã 214 toStep1( form, false ); 215 } ); 216 217 const init = () => { 218 document.querySelectorAll( '.wpcf7 > form' ).forEach( setup ); 219 }; 220 221 if ( 'loading' === document.readyState ) { 222 document.addEventListener( 'DOMContentLoaded', init ); 223 } else { 224 init(); 225 } 226})();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.