63
votes

I've got a date text field I wish to only sometimes attach a DatePicker to, because I have some of my own text-handling scripts which handle partial date strings. Calling .remove or .destroy leaves text formatting behavior on the input field, however, which converts my "8" string into a "8/18/2010". Even worse, if I start deleting, it steadfastly assumes that, once I reach "8/18/20", I actually wanted "8/18/2020".

What would be the best way to completely, entirely, make-it-like-it-never-was remove the datepicker from my page? I can also use it if it just ignores text I enter entirely at all times, though in that case I'd prefer it to appear on a double-click / an image-as-button, not always.

edit:

this is all within a jqGrid, where 'selector' is a text box on a date column:

function showPicker(selector) {
    $(selector).datepicker({
        onClose: function() {
            $(selector).datepicker('remove'); 
            // or 'destroy' or $('.datepicker').remove(); or $(this).datepick('remove');
        }
    });
}

This prevents it from coming back, but not from manipulating my text field. No other code (that I'm aware of) is manipulating that field's contents, just jqGrid watching for the enter-key to send the data. Looking at the page's generated code, the datepicker div is even still at the bottom.

edit2: I get the exact same behavior if I do this:

<html>
<body>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.4.2.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.4/jquery-ui.js"></script>
<link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.4/themes/base/jquery-ui.css" rel="stylesheet" type="text/css"  />
<script type="text/javascript">
$(document).ready( function(){
 $("#pickle").datepicker({
  onClose: function(){
   $(this).datepicker('remove');
  }
 });
});
</script>
<input type="text" id="pickle" />
</body>
</html>

That causes identical behavior to what I'm seeing, but changing it to 'destroy' works here but not on my page. Odd.

4

4 Answers

124
votes

This removes .datepicker COMPLETELY:

$( selector ).datepicker( "destroy" );
$( selector ).removeClass("hasDatepicker").removeAttr('id');

Documentation:
https://api.jqueryui.com/datepicker/#method-destroy
also read the comments below

8
votes

I solved the problem by removing the datepicker classes and then calling the unbind method on the element tied to the datepicker. That seemed to get rid of it!

eg:

$('#myelement').datepicker();

/////////datepicker attached to myelement//////

and then:

$('#myelement').removeClass('calendarclass');
$('#myelement').removeClass('hasDatepicker');
$('#myelement').unbind();

Just removing the classes still let the input element invoke the datepicker when clicked in. possibly unbind() by itself would do the job, but I'm kind of a belt-and-braces chap.

3
votes

depending on your situation, you could do it server side

Ex. in asp-like sytax

<% if( showDatePicker ) {%>
    $('#dp-div').DatePicker(); // or whatever
<% } %>

Edit
How about setting the dateFormat of the datepicker? ie

$( ".selector" ).datepicker({ dateFormat: 'yy-mm-dd' });

you might be wanting

$( ".selector" ).datepicker({ dateFormat: '...' });
0
votes

In single page application, even if the contents of the page change, jquery ui remains garbage. So I do like this in single page application.

(function($) {

    if ($.ui !== null && typeof $.ui !== typeof undefined) {
        /**
         * dialog fix
         */
        var $oDialog = $.fn.dialog
        $.fn.dialog = function(mth, dialogOpts) {
            if (mth !== null && typeof mth === 'string') {
                if (mth === 'clean') {
                    var id = $(this).attr('id');   // you must set id
                    if (id !== null && typeof id !== typeof undefined) {
                        // garbage jquery ui elements remove
                        $('[aria-describedby="' + id + '"]', document).each(function() {
                            if ($(this).dialog('instance')) {
                                $(this).dialog('destroy');
                            }
                            $(this).remove();
                        });
                    }
                    return this;
                } else if (mth === 'open' && dialogOpts !== null && typeof dialogOpts === 'object') {
                    if ($oDialog.apply(this, ['instance'])) {
                        $oDialog.apply(this, ['option', dialogOpts]);
                        return $oDialog.apply(this, ['open']);
                    } else {
                        return $oDialog.apply(this, dialogOpts);
                    }
                }
            }

            return $oDialog.apply(this, arguments);
        };
    }
})(jQuery);

use like this in page script

// target layer in my page
var $xlsDiv = $('#xlsUpFormDiv');

$xlsDiv.dialog('clean');    // clean garbage dialog

var dialogOpts = {
    autoOpen: false,
    closeOnEscape: true,
    height: 800,
    width: 600,
    modal: true,
    buttons: ...,
    close: function() {
        $xlsForm.reset();
    }
};

// initialize original jquery ui
$xlsDiv.dialog(dialogOpts);

// open button click
$('#btnViewXlsUpForm').on("click", function() {
    $xlsDiv.dialog('open', dialogOpts);
});