Does anyone know of any Javascript or CSS plugin that can generate this type of progress bar?
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>
You can use this code that I found at bootsnipp .
Note you will only have to do a javascript script to change the classes.
There are others similar on the same site: link
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>