Табуляция и прямой ввод в UIBootstrap и Angularjs datepicker

Мы работаем над SPA с использованием Angularjs и Breeze на основе шаблона HotTowel

У нас есть несколько datePickers на странице, которые вызывают следующие проблемы:

  • Когда пользователь входит в средство выбора даты, средство выбора даты открывается, но не закрывается, когда пользователь переходит к следующему элементу управления. Поскольку датпикеры располагаются в одном столбце пользовательского интерфейса, это приводит к тому, что раскрывающийся список покрывает поля ниже. Единственный способ очистить их - выбрать дату или щелкнуть в другом месте формы.

  • Пользователь не может ввести дату в область ввода при редактировании существующей записи, привязанной к модели данных. Если они выделят дату и попытаются ввести ее, она удалит существующую дату и не позволит пользователю ввести новую. Если они нажмут X, чтобы очистить поле ввода, они не смогут ввести новую дату. Если они поместят курсор в конец даты и обратный пробел, дата исчезнет, ​​а в окне выбора календаря будет установлено значение января 1902 года.

По сути, это нормально, если пользователи готовы взять мышь и щелкнуть дату в средстве выбора и никогда не пытаться ввести дату. Это нереально для нашего сообщества пользователей.

Вот 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>

Мы используем двустороннюю привязку с ng-моделью.

Любая помощь будет оценена.

Спасибо


person jwgreg    schedule 13.02.2014    source источник
comment
Меня тоже беспокоит то же самое. Решали когда-нибудь эту проблему?   -  person zszep    schedule 06.03.2014
comment
Мы были заняты другими вопросами и пока не нашли хорошего решения. Однако мы вернемся к этому в ближайшие пару недель. Когда решение будет найдено, я опубликую его здесь. Мы почти уверены, что это результат двухсторонней привязки.   -  person jwgreg    schedule 06.03.2014
comment
Прямо сейчас я тоже занимаюсь исследованиями. Я думаю, что иду по правильному пути, поэтому, как только у меня что-то будет, я тоже опубликую.   -  person zszep    schedule 07.03.2014
comment
Вы когда-нибудь находили решение этой проблемы?   -  person sharpmachine    schedule 30.08.2015


Ответы (3)


Была та же проблема, и я нашел проблемный код: это строка 4786 в 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;
}

Проблема в том, что программа angulars dirty checker выполняет просто ===, поэтому в конце она перезаписывает значение представления, потому что оно не такое же, как в модели (потому что ветер пропускает обновление). если вы опустите часть после || вы можете вводить значения как обычно, хотя тогда я столкнулся с другим набором проблем.

Это несоответствие между взглядом angular на данные и легкостью. Надеюсь, Уорд это видит. Я куплю билет. Не уверен, что было бы хорошим местом для этого, но я думаю, что ветер будет единственным (потому что angular отлично работает с pojos). Я бы обновил ссылку без побочных эффектов самого обновления.

person Bruno Altinet    schedule 21.05.2014

Мне нужно поработать репродукцию, если вы хотите, чтобы я разобрался с этим. Было бы неплохо что-нибудь в плункере.

Я не думаю, что мы можем изменить наш тест собственности. Мы пошли на такие неприятности по уважительной причине. В Angular нет понятия DataType, поэтому он не может делать то, что делаем мы.

Но мы должны прийти к подходящему решению, возможно, с использованием Angular. Например, вы можете написать для этого тривиальную директиву. Возможно, вы сможете справиться с этим с существующим Ng; Я смутно припоминаю, что вы можете указать парсер привязки, который может дублировать логику бриза. Прошло слишком много времени с тех пор, как я смотрел на это, но я думаю, что оно есть.

person Ward    schedule 24.12.2014

Я столкнулся с той же проблемой и решил ее, создав переменную-заполнитель с локальной областью видимости в модели представления для привязки к средству выбора даты.

<input type="text"
    class="form-control"
    datepicker-popup="M/d/yyyy"
    is-open="vm.openedStartDate"
    ng-model="vm.selectedStartDate"
    close-text="Close"
    show-button-bar="false" />

Это обеспечивает желаемое поведение датпикера.

Затем я устанавливаю значение объекта Breeze для этой локальной переменной непосредственно перед сохранением изменений:

 task.StartDate = vm.selectedStartDate;
 task.EndDate = vm.selectedEndDate;
 datacontext.saveChanges();

Это не идеально, но это жизнеспособное решение проблемы, которую вы описываете.

person Brandon Johnson    schedule 25.08.2015