воскресенье, 8 июля 2012 г.

Ограничиваем ввод только цифрами с помощью кастомного биндинга Knockout

Я уже писал как можно применить кастомный биндинг, чтоб прицепить jquery datepicker. Сегодня я покажу еще один пример.
Иногда возникает необходимость ограничить пользовательский ввод по какому-то критерию, например разрешить вводить только цифры или только текст без цифр, если это имя или город.
В данной статье я покажу как ограничить ввод только цифрами, но в дальнейшем можно будет развить эту тему и фильтровать на основе какого-нибудь дополнительного критерия.
Решение по фильтрации я не изобретал и взял первое попавшееся на stackoverflow. Его мы и будем использовать.

Начнем с написания кастомного биндинга.

 ko.bindingHandlers.inputFilter = {
        init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
            var filter = ko.utils.unwrapObservable(valueAccessor());

            if (filter == 'Numbers') {
                $(element).keydown(function (event) {
                    // Allow: backspace, delete, tab, escape, and enter
                    if (event.keyCode == 46 || event.keyCode == 8 || event.keyCode == 9 || event.keyCode == 27 || event.keyCode == 13 ||
                    // Allow: Ctrl+A
            (event.keyCode == 65 && event.ctrlKey === true) ||
                    // Allow: home, end, left, right
            (event.keyCode >= 35 && event.keyCode <= 39)) {
                        // let it happen, don't do anything
                        return;
                    }
                    else {
                        // Ensure that it is a number and stop the keypress
                        if (event.shiftKey || (event.keyCode < 48 || event.keyCode > 57) && (event.keyCode < 96 || event.keyCode > 105)) {
                            event.preventDefault();
                        }
                    }
                });
            }

        },
        update: function (element, valueAccessor, allBindingsAccessor, viewModel) {
            // we don't need update.
        }
    };

function CarViewModel (){
   this.Age = ko.observable(10);
};

var car = new CarViewModel();
ko.applyBindings(car);

Ну и рабочий пример.


Тут ничего военного не появилось, все тот же init и update. В инит находится код, который я полностью скопировал с ответа на stackoverflow.
Если вы посмотрите на html, то увидите там строчку:

data-bind="value: Age, inputFilter: 'Numbers'

Это значит что мы хотим связать наш инпут со значением поля Age и добавляем наш кастомный биндинг с параметром Numbers.
Когда вызывается метод init мы получаем значение, которое передали в inputFilter, в данном случае это будет 'Numbers'. Это значение получается в данной строке

var filter = ko.utils.unwrapObservable(valueAccessor());

ну а дальше все ясно вроде, если это Number цепляем обработчик.
В данном случае, нам не нужен update, нам достаточно прицепить обработчик keydown один раз в init и все, потом он будет жить своей жизнью.

Помоему получилось красиво!

Что можно сделать лучше:
  • Код, который у меня находится в init можно вынести в плагин jquery или просто найти готовый плагин, ссылки на них есть в тоже же ответе.
  • Можно ввести в дело еще один параметр например Characters и фитровать только по буквам.
  • Можно пойти дальше и передавать допустимые символы, например !"№;%@ или еще лучше принимать шаблон. Я думаю изобретать парсер шаблона не придется, есть jquery плагины, досточно будет просто принять шаблон через custom binding.
Вопросы приветствуются.

1 комментарий:

  1. Wynn Hotel Casino and Resort - Mapyro
    Find your 하남 출장마사지 way 천안 출장샵 around the casino, find where everything is located with these 수원 출장샵 helpful reviews. Wynn 춘천 출장안마 Tower Suites 영천 출장마사지 Hotel and Casino.

    ОтветитьУдалить