7

I know that there are simmilar questons, but I really can't find an answer fitting on my issue.

I have this HTML table witch is looping trough an array - defined in my viewModel:

<div class="formElement" id="AssimilationDT" style="overflow-x: auto; width: 100em;">           
               <table class="dataTable">
<thead>
    <tr>
        <th> 1 </th>
        <th> 2 </th>
        <th> 3</th>
        <th> 4</th>
        <th> 5</th>
        <th> 6</th>
        <th> 7</th>
        <th> 8</th>
        <th> 9</th>
        <th> 10</th>
        <th> 11</th>
        <th> 12/th>
        <th> 13</th>
        <th> 14</th>
        <th> 15</th>
        <th> 16</th>
        <th></th>
    </tr>   
</thead>
<tbody data-bind="foreach: assimilationRows">
    <tr>
        <td><input type="text" name="AssimilationDate" id="AssimilationDate" data-bind="event: { mouseover: assimilationDatePicker}, value: AssimilationDate"></td>
        <td><input type="text" name="InvoiceSum" data-bind="value: InvoiceSum"></td>
        <td><input type="text" name="FondAssimAmm" data-bind="value: FondAssimAmm"></td>
        <td><input type="text" name="FondSgebFondPerc" data-bind="value: FondSgebFondPerc"></td>
        <td><input type="text" name="FondWholeAssimPerc" data-bind="value: FondWholeAssimPerc"></td>
        <td><input type="text" name="SgebAssimAmm" data-bind="value: SgebAssimAmm"></td>
        <td><input type="text" name="SgebFondSgeb" data-bind="value: SgebFondSgeb"></td>
        <td><input type="text" name="SgebWholeAssimPerc" data-bind="value: SgebWholeAssimPerc"></td>
        <td><input type="text" name="FondSuppl" data-bind="value: FondSuppl"></td>
        <td><input type="text" name="FondSupplNum" data-bind="value: FondSupplNum"></td>
        <td><input type="text" name="FondSupplInvNum" data-bind="value: FondSupplInvNum"></td>
        <td><input type="text" name="FondDesc" data-bind="value: FondDesc"></td>
        <td><input type="text" name="SgebSuppl" data-bind="value: SgebSuppl"></td>
        <td><input type="text" name="SgebSupplNum" data-bind="value: SgebSupplNum"></td>
        <td><input type="text" name="SgebSupplInvNum" data-bind="value: SgebSupplInvNum"></td>
        <td>
                <img src="/HDSHubCreditMonitoring/js/images/close.jpg" alt="Close" data-bind="click: $root.removeAssimilationRow"> 
        </td>
    </tr>
</tbody>
</table>
<button type="button" id="newSupplierRow" class="button" data-bind="click: newAssimilationRow">Добави Ред</button>
           </div>

what I have in my viewModel is the below code - containing the table rows and it is supposed to execute the .datepicker:

AssimilationInfo = function(clientNum){
                    this.AssimilationDate = null;
                    this.InvoiceSum = null;
                    this.FondAssimAmm = null;
                    this.FondSgebFondPerc = null;
                    this.FondWholeAssimPerc = null;
                    this.SgebAssimAmm = null;
                    this.SgebFondSgeb = null;
                    this.SgebWholeAssimPerc = null;
                    this.FondSuppl = null;
                    this.FondSupplNum = null;
                    this.FondSupplInvNum = null;
                    this.FondDesc = null;
                    this.SgebSuppl = null;
                    this.SgebSupplNum = null;
                    this.SgebSupplInvNum = null;
                    this.SgebDesc = null;
                    assimilationDatePicker = (function() {
                        $( "#AssimilationDate" ).datepicker({
                            yearRange: "-20:+100",
                            changeMonth: true,
                            changeYear: true,
                            dateFormat: "d-M-y"
                        });
                    });
                },

AND

newAssimilationRow = function (){
                      this.assimilationRows.push(new AssimilationInfo(this.clientNumber()));
                  },

                  removeAssimilationRow = function (ca){
                      assimilationRows.remove(ca);
                  },

The above functions are adding, or removing a rows in the HTML table. The problem I'm facing is that the .datepicker is working only on the 1st table row - if I add another row, it is just not working.

