Componente de mês e ano com botões - bootstrap 5


Com opção de escolha mês e ano - #bootstrap 5 e #javascript puro. Responsivo e com #exemplo para busca de dados via API.

Este #componente é prático e intuitivo para que o usuário selecione períodos em #mes ou #ano sem a necessidade de digitar porque utiliza #buttons como manipulação.

Melhorias são sempre uma boa evolução para a ideia e o código é livre baixa baixar, modificar e compartilhar.

 

{label: "Agosto", mes: "8", ano: "2020"}
ano: "2020"
label: "Agosto"
mes: "8"
__proto__: Object

 


 

<!DOCTYPE html>
<html lang="en" dir="ltr">

<head>
  <meta charset="utf-8">
  <title>Div meses</title>
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.9.1/font/bootstrap-icons.css">
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">

</head>
<!-- created by @BrCodeSnippets -->

<body>
  <div class="container-full mt-3">
    <div class="row m-0">
      <div class="col-12">
        <label for="">Selecione ano</label>
        <select class="form-select mb-3" name="ano" id="ano">
          <option value="2020">2020</option>
          <option value="2021">2021</option>
          <option value="2022">2022</option>
          <option value="2023">2023</option>
          <option value="2024">2024</option>
          <option value="2025">2025</option>
        </select>
        <div class="btn-group d-flex" role="group" aria-label="..." id="meses">
        </div>
        <div class=" alert-secondary fs-2 my-2 text-center p-3" id="mes">
        </div>
        Mês selecionado:
        <input id="inputMes" class="form-control" type="text" name="" value="" placeholder="Selecione um mês acima">
        <button class="btn btn-success w-100 mt-3 shadow" type="button" name="button">Avançar</button>
      </div>
    </div>
  </div>
</body>

<script type="text/javascript">
  // meses
  let dateNow = new Date();
  let mesAtual = dateNow.getMonth();
  let anoAtual = dateNow.getFullYear();
  let divMes = document.getElementById("mes");
  let divMeses = document.getElementById("meses");
  let inputMes = document.getElementById("inputMes");
  let inputAno = document.getElementById("ano");
  // aqui pode ser internacionalizado
  let meses = ['Janeiro', 'Fevereiro', 'Março', 'Abril', 'Maio', 'Junho', 'Julho', 'Agosto', 'Setembro', 'Outubro', 'Novembro', 'Dezembro'];
  let btnEsquerdo = ' <a data-acao="anterior"  class="btn btn-success" href="#">  << <i class="fa fa-arrow-left" aria-hidden="true"></i>  </a> ';
  let btnDireito = ' <a data-acao="proximo"  class="btn btn-success" href="#">  <i class="fa fa-arrow-right" aria-hidden="true"></i> >> </a> ';

  divMes.innerHTML = meses[mesAtual]; //((d.getMonth() + 1) < 10 ? '0' + (d.getMonth() + 1) : (d.getMonth() + 1));

  function render(mesAtual) {
    mesAtual = (mesAtual < 1) ? 1 : ((mesAtual >= 11) ? 10 : mesAtual);
    htmlMeses = "";
    mesAnterior = (mesAtual - 1);
    mesProximo = (mesAtual + 1);

    htmlMeses += btnEsquerdo;

    for (i = mesAnterior; i <= mesProximo; i++) {
      htmlMeses += '<button id="m-' + (i + 1) + '" data-mes="' + (i + 1) + '" href="#" class="btn btn-info w-100"> ' + meses[i] + ' </button>';
    }

    htmlMeses += btnDireito;

    divMeses.innerHTML = htmlMeses;

  }
  // load
  render(mesAtual);

  // ações dentro da div meses []

  document.getElementById('meses').addEventListener('click', async function() {

    event.preventDefault();
    let target = event.target;

    if (target.tagName == 'A') {
      let acao = target.getAttribute('data-acao');
      mesAtual = (acao == "anterior") ? ((mesAtual < 2) ? 10 : ((mesAtual > 10) ? 10 : (mesAtual - 1))) : ((mesAtual <= 9) ? (mesAtual + 1) : 1);
    }

    if (target.tagName == 'BUTTON') {

      // Aqui poderíamos ter uma async function para um API buscar dados externos...
      const dados = await getData({
        label: meses[target.getAttribute('data-mes') - 1],
        mes: target.getAttribute('data-mes'),
        ano: inputAno.value
      });

      data_mes = target.getAttribute('data-mes');
      divMes.innerHTML = dados;
      inputMes.value = target.getAttribute('data-mes') + ' - ' + meses[target.getAttribute('data-mes') - 1];
    }
    render(mesAtual);
  });

  // Exemplo
  async function getData(obj) {
    console.log(obj);
    return 'Dados de (mes ' + obj.mes + ') ' + obj.label + ' de ' + obj.ano;
  }
