load datepicker plugin on page called with ajax

Asked

Viewed 1,160 times

2

I’m using the plugin datepicker

All my datepicker input, has the class called datepicker

<input type="text" class="datepicker">

So, I have only one configuration for datepicker and can use on all pages, so I do the configuration in a file dateconfig.js, in that file I only have the following code:

 $(".datepicker").datepicker({
        dateFormat: 'dd/mm/yy',
        dayNames: ['Domingo','Segunda','Terça','Quarta','Quinta','Sexta','Sábado','Domingo'],
        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']
    });

But I have a page with a table and in it there is the input with the class="datepicker"

But when I call a modal via ajax, and in it there is also a input, it does not load the plugin, so on the page of this modal I copy the configuration code and add inside a tag <script> //Configuration code cited above </script>, doing this he adds the plugin, but there on my page with the table, he doubles the plugin, creating 2 calendars of datepicker

How could I solve these two problems?

Edit

The way I currently make the call of the modal is this:

in my "index/grid/table"

<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
    <div class="modal-dialog">
        <div class="modal-content" id="modalContent">
        </div>
    </div>
</div>

my call from ajax, I used a html helper of asp.net mvc, but I believe he interprets himself as this call from jquery:

        $.ajax({
            type: "GET",
            url: "URL",
            success: function (result) {
                $("#modalContent").html(result);
            },
            complete: function (msg) {
                $('#myModal').modal('show');
            }
        });
  • What code are you using to open the modal?

  • @Sergio edited the question, it’s like this...

  • Okay, I’m leaving work right now I’ll look over here, but why don’t you join $("#modalContent .datepicker").datepicker({ within that complete: function (msg) { AJAX. So it will only add datepicker to this input(s) that the modal has received.

  • @Sergio, but every ajax request, I will have to do this? becomes the code of a simple repetitive "get"

4 answers

1


I would change the file dateconfig.js to deal with the datepicker in a more pragmatic way:

Solution

// Opções para o Datepicker
var options = {
    dateFormat: 'dd/mm/yy',
    dayNames: ['Domingo','Segunda','Terça','Quarta','Quinta','Sexta','Sábado','Domingo'],
    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']
};

// Controlo para instanciar e/ou apresentar o datepicker
$("body").on("click", ".datepicker", function(){

    var $this = $(this);

    if (!$this.hasClass("hasDatepicker")) {
        $this.datepicker(options);
    }

    $this.datepicker("show");
});

Explanation

  1. We’re delegating an event to the element body that will fire every time you click on an element with the class datepicker.

  2. The plugin datepicker when creating an instance, leaves in the elements the control class hasDatepicker. This allows us to check if the element that received the click already has an instance and so go straight to the presentation of the calendar.

  3. Finally, by clicking on the elements with the class datepicker we will open the same.

In this way, either asynchronously or "regularly", all the work related to the datepicker is performed in your file dateconfig.js and you do not need to take additional measures to manage the plugin.

Example

The example below is also found in Jsfiddle.

// Opções para o Datepicker
var options = {
    dateFormat: 'dd/mm/yy',
    dayNames: ['Domingo','Segunda','Terça','Quarta','Quinta','Sexta','Sábado','Domingo'],
    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']
};

// Controlo para instanciar e/ou apresentar o datepicker
$("body").on("click", ".datepicker", function(){
    
    var $this = $(this);
    
    if (!$this.hasClass("hasDatepicker")) {
        $this.datepicker(options);
    }
    
    $this.datepicker("show");
});


// Gerar elementos simulando chamada Ajax
$('button').on("click", function(){ $('body').append($('<input/>').addClass('datepicker'))});
<link href="//code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>

<input type="text" class="datepicker"> <button>+</button>

0

The problem here is that there is content to be created dynamically and it would be necessary delegate datepicker to not run duplicate code and thereby generate multiple datepicker windows for each input.

A solution is create a new instance every time new content is added to the DOM. It’s best to do this in the AJAX call like this:

var formato = {
    dateFormat: 'dd/mm/yy',
    dayNames: ['Domingo','Segunda','Terça','Quarta','Quinta','Sexta','Sábado','Domingo'],
    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']
};

// ... depois dentro do ajax: 

complete: function (msg) {
    $('#myModal').modal('show');
    $("#conteiner-do-modal .datepicker").datepicker(formato);
}

and thus only new inputs will be selected.

Another solution is call the datepicker delegating an event, for example focusin:

$("body").on("input.datepicker", "focusin", function(){
   $(this).datepicker(formato);
});

Example: https://jsfiddle.net/6ajoomct/

0

To start, the settings you can set using the function setDefaults.

$.datepicker.setDefaults({
    dateFormat: 'dd/mm/yy'
});

Now, to add datepicker only to class inputs datepicker and which do not yet have the datepicker initialized, you can do the following:

$(".datepicker:data(datepicker)").datepicker();

How it works? Ui jquery plugins always store the created object instance in the element, using the plugin name (in this case, datepicker). So, to check if the plugin has already been initialized in the element, just check for the existence of the instance in it.

A final version of your code could be as follows:

function iniciarDatepicker() {
    // você pode passar as configurações aqui ou setar via o setDefults
    $(".datepicker:data(datepicker)").datepicker();
}

So you can always call the same function.

0

You will have to apply the plugin only to elements that have been loaded via AJAX into the modal container:

$("#conteiner-do-modal .datepicker").datepicker({
        dateFormat: 'dd/mm/yy',
        dayNames: ['Domingo','Segunda','Terça','Quarta','Quinta','Sexta','Sábado','Domingo'],
        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']
    });

I’m assuming the modal container has the id="conteiner-do-modal".

Avoiding repetitions

In order to make no mistake in repeating, you can create a method that applies the plugin using a jQuery selector, and this function will be available globally for those who want to call:

function setupDatepicker(seletor) {
    $(seletor).datepicker({
        dateFormat: 'dd/mm/yy',
        dayNames: ['Domingo','Segunda','Terça','Quarta','Quinta','Sexta','Sábado','Domingo'],
        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']
    });
}

So in every place you have to call, do it the appropriate way:

  • on the home page:

    setupDatepicker(".datepicker");
    
  • after loading the modal:

    setupDatepicker("#conteiner-do-modal .datepicker");
    

The above code in plugin form:

(function ( $ ) {

    $.fn.setupDatepicker = function() {
        this.datepicker({
            dateFormat: 'dd/mm/yy',
            dayNames: ['Domingo','Segunda','Terça','Quarta','Quinta','Sexta','Sábado','Domingo'],
            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']
        });
        return this;
    };

}( jQuery ));

To use do so:

  • on the home page:

    $(".datepicker").setupDatepicker();
    
  • after loading the modal:

    $("#conteiner-do-modal .datepicker").setupDatepicker();
    
  • Hello @Miguel Angelo, thank you for answering, but there is no other way? making it seems so repetitive the code...

  • in fact this problem of not loading, is practically in all plugins, rsrsrs =/

  • I edited the answer with something to avoid code repetition errors.

  • thanks, I figured I could do something like this... But the file with the function, It should be passed on the page that will be loaded by ajax right? Is that I see that some plugins, even need to pass the files inside the page being loaded...

  • It is not necessary if there is a guarantee that the file is already loaded on the main page. Otherwise, then yes, you will need to include the file in the AJAX upload.

  • @Rod A cool option would be to create a plugin, which makes the above code... but I would have to see how to make a plugin for jQuery because I don’t know right now.

  • You can repeat this process with the other plugins... I don’t think you have a better way. Then tell me what you found. =)

Show 2 more comments

Browser other questions tagged

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