最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Why I can't use datepicker twice in the same table? - Stack Overflow

programmeradmin0浏览0评论

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.

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.

Share Improve this question edited Oct 17, 2013 at 7:21 Slim asked Oct 17, 2013 at 7:07 SlimSlim 1,7445 gold badges38 silver badges60 bronze badges 6
  • 2 because you creating datepicker for id: $( "#AssimilationDate" ).datepicker, thy to add class selector: $( ".AssimilationDate" ).datepicker and in form also <td><input type="text" name="AssimilationDate" id="AssimilationDate" class="AssimilationDate" data-bind="event: { mouseover: assimilationDatePicker}, value: AssimilationDate"></td> – krasu Commented Oct 17, 2013 at 7:11
  • @krasu it worked, but, now it updates only the value of the 1st box :( – Slim Commented Oct 17, 2013 at 7:13
  • assimilationDatePicker = ... - is global objcet, try this this.assimilationDatePicker = ..., I don't have expertise with knockout.js, so don't sure it will help – krasu Commented Oct 17, 2013 at 7:15
  • still the same. Thanks for trying to help me!!! – Slim Commented Oct 17, 2013 at 7:18
  • any chance to have jsfiddle demo? – krasu Commented Oct 17, 2013 at 7:19
 |  Show 1 more comment

7 Answers 7

Reset to default 6 +100

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.

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

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

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

Cheers

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....

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.

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

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

发布评论

评论列表(0)

  1. 暂无评论