Ir ao conteúdo
  • Cadastre-se

Javascript Barra de Progresso em Formulário dividido por Abas!


Posts recomendados

Tenho uma barra de progresso que deve mostrar a porcentagem de preenchimento de um formulário dividido em abas, sendo que cada aba contem um "form".

 

Essa barra de progresso e um plug-in do JQuery (FormProgressBar) que é ativado através de campos preenchidos com o parâmetro "required".

 

Na primeira aba a barra de porcentagem funciona perfeitamente, porém quando mudo para outra aba contendo outro form a barra de porcentagem some. Gostaria que a barra de porcentagem não sumisse ao mudar de aba e que ela continuasse a contagem ate o final do formulário, como resolvo isso?

 

1- Aqui a barra funcionando corretamente na primeira aba do formulário.

 

barraprogresso.png.84beb2416c17b7bd36746c3f801b6cae.png

 

2- Aqui a barra some quando eu vou para outra aba do formulário.

 

barraprogresso2.png.44593eb722840876b955c508e2a94cd4.png

 

Este é o código HTML do form dessas duas Abas, estou usando nas duas a class "formProgress" para chamar o plug-in da barra de progresso.

 

<form action="/Pasta/SalvarInquerito" method="post" id="FormInquerito" class="formProgress"></form>

<form method="post" action="/Pasta/SalvarCrime" id="FormCrime" class="formProgress"></form>

 

Este é o JS do formProgressBar com formatações CSS da barra que e chamada no HTML.

$(".formProgress").formProgressBar({
  
    percentCounting: true, // default: false
    height: 16,// default: 10
    // default: 500
    transitionTime: 500,
    //ease, linear, ease-in, ease-out, ease-in-out
    transitionType: 'ease-in',
    
});

 

E este é o código base do plug-in.

