2

Well in other cases i will get datepicker binded to my textbox which will be straight forward but not in this case .

Fiddle link : http://jsfiddle.net/JL26Z/1/ .. while to setup perfect seanrio i tried but unable to bind datepicker to textboxes . except that everything is in place

My code :

**<script id="Customisation" type="text/html">** // here i need to have text/html 



               <table style="width:1100px;height:40px;" align="center" >

                     <tr>

                    <input style="width:125px;height:auto;" class="txtBoxEffectiveDate" type="text" id="txtEffective" data-bind="" /> 
</tr>
    </script>

The above code is used for my dynamic generation of same thing n no of time when i click each time on a button . So above thing is a TEMPLATE sort of thing .

My knockout code :

    <div data-bind="template:{name:'Customisation', foreach:CustomisationList},visible:isVisible"></div>

<button data-bind="click:$root.CustomisatioAdd" >add </button>

I tried same old way to bind it with datepicker

$('#txtEffective').datepicker();  // in document.ready i placed 

Actually to test this i created a textbox with some id outside script with text/html and binded datepicker to it and It is working fine sadly its not working for the textbox inside text/html and i want to work at any cost.

PS: well i haven't posted my view model as it is not required in this issue based senario

View model added with Js

var paymentsModel = function ()
{
            function Customisation()
            {
                var self = this;
            }

            var self = this;
            self.isVisible = ko.observable(false);
            self.CustomisationList = ko.observableArray([new Customisation()]);
            self.CustomisationRemove = function () {
                self.CustomisationList.remove(this);
            };
            self.CustomisatioAdd = function () {
                if (self.isVisible() === false)
                {
                    self.isVisible(true);
                }
                else
                {
                    self.CustomisationList.push(new Customisation());
                }
            };
}

    $(document).ready(function()
    {

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

        ko.applyBindings(new paymentsModel());

    });

Any possible work around is appreciated

Regards

super cool
  • 6,003
  • 2
  • 30
  • 63

2 Answers2

1

Dynamic entities need to have datepicker applied after they are created. To do this I'd use an on-click function somewhere along the lines of

HTML

<!-- Note the id added here -->
<button data-bind="click:$root.CustomisatioAdd" id="addForm" >add </button>


<script>
    $(document).on('click', '#addForm', function(){
        $('[id$="txtEffective"]').datepicker();
    }); 
</script>
Community
  • 1
  • 1
