Guide to activating the 'Next' button on WP Forms using JavaScript code when certain conditions are fulfilled

Is there a way to adjust the JavaScript code provided so that the visibility of the "Next" button is dependent on whether at least one item in the 'wpforms-icon-choices-item' class has the '.wpform-selected' class on the current page or after clicking the 'wpformButtonBack' button? This needs to be done without affecting the functionality of the 'progressNextReset' and 'progressBackReset' functions. Below, you will find the appropriate HTML markup for this code.

Javascript:

const choiceItems = document.querySelectorAll('.wpforms-icon-choices-item');
const wpformsPage = document.querySelectorAll('.wpforms-page')
const wpformButtonNext = document.querySelectorAll('.wpforms-page-next');
const wpformButtonBack = document.querySelectorAll('.wpforms-page-prev');
const wpformsFields = document.querySelectorAll('.wpforms-field');
const wpformsIndicatorWrap = document.querySelector('.wpforms-page-indicator-page-progress-wrap');
const wpformsIndicatorProgress = document.querySelector('.wpforms-page-indicator-page-progress');
const wpformsIndicatorContainer = document.createElement('div');
wpformsIndicatorContainer.className = 'wpforms-page-indicator-container';
wpformsIndicatorProgress.appendChild(wpformsIndicatorContainer);
const wpformsIndicatorText = document.createElement('div');
wpformsIndicatorText.className = 'wpforms-page-indicator-text';
wpformsIndicatorContainer.appendChild(wpformsIndicatorText);
const wpformsIndicatorProgressWidth = Math.round(parseFloat(wpformsIndicatorProgress.style.width));
wpformsIndicatorText.innerText = wpformsIndicatorProgressWidth + '% geschaft';

for (var item = 0; item < choiceItems.length; item++) {
    const choiceItemOnHover = document.createElement('div');
    choiceItemOnHover.className = "wpforms-choices-header-onhover";
    const label = choiceItems[item].querySelector('.wpforms-icon-choices-label');
    choiceItemOnHover.innerText = label ? label.innerText : '';
    choiceItems[item].append(choiceItemOnHover);
}

wpformButtonNext.forEach((button) => {
    button.style.visibility = 'hidden'
});

function showButton() {

    // Toggle the class on wpformButtonNext elements based on the condition
    wpformButtonNext.forEach((button) => {
        button.style.visibility = 'visible'
    });
}

function hideButton() {

    const currentPageIndex = Array.from(wpformsPage).findIndex(
        (page) => page.getAttribute('data-page') === '1'
    );

    // Check if the current page has any item without 'wpforms-selected' class
    const isItemSelected = Array.from(wpformsPage[currentPageIndex].querySelectorAll('.wpforms-icon-choices-item')).some(
        (item) => !item.classList.contains('wpforms-selected')
    );

    // Toggle the visibility of wpformButtonNext elements on the current and next pages
    for (let a = 0; a < wpformButtonNext.length; a++) {
        if (a === currentPageIndex || a === currentPageIndex + 1) {
            // Check if the current page or next page
            if (isItemSelected) {
                console.log('7707');
                wpformButtonNext[a].style.visibility = 'visible';
            } else {
                console.log('666');
                wpformButtonNext[a].style.visibility = 'hidden';
            }
        }
    }
}

function progressNextReset() {
    const pixelPro...etc...

} else {
    console.error('wpformButtonNext not found');
}

HTML markup via link view-source:

I am attempting to tweak the JavaScript code so that the "Next" button appears on 'wpforms-page' pages when an item in the 'wpforms-icon-choices-item' class has the '.wpform-selected' class, or after clicking the 'wpformButtonBack' button. It is crucial that the 'progressNextReset' and 'progressBackReset' functions remain functional as intended.

Answer №1

const items = document.querySelectorAll('.step-form .icon-choices');
const pageElements = document.querySelectorAll('.step-form .page');
const lastPage = document.querySelectorAll('.step-form .page.last.footer-btns');
const buttonNext = document.querySelectorAll('.step-form .page-next');
const buttonBack = document.querySelectorAll('.step-form .page-prev');
const fields = document.querySelectorAll('.step-form .field');
const progressWrap = document.querySelector('.step-form .progress-wrap');
const progressIndicator = document.querySelector('.step-form .progress');
const container = document.createElement('div');
container.className = 'indicator-container';
progressIndicator.appendChild(container);
const textElement = document.createElement('div');
textElement.className = 'indicator-text';
container.appendChild(textElement);
const progressBarWidth = Math.round(parseFloat(progressIndicator.style.width));
textElement.innerText = progressBarWidth + '% complete';

