Progress bar plugin with steps

0

Does anyone know of any Javascript or CSS plugin that can generate this type of progress bar?

    
asked by anonymous 01.11.2017 / 17:49

2 answers

5

It's been a work to do, but here it is. Click the blue Run button below to see it working.

/* JavaScript para incluir. */

jQuery.fn.extend({
    stepProgressBar: function(currentStep) {
        currentStep = currentStep || this.currentStep() || 1;
        let childs = this
                .addClass("step-progress-bar")
                .find("li")
                .removeClass("step-past step-present step-future");

        childs.find(".content-stick").removeClass("step-past step-future");

        let size = childs.length < 1 ? 100 : 100 / childs.length;
        childs.css("width", size + "%");

        for (let i = 0; i < childs.length; i++) {
            let child = $(childs[i]);
            if (child.find("span.content-wrapper").length === 0) {
                child.wrapInner("<span class='content-wrapper'></span>");
                if (i > 0) child.append("<span class='content-stick'></span>");
                child.prepend("<span class='content-bullet'>" + (i + 1) + "</span>");
            }
            let stepName = i < currentStep - 1 ? "step-past"
                    : i === currentStep - 1 ? "step-present"
                    : "step-future";
            child.addClass(stepName);
            if (i > 0) {
                let stickName = stepName === "step-present" ? "step-past" : stepName;
                child.find(".content-stick").addClass(stickName);
            }
            child.css("z-index", childs.length - i);
            child.find(":before").css("z-index", childs.length - i + 2);
        }
        return this;
    },

    currentStep: function() {
        var childs = this.find("li");
        for (let i = 0; i < childs.length; i++) {
            if ($(childs[i]).is(".step-present")) return i + 1;
        }
        return 1;
    },

    countSteps: function() {
        return this.find("li").length;
    },

    isFirstStep: function() {
        return this.countSteps() === 1;
    },

    isLastStep: function() {
        return this.countSteps() === this.currentStep();
    },

    previousStep: function() {
        if (!this.isFirstStep()) this.stepProgressBar(this.currentStep() - 1);
    },

    nextStep: function() {
        if (!this.isLastStep()) this.stepProgressBar(this.currentStep() + 1);
    },

    rewind: function() {
        this.stepProgressBar(1);
    },

    fastForward: function() {
        this.stepProgressBar(this.countSteps());
    },

    controlProgressBar: function(progressBar) {
        let rewind = function() { progressBar.rewind(); };
        let next = function() { progressBar.nextStep(); };
        let previous = function() { progressBar.previousStep(); };
        let fastForward = function() { progressBar.fastForward(); };
        this.empty();
        $("<input type='button' class='step-progress-bar-button rewind' value='⏪' />").on('click', rewind).appendTo(this);
        $("<input type='button' class='step-progress-bar-button previous' value='◀️' />").on('click', previous).appendTo(this);
        $("<input type='button' class='step-progress-bar-button next' value='▶' />").on('click', next).appendTo(this);
        $("<input type='button' class='step-progress-bar-button fast-forward' value='⏩' />").on('click', fastForward).appendTo(this);
        return this;
    }
});

/* JavaScript na página. */

$("#barra-simples-1").stepProgressBar();
$("#barra-simples-2").stepProgressBar();
$("#barra-simples-3").stepProgressBar(3);

let pb = $("#barra-controle-basico").stepProgressBar(2);
$("#controle-basico").controlProgressBar(pb);

$("#controle-macarrao").controlProgressBar($("#barra-macarrao").stepProgressBar(4));

let ca = $("#barra-controle-personalizado").stepProgressBar(1);
let cb = $("#controle-personalizado").controlProgressBar(ca);
cb.find(".rewind, .fast-forward").remove();

$("#cores-personalizadas").stepProgressBar(4);

let temp = $("#cores-temperatura").stepProgressBar(3);
$("#controle-temperatura").controlProgressBar(temp);
/* CSS principal da barra de progresso. Não deve ser alterado. */

ol.step-progress-bar {
    list-style: none;
    padding: 0;
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
}

ol.step-progress-bar li {
    display: inline-block;
    vertical-align: top;
    text-align: center;
    flex: 1 1;
    position: relative;
    margin: 0 5px 0;
}

ol.step-progress-bar li span.content-bullet {
    border-radius: 100%;
    display: block;
    text-align: center;
    transform: translateX(-50%);
    margin-left: 50%;
}

