Applying datepicker to a dynamic input with Jquery

Asked

Viewed 486 times

5

I have a form where you can add several fields with datepicker. However, when adding a new field to the form, the Jquery datepicker is not loaded.

This is the JS responsible for cloning and adding the fields to the form:

$(document).ready(function () {

hideBtnDel();

function hideBtnDel() {
    if ($("#digitalCertificates .digitalCertificate").length <= 1) {
        $("#digitalCertificates .digitalCertificate .removeDigitalCertificate").addClass('disabled');
        $("#digitalCertificates .digitalCertificate .removeDigitalCertificate").prop('disabled', true);
    } else {
        $("#digitalCertificates .digitalCertificate .removeDigitalCertificate").removeClass('disabled');
        $("#digitalCertificates .digitalCertificate .removeDigitalCertificate").prop('disabled', false);
    }
    removeDigitalCertificate();
}

function removeDigitalCertificate() {
    $(".removeDigitalCertificate").unbind("click");
    $(".removeDigitalCertificate").bind("click", function () {
        $(this).parents('.digitalCertificate').remove();
        hideBtnDel();
    });
}

$("#addDigitalCertificate").click(function () {
    event.preventDefault();
    newDigitalCertificate = $("#digitalCertificates .digitalCertificate:first").clone();
    newDigitalCertificate.find("input[type='text']").val("");
    newDigitalCertificate.find("input[type=hidden]").val("");
    newDigitalCertificate.find("input[type='checkbox']").prop('checked', false);
    newDigitalCertificate.find("select").val("");
    newDigitalCertificate.insertAfter("#digitalCertificates .digitalCertificate:last");
    hideBtnDel();
});

Doing a search, I found this, which in theory should solve the problem but did not work, it even enters the function, but the datepicker is not applied (I added it right after the '$(Document). ready(Function() {...}' from the above block):

$(document).on('focus', '.datepicker', function () {
    console.log('teste');
    $(this).datepicker({
        dateFormat: 'dd/mm/yy',
        dayNames: ['Domingo', 'Segunda', 'Terça', 'Quarta', 'Quinta', 'Sexta', 'Sábado'],
        dayNamesMin: ['D', 'S', 'T', 'Q', 'Q', 'S', 'S', 'D'],
        dayNamesShort: ['Dom', 'Seg', 'Ter', 'Qua', 'Qui', 'Sex', 'Sáb', 'Dom'],
        monthNames: ['Janeiro', 'Fevereiro', 'Março', 'Abril', 'Maio', 'Junho', 'Julho', 'Agosto', 'Setembro', 'Outubro', 'Novembro', 'Dezembro'],
        monthNamesShort: ['Jan', 'Fev', 'Mar', 'Abr', 'Mai', 'Jun', 'Jul', 'Ago', 'Set', 'Out', 'Nov', 'Dez'],
        nextText: 'Próximo',
        prevText: 'Anterior',
    });
});

Have some other way to load this datepicker dynamically?

  • Try to put $("#digitalCertificates").datepicker() where the clone is created.

  • @Leandrade also tried it, it didn’t work.

  • 1

    Include the class datepicker in the inputs where you want it to be applied: <input class="datepicker"....>. If you already have other classes, just include it: <input class="datepicker outraClasse MaisOutra"...>. When you focus on input, datepicker will automatically be applied.

  • @When cloning the field, the 'datepicker' class is also cloned, so all inputs already come with this class (if I understood what you meant).

1 answer

4


After inserting the clone, remove the class hasDatepicker of input. This class is inserted by Datepicker and when cloning the element with this class, Datepicker is understanding that it has already been applied to input, when in fact it was not.

Just insert this line after inserting the clone (after the insertAfter):

$("#digitalCertificates .digitalCertificate:last")
.removeClass("hasDatepicker");

Example:

$(document).ready(function () {
   $("#addDigitalCertificate").click(function (event) {
      event.preventDefault();
      newDigitalCertificate = $("#digitalCertificates .digitalCertificate:first").clone();
      newDigitalCertificate.insertAfter("#digitalCertificates .digitalCertificate:last");
      $("#digitalCertificates .digitalCertificate:last")
      .removeClass("hasDatepicker");
   });
   
   $(document).on('focus', '.datepicker', function () {
      $(this).datepicker({
      dateFormat: 'dd/mm/yy',
      dayNames: ['Domingo', 'Segunda', 'Terça', 'Quarta', 'Quinta', 'Sexta', 'Sábado'],
      dayNamesMin: ['D', 'S', 'T', 'Q', 'Q', 'S', 'S', 'D'],
      dayNamesShort: ['Dom', 'Seg', 'Ter', 'Qua', 'Qui', 'Sex', 'Sáb', 'Dom'],
      monthNames: ['Janeiro', 'Fevereiro', 'Março', 'Abril', 'Maio', 'Junho', 'Julho', 'Agosto', 'Setembro', 'Outubro', 'Novembro', 'Dezembro'],
      monthNamesShort: ['Jan', 'Fev', 'Mar', 'Abr', 'Mai', 'Jun', 'Jul', 'Ago', 'Set', 'Out', 'Nov', 'Dez'],
      nextText: 'Próximo',
      prevText: 'Anterior',
      });
   });

});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/smoothness/jquery-ui.css">
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>

<div id="digitalCertificates">
   <input type="text" class="digitalCertificate datepicker">
</div>
<br>
<a href="#" id="addDigitalCertificate">Adicionar</a>

Something else:

Include the parameter event in the function of the event:

$("#addDigitalCertificate").click(function (event) {...
                                              ↑

Without including the parameter, the event.preventDefault(); will not work in Firefox, for example.

  • 1

    Thank you very much. This block didn’t work '$("#digitalCertificates .digitalCertificate:last") . removeClass("hasDatepicker");', but I replace it with this 'newDigitalCertificate.find('input.hasDatepicker'). removeClass('hasDatepicker'). removeAttr('id');' added before insertAfter'.

  • I’m glad you decided.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.