$.fn.formProgressBar = function(options) {

    var defaults = {
        readCount: false,
        validClass: 'valid',
        invalidClass: 'error',
        percentCounting: true,
        transitionTime: 0,
        height: 10,
        transitionType: 'ease', //ease, linear, ease-in, ease-out, ease-in-out
        parentElement: "body"
    };

    var settings = $.extend( {}, defaults, options );

    //$(settings.parentElement).prepend("<div id='jQueryProgressFormBar'><div></div></div>")
    $("#jQueryProgressFormBar").css("width","100%").css("height",settings.height).css("z-index",10000)
    $("#jQueryProgressFormBar>div").css({
        WebkitTransition : 'all '+settings.transitionTime+'ms '+settings.transitionType,
        MozTransition    : 'all '+settings.transitionTime+'ms '+settings.transitionType,
        MsTransition     : 'all '+settings.transitionTime+'ms '+settings.transitionType,
        OTransition      : 'all '+settings.transitionTime+'ms '+settings.transitionType,
        transition       : 'all '+settings.transitionTime+'ms '+settings.transitionType
    }).css("height",settings.height);

    this.elementsRequied = function () {
        var formElements = $(this).find("input[required], textarea[required], select[required]").toArray()
        arr = [];
        formElements.map(function (item) {

            arr[item.name] = 0;
            if(item.checked)
                arr[item.name] = 1;
        })
        return arr;
    }
    this.refresh = function () {
        formFields = this.elementsRequied();
    }
    this.renderBar = function () {
        var correctFields = 0
        var length = 0;
        var error = false;

        for(var item in formFields){
            if(formFields[item]==1){
                correctFields++;
            }
            if(formFields[item]==-1)
                error=true;
            length++;
        }

        var percentOfSuccess = (correctFields/length*100).toFixed(2);
        if(settings.percentCounting)
            $("#jQueryProgressFormBar>div").text(Math.round(percentOfSuccess)+" %")
        $("#jQueryProgressFormBar>div").css("width",percentOfSuccess+"%")
        if(error==true)
            $("#jQueryProgressFormBar>div").addClass('warn')
        else
            $("#jQueryProgressFormBar>div").removeClass('warn').removeClass('error')

    }
    this.bindElements = function () {
        var editBar = this.renderBar
        $(this).find("input[required], textarea[required], select[required]").change(function () {
            if(!settings.readCount){
                switch ($(this).prop('nodeName')){
                    case "INPUT":
                        switch ($(this).attr("type")){
                            case "text":
                                if($(this).val()!=""){
                                    formFields[$(this).attr("name")]=1
                                }else{
                                    formFields[$(this).attr("name")]=-1
                                }
                                break;
                            case "email":
                                var re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
                                if(re.test(String($(this).val()).toLowerCase())){
                                    formFields[$(this).attr("name")]=1
                                }else{
                                    formFields[$(this).attr("name")]=-1
                                }
                                break;
                            case "number":
                                if($.isNumeric($(this).val())){
                                    formFields[$(this).attr("name")]=1
                                }else{
                                    formFields[$(this).attr("name")]=-1
                                }
                                break;
                            case "checkbox":
                                if($(this).is(':checked')){
                                    formFields[$(this).attr("name")]=1
                                }else{
                                    formFields[$(this).attr("name")]=-1
                                }
                                break;
                            case "radio":
                                if($(this).is(':checked')){
                                    formFields[$(this).attr("name")]=1
                                }else{
                                    formFields[$(this).attr("name")]=-1
                                }
                                break;
                        }
                        break;
                    case "SELECT":
                        if($(this).val()!=""){
                            formFields[$(this).attr("name")]=1
                        }else{
                            formFields[$(this).attr("name")]=-1
                        }
                        break;

                }

            }else{
                switch ($(this).attr("type")){
                    case "checkbox":
                        if($(this).is(':checked')){
                            formFields[$(this).attr("name")]=1
                        }else{
                            formFields[$(this).attr("name")]=-1
                        }
                        break;
                    case "radio":
                        if($(this).is(':checked')){
                            formFields[$(this).attr("name")]=1
                        }else{
                            formFields[$(this).attr("name")]=-1
                        }
                        break;
                }
            }
            editBar();
        })

        if(settings.readCount) {
            var $div = $(this).find("input[required], textarea[required], select[required]");
            var observer = new MutationObserver(function (mutations) {
                mutations.forEach(function (mutation) {
                    if (mutation.attributeName === "class") {
                        if ($(mutation.target).hasClass(settings.validClass)) {
                            formFields[$(mutation.target).attr("name")] = 1
                        } else if ($(mutation.target).hasClass(settings.invalidClass)) {
                            formFields[$(mutation.target).attr("name")] = -1
                        }
                        editBar();
                    }
                });
            });
            $div.map(function (item) {
                observer.observe($div[item], {
                    attributes: true
                });
            })
        }
;
        $(this).submit(function (e) {
            if($("#jQueryProgressFormBar>div").hasClass('warn')){
                $("#jQueryProgressFormBar>div").removeClass("warn").addClass("error")
                e.preventDefault()
                return
            }
            var correctFields = 0

            for(var item in formFields){
                if(formFields[item]==1){
                    correctFields++;
                }
                length++;
            }
            if(correctFields!=length){
                $("#jQueryProgressFormBar>div").removeClass("warn").addClass("error")
                e.preventDefault()
                return
            }

            $("#jQueryProgressFormBar>div").removeClass("warn").removeClass("error")


        })
    }

    var formFields = this.elementsRequied();



    this.bindElements()

    return this;
};

$.fn.formProgressBar

 

Link para o comentário
Compartilhar em outros sites

Se você está perdendo a porcentagem provavelmente é porque o valor da variável que define a porcentagem está sendo resetado durante a troca de abas.

 

Talvez você consiga resolver isso usando Steppers porque vai conseguir colocar vários elementos de formulário dentro de uma única tag <form> e fazendo isso você evita ficar usando o submit para cada aba do formulário.

Tem vários mini-frameworks que disponibilizam steps com ou sem Jquery.

 

Se quiser resolver isso mais eficientemente seria legal você debuggar essa aplicação para saber quando formProgressBar é chamado, tenho quase certeza que ele é chamado quando ocorre o evento de troca de abas, assim resetando os valores.

Esse vídeo mostra como usar o debugger no Chrome: https://youtu.be/H0XScE08hy8

Esse vídeo mostra como usar o debugger no Firefox: https://youtu.be/bwUNifZ4WrY (Legendado em português porque a Mozilla é deus em forma de empresa)

 

Caso você queira debuggar pelo vscode, existem as extensões Firefox Debugger e Chrome Debugger que são bem documentadas e simples de serem usadas.

 

Se quiser ver de forma mais detalhada, esse cara fez vários vídeos explicando como fazer Multi-Form's com barra de progresso: https://www.youtube.com/watch?v=4fzT7hdyL7k (Apesar que usar apenas um stepper pronto é mais produtivo.)

 

Link para o comentário
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...