ol.step-progress-bar li span.content-wrapper {
    display: inline-block;
    overflow: visible;
    width: 100%;
    padding: 0;
}

ol.step-progress-bar li span.content-stick {
    position: absolute;
    display: block;
    width: 100%;
    height: 8px;
    z-index: -1;
    transform: translate(-50%, -50%);
}

/* Cores. Sinta-se livre para alterar. */

/* Cor padrão.
   Passado: #2dcd73 (verde) e branco.
   Presente: #4c92d9 (azul) e branco.
   Futuro: #dde2e3 (cinza claro) e #869398 (cinza escuro).
*/

ol.step-progress-bar li.step-past *,
ol.step-progress-bar li.step-present .content-stick {
    color: #2dcd73;
    background: #2dcd73;
}

ol.step-progress-bar li.step-present * {
    color: #4c92d9;
    background: #4c92d9;
}

ol.step-progress-bar li .content-bullet {
    color: white;
}

ol.step-progress-bar li.step-future * {
    color: #869398;
    background: #dde2e3;
}

ol.step-progress-bar li .content-wrapper {
    background: transparent;
}

/* Cor especial 1.
   Passado: vemelho
   Presente: laranja
   Futuro: amarelo
   Cor dos números: azul
*/

ol.step-progress-bar.cor-especial li.step-past *,
ol.step-progress-bar.cor-especial li.step-present .content-stick {
    color: red;
    background: red;
}

ol.step-progress-bar.cor-especial li.step-present * {
    color: orange;
    background: orange;
}

ol.step-progress-bar.cor-especial li.step-future * {
    color: yellow;
    background: yellow;
}

ol.step-progress-bar.cor-especial li .content-bullet {
    color: blue;
}

ol.step-progress-bar.cor-especial li .content-wrapper {
    background: transparent;
}

/* Cor especial 2. */

#gelado * {
    color: blue;
    background: blue;
}

#frio * {
    color: cyan;
    background: cyan;
}

#morno * {
    color: lime;
    background: lime;
}

#quente * {
    color: yellow;
    background: yellow;
}

#fervendo * {
    color: red;
    background: red;
}

#cores-temperatura .content-wrapper {
    background: transparent;
}

#cores-temperatura .content-bullet {
    color: black;
}

#cores-temperatura .content-wrapper {
    text-shadow: 0 0 1px black, 0 0 8px purple;
}

#cores-temperatura li.step-present {
    font-weight: bold;
    font-size: 120%;
}

#cores-temperatura li.step-present .content-bullet {
    width: 55px;
    line-height: 55px;
    transform: translate(-27px, -9px);
    font-size: 200%;
    color: pink;
    text-shadow: 0 1px black, 1px 0 black, -1px 0 black, 0 -1px black;
}

#cores-temperatura li .content-stick {
    background: purple;
}

/* Tamanhos. */

/* Tamanho pequeno:
   Bolinha de 25px de diâmetro.
   Fonte 75%.
   Conector 4px de altura.
*/

ol.step-progress-bar.small li .content-bullet {
    width: 25px;
    line-height: 25px;
}

ol.step-progress-bar.small li {
    font-size: 75%;
}

ol.step-progress-bar.small li .content-stick {
    top: 12.5px; /* Metade do diâmetro. */
    height: 4px;
}

/* Tamanho médio:
   Bolinha de 37px de diâmetro.
   Fonte 100%.
   Conector 6px de altura.
*/

ol.step-progress-bar.mid li .content-bullet {
    width: 37px;
    line-height: 37px;
}

ol.step-progress-bar.mid li {
    font-size: 100%;
}

ol.step-progress-bar.mid li .content-stick {
    top: 18.5px; /* Metade do diâmetro. */
    height: 6px;
}

/* Tamanho grande:
   Bolinha de 49px de diâmetro.
   Fonte 120%.
   Conector 8px de altura.
*/

ol.step-progress-bar.large li .content-bullet {
    width: 49px;
    line-height: 49px;
}

ol.step-progress-bar.large li {
    font-size: 125%;
}