for (var index = 0; index < items.length; index++) {
    const hoverItem = document.createElement('div');
    hoverItem.className = "choices-header-onhover";
    const labelElement = items[index].querySelector('.step-form .icon-choices-label');
    hoverItem.innerText = labelElement ? labelElement.innerText : '';
    items[index].append(hoverItem);
}

hideButton();

function hideButton() {
    buttonNext.forEach((btn, index) => {
        const currentPage = pageElements[index];
        if (currentPage.getAttribute('data-page')) {
            const selectedItems = currentPage.querySelectorAll(`.step-form .icon-choices-item.wpforms-selected`);
            if (selectedItems.length === 0) {
                btn.style.visibility = 'hidden';
            } else {
                btn.style.visibility = 'visible';
            }
        } else {
            btn.style.visibility = 'hidden';
        }
    });
}

function showButton() {

    buttonNext.forEach((btn) => {
        btn.style.visibility = 'visible'
    });
}

function nextProgress() {
    const total = pageElements.length;
    const currIndex = Array.from(pageElements).indexOf(this.closest('.step-form .page'));

    if (currIndex === total - 1) {
        const pixelWidth = '95%'; // Set pixel width to 95% for the last page
        progressIndicator.style.width = pixelWidth;
        const percentValue = '95'; // Set actual percent value to 95 for the last page
        textElement.innerText = percentValue + '% complete';
    } else {
        const pixelWidth = window.getComputedStyle(progressIndicator).getPropertyValue('width');
        const currentWidth = window.getComputedStyle(progressWrap).getPropertyValue('width');
        const percentage = Math.round((parseFloat(pixelWidth) / parseFloat(currentWidth)) * 100);
        const actualPercent = progressBarWidth + percentage;
        textElement.innerText = actualPercent + '% complete';
    }
    hideButton();
}

function backProgress() {
    const pixelWidth = window.getComputedStyle(progressIndicator).getPropertyValue('width');
    const currentWidth = window.getComputedStyle(progressWrap).getPropertyValue('width');
    const percentage = Math.round((parseFloat(pixelWidth) / parseFloat(currentWidth)) * 100);
    const actualPercent = progressBarWidth - percentage;
    textElement.innerText = -actualPercent + '% complete';
    showButton();
}

