0

I'm using Magento 2.4.1 and i successfully add datepicker in checkout page like this:

js file

define([
    'jquery',
    'ko',
    'Magento_Ui/js/form/element/abstract',

], function ($, ko, Component) {
    'use strict';
    return Component.extend({
        initialize: function () {
            this._super();
            ko.bindingHandlers.datepicker = {
                init: function (element, valueAccessor, allBindingsAccessor) {
                    var $el = $(element);
                    var writable = valueAccessor();
                    if (!ko.isObservable(writable)) {
                        var propWriters = allBindingsAccessor()._ko_property_writers;
                        if (propWriters && propWriters.datepicker) {
                            writable = propWriters.datepicker;
                        } else {
                            return;
                        }
                    }
                    writable($(element).val());
                },
                update: function (element, valueAccessor) {
                    var widget = $(element).data("DatePicker");

                    if (widget) {
                        var date = ko.utils.unwrapObservable(valueAccessor());
                        widget.date(date);
                    }

                }
            };
            return this;
        }
    });
});

html file

<div class="deliver-date-container">
  <input class="input-text" type="text" data-bind="
      event: {change: userChanges},
      hasFocus: focused,
      value: value,
      datepicker: true,
      attr: {
          name: inputName,
          placeholder: placeholder,
          'aria-describedby': noticeId,
          disabled: disabled
      }" readonly="true" name="ddate" />
</div>

In another JS file i tried to set the value like this:

$('[name="ddate"]').datepicker('setDate', customDate);

but when i submit the form it always get an empty error enter image description here

1 Answer 1

0

I have used recently a datepicker custom binding script similar to yours, see below:

define([
    'jquery',
    'ko',
    'uiComponent',
    'mage/translate',
    'underscore',
], function ($, ko, Component, $t, _) {
    'use strict';

    return Component.extend({
        defaults: {
            template: 'Mbs_DatePicker/shipping-datepicker',
            selectedShipmentDates: ko.observable([])
        },
        initialize: function () {
            this._super();
            this.initDatepicker();
        },
        initDatepicker: function () {
            var defaults = {};
            var self = this;

            ko.bindingHandlers.datepicker = {
                /**
                 * Initializes calendar widget on element and stores it's value to observable property.
                 * Datepicker binding takes either observable property or object
                 *  { storage: {ko.observable}, options: {Object} }.
                 * For more info about options take a look at "mage/calendar" and jquery.ui.datepicker widget.
                 * @param {HTMLElement} el - Element, that binding is applied to
                 * @param {Function} valueAccessor - Function that returns value, passed to binding
                 */
                init: function (el, valueAccessor) {
                    var config = valueAccessor(),
                        observable,
                        options = {
                            datepicker: { storage: 'deliveryDate', options: options },
                            valueUpdate: 'deliveryDate',
                            attr: {
                                value: 'deliveryDate',
                                name: 'shipment_date'
                            }
                        };

                    defaults = {}

                    _.extend(options, defaults);

                    if (typeof config === 'object') {
                        _.extend(options, config.options);
                    } else {
                        observable = config;
                    }

                    require([
                        'mage/calendar'
                    ], function (shipping) {
                        $(el).calendar(options);

                        ko.utils.registerEventHandler(el, 'change', function () {
                            $.event.trigger({type: "setShipmentDate", date: this.value});
                        });
                    });
                },

                /**
                 * Update calendar widget on element and stores it's value to observable property.
                 * Datepicker binding takes either observable property or object
                 *  { storage: {ko.observable}, options: {Object} }.
                 * @param {HTMLElement} element - Element, that binding is applied to
                 * @param {Function} valueAccessor - Function that returns value, passed to binding
                 */
                update: function (element, valueAccessor) {
                    var config = valueAccessor(),
                        $element = $(element),
                        observable,
                        options = {},
                        newVal;

                    _.extend(options, defaults);

                    if (typeof config === 'object') {
                        observable = config.storage;
                        _.extend(options, config.options);
                    } else {
                        observable = config;
                    }
                }
            };
        }
    });
});

in this script, the line $.event.trigger({type: "setShipmentDate", date: this.value}); is what I used to propagate the datepicker value to my system

the other part of the code was looking like this:

var mixin = {
        initialize: function () {
            var self = this;
            this._super();

            $(document).on('setShipmentDate', function (e) {
                localStorage.setItem('shipment_date', e.date);
            });
        },....

As you can see, my work around is to use the localStorage when the datepicker value gets selected. Then, in your javascript, you can listen to this event triggered using the snippet just above.

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.