I'm pretty sure that I can't call it correctly, but I'm not able to spot the issue as a beginner. Is there a way to call the datepicker on every table row?

UPDATE

I added

assimilationDatePicker = (function() {
                        $( ".AssimilationDate" ).datepicker({
                            yearRange: "-20:+100",
                            changeMonth: true,
                            changeYear: true,
                            dateFormat: "d-M-y"
                        });
                    });

and now it shows on every row, but only the value of the 1st row input is updated.

Slim
  • 1,708
  • 5
  • 37
  • 60

7 Answers7

6

The problem you are facing after update is in using same id for all your datepickers. You should remove id from datepicker element and then jquery-ui will generate it automatically and everything will work. I've modified a bit jsbin code of @Kishorevarma to demonstrate it.


Also, I recommend you to use custom binding for datepicker, here is good example of it.

ko.bindingHandlers.datepicker = {
    init: function(element, valueAccessor, allBindingsAccessor) {
        //initialize datepicker with some optional options
        var options = allBindingsAccessor().datepickerOptions || {},
            $el = $(element);

        $el.datepicker(options);

        //handle the field changing
        ko.utils.registerEventHandler(element, "change", function () {
            var observable = valueAccessor();
            observable($el.datepicker("getDate"));
        });

        //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);
        }
    }
};

Then you'll just need to replace your input with

<input data-bind="datepicker: myDate, datepickerOptions: {
                        yearRange: "-20:+100",
                        changeMonth: true,
                        changeYear: true,
                        dateFormat: "d-M-y"
                    }" />

This is much cleaner and more readable than using mouseover event.

Community
  • 1
  • 1
dIsoVi
  • 869
  • 7
  • 14
3

If you call datepicket using ID, it will work for only one element. You need to set a common class for the elements, which needs to show a datepicket, something like below

suppose, you set the class like class="datepicketTxt"

then call the datepicker like this

                    $( ".datepicketTxt").datepicker({
                        yearRange: "-20:+100",
                        changeMonth: true,
                        changeYear: true,
                        dateFormat: "d-M-y"
                    });
Nauphal
  • 6,194
  • 4
  • 27
  • 43
2

Your question's answer is quite obvious one i am explaining my answer by giving example you have one element and one jquery like this one

<input type="text" name="AssimilationDate" id="AssimilationDate" data-bind="event: { mouseover: assimilationDatePicker}, value: AssimilationDate">

right? now if you see that your id is AssimilationDate But problem is that one control have one unique id per page so this can not be possible

now what to do? i am taking two inputs now

<input type="text" name="AssimilationDate" id="AssimilationDate" class="Assimilation" data-bind="event: { mouseover: assimilationDatePicker}, value: AssimilationDate">


 <input type="text" name="AssimilationDate1" class="Assimilation"  id="AssimilationDate1" data-bind="event: { mouseover: assimilationDatePicker}, value: AssimilationDate">

and your javascript function will looks like this one

assimilationDatePicker = (function() {
                        $( ".Assimilation" ).datepicker({
                            yearRange: "-20:+100",
                            changeMonth: true,
                            changeYear: true,
                            dateFormat: "d-M-y"
                        });
                    });

This is only for two controls you can multiply it n times using class so if one control you want to use then just use id and if multiple then use same class in multiple ids i hope this will help to get your solution regards....

Just code
  • 13,553
  • 10
  • 51
  • 93
2

I hope this will solve your problem for sure. I have written a sample code here

 http://jsbin.com/UgELONO/2/edit

Cheers

Kishorevarma
  • 936
  • 6
  • 23
2

There can only be a single ID per page, which must be unique, use a class as the selector for multiple elements when applying datepicker.

Mike Lyons
  • 1,748
  • 2
  • 20
  • 33
1

Change the content of the function "assimilationDatePicker" to

   $(arguments[1].target).datepicker({
                yearRange: "-20:+100",
                changeMonth: true,
                changeYear: true,
                dateFormat: "d-M-y"
            });

You can read up on the document here regarding the arguments passed when you use the Event binding

http://knockoutjs.com/documentation/event-binding.html

eggward
  • 345
  • 1
  • 5
1

use different <script></script> tag for every call.

Ankit
  • 4,755
  • 2
  • 22
  • 14