Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UIBootstrap and Angularjs datepicker tabbing and direct entry

We are working on a SPA using Angularjs and Breeze based on the HotTowel template

We have multiple datePickers on the page that are giving us the following problems:

  • When the user tabs into a datepicker the datepicker opens but will not close when the user tabs to the next control. Since the datepickers are stacked in the same column of the ui, this causes the dropdown to cover the fields below. The only way to clear them is to select a date or click elsewhere on the form

  • The user cannot key a date into the input area when editing an existing record that is bound to the data model. If they highlight the date and try to enter it, it erases the existing date and will not allow the user key a new one. If they click the X to clear the input field, they cannot key a new date. If they position their cursor at the end of the date, and backspace, the date disappears and the calendar picker is set to January of 1902.

Essentially, this fine if the users are willing to pick up a mouse and click a date in the picker and never try to enter a date. That is not realistic for our user community.

Here is the html:

                                <label for="ApplicationCompleteDate" data-ng-show="vm.mode === 'edit'"><strong>Application Complete Date:</strong></label>
                            <div class="input-append" data-ng-show="vm.mode === 'edit'">
                                <span>
                                    <input name="ApplicationCompleteDate" type="text" class="form-control input-medium" tabindex="16" placeholder="{{vm.format}}"
                                           datepicker-popup="{{vm.format}}" close-text="Close" show-weeks='false'
                                           is-open="vm.applicationCompleteDateOpened"
                                           datepicker-options="vm.dateOptions"
                                           data-ng-model="vm.formData.dateApplicationComplete"
                                           data-ng-required="vm.applicationCompleteDateRequired"
                                           data-ng-readonly="(!user.isInUserGroup && vm.mode === 'new') || (!user.isInCPUGroup && vm.mode === 'edit')" />
                                </span>
                                <span class="add-on">
                                    <a href="#" data-ng-click="vm.applicationCompleteDateOpen($event)"><i class="icon-calendar"></i></a>
                                </span>
                            </div>
                            <label for="DecisionDatePicker" data-ng-show="vm.mode === 'edit'"><strong>Decision Date:</strong></label>
                            <div class="input-append" data-ng-show="vm.mode === 'edit'">
                                <span>
                                    <input name="DecisionDatePicker" id="ddpID" type="text" class="form-control input-medium" tabindex="14" placeholder="{{vm.format}}"
                                           datepicker-popup="{{vm.format}}" close-text="Close" show-weeks='false'
                                           is-open="vm.decisionDateOpened"
                                           datepicker-options="vm.dateOptions"
                                           data-ng-model="vm.formData.dateDecision"
                                           data-ng-required="vm.decisionDateRequired"
                                           data-ng-readonly="(!user.isInUserGroup && vm.mode === 'new') || (!user.isInCPUGroup && vm.mode === 'edit')" />
                                </span>                                    
                                <span class="add-on">
                                    <a href="#" data-ng-click="vm.decisionDateOpen($event)"><i class="icon-calendar"></i></a>
                                </span>
                            </div>
                            <label for="DateClosedPicker" data-ng-show="vm.mode === 'edit'"><strong>Closed Date:</strong></label>
                            <div class="input-append" data-ng-show="vm.mode === 'edit'">
                                <span>
                                    <input name="DateClosedPicker" type="text" class="form-control input-medium" tabindex="15" placeholder="{{vm.format}}"
                                           datepicker-popup="{{vm.format}}" close-text="Close" show-weeks='false'
                                           is-open="vm.dateClosedOpened"
                                           datepicker-options="vm.dateOptions"
                                           data-ng-model="vm.formData.dateClosed"
                                           data-ng-required="false"
                                           data-ng-readonly="(!user.isInUserGroup && vm.mode === 'new') || (!user.isInCPUGroup && vm.mode === 'edit')" />
                                </span>                                    
                                <span class="add-on">
                                    <a href="#" data-ng-click="vm.dateClosedOpen($event)"><i class="icon-calendar"></i></a>
                                </span>
                            </div>

We are using two-way binding with ng-model.

Any help would be appreciated.

Thanks

like image 215
jwgreg Avatar asked Nov 02 '22 05:11

jwgreg


1 Answers

Had the same problem and i found the problematic code: it's line 4786 in breeze.debug.js

    // exit if no change - extra cruft is because dateTimes don't compare cleanly.
if (newValue === oldValue || (dataType && dataType.isDate && newValue && oldValue && newValue.valueOf() === oldValue.valueOf())) {
    return;
}

Problem is that angulars dirty checker is doing just === so in the end it overwrites the view value because it's not the same as in the model (because breeze skips the update). if you omit the part after || you can enter values normally, altough i then ran into a different set of problems.

This is a mismatch between angular's way of looking at data and breeze. I hope Ward sees this. I'll pull up a ticket. Not sure what would be a good place to handle it, but i think breeze would be the one (because angular works fine with pojos). I would update the reference without the sideffects of the update itself.

like image 71
Bruno Altinet Avatar answered Nov 10 '22 04:11

Bruno Altinet