ol.step-progress-bar.large li .content-stick {
    top: 24.5px; /* Metade do diâmetro. */
    height: 8px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><h3>Exemplo1,umabarrasimples</h3><olid="barra-simples-1" class="small">
    <li>Passo 1</li>
    <li>Passo 2</li>
    <li>Passo 3</li>
</ol>

<h3>Exemplo 2, uma barra simples com progresso definido no HTML</h3>

<ol id="barra-simples-2" class="mid">
    <li>A</li>
    <li class="step-present">B</li>
    <li>C</li>
</ol>

<h3>Exemplo 3, uma barra simples com progresso definido no JS</h3>

<ol id="barra-simples-3" class="large">
    <li>Cadastrar os dados</li>
    <li>Confirmar o e-mail</li>
    <li>Efetuar a compra</li>
    <li>Realizar o pagamento</li>
</ol>

<h3>Exemplo 4: Com botões de controle</h3>

<ol id="barra-controle-basico" class="mid">
    <li>Preparar</li>
    <li>Apontar</li>
    <li>Fogo</li>
</ol>

<div id="controle-basico"></div>

<h3>Exemplo 5: Com botões de controle personalizados</h3>

<ol id="barra-controle-personalizado" class="large">
    <li>Nova</li>
    <li>Crescente</li>
    <li>Cheia</li>
    <li>Minguante</li>
</ol>

<div id="controle-personalizado"></div>

<h3>Exemplo 6: Fazendo um macarrão instantâneo</h3>

<ol id="barra-macarrao" class="small">
    <li>Colocar água na panela</li>
    <li>Ligar o fogo</li>
    <li>Ferver</li>
    <li>Acrescentar o macarrão</li>
    <li>Cozinhar por 3 minutos</li>
    <li>Desligar o fogo</li>
    <li>Acrescentar o tempero</li>
    <li>Servir</li>
</ol>

<div id="controle-macarrao"></div>

<h3>Exemplo 7: Cores personalizadas 1</h3>

<ol id="cores-personalizadas" class="large cor-especial">
    <li>Juntar dinheiro</li>
    <li>Construir robôs</li>
    <li>Declarar guerra</li>
    <li>Atacar os inimigos</li>
    <li>Dominar o mundo</li>
</ol>

<h3>Exemplo 8: Cores personalizadas 2</h3>

<ol id="cores-temperatura" class="mid">
    <li id="gelado">Gelado</li>
    <li id="frio">Frio</li>
    <li id="morno">Morno</li>
    <li id="quente">Quente</li>
    <li id="fervendo">Fervendo</li>
</ol>

<div id="controle-temperatura"></div>
    
02.11.2017 / 22:38
2

Bootsnipp

You can use this code that I found at bootsnipp .

  

link

Note you will only have to do a javascript script to change the classes.

There are others similar on the same site: link

Example

I made an example of a possible application using the link I reported. I apologize for the size of the code.

/* 
  Exemplo de possível funcionalidade
  O código abaixo desativa a "Etapa" que já foi completada
*/


// Funções utilitárias
function active(div) {
    div.classList.remove('disabled');
    div.classList.remove('complete');
    div.classList.add('active');
}

function complete(div) {
    div.classList.remove('disabled');
    div.classList.remove('active');
    div.classList.add('complete');
}

function disabled(div) {
    div.classList.remove('active');
    div.classList.remove('complete');
    div.classList.add('disabled');
}



// Desativando as etapas
function desativaEtapa1() {
    var etapa1 = document.getElementById("etapa1");
    var etapa2 = document.getElementById("etapa2");
    var etapa3 = document.getElementById("etapa3");
    
    disabled(etapa3)
    disabled(etapa2);
    disabled(etapa1);
}

function desativaEtapa2() {
    var etapa1 = document.getElementById("etapa1");
    var etapa2 = document.getElementById("etapa2");
    var etapa3 = document.getElementById("etapa3");

    complete(etapa1);
    disabled(etapa2);
    disabled(etapa3);
}

function desativaEtapa3() {
    var etapa1 = document.getElementById("etapa1");
    var etapa2 = document.getElementById("etapa2");
    var etapa3 = document.getElementById("etapa3");

    complete(etapa1);
    complete(etapa2);
    disabled(etapa3);
}
/* 
  Código retirado do site https://bootsnipp.com/
  Creditos totais para o usuário alilishan
  Link do código:
  https://bootsnipp.com/snippets/featured/form-process-steps
*/

.bs-wizard {margin-top: 40px;}

/*Form Wizard*/
.bs-wizard {border-bottom: solid 1px #e0e0e0; padding: 0 0 10px 0;}
.bs-wizard > .bs-wizard-step {padding: 0; position: relative;}
.bs-wizard > .bs-wizard-step + .bs-wizard-step {}
.bs-wizard > .bs-wizard-step .bs-wizard-stepnum {color: #595959; font-size: 16px; margin-bottom: 5px;}
.bs-wizard > .bs-wizard-step .bs-wizard-info {color: #999; font-size: 14px;}
.bs-wizard > .bs-wizard-step > .bs-wizard-dot {position: absolute; width: 30px; height: 30px; display: block; background: #fbe8aa; top: 45px; left: 50%; margin-top: -15px; margin-left: -15px; border-radius: 50%;} 
.bs-wizard > .bs-wizard-step > .bs-wizard-dot:after {content: ' '; width: 14px; height: 14px; background: #fbbd19; border-radius: 50px; position: absolute; top: 8px; left: 8px; } 
.bs-wizard > .bs-wizard-step > .progress {position: relative; border-radius: 0px; height: 8px; box-shadow: none; margin: 20px 0;}
.bs-wizard > .bs-wizard-step > .progress > .progress-bar {width:0px; box-shadow: none; background: #fbe8aa;}
.bs-wizard > .bs-wizard-step.complete > .progress > .progress-bar {width:100%;}
.bs-wizard > .bs-wizard-step.active > .progress > .progress-bar {width:50%;}
.bs-wizard > .bs-wizard-step:first-child.active > .progress > .progress-bar {width:0%;}
.bs-wizard > .bs-wizard-step:last-child.active > .progress > .progress-bar {width: 100%;}
.bs-wizard > .bs-wizard-step.disabled > .bs-wizard-dot {background-color: #f5f5f5;}
.bs-wizard > .bs-wizard-step.disabled > .bs-wizard-dot:after {opacity: 0;}
.bs-wizard > .bs-wizard-step:first-child  > .progress {left: 50%; width: 50%;}
.bs-wizard > .bs-wizard-step:last-child  > .progress {width: 50%;}
.bs-wizard > .bs-wizard-step.disabled a.bs-wizard-dot{ pointer-events: none; }
/*END Form Wizard*/
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>

<div class="container">     
    <div class="row bs-wizard" style="border-bottom:0;">         
        <div id="etapa1" class="col-xs-3 bs-wizard-step complete">
            <!-- Etapa 1 -->
            <div class="text-center bs-wizard-stepnum">
                Etapa 1
            </div>
            <!-- Barra de progresso -->
            <div class="progress">
                <div class="progress-bar"></div>
            </div>
            <!-- Texto abaixo da barra -->
            <a href="#" onclick="desativaEtapa1()" class="bs-wizard-dot"></a>
            <div class="bs-wizard-info text-center">
                Texto 1.
            </div>
        </div>    
                
        <div id="etapa2" class="col-xs-3 bs-wizard-step complete">
            <!-- Etapa 2 -->
            <div class="text-center bs-wizard-stepnum">
                Etapa 2
            </div>
            <!-- Barra de progresso -->
            <div class="progress">
                <div class="progress-bar"></div>
            </div>
            <!-- Texto abaixo da barra -->
            <a href="#" onclick="desativaEtapa2()" class="bs-wizard-dot"></a>
            <div class="bs-wizard-info text-center">
                Texto 2.
            </div>
        </div>

        <div id="etapa3" class="col-xs-3 bs-wizard-step active">
            <!-- Etapa 3 -->
            <div class="text-center bs-wizard-stepnum">
                Etapa 3
            </div>
            <!-- Barra de progresso -->
            <div class="progress">
                <div class="progress-bar"></div>
            </div>
            <!-- Texto abaixo da barra -->
            <a href="#" onclick="desativaEtapa3()" class="bs-wizard-dot"></a>
            <div class="bs-wizard-info text-center">
                Texto 3.
            </div>
        </div>

        <div id="etapa4" class="col-xs-3 bs-wizard-step disabled">
            <!-- Etapa 4 -->
            <div class="text-center bs-wizard-stepnum">
                Etapa 4
            </div>
            <!-- Barra de progresso -->
            <div class="progress">
                <div class="progress-bar"></div>
            </div>
            <!-- Texto abaixo da barra -->
            <a href="#" class="bs-wizard-dot"></a>
            <div class="bs-wizard-info text-center">
                Texto 4.
            </div>
        </div> 
    </div>        
</div>
    
01.11.2017 / 18:41