4

I am trying to override my datepicker plugin and implement my own custom datepicker. I'm putting my code in a global js file in order to override as soon as the page loads.

(function($) {
    var originalVal = $.fn.datepicker;
    $.fn.datepicker = function(val1, val2, val3) {
        console.log(val1); // option
        console.log(val2); // maxDate
        console.log(val3); // 09/06/2017
        // var dp = originalVal.clone();
        // console.log(dp);
        var _options = {
            changeYear: true,
            changeMonth: true
        }

        if (val1 == "option") {
            _options[val2] = val3
            console.log(_options[val2]);
        }
        else {
            _options = $.extend(_options, val1)
        }

        console.log(_options); //Object { changeYear: true, changeMonth: true, maxDate: Date 2017-09-06T06:52:32.449Z }

        return originalVal.call(this, _options);
    };
})(jQuery);

This works perfectly as the page loads and changeYear and changeMonth is available along with restriction of max date as 09/06/2017.

Here is my page code:

</head>
<body>
    <input type="text"  id="pickDate2" >
    <input type="text"  id="pickDate3" >
    <script>
    $("#pickDate2").datepicker();
    $("#pickDate3").datepicker('option','maxDate',new Date());
    $("#pickDate2").change(function(){
        var val = $(this).val();
        $("#pickDate3").datepicker('option','minDate',Date.parse(val));
    })
    </script>
</body>
</html>

Now, after the page loads, when the below code is executed, min date is not set

$("#pickDate2").change(function(){
    var val = $(this).val();
    $("#pickDate3").datepicker('option','minDate',09/03/2017);
})

When, I check the console for my plugin override code, the parameters seem to be fine.

console.log(_options);//Object { changeYear: true, changeMonth: true, minDate: Date 2017-09-03T18:15:00.000Z }

As far as I know, the JavaScript call function is not executing the second time. I couldn't find anything concrete since I searched the web for it. I want the plugin to accept parameters the second time as well.

3
  • In the above, you never initialize the datepicker on #pickDate3. Commented Sep 6, 2017 at 8:55
  • Yes i did, above my change function Commented Sep 6, 2017 at 8:56
  • No. $("#pickDate3").datepicker('option','maxDate',new Date()); is a method call, not an initialization. It's ignored if you do it on an element that has never had a datepicker initialized on it. Commented Sep 6, 2017 at 8:58

1 Answer 1

1

Your code calls the original datepicker function, but always as though it were initializing a datepicker from scratch. You're intercepting an "option" call and turning it into an init call. Clearly, it doesn't allow multiple initializations.

Instead, you need to detect whether an initialization or "method" call is being made, and do the method call if it's a method call. Separately, there's no need for you to intercept "option" unless it's setting changeYear or changeMonth to something you don't want.

Something along these lines (further tweaking may be needed):

(function($) {
    var originalVal = $.fn.datepicker;
    $.fn.datepicker = function(val1, val2, val3) {
        if (val1 === "option") {
            if (val2 === "changeYear" || val2 === "changeMonth") {
                return this; // Ignore it
            }
        }
        if (typeof val1 === "string") {
            // Method call, pass through
            return originalVal.apply(this, arguments); 
        }
        // Init call, ensure our options are set and pass it on
        var _options = $.extend({}, val1, {
            changeYear: true,
            changeMonth: true
        });
        return originalVal.call(this, _options);
    };
})(jQuery);

The above works for me. Here's your example without the change above, just with normal jQuery and jQuery UI (I added the missing $("#pickDate3").datepicker();):

$("#pickDate2").datepicker();
$("#pickDate3").datepicker();
$("#pickDate3").datepicker('option', 'maxDate', new Date());
$("#pickDate2").change(function() {
  var val = $(this).val();
  $("#pickDate3").datepicker('option', 'minDate', Date.parse(val));
})
<link href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.css" rel="stylesheet"/>

<input type="text" id="pickDate2">
<input type="text" id="pickDate3">

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>

And here it is with the change above; note that your changeYear and changeMonth options are added as intended, and the maxDate change is also respected when we change the first input:

(function($) {
    var originalVal = $.fn.datepicker;
    $.fn.datepicker = function(val1, val2, val3) {
        if (val1 === "option") {
            if (val2 === "changeYear" || val2 === "changeMonth") {
                return this; // Ignore it
            }
        }
        if (typeof val1 === "string") {
            // Method call, pass through
            return originalVal.apply(this, arguments); 
        }
        // Init call, ensure our options are set and pass it on
        var _options = $.extend({}, val1, {
            changeYear: true,
            changeMonth: true
        });
        return originalVal.call(this, _options);
    };
})(jQuery);
$("#pickDate2").datepicker();
$("#pickDate3").datepicker();
$("#pickDate3").datepicker('option', 'maxDate', new Date());
$("#pickDate2").change(function() {
  var val = $(this).val();
  $("#pickDate3").datepicker('option', 'minDate', Date.parse(val));
})
<link href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.css" rel="stylesheet"/>

<input type="text" id="pickDate2">
<input type="text" id="pickDate3">

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>

Sign up to request clarification or add additional context in comments.

7 Comments

@T.J.Cowder , the apply function on method call didn't help as well, issue is same as before. Wouldn't apply be same as call in this case?
@SauravDangol: No. The apply above passes along the original arguments unchanged. But the main change above was properly handling a method call vs. an initialization. I'm very surprised that didn't work, what lib is this?
,my datepicker version is 1.8.24.Also, Im being blunt here, correct me if im wrong, im passing arguments as follows: if (typeof val1 === "string") { var option = {} option[val2] = val3 return originalVal.apply(this, [option]); }
@SauravDangol: Version of what datepicker? jQuery UI? Some other one? Re the code: No, you're not passing them along, you're converting a call with (string, string, value) to a call with (object), which is seen as an init call. That's why I changed that above, so that when doing a "method" call, we continue to pass (string, string, value).
the initialization seemed to be the problem as you suggested. It worked as expected now. Appreciate your time and effort.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.