PageSourceSearch

https://boisehunterhomes.com/wp-content/themes/wpresidence/js/wpestate_login_register.js?ver=5.3.0

js boisehunterhomes.com collected 2026-10-05 01:32:46 UTC 28,263 bytes, 804 lines download raw bytes

1/*global $, jQuery,wpestate_login_register_vars, ajaxcalls_vars, document, control_vars, window*/
2
3
4jQuery(document).ready(function ($) { 
5    "use strict";
6     
7    jQuery('#login-modal_close').on( 'click', function(event) {
8        jQuery('#modal_login_wrapper').hide();
9    });
10    wpestate_trigger_login_action();
11    wpestate_trigger_register_action();
12    wpestate_trigger_forgot_password_action();
13    wpestate_controls_show_hide_login_register_forgot_form();
14    wpestate_initializePasswordVisibilityToggle();
15    wpestate_handle_social_login();
16    wpestate_handle_password_change();
17})  
18
19/**  
20 * reCAPTCHA Initialization Function
21 * 
22 * This function initializes reCAPTCHA widgets for all elements with the class
23 * 'wpestate_register_form_captcha'. It's designed to be used as a callback
24 * when the reCAPTCHA script is loaded.
25 *
26 * @global {Array} widgetRecaptchas - Stores the IDs of all rendered reCAPTCHA widgets
27 * @global {Object} control_vars - Expected to contain the reCAPTCHA site key
28 * 
29 * Usage:
30 * 1. Ensure the reCAPTCHA script is loaded with this function as a callback
31 * 2. Add the class 'wpestate_register_form_captcha' to any element where you want a reCAPTCHA widget
32 * 
33 * Note: This function assumes that 'control_vars.captchakey' contains a valid reCAPTCHA site key
34 */
35
36var widgetRecaptchas = [];
37var wpestate_onloadCallback = function() {
38    // Find all elements with the class 'wpestate_register_form_captcha'
39    var captchaElements = document.getElementsByClassName('wpestate_register_form_captcha');
40
41    // Render reCAPTCHA for each element found
42    for (var i = 0; i < captchaElements.length; i++) {
43        var widgetRecaptcha = grecaptcha.render(captchaElements[i], {
44            'sitekey': control_vars.captchakey,
45            'theme': 'light'
46        });
47        widgetRecaptchas.push(widgetRecaptcha);
48    }
49};
50
51
52
53
54/**
55 * Handle password change events
56 * 
57 * This function sets up event handlers for password change functionality.
58 * It handles both Enter key presses in password fields and clicks on the
59 * change password button.
60 *
61 * @since 1.0.0
62 * 
63 * @requires jQuery
64 * @requires wpestate_change_pass_profile function (assumed to exist)
65 * 
66
67 */ 
68
69
70
71function wpestate_handle_password_change() {
72    const ENTER_KEY_CODE = 13;
73    const passwordFields = '#oldpass, #newpass, #renewpass';
74    const changePasswordButton = '#change_pass';
75
76    // Handle Enter key press in password fields
77    jQuery(passwordFields).on('keydown', function(event) {
78        if (event.keyCode === ENTER_KEY_CODE) {
79            event.preventDefault();
80            wpestate_change_pass_profile();
81        } 
82    }); 
83   
84    // Handle click on change password button
85    jQuery(changePasswordButton).on('click', function(event) {
86        event.preventDefault();
87        wpestate_change_pass_profile();
88    });
89}
90
91
92function wpestate_change_pass_profile() {
93    "use strict";
94    var oldpass, newpass, renewpass, securitypass, ajaxurl;
95    oldpass = jQuery('#oldpass').val();
96    newpass = jQuery('#newpass').val();
97    renewpass = jQuery('#renewpass').val();
98    securitypass = jQuery('#security-pass').val();
99    ajaxurl = ajaxcalls_vars.admin_url + 'admin-ajax.php';
100
101    jQuery.ajax({
102        type: 'POST',
103        url: ajaxurl,
104        data: {
105            'action': 'wpestate_ajax_update_pass',
106            'oldpass': oldpass,
107            'newpass': newpass,
108            'renewpass': renewpass,
109            'security-pass': securitypass
110        },
111        success: function (data) {
112            jQuery('#profile_pass').empty().append('<div class="login-alert">' + data + '<div>');
113            jQuery('#oldpass, #newpass, #renewpass').val('');
114        },
115        error: function (errorThrown) {
116        }
117    });
118}
119
120
121
122
123
124/**
125 * Handle social login button clicks
126 * 
127 * This function sets up a click event handler for social login buttons.
128 * When clicked, it sends an AJAX request to generate a social login link
129 * and redirects the user to the generated URL.
130 *
131 * @since 1.0.0
132 * 
133 * @requires jQuery
134 * @requires ajaxcalls_vars.admin_url
135 * 
136 * @example
137 * // Call this function when the document is ready
138 * $(document).ready(function() {
139 *     wpestate_handle_social_login();
140 * });
141 */
142function wpestate_handle_social_login() {
143    jQuery('.wpestate_social_login').on('click', function(event) {
144        event.preventDefault(); // Prevent default button action
145
146        // Get the AJAX URL from the global variable
147        var ajaxUrl = ajaxcalls_vars.admin_url + 'admin-ajax.php';
148
149        // Extract social login type and nonce from the clicked button
150        var socialLoginType = jQuery(this).attr('data-social');
151        var socialLoginNonce = jQuery(this).parent().find('.wpestate_social_login_nonce').val();
152
153        // Send AJAX request to generate social login link
154        jQuery.ajax({
155            type: 'POST',
156            url: ajaxUrl,
157            data: {
158                'action': 'wpestate_social_login_generate_link',
159                'social_type': socialLoginType,
160                'nonce': socialLoginNonce
161            },
162            success: function(response) {
163                // Redirect to the generated social login URL
164                window.location.href = response;
165            },
166            error: function(jqXHR, textStatus, errorThrown) {
167                // Log error for debugging
168                console.error('Social login error:', textStatus, errorThrown);
169                // Optionally, display an error message to the user
170                alert('An error occurred during social login. Please try again.');
171            }
172        });
173    });
174}
175
176
177
178/**
179 * Controls the visibility of login, register, and forgot password forms.
180 * 
181 * This function sets up click event handlers for form switching buttons
182 * in the WpResidence theme's login widget. It manages the visibility of
183 * different form sections (login, register, forgot password) and their
184 * corresponding switch buttons.
185 * 
186 * @since 1.0.0
187 * @requires jQuery
188 * 
189 * Usage:
190 * - Call this function after the DOM is ready.
191 * - Ensure that the form structure follows the expected HTML layout:
192 *   - Forms should have classes: wpestate_login_form_wrapper, wpestate_register_form_wrapper, wpestate_forgot_form_wrapper
193 *   - Switch buttons should have classes: wpestate_login_form_switch_login, wpestate_login_form_switch_register, wpestate_login_form_switch_forgot
194 * 
195 * @return {void}
196 */
197function wpestate_controls_show_hide_login_register_forgot_form() {
198
199    jQuery('.wpestate_login_form_switch_login, .wpestate_login_form_switch_register, .wpestate_login_form_switch_forgot').on('click', function (event) {
200        event.preventDefault();
201        var $this = jQuery(this);
202        var form_wrapper = $this.parent().parent();
203        var clicked_type = $this.attr('class').split('_').pop();
204
205        // Hide all forms and show all switches
206        form_wrapper.find('.wpestate_login_form_wrapper, .wpestate_register_form_wrapper, .wpestate_forgot_form_wrapper').hide();
207        form_wrapper.find('.wpestate_login_form_switch_login, .wpestate_login_form_switch_register, .wpestate_login_form_switch_forgot').show();
208
209        // Show the clicked form and hide its switch
210        form_wrapper.find('.wpestate_' + clicked_type + '_form_wrapper').show().find('[autofocus]').focus();
211        $this.hide();
212    });
213}
214
215
216
217/**
218 * Toggles password visibility for input fields.
219 * 
220 * This function sets up a click event handler for elements with the class 'show_hide_password'.
221 * When clicked, it toggles the visibility of the adjacent password input field and updates
222 * the icon class accordingly.
223 *
224 * @requires jQuery
225 * 
226 * Usage:
227 * - Call this function after the DOM is ready.
228 * - Ensure that the HTML structure follows the expected layout:
229 *   - A container element with a child element having the class 'show_hide_password'
230 *   - An input field (type="password") as a sibling to the 'show_hide_password' element
231 * 
232 * HTML structure example:
233 * <div class="password-container">
234 *   <input type="password" name="password" />
235 *   <i class="show_hide_password fa fa-eye-slash"></i>
236 * </div>
237 * 
238 * @return {void}
239 */
240function wpestate_initializePasswordVisibilityToggle() {
241    jQuery('.show_hide_password').on('click', function() {
242        // Find the password input field within the same parent container
243        var passField = jQuery(this).parent().find(':input');
244        
245        if (passField.attr('type') === "password") {
246            // If the field is a password, change it to text and update the icon
247            passField.attr('type', 'text');
248            jQuery(this).removeClass('fa-eye-slash').addClass('fa-eye');
249        } else {
250            // If the field is text, change it back to password and update the icon
251            passField.attr('type', 'password');
252            jQuery(this).removeClass('fa-eye').addClass('fa-eye-slash');
253        }
254    });
255}
256
257
258
259/**
260 * Sets up event handlers for user registration actions.
261 * 
262 * This function initializes click and keydown event handlers for the registration
263 * form elements in the WpResidence theme. It handles both button clicks and
264 * Enter key presses on input fields to trigger the user registration process.
265 *
266 * @requires jQuery
267 * @requires wpestate_register_user function (not defined here)
268 * 
269 * Usage:
270 * - Call this function after the DOM is ready and after defining wpestate_register_user.
271 * - Ensure that the HTML structure follows the expected layout:
272 *   - Registration form wrapper with class 'wpestate_register_form_wrapper'
273 *   - Submit button with class 'wpestate_register_submit_button'
274 *   - Input fields with classes 'wpestate_register_form_email', 'wpestate_register_form_username',
275 *     'wpestate_register_form_password', 'wpestate_register_form_user_t
275ype'
276 * 
277 * @return {void}
278 */
279function wpestate_trigger_register_action() {
280    const $document = jQuery(document);
281    const ENTER_KEY_CODE = 13;
282
283    // Handle click on register submit button
284    $document.on('click', '.wpestate_register_submit_button', function(event) {
285        wpestate_register_user(jQuery(this));
286    });
287
288    // Handle Enter key press on registration form fields
289    $document.on('keydown', '.wpestate_register_form_email, .wpestate_register_form_username, .wpestate_register_form_password, .wpestate_register_form_user_type', function(event) {
290        if (event.keyCode === ENTER_KEY_CODE) {
291            event.preventDefault();
292            const $submitButton = jQuery(this).closest('.wpestate_register_form_wrapper').find('.wpestate_register_submit_button');
293            wpestate_register_user($submitButton);
294        }
295    });
296}
297
298
299
300
301/**
302 * Retrieves the reCAPTCHA response for a specific form.
303 *
304 * This function is designed to work with multiple reCAPTCHA instances on a single page.
305 * It uses the global `widgetRecaptchas` array to identify the correct reCAPTCHA widget
306 * associated with the given form wrapper.
307 *
308 * @param {HTMLElement} formWrapper - The DOM element wrapping the form containing the reCAPTCHA.
309 *                                    This should be a parent element that contains the
310 *                                    .wpestate_register_form_captcha element.
311 *
312 * @returns {string|null} The reCAPTCHA response string if successful, or null if:
313 *                        - reCAPTCHA is not enabled
314 *                        - The reCAPTCHA element is not found in the form
315 *                        - The corresponding widget ID cannot be found
316 *                        - The reCAPTCHA response is empty
317 *
318 * @requires grecaptcha - The global reCAPTCHA object provided by Google's reCAPTCHA API.
319 * @requires control_vars.usecaptcha - A global variable indicating whether reCAPTCHA is enabled.
320 * @requires widgetRecaptchas - A global array containing the widget IDs of rendered reCAPTCHAs.
321 *
322 * @throws {ConsoleWarning} If the reCAPTCHA element is not found or the widget ID cannot be determined.
323 *
324 * @example
325 * const formWrapper = document.querySelector('.my-form-wrapper');
326 * const recaptchaResponse = getRecaptchaResponse(formWrapper);
327 * if (recaptchaResponse) {
328 *     // Proceed with form submission
329 * } else {
330 *     // Handle missing reCAPTCHA response
331 * }
332 */
333
334function getRecaptchaResponse(formWrapper) {
335    // Check if reCAPTCHA is enabled
336    if (typeof grecaptcha === 'undefined' || 
337        !grecaptcha || 
338        control_vars.usecaptcha !== 'yes') {
339        return null;
340    }
341
342    // Find the reCAPTCHA element within the form wrapper
343    const recaptchaElement = formWrapper.querySelector('.wpestate_register_form_captcha');
344    if (!recaptchaElement) {
345        console.warn('reCAPTCHA element not found in the form');
346        return null;
347    }
348
349    // Find the index of this reCAPTCHA element
350    const captchaElements = document.getElementsByClassName('wpestate_register_form_captcha');
351    const index = Array.from(captchaElements).indexOf(recaptchaElement);
352
353    if (index === -1 || index >= widgetRecaptchas.length) {
354        console.warn('Could not find corresponding widget ID for this reCAPTCHA');
355        return null;
356    }
357
358    // Get the reCAPTCHA response using the widget ID
359    const response = grecaptcha.getResponse(widgetRecaptchas[index]);
360
361    if (!response) {
362        console.warn('reCAPTCHA response is empty');
363    }
364
365    return response;
366}
367
368
369
370/**
371 * Handles the user registration process.
372 * 
373 * This function collects user input, validates it, and sends an AJAX request
374 * to register a new user in the WpResidence theme.
375 *
376 * @param {jQuery} $submitButton - The jQuery object of the submit button that triggered the registration.
377 * @requires jQuery
378 * @requires ajaxcalls_vars global object
379 * @requires control_vars global object
380 * @requires grecaptcha (if control_vars.usecaptcha is 'yes')
381 * 
382 * Expected HTML structure:
383 * - Form wrapper with class 'wpestate_register_form_wrapper'
384 * - Input fields with specific classes for username, email, password, etc.
385 * - Terms agreement checkbox
386 * - Message area for displaying status messages
387 * 
388 * @return {void}
389 */
390function wpestate_register_user($submitButton) {
391    "use strict";
392    
393    const $formWrapper = $submitButton.closest('.wpestate_register_form_wrapper');
394    const $messageArea = $formWrapper.find('.wpestate_register_message_area');
395    const ajaxurl = wpestate_login_register_vars.admin_url + 'admin-ajax.php';
396
397    // Display processing message
398    $messageArea.html('<div class="login-alert">
398' + wpestate_login_register_vars.procesing + '</div>');
399    // Collect form data
400    const formData = {
401        user_login_register: $formWrapper.find('.wpestate_register_form_usenmame').val(),
402        user_email_register: $formWrapper.find('.wpestate_register_form_email').val(),
403        security_nonce: $formWrapper.find('.wpestate_register_form_security').val(),
404        user_pass: ajaxcalls_vars.userpass === 'yes' ? $formWrapper.find('.wpestate_register_form_password').val() : '',
405        user_pass_retype: ajaxcalls_vars.userpass === 'yes' ? $formWrapper.find('.wpestate_register_form_password_retype').val() : '',
406        new_user_type: $formWrapper.find('.wpestate_register_form_user_type').length > 0 ? $formWrapper.find('.wpestate_register_form_user_type').val() : '',
407  
408    };
409
410    // Get reCAPTCHA response if it's enabled
411    if (control_vars.usecaptcha === 'yes') {
412         // Get reCAPTCHA response if it's enabled
413         
414        const recaptchaResponse = getRecaptchaResponse($formWrapper[0]);
415        if (control_vars.use_captcha === 'yes' && !recaptchaResponse) {
416            $messageArea.html('<div class="login-alert">Please complete the reCAPTCHA.</div>');
417            return;
418        }
419        
420        formData.capthca = recaptchaResponse;
421
422    }
423    
424    
425    // Validate form data
426    if (!wpestate_validateRegistrationData($formWrapper, formData)) {
427        return;
428    }
429
430    // Send AJAX request 
431    jQuery.ajax({
432        type: 'POST',
433        dataType: 'json',
434        url: ajaxurl,
435        data: {
436            action: 'wpestate_to_register_user',
437            ...formData,
438            type: 1
439        },
440        success: function(response) {
441            wpestate_handleRegistrationResponse($formWrapper, $messageArea, response);
442        },
443        error: function(errorThrown) {
444            console.error('Registration error:', errorThrown);
445            $messageArea.html('<p>An error occurred during registration. Please try again.</p>');
446        }
447    });
448}
449
450
451
452
453
454/**
455 * Validates the registration form data.
456 * 
457 * @param {jQuery} $formWrapper - The form wrapper element.
458 * @param {Object} formData - The collected form data.
459 * @return {boolean} True if data is valid, false otherwise.
460 */
461function wpestate_validateRegistrationData($formWrapper, formData) {
462    const $messageArea = $formWrapper.find('.wpestate_register_message_area');
463
464    if (!$formWrapper.find('.wpestate_register_form_agree_terms').is(":checked")) {
465        $messageArea.html(`<div class="login-alert">${control_vars.terms_cond}</div>`);
466        return false;
467    }
468
469    if (formData.new_user_type === 0 && $formWrapper.find('.wpestate_register_form_user_type').length > 0) {
470        $messageArea.html(`<div class="login-alert">${control_vars.user_type_warn}</div>`);
471        return false;
472    }
473
474    return true;
475}
476
477
478
479
480/**
481 * Handles the registration response from the server.
482 * 
483 * @param {jQuery} $formWrapper - The form wrapper element.
484 * @param {jQuery} $messageArea - The message area element.
485 * @param {Object} response - The server response object.
486 */
487function wpestate_handleRegistrationResponse($formWrapper, $messageArea, response) {
488  
489    if(response.register === true) {
490        $messageArea.html(`<div class="wpestate_success">${response.message}</div>`);
491    }else{
492        $messageArea.html(`<div class="login-alert">${response.message}</div>`);
493    }
494
495
496    // Clear form fields
497    $formWrapper.find('input[type="text"],input[type="email"], input[type="password"]').val('');
498    $formWrapper.find('select').val(0);
499
500    if(response.register === true) {
501        setTimeout(() => {
502            $formWrapper.parent().find('.wpestate_login_form_switch_login').trigger('click');
503        }, 1500);
504    }
505}
506
507
508
509
510/**
511 * Set up event listeners for the login functionality.
512 * 
513 * This function attaches event listeners to login-related elements:
514 * - Click event on the login submit button
515 * - Keydown event (Enter key) on login form fields
516 * 
517 * When triggered, these events call the wpestate_login_user function
518 * to process the login attempt.
519 * 
520 * @since 1.0.0
521 * 
522 * @returns {void}
523 */
524function wpestate_trigger_login_action() {
525    const $document = jQuery(document);
526    const ENTER_KEY_CODE = 13;
527
528    // Handle click on login submit button
529    $document.on('click', '.wpestate_login_submit_button', function(event) {
530        // Call login function, passing the clicked button as a jQuery object
531        wpestate_login_user(jQuery(this));
532    });
533
534    // Handle Enter key press on login form fields
535    $document.on('keydown', '.wpestate_login_form_username, .wpestate_login_form_password', function(event) {
536        if (event.keyCode === ENTER_KEY_CODE) {
537            event.preventDefault(); // Prevent default Enter key behavior
538            
539            // Find the submit button within the same form wrapper
540            const $submitButton = jQuery(this).closest('.wpestate_login_form_wrapper').find('.wpestate_login_submit_button');
541            
542            // Call login function, passing the found submit button as a jQuery object
543            wpestate_login_user($submitButton);
544        }
545    });
546}
547
548
549/**
550 * Process user login attempt
551 * 
552 * This function handles the user login process. It collects form data,
553 * validates it, sends an AJAX request to the server for authentication,
554 * and handles the response.
555 *  * @param {jQuery} $submitButton - The jQuery object of the submit button that triggered the login attempt.
556 */
557
558function wpestate_login_user($submitButton) {
559    "use strict";
560
561    const $formWrapper = $submitButton.closest('.wpestate_login_form_wrapper');
562    const $messageArea = $formWrapper.find('.login_register_message_area');
563    const ajaxurl = wpestate_login_register_vars.admin_url + 'admin-ajax.php';
564    // Display processing message
565    $messageArea.html('<div class="login-alert">' + wpestate_login_register_vars.login_loading + '</div>');
566
567    // Collect form data
568    const formData = {
569        login_user: $formWrapper.find('.wpestate_login_form_username').val(),
570        login_pwd: $formWrapper.find('.wpestate_login_form_password').val(),
571        security_nonce: $formWrapper.find('.wpestate_social_login_nonce').val(),
572        ispop: $formWrapper.find('.loginpop').val() || '0'
573    };
574
575    if (jQuery('#loginpop_submit').val() === '3') {
576        ispop = 3;
577    }
578
579    // Validate form data
580    if (!wpestate_validateLoginData($formWrapper, formData)) {
581        return;
582    }
583
584    // Send AJAX request
585    jQuery.ajax({
586        type: 'POST',
587        dataType: 'json',
588        url: ajaxurl,
589        data: {
590            action: 'wpestate_ajax_login_user',
591            ...formData
592        },
593        success: function(response) {
594            wpestate_handleLoginResponse($formWrapper, $messageArea, response);
595        },
596        error: function(jqXHR, textStatus, errorThrown) {
597            console.error('Login error:', jqXHR.responseText, textStatus, errorThrown);
598            $messageArea.html('<p>An error occurred during login. Please try again.</p>');
599        }
600    });
601}
602
603
604
605/**
606 * Validate login form data
607 * 
608 * @param {jQuery} $formWrapper - The form wrapper jQuery object
609 * @param {Object} formData - The form data object
610 * @returns {boolean} - True if data is valid, false otherwise
611 */
612function wpestate_validateLoginData($formWrapper, formData) {
613    // Implement validation logic here
614    // For example:
615    if (!formData.login_user || !formData.login_pwd) {
616        $formWrapper.find('.login_register_message_area').html('<div class="login-alert">Please enter both username and password.</div>');
617        return false;
618    }
619    return true;
620}
621
622/**
623 * Handle login response from server
624 * 
625 * @param {jQuery} $formWrapper - The form wrapper jQuery object
626 * @param {jQuery} $messageArea - The message area jQuery object
627 * @param {Object} response - The server response object
628 */
629
630
631
632function wpestate_handleLoginResponse($formWrapper, $messageArea, response) {
633    const extraClass = response.loggedin ? 'wpestate_success' : '';
634   
635
636    if(response.loggedin === true) {
637        $messageArea.html(`<div class="wpestate_success">${response.message}</div>`);
638    }else{
639        $messageArea.html(`<div class="login-alert">${response.message}</div>`);
640    }
641
642    if (response.loggedin) {
643        if (parseInt(response.ispop, 10) === 1 || parseInt(response.ispop, 10) === 3  ) {
644            ajaxcalls_vars.userid = response.newuser;
645            jQuery('#login-modal_close').trigger('click');
646       
647
648            // update menu bar 
649
650            var usericon = '<div class="menu_user_picture" style="background-image: url(' + response.picture + ')"></div>    <a class="navicon-button x"><div class="navicon"></div></a>';
651        
652           
653            jQuery('#user_menu_u').append(usericon).addClass('user_loged');
654            jQuery('.submit_action').remove();
655            jQuery('.submit_listing').remove();
656            jQuery('#agent_property_ajax_nonce').val(response.nonce_contact);
657            jQuery('#user_menu_u').after(response.menu.desktop);
658
659
660            //update mobile menu bar
661            jQuery('.login_sidebar').hide();
662            jQuery('.mobilemenu-close-user').after(response.menu.mobile);
663   
664            var mobile_user_icon = '<div class="menu_user_picture" style="background-image: url(' + response.picture + ');"></div>'
665            jQuery('.mobile-trigger-user').empty().append(mobile_user_icon);
666            // close user drawer if on movbie
667            if(wpestate_isMobileOrTablet()){
668                jQuery('.mobilemenu-close-user').trigger('click');
669            }
670         
671            wpestate_open_menu();
672
673        }else if (parseInt(response.ispop, 10) === 2) {   
674          
675            location.reload();
676
677        } else {
678            document.location.href = wpestate_login_register_vars.login_redirect;
679        }
680
681
682        jQuery('#user_not_logged_in').hide();
683        jQuery('#user_logged_in').show();
684    } else {
685        $formWrapper.find('.wpestate_login_form_username').val('');
686        $formWrapper.find('.wpestate_login_form_password').val('');
687    }
688}
689
690
691
692
693
694/**
695 * Set up event listeners for forgot password functionality
696 * 
697 * This function handles forgot password actions including
698 * button clicks and Enter key presses on email input fields.
699 * 
700 * @since 1.0.0
701 * 
702 * @requires jQuery
703 * @requires wpestate_forgot function (assumed to exist)
704 */
705function wpestate_trigger_forgot_password_action() {
706    const $document = jQuery(document);
707    const ENTER_KEY_CODE = 13;
708
709    // Handle click on forgot password submit buttons
710    $document.on('click', '.wpestate_forgot_password_submit_button', function(event) {
711       
712        wpestate_forgot( jQuery(this) );
713    });
714
715    // Handle Enter key press on forgot password email input fields
716    $document.on('keydown', '.wpestate_forgot_form_email', function(event) {
717        if (event.keyCode === ENTER_KEY_CODE) {
718            event.preventDefault();
719            const $submitButton = jQuery(this).closest('.wpestate_forgot_form_wrapper').find('.wpestate_forgot_password_submit_button');
720          
721            wpestate_forgot($submitButton);
722        }
723    });
724}
725
726
727
728
729
730/**
731 * Process forgot password request
732 *
733 * @param {jQuery} $submitButton - The jQuery object of the submit button
734 */
735function wpestate_forgot($submitButton) {
736    "use strict";
737
738    const $formWrapper = $submitButton.closest('.wpestate_forgot_form_wrapper');
739    const $messageArea = $formWrapper.find('.login_register_message_area');
740    const ajaxurl = wpestate_login_register_vars.admin_url + 'admin-ajax.php';
741
742    // Display processing message
743    $messageArea.html('<div class="login-alert">' + wpestate_login_register_vars.procesing + '</div>');
744
745    // Collect form data
746    const formData = {
747        forgot_email: $formWrapper.find('.wpestate_forgot_form_email').val(),
748        security_nonce: $formWrapper.find('.wpestate_forgot_form_security').val(),
749        postid: $formWrapper.find('#postid').val() || '',
750      
751    };
752
753    // Validate form data
754    if (!wpestate_validateForgotPasswordData($formWrapper, formData)) {
755        return;
756    }
757
758    // Send AJAX request
759    jQuery.ajax({
760        type: 'POST',
761        dataType: 'json',
762        url: ajaxurl,
763        data: {
764            action: 'wpestate_ajax_forgot_pass_user',
765            ...formData
766        },
767        success: function(response) {
768            wpestate_handleForgotPasswordResponse($formWrapper, $messageArea, response);
769        },
770        error: function(jqXHR, textStatus, errorThrown) {
771            console.error('Forgot password error:', textStatus, errorThrown);
772            $messageArea.html('<p>An error occurred. Please try again.</p>');
773        }
774    });
775}
776
777/**
778 * Validate forgot password form data
779 *
780 * @param {jQuery} $formWrapper - The form wrapper jQuery object
781 * @param {Object} formData - The form data object
782 * @returns {boolean} - True if data is valid, false otherwise
783 */
784function wpestate_validateForgotPasswordData($formWrapper, formData) {
785
786    if (!formData.forgot_email) {
787        $formWrapper.find('.login_register_message_area').html(`<div class="login-alert">${wpestate_login_register_vars.forgot_warning}</div>`);
788        return false;
789    }
790    return true;
791}
792
793/**
794 * Handle forgot password response
795 *
796 * @param {jQuery} $formWrapper - The form wrapper jQuery object
797 * @param {jQuery} $messageArea - The message area jQuery object
798 * @param {Object} response - The response from the server
799 */
800function wpestate_handleForgotPasswordResponse($formWrapper, $messageArea, response) {
801    const extraClass = response.reset === true ? 'wpestate_success' : '';
802    $formWrapper.find('.wpestate_forgot_form_email').val('');
803    $messageArea.html(`<div class="login-alert ${extraClass}">${response.message}</div>`);
804}

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.