1/** 2 * Headwall WP Tutorials Checkout Fancy Placeholders : WPTCFP 3 * 4 * https://wp-tutorials.tech/refine-wordpress/show-woocommerce-checkout-labels-in-the-input-fields/ 5 * 6 */ 7 8(function($) { 9 'use strict'; 10 11 // Diagnostics. 12 // console.log('Checkout Fancy Placeholders : load'); 13 14 if (typeof wptcfp !== 'undefined') { 15 16 // Tidy up the wptcfp that was rinsed through json_encode() 17 wptcfp.isCheckout = (wptcfp.isCheckout === '1'); 18 19 20 /** 21 * Initialise event handlers. If we're on the checkout page then we need 22 * to listen for init_checkout and updated_checkout. If we're not on the 23 * checkout page, just listen for the window's load event. 24 */ 25 wptcfp.init = () => { 26 if (wptcfp.isCheckout) { 27 // This is fired once, as WooComemrce configures the checkout. 28 $(window).on('init_checkout', wptcfp.checkoutInitialised); 29 30 // This can be fired multiple times, like when the shipping method 31 // changes. 32 $(window).on('updated_checkout', wptcfp.reconfigureFields); 33 } else { 34 $(window).on('load', wptcfp.reconfigureFields); 35 } 36 }; 37 38 39 /** 40 * After the checkout has initialised, listen for the country-change event 41 * and then configure the fields. 42 */ 43 wptcfp.checkoutInitialised = () => { 44 // Diagnostics. 45 // console.log('checkoutInitialised'); 46 47 // When the billing/shipping country changes, we need to refresh all our labels 48 $('#billing_country, #shipping_country').on('change', wptcfp.refreshAllLabels); 49 50 wptcfp.reconfigureFields(); 51 }; 52 53 54 /** 55 * Is this element eligible to be configures as a fancy placholder? 56 * @param INPUT|SELECT inputElement The element to check 57 * (not the form-row). 58 * @return bool 59 */ 60 wptcfp.isElementEligible = (inputElement) => { 61 const id = $(inputElement).prop('id'); 62 return (id && !wptcfp.ignoreFields.includes(id)); 63 }; 64 65 66 /** 67 * This is our core function that scans all checkout INPUT/SELECT element, 68 * looking for fields elegible for fancy placeholders. 69 */ 70 wptcfp.reconfigureFields = () => { 71 // Diagnostics 72 // console.log('wptcfp : Configure fields'); 73 74 let elementCount = 0; 75 76 $(wptcfp.selector).each(function(index, inputElement) { 77 const formRow = $(inputElement).closest('.form-row'); 78 79 if (wptcfp.isElementEligible(inputElement)) { 80 // It's safe to call addClass() even if the element already has 81 // that class. jQuery checks first and won't add it multiple 82 // times. 83 $(formRow).addClass('has-fancy-placeholder'); 84 85 // We use the "has-events" class to record that we've already 86 // connected an element's event handlers. 87 if (!$(inputElement).hasClass('has-events')) { 88 // We want to refresh the element when any of these evers are 89 // triggered for it. 90 $(inputElement).on('blur focus change validate', wptcfp.inputChanged); 91 92 $(formRow).addClass('has-events'); 93 } 94 95 wptcfp.refreshField(inputElement); 96 97 ++elementCount; 98 } 99 }); 100 101 // If we've (re)configured one or more elements, wait a small delay (50ms) 102 // and then strip out any placeholders that WooCommerce might have 103 // automatically (re)added. 104 if (elementCount > 0) { 105 setTimeout(wptcfp.stripHtmlPlacehodlers, 50); 106 } 107 }; 108 109 110 /** 111 * Find all elements that are eligible for fancy placehodlers, and remove 112 * built-in placeholders that WooCommerce might have automatically (re)added. 113 */ 114 wptcfp.stripHtmlPlacehodlers = () => { 115 $(wptcfp.selector).each(function(index, inputElement) { 116 117 if (wptcfp.isElementEligible(inputElement)) { 118 $(inputElement).removeAttr('placeholder'); 119 $(inputElement).removeAttr('data-placeholder'); 120 } 121 122 }); 123 }; 124 125 126 /** 127 * Handle when an input element has changed its value. 128 */ 129 wptcfp.inputChanged = (event) => { 130 wptcfp.refreshField(event.target); 131 }; 132 133 134 /** 135 * Refresh an individual field's properties. 136 */ 137 wptcfp.refreshField = (inputElement) => { 138 if (wptcfp.isElementEligible(inputElement)) { 139 const formRow = $(inputElement).closest('.form-row'); 140 const labelElement = $(inputElement).closest('label'); 141 142 const inputCount = $(formRow).find('input').length; 143 const selectCount = $(formRow).find('select').length; 144 145 // If this form-row has a SELECT element, but not an INPUT element, 146 // hide the label now. 147 if (selectCount && !inputCount) { 148 $(labelElement).css('display', 'none'); 149 } else { 150 $(labelElement).css('display', 'block'); 151 152 if ($(inputElement).is(":focus")) { 153 $(formRow).addClass('has-focus'); 154 } else { 155 $(formRow).removeClass('has-focus'); 156 } 157 158 if ($(inputElement).val()) { 159 $(formRow).addClass('has-value'); 160 } else { 161 $(formRow).removeClass('has-value'); 162 } 163 } 164 } 165 }; 166 167 168 /** 169 * Main entry point 170 */ 171 wptcfp.init(); 172 173 174 } 175 176})(jQuery);
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.