Подтверждение нокаута и Qtip - PullRequest
5 голосов
/ 17 февраля 2012

В настоящее время я использую Jquery Validation и Qtip вместе, чтобы справиться с фактической проверкой и отображением информации на экране, используя приятные подсказки стиля подсказок при ошибках проверки с использованием компонента errorPlacement опций проверки.

viewModel имеет свой собственный пользовательский метод для настройки и запуска проверки и обратных вызовов, однако я пытался найти более хороший способ сделать это, будь то добавление пользовательской привязки для настройки моих правил проверки через привязки данных или альтернативныйкстати, но все равно дает те же результаты (то есть errorPlacement запускается при возникновении ошибки проверки и сообщает Qtip, что нужно отобразить ошибку для данного элемента).

Теперь, прежде чем я сам приступил к созданию, я только что проверил онлайн иfound Knockout Validation , который я изначально считал хорошей идеей, я мог бы применить свою логику проверки непосредственно к данным в моей viewModel, а затем просто найти какой-то обратный вызов для получения Qtip, чтобы пнуть, однако кажется, что нет никакого обратного вызова, который я могу найти документированным.Библиотека, кажется, делает все, что я хочу, для проверки правильности, а не для отображения.Я просмотрел исходный код и примеры, но не увидел ничего, кроме ko.validation.group (viewModel), который дал бы мне наблюдаемую информацию, содержащую ошибки, но я не уверен, смогу ли я использовать это так же, как и яОжидается.

Вот пример того, как происходит моя текущая проверка:

/*globals $ ko */
function SomeViewModel() {

    this.SetupValidation = function () {
        var formValidationOptions = {
            submitHandler: self.DoSomethingWhenValid,
            success: $.noop,
            errorPlacement: function (error, element) {
                if (!error.is(':empty'))
                { qtip.DoSomethingToDisplayValidationErrorForElement(element, error); }
                else
                { qtip.DoSomethingToHideValidationErrorForElement(element); }
            }
        };

        $(someForm).validate(formValidationOptions);
        this.SetupValidationRules();
    };

    this.SetupValidationRules = function() {
        $(someFormElement1).rules("add", { required: true, minlength: 6, maxlength: 20, alphaNumeric: true });
        $(someFormElement2).rules("add", { required: true, minlength: 6, maxlength: 20 });
        $(someFormElement3).rules("add", { required: true, email: true, });
    };
}

В настоящее время я уверен, что могу устранить потребность в методе правил проверки, добавив пользовательскую привязку, чтобы я могустановите валидацию в привязке данных, однако, если возможно, я бы хотел использовать такой же подход обратного вызова с существующей привязкой Knockout-Validation.

Ответы [ 2 ]

5 голосов
/ 24 февраля 2012

Я не использовал Knockout-Validation специально, но в прошлом написал нечто подобное.Быстрый взгляд на источник показывает, что каждая расширенная наблюдаемая получает суб-наблюдаемую isValid .Это может быть использовано для скрытия сообщений show в вашей разметке с использованием обычных видимых привязок нокаута.

Чтобы заставить QTip работать, пользовательская привязка может подписаться на это свойство isValid и выполнить необходимую инициализацию для отображения / скрытия QTip при запуске.

РЕДАКТИРОВАТЬ

Вот пример для начала

http://jsfiddle.net/madcapnmckay/hfcj7/

HTML:

<!-- Note that you have to reference the "qtipValMessage" binding -->
<!-- using the "value" binding alone is not enough                -->
<input data-bind="value: emailAddress, qtipValMessage : emailAddress" />

JS:

ko.bindingHandlers.qtipValMessage = {
    init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
        var observable = valueAccessor(), $element = $(element);
       if (observable.isValid) {
            observable.isValid.subscribe(function(valid) {
                if (!valid) {
                    $element.qtip({
                        overwrite: true,
                        content: {
                            text: observable.error
                        }
                     });
                 } else {
                     $element.qtip("destroy");
                 }
           });
       }
    }
};
1 голос
/ 13 марта 2013

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

Это в значительной степени основано на посте madcapnmckay, но исправляет ошибку, указанную MorganTiley,Оригинал работает, только если пользователь изменил наблюдаемое.Если нет, то код никогда не запускается.Итак, я изменил его так, чтобы он запускал код всплывающей подсказки при его создании, а также при изменении.

ko.bindingHandlers.qtipValMessage = {
    init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
        var observable = valueAccessor(), $element = $(element);
        if (observable.isValid) {
            var updateTooltip = function (valid) {
                if (!valid) {
                    $element.qtip({
                        overwrite: true,
                        content: {
                            text: observable.error
                        }
                    });
                } else {
                    $element.qtip("destroy");
                }
            }
            updateTooltip();
            observable.isValid.subscribe(updateTooltip);
        }
    }
};

Единственным недостатком является то, что всплывающая подсказка будет отображаться при наведении, прежде чем проверка выбивания будет иметьбыл выполнен (например, у вас есть «обязательная» проверка в поле, перед тем, как вы нажмете «Отправить», появится всплывающая подсказка о том, что поле является обязательным, но поле не будет выделено розовым цветом).Однако, как только вы измените поле, всплывающая подсказка исчезнет, ​​если поле действительно.

Мое приложение не использовало qtip, а скорее всплывающую подсказку Twitter Bootstrap, так что здесь также есть код для этого.

ko.bindingHandlers.invalidTooltip = {
    init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
        var observable = valueAccessor(), $element = $(element);
        if (observable.isValid) {
            var updateTooltip = function (valid) {
                if (!valid) {
                    $element.attr("data-original-title", observable.error);
                    $element.tooltip();

                } else {
                    $element.tooltip("destroy");
                }
            }
            updateTooltip();
            observable.isValid.subscribe(updateTooltip);
        }
    }
};
...