Greg
  • 1,845
  • 2
  • 16
  • 26
  • well thats idea was great :) but on click of add i am performing other action i.e pushing . Well i tried `$('[id$="txtEffective"]').datepicker();` before pushing sadly it does nothing any better suggestions – super cool Jun 05 '14 at 13:12
  • Did you try the entire code block of my suggestion? The key part is that you use $(document).on('click', '#addForm', function(){} (which should work even if your button has another function), so that all newly created customisations become datepickers. – Greg Jun 05 '14 at 13:19
  • oops just tried its working in wierd way . on load datepicker not getting applied for textbox-1 when i click add the datepicker is getting applied to textbox-1 but to newly added text-box-2 datepicker is not binding and so on and when i again click datepicker applied to text-box-2 but not again to textbox-3 and it continues – super cool Jun 05 '14 at 13:31
  • sadly i tried hard to set a fiddle which demostrates excatly but i am helpless . – super cool Jun 05 '14 at 13:37
  • 1
    Then within your onclick function call $('*[id^="text-box"]').datepicker() (notice the change from the $ to ^, this will select all id's that start with "text-box") – Greg Jun 05 '14 at 13:57
  • humm i will try and let you know by tomorrow . with in this when i select date from datepicker which is attached to textbox-2 in weird way its getting set in text-box-1 .. lots of unconventional stuff going on sadly . – super cool Jun 05 '14 at 15:15
1

The best way I've found to do this is create a simple bindingHandler.

This is adapted from code I have locally, you may need to tweak it...

** code removed, see below **

Then update your template:

** code removed, see below **

By using a bindingHandler you don't need to try to hook this up later, it's done by knockout when it databinds.

Hope this is helpful.

EDIT

I created a fiddle, because I did indeed need to tweak the date picker binding quite a lot. Here's a link to the Fiddle, and here's the code with some notes. First up, the HTML:

<form id="employeeForm" name="employeeForm" method="POST">
    <script id="PhoneTemplate" type="text/html">
        <div>
            <span>
                <label>Country Code:</label>
                <input type="text" data-bind="value: countryCode"  />
            </span>
            <span><br/>
                <label>Date:</label>
                <input type="text" data-bind="datepicker: date"  />
            </span>
            <span>
                <label>Phone Number:</label>
                <input type="text" data-bind="value: phoneNumber" />
            </span>
            <input type="button" value="Remove" data-bind="click: $parent.remove" />
        </div>
    </script>
    <div>
        <h2>Employee Phone Number</h2>
        <div data-bind="template:{name:'PhoneTemplate', foreach:PhoneList}">
        </div>
        <div>
            <input type="button" value="Add Another" data-bind="click: add" />
        </div>
    </div>
</form>

Note I removed the id=... from in your template; because your template repeats per phone number, and ids must be unique to be meaningful. Also, I removed the datepicker: binding from the country code and phone number elements, and added it only to the date field. Also - the syntax changed to "datepicker: ". If you need to specify date picker options, you would do it like this:

<input type="text" data-bind="datepicker: myObservable, datepickerOptions: { optionName: optionValue }" />

Where optionName and optionValue would come from the jQueryUI documentation for datepicker.

Now for the code and some notes:

// Adapted from this answer:
// https://stackoverflow.com/a/6613255/1634810
ko.bindingHandlers.datepicker = {
    init: function(element, valueAccessor, allBindingsAccessor) {
        //initialize datepicker with some optional options
        var options    = allBindingsAccessor().datepickerOptions || {},
            observable = valueAccessor(),
            $el        = $(element);

        // Adapted from this answer:
        // https://stackoverflow.com/a/8147201/1634810
        options.onSelect = function () {
            if (ko.isObservable(observable)) {
                observable($el.datepicker('getDate'));
            }
        };

        $el.datepicker(options);

        // set the initial value
        var value = ko.unwrap(valueAccessor());
        if (value) {
            $el.datepicker("setDate", value);
        }

        //handle disposal (if KO removes by the template binding)
        ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
            $el.datepicker("destroy");
        });
    },
    update: function(element, valueAccessor) {
        var value = ko.utils.unwrapObservable(valueAccessor()),
            $el = $(element);

        //handle date data coming via json from Microsoft
        if (String(value).indexOf('/Date(') === 0) {
            value = new Date(parseInt(value.replace(/\/Date\((.*?)\)\//gi, "$1")));
        }

        var current = $el.datepicker("getDate");

        if (value - current !== 0) {
            $el.datepicker("setDate", value);
        }
    }
};

function Phone() {
    var self = this;

    self.countryCode = ko.observable('');
    self.date        = ko.observable('');
    self.phoneNumber = ko.observable('');
}  

function PhoneViewModel() {
    var self = this;
    self.PhoneList = ko.observableArray([new Phone()]);
    self.remove = function () {
        self.PhoneList.remove(this);
    };
    self.add = function () {
        self.PhoneList.push(new Phone());
    };
}

var phoneModel = new PhoneViewModel();

ko.applyBindings(phoneModel);

Note the very updated binding handler which was adapted from this answer for the binding, and this answer for handling onSelect.

I also included countryCode, date, and phoneNumber observables inside your Phone() object, and turned your model into a global variable phoneModel. From a debugger window (F12 in Chrome) you can type something like:

phoneModel.PhoneList()[0].date()

This will show you the current value of the date.

I notice that your form is set up to post somewhere. I would recommend instead that you add a click handler to a "Submit" button and post the values from your phoneModel using ajax.

Hope this edit helps.

Community
  • 1
  • 1
Paul
  • 1,502
  • 11
  • 19
  • i will look into it . looks hopeful – super cool Jun 06 '14 at 07:05
  • mate well i made things to works but small minor issue when i select date-picker from in what ever textbox the date is getting entered into text-box-1 only not into selected textbox example : when i select date from txtbox-3 the selected date coming at text-box one . My updated fiddle : http://jsfiddle.net/JL26Z/7/ – super cool Jun 06 '14 at 07:33
  • Thnkx a lot Paul , I need the onselect event, thnx for correct answer – D S Jul 28 '15 at 14:47