if (items) {

    for (var i = 0; i < buttonNext.length; i++) {
        buttonNext[i].addEventListener('click', nextProgress);
    }
    for (var i = 0; i < buttonBack.length; i++) {
        buttonBack[i].addEventListener('click', backProgress);
    }
    for (var i = 0; i < items.length; i++) {
        items[i].addEventListener('click', nextProgress);
    }

} else {
    console.error('buttonNext not found');
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Incorporating HTML/PHP elements into JQuery

I am currently working on a website project for a manufacturing company that involves PHP, HTML, CSS, and JQuery. My goal is to create a seamless user experience where they can easily contact sales representatives for quotes and other information by clicki ...

Navigating through a series of items in VueJS can be easily accomplished by using a

Below is the Vue instance I have created: new Vue({ el: '#app', data: { showPerson: true, persons: [ {id: 1, name: 'Alice'}, {id: 2, name: 'Barbara'}, {id: 3, name: &a ...

Exploring ways to utilize Next.js (React) for formatting date and time with either Moment.js or alternate

When deciding on the best method for handling date formats in my next front-end app, should I use Moment.js or JavaScript functions? The data is sourced from the backend as the date type, and I want it to be displayed in a user-friendly format while consid ...

AngularJS routing not rendering the correct view

I'm encountering a routing problem with my AngularJS/ExpressJS application. The issue is that login.ejs and signup.ejs are partial views, while welcome.ejs serves as the main template. The intention is for these views to load in a ui-view container wi ...

Choosing between creating a class with a shared instance or not

I'm curious if my class is shared across instances: for example, I have a route that looks like this: /student/:id When this route triggers the controller (simplified version): module.exports = RecalculateStudents; const recalculateActiveStudent ...

Creating a Vue.js component that animates text to fade in and out within a textarea when a button

I need assistance with updating a <textarea> element in my Vue application. Currently, I have the textarea bound to some data in my state. However, when a button is clicked, I want the existing data in the textarea to fade out and be replaced with ne ...

Using i18next to alter language in a React app

Implementing the i18next translation system into my React app was a breeze thanks to a helpful guide I found. However, I'm facing an issue with changing the language manually. The guide covered the setup process perfectly, but lacked information on ho ...

Error Received While Attempting to Log in using Ajax

Having an issue with logging in using ajax and php. I am able to log in successfully, but when trying to display an alert message and refresh the page upon login, it gives me an error without refreshing. However, upon manually refreshing the page, I can se ...

How to bypass validation for required input in jQuery validate plugin

As an example, consider the <input name="surname" id="surname" type="text">. Sometimes I want to hide this input and make it non-required. My current workaround is to set a value such as "some value" when hiding the input, and then remove this value ...

What is the best way to toggle the visibility of a div using a button? And how can you incorporate a visual effect on the button when

I'm trying to implement a button that can hide and show a div, but for some reason, it only shows the div and doesn't hide it when clicked. Check out my fiddle: http://jsfiddle.net/4vaxE/24/ This is my code: <div class="buttons" style="bac ...

Experimenting with the routerLink directive in Angular 2

Currently, I am in the process of testing routing functionality. As part of this, I have moved my navbar to a separate component called MdNavbar, which primarily consists of HTML and CSS. The RouteConfig is located in another component where MdNavbar is in ...

Integrating HTML, JavaScript, PHP, and MySQL to enhance website functionality

Exploring the intricacies of HTML, JavaScript, PHP, and MySQL, I have been working on an order form to understand their interactions. View Order Form The aim of this table is to allow users to input a quantity for a product and have JavaScript automatica ...

Is there a way to adjust the size of a table display to ensure that both vertical and horizontal scroll bars are constantly visible?

[edits added below per the request to see code. Edits also added to the original post to clarify the ask - marked in bold] My application features a broad table with the potential for many rows, generated by django-tables2 using the bootstrap5-responsive ...

Footnote fiascos

I am currently in the process of creating a footer for my webpage and have implemented the following CSS styling: #footer { height: 100px; background-color: #F3F3F3; position: absolute; bottom: 0; } Although the footer is displaying at th ...

Alter the class when $dirty occurs in Angular

I've recently started working with angular js and am attempting to incorporate animations into my login page. I have created a controller that will modify the class of the input field when clicked and when blurred. app.controller("con", function($sc ...

Having trouble parsing asynchronous script with cheerio parser

Utilizing cheerio for web crawling poses a challenge when encountering websites with asynchronous scripts. When attempting to extract all the scripts from such websites, they are often missed in the process. Here is an example of the code I am currently us ...

Best practices for locating unique symbols within a string and organizing them into an array using JavaScript

Here is an example string: "/city=<A>/state=<B>/sub_div=<C>/type=pos/div=<D>/cli_name=Cstate<E>/<F>/<G>" The characters A, B, C, and so on are variables, and their count is not fixed. Can you determine how many ...

CSS KeyFrame animations

My goal is to have my elements gracefully fade in with 2 lines extending out of a circle, one to the left and one to the right. However, I am struggling to achieve this. Every time I attempt to display the lines, it ends up shrinking the entire design. M ...

A role requiring coordinates x, y, and z with significant values

http://jsfiddle.net/eho5g2go/ var offset=10000000; ... camera.position.set(offset,offset,400); mesh.position.set(offset-300,offset,0); camera.lookAt(mesh.position); ... animate(); The "offset" variable is crucial for determining the camera and mesh p ...

Encountering a theme issue in the makeStyles function within Material-UI version 5

While working on some React components, I created a styles.js file for each of them. I am following a YouTube tutorial that uses material-ui version 4, so I decided to upgrade to V5. Code snippet for the component (Form): import React from 'react&apo ...