', {
class: classes.indicatorSeparator
});
}
createStepsButtons() {
const {
selectors
} = this.getSettings(),
stepsElements = {};
this.injectButtonsToSteps(stepsElements);
stepsElements.$buttonsContainer = this.elements.$stepWrapper.find(selectors.buttons);
stepsElements.$buttonsWrappers = stepsElements.$buttonsContainer.children(selectors.buttonWrapper);
return stepsElements;
}
injectButtonsToSteps() {
const totalSteps = this.elements.$stepWrapper.length;
this.elements.$stepWrapper.each((index, el) => {
const $el = jQuery(el),
$container = this.getButtonsContainer();
let $nextButton;
if (index) {
$container.append(this.getStepButton('previous', index));
$nextButton = index === totalSteps - 1 ? this.getSubmitButton() : this.getStepButton('next', index);
} else {
$nextButton = this.getStepButton('next', index);
}
$container.append($nextButton);
$el.append($container);
});
}
getButtonsContainer() {
const {
classes
} = this.getSettings(),
stepsSettings = this.getElementSettings(),
buttonColumnWidthClasses = [classes.buttons, classes.column, 'elementor-col-' + stepsSettings.button_width];
return jQuery('
', {
class: buttonColumnWidthClasses.join(' ')
});
}
extractResponsiveSizeFromSubmitWrapper() {
let sizeClasses = [];
this.elements.$submitWrapper.removeClass((index, className) => {
sizeClasses = className.match(/elementor-(sm|md)-[0-9]+/g)?.join(' ');
return sizeClasses;
});
this.elements.$buttonsContainer.addClass(sizeClasses);
}
getStepButton(buttonType, index) {
const {
classes
} = this.getSettings(),
$button = this.getButton(buttonType, index).on('click', () => this.applyStep(buttonType)),
buttonWrapperClasses = [classes.fieldGroup, classes.buttonWrapper, 'elementor-field-type-' + buttonType];
return jQuery('
', {
class: buttonWrapperClasses.join(' ')
}).append($button);
}
getSubmitButton() {
const {
classes
} = this.getSettings();
this.elements.$submitButton.addClass(classes.button);
// TODO: When a solution for the conditions will be found, check if can remove the elementor-col-x manipulation.
return this.elements.$submitWrapper.attr('class', (index, className) => {
return this.replaceClassNameColSize(className, '');
}).removeClass(classes.column).removeClass(classes.buttons).addClass(classes.buttonWrapper);
}
replaceClassNameColSize(className, value) {
return className.replace(/elementor-col-([0-9]+)/g, value);
}
getButton(buttonType, index) {
const {
classes
} = this.getSettings(),
submitSizeClass = this.elements.$submitButton.attr('class').match(/elementor-size-([^\W\d]+)/g),
buttonClasses = [classes.elementorButton, submitSizeClass, classes.button, classes.button + '-' + buttonType];
return jQuery('', {
type: 'button',
text: this.getButtonLabel(buttonType, index),
class: buttonClasses.join(' '),
'data-direction': buttonType
});
}
getButtonLabel(buttonType, index) {
const stepsSettings = this.getElementSettings(),
stepData = this.data.steps[index],
buttonName = buttonType + 'Button',
buttonSettingsProp = `step_${buttonType}_label`;
return stepData[buttonName] || stepsSettings[buttonSettingsProp];
}
applyStep(direction) {
const nextIndex = 'next' === direction ? this.state.currentStep + 1 : this.state.currentStep - 1;
if ('next' === direction && !this.isFieldsValid(this.elements.$stepWrapper)) {
return false;
}
this.goToStep(nextIndex);
this.state.currentStep = nextIndex;
if ('progress_bar' === this.state.stepsType) {
this.setProgressBar();
} else if ('none' !== this.state.stepsType) {
this.updateIndicatorsState(direction);
}
}
goToStep(index) {
const {
classes
} = this.getSettings();
this.elements.$stepWrapper.eq(this.state.currentStep).addClass(classes.hidden);
this.elements.$stepWrapper.eq(index).removeClass(classes.hidden);
const $firstFocusableField = this.getFirstFocusableField(index);
if (!$firstFocusableField) {
return;
}
$firstFocusableField.attr('tabindex', '0');
$firstFocusableField.trigger('focus');
}
getFirstFocusableField(index) {
const $fieldGroups = this.elements.$stepWrapper.eq(index).children(this.getSettings('selectors.fieldGroup'));
let $firstFocusableField = null;
$fieldGroups.each((fieldGroupIndex, element) => {
const $fieldGroup = jQuery(element);
const $focusableElement = this.getFocusableElement($fieldGroup);
if (!!$focusableElement) {
$firstFocusableField = $focusableElement;
return false;
}
});
return $firstFocusableField;
}
getFocusableElement($fieldGroup) {
if (!$fieldGroup.is(':visible')) {
return;
}
const $inputFieldInFieldGroup = $fieldGroup.find(':input').first();
const fieldGroupHasInputField = !!$inputFieldInFieldGroup.length;
if (fieldGroupHasInputField) {
return $inputFieldInFieldGroup;
}
return $fieldGroup;
}
isFieldsValid($stepWrapper) {
let isValid = true;
$stepWrapper.eq(this.state.currentStep).find('.elementor-field-group :input').each((index, el) => {
if (!el.checkValidity()) {
el.reportValidity();
return isValid = false;
}
});
return isValid;
}
isLastStep() {
return this.state.currentStep === this.data.steps.length - 1;
}
resetForm() {
this.state.currentStep = 0;
this.resetSteps();
if ('progress_bar' === this.state.stepsType) {
this.setProgressBar();
} else if ('none' !== this.state.stepsType) {
this.elements.$currentIndicator = this.elements.$indicators.eq(this.state.currentStep);
this.resetIndicators();
}
}
resetSteps() {
const {
classes
} = this.getSettings();
this.elements.$stepWrapper.addClass(classes.hidden).eq(0).removeClass(classes.hidden);
}
resetIndicators() {
const {
classes
} = this.getSettings(),
stateTypes = ['inactive', 'active', 'completed'],
stateClasses = stateTypes.map(state => classes.indicator + '--state-' + state);
this.elements.$indicators.removeClass(stateClasses.join(' ')).not(this.elements.$indicators.eq(0)).addClass(classes.indicatorInactive);
this.elements.$indicators.eq(0).addClass(classes.indicatorActive);
}
updateIndicatorsState(direction) {
const {
classes
} = this.getSettings(),
indicatorsClasses = {
current: {
remove: classes.indicatorActive,
add: 'next' === direction ? classes.indicatorCompleted : classes.indicatorInactive
},
next: {
remove: 'next' === direction ? classes.indicatorInactive : classes.indicatorCompleted,
add: classes.indicatorActive
}
};
this.elements.$currentIndicator.removeClass(indicatorsClasses.current.remove).addClass(indicatorsClasses.current.add);
this.elements.$currentIndicator = this.elements.$indicators.eq(this.state.currentStep);
this.elements.$currentIndicator.removeClass(indicatorsClasses.next.remove).addClass(indicatorsClasses.next.add);
// Updating an indicator svg fill color, if loaded inside an object tag.
this.data.indicatorsWithObjectTags.forEach($element => {
$element.contents().children('svg').css('fill', $element.css('fill'));
});
}
updateValue(updatedValue) {
const actionsMap = {
step_type: () => this.updateStepsType(),
step_icon_shape: () => this.updateStepsShape(),
step_next_label: () => this.updateStepButtonsLabel('next'),
step_previous_label: () => this.updateStepButtonsLabel('previous')
};
if (actionsMap[updatedValue]) {
actionsMap[updatedValue]();
}
}
updateStepsType() {
const stepsSettings = this.getElementSettings();
if (this.elements.$indicatorsWrapper) {
this.elements.$indicatorsWrapper.remove();
}
if ('none' !== stepsSettings.step_type) {
this.rebuildIndicators();
}
this.state.stepsType = stepsSettings.step_type;
}
rebuildIndicators() {
this.elements = {
...this.elements,
...this.createStepsIndicators()
};
this.initProgressBar();
}
updateStepsShape() {
const stepsSettings = this.getElementSettings(),
{
selectors,
classes
} = this.getSettings(),
shapeClassStart = classes.indicator + '--shape-',
currentShapeClass = shapeClassStart + this.state.stepsShape,
newShapeClass = shapeClassStart + stepsSettings.step_icon_shape;
let elementsTargetType = '';
if (stepsSettings.step_type.includes('icon')) {
elementsTargetType = 'icon';
} else if (stepsSettings.step_type.includes('number')) {
elementsTargetType = 'number';
}
this.elements.$indicators.children(selectors.indicator + '__' + elementsTargetType).removeClass(currentShapeClass).addClass(newShapeClass);
this.state.stepsShape = stepsSettings.step_icon_shape;
}
updateStepButtonsLabel(buttonType) {
const {
selectors
} = this.getSettings(),
buttonSelector = {
previous: selectors.button + '-previous',
next: selectors.button + '-next'
};
this.elements.$stepWrapper.each((index, el) => {
jQuery(el).find(buttonSelector[buttonType]).text(this.getButtonLabel(buttonType, index));
});
}
onFormError() {
const {
selectors
} = this.getSettings(),
$errorStepElement = this.elements.$form.find(selectors.formHelpInline).closest(selectors.stepWrapper);
if ($errorStepElement.length) {
this.goToStep($errorStepElement.index());
}
}
onElementChange(updatedValue) {
if (!this.isStepsExist()) {
return;
}
this.updateValue(updatedValue);
}
}
exports["default"] = FormSteps;
/***/ }),
/***/ "../modules/forms/assets/js/frontend/handlers/recaptcha.js":
/*!*****************************************************************!*\
!*** ../modules/forms/assets/js/frontend/handlers/recaptcha.js ***!
\*****************************************************************/
/***/ ((__unused_webpack_module, exports) => {
Object.defineProperty(exports, "__esModule", ({
value: true
}));
exports["default"] = void 0;
class Recaptcha extends elementorModules.frontend.handlers.Base {
getDefaultSettings() {
return {
selectors: {
recaptcha: '.elementor-g-recaptcha:last',
submit: 'button[type="submit"]',
recaptchaResponse: '[name="g-recaptcha-response"]'
}
};
}
getDefaultElements() {
const {
selectors
} = this.getDefaultSettings(),
elements = {
$recaptcha: this.$element.find(selectors.recaptcha)
};
elements.$form = elements.$recaptcha.parents('form');
elements.$submit = elements.$form.find(selectors.submit);
return elements;
}
bindEvents() {
this.onRecaptchaApiReady();
}
isActive(settings) {
const {
selectors
} = this.getDefaultSettings();
return settings.$element.find(selectors.recaptcha).length;
}
addRecaptcha() {
const settings = this.elements.$recaptcha.data(),
isV2 = 'v3' !== settings.type,
captchaIds = [];
captchaIds.forEach(id => window.grecaptcha.reset(id));
const widgetId = window.grecaptcha.render(this.elements.$recaptcha[0], settings);
this.elements.$form.on('reset error', () => {
window.grecaptcha.reset(widgetId);
});
if (isV2) {
this.elements.$recaptcha.data('widgetId', widgetId);
} else {
captchaIds.push(widgetId);
this.elements.$submit.on('click', e => this.onV3FormSubmit(e, widgetId));
}
}
onV3FormSubmit(e, widgetId) {
e.preventDefault();
window.grecaptcha.ready(() => {
const $form = this.elements.$form;
grecaptcha.execute(widgetId, {
action: this.elements.$recaptcha.data('action')
}).then(token => {
if (this.elements.$recaptchaResponse) {
this.elements.$recaptchaResponse.val(token);
} else {
this.elements.$recaptchaResponse = jQuery(' ', {
type: 'hidden',
value: token,
name: 'g-recaptcha-response'
});
$form.append(this.elements.$recaptchaResponse);
}
// Support old browsers.
const bcSupport = !$form[0].reportValidity || 'function' !== typeof $form[0].reportValidity;
if (bcSupport || $form[0].reportValidity()) {
$form.trigger('submit');
}
});
});
}
onRecaptchaApiReady() {
if (window.grecaptcha && window.grecaptcha.render) {
this.addRecaptcha();
} else {
// If not ready check again by timeout..
setTimeout(() => this.onRecaptchaApiReady(), 350);
}
}
}
exports["default"] = Recaptcha;
/***/ })
}]);
//# sourceMappingURL=form.151b991a4cbdda620c22.bundle.js.map