</script>

</html>

Javascript

// meses
  let dateNow = new Date();
  let mesAtual = dateNow.getMonth();
  let anoAtual = dateNow.getFullYear();
  let divMes = document.getElementById("mes");
  let divMeses = document.getElementById("meses");
  let inputMes = document.getElementById("inputMes");
  let inputAno = document.getElementById("ano");
  // aqui pode ser internacionalizado
  let meses = ['Janeiro', 'Fevereiro', 'Março', 'Abril', 'Maio', 'Junho', 'Julho', 'Agosto', 'Setembro', 'Outubro', 'Novembro', 'Dezembro'];
  let btnEsquerdo = ' <a data-acao="anterior"  class="btn btn-success" href="#">  << <i class="fa fa-arrow-left" aria-hidden="true"></i>  </a> ';
  let btnDireito = ' <a data-acao="proximo"  class="btn btn-success" href="#">  <i class="fa fa-arrow-right" aria-hidden="true"></i> >> </a> ';

  divMes.innerHTML = meses[mesAtual]; //((d.getMonth() + 1) < 10 ? '0' + (d.getMonth() + 1) : (d.getMonth() + 1));

  function render(mesAtual) {
    mesAtual = (mesAtual < 1) ? 1 : ((mesAtual >= 11) ? 10 : mesAtual);
    htmlMeses = "";
    mesAnterior = (mesAtual - 1);
    mesProximo = (mesAtual + 1);

    htmlMeses += btnEsquerdo;

    for (i = mesAnterior; i <= mesProximo; i++) {
      htmlMeses += '<button id="m-' + (i + 1) + '" data-mes="' + (i + 1) + '" href="#" class="btn btn-info w-100"> ' + meses[i] + ' </button>';
    }

    htmlMeses += btnDireito;

    divMeses.innerHTML = htmlMeses;

  }
  // load
  render(mesAtual);

  // ações dentro da div meses []

  document.getElementById('meses').addEventListener('click', async function() {

    event.preventDefault();
    let target = event.target;

    if (target.tagName == 'A') {
      let acao = target.getAttribute('data-acao');
      mesAtual = (acao == "anterior") ? ((mesAtual < 2) ? 10 : ((mesAtual > 10) ? 10 : (mesAtual - 1))) : ((mesAtual <= 9) ? (mesAtual + 1) : 1);
    }

    if (target.tagName == 'BUTTON') {

      // Aqui poderíamos ter uma async function para um API buscar dados externos...
      const dados = await getData({
        label: meses[target.getAttribute('data-mes') - 1],
        mes: target.getAttribute('data-mes'),
        ano: inputAno.value
      });

      data_mes = target.getAttribute('data-mes');
      divMes.innerHTML = dados;
      inputMes.value = target.getAttribute('data-mes') + ' - ' + meses[target.getAttribute('data-mes') - 1];
    }
    render(mesAtual);
  });

  // Exemplo
  async function getData(obj) {
    console.log(obj);
    return 'Dados de (mes ' + obj.mes + ') ' + obj.label + ' de ' + obj.ano;
  }