Новости

Knockout: Перемикаємо перевірку введення на російську мову або Knockout.Validation Localize (Globalize)

  1. Підготуємо проект до експериментів
  2. контролер
  3. JavaScript ViewModel'и
  4. Форма (подання)
  5. час перевіряти
  6. Ключовий момент Localization або Globalize.culture

ru-RU | створено: 04.03.2013 | опубліковано: 04.03.2013 | оновлено: 01.01.2018 | переглядів за весь час: 9148

Якщо ви використовуєте Knockoutjs, то напевно вже не раз доводилося робити перевірку даних, які вводить користувач. А як ви перевіряли введення дати і дрібних чисел? В цей статті налаштуємо валідацію Knockout.Validations на роботу "по-російськи".

Підготуємо проект до експериментів

Створимо новий проект для тесту. Оновимо встановлені пакети, і встановимо пару-трійку нових. Перший пакет буде jssite , Він повинен бути вам вже знаком. Після нього встановимо ще один пакет kolite, про який трохи пізніше. встановимо Knockout.Validations (Треба його теж включити в набір скриптів пакету jssite). А Knockoutjs вже встановився разом з пакетом jssite.

А ще я видалив відразу ж файл BundleConfig.cs і все що з ним пов'язано. Причини можна почитати в інший статті .

Так як я використав для створення нового проекту MvcApplication шаблон Basic (з'являється після установки ASP.NET and Web Tools 2012.2 Released ), То мій шаблон виглядає так _Layout.cshtml:

<! DOCTYPE html> <html> <head> <meta charset = "utf-8" /> <meta name = "viewport" content = "width = device-width" /> <title> @ ViewBag.Title </ title > <link href = "~ / Content / all.min.css" rel = "stylesheet" /> <script src = "~ / Scripts / modernizr-2.6.2.min.js"> </ script> </ head > <body> @RenderBody () <script src = "~ / Scripts / jquery-1.9.1.min.js"> </ script> <script src = "~ / Scripts / amplify.min.js"> </ script> <script src = "~ / Scripts / underscore.min.js"> </ script> <script src = "~ / Scripts / moment.min.js"> </ script> <script src = "~ / Scripts /toastr.min.js "> </ script> <script src =" ~ / Scripts / knockout-2.2.1.js "> </ script> <script src =" ~ / Scripts / knockout.validation.js "> </ script> <script src = "~ / Scripts / knockout.mapping-latest.js"> </ script> <script src = "~ / Scripts / knockout.dirtyFlag.js"> </ script> <script src = "~ / Scripts / knockout.command.js"> </ script> <script src = "~ / Scripts / knockout.activity.js"> </ script> <script src = "~ / Scripts / app / site.bindingHandlers .js "> </ script> <script src =" ~ / Scripts / app / site.core.js "> </ script> <script src =" ~ / Script s / app / site.services.js "> </ script> <script src =" ~ / Scripts / app / site.controls.js "> </ script> @RenderSection (" scripts ", required: false) </ body> </ html>

контролер

За замовчуванням в моєму шаблоні немає контролера, хоча в маршрутах (RouteConfog.cs) прописаний "Home", його-то я і створив. А також створив уявлення (View) для одного єдиного методу цього контролера. Поки воно ось таке:

@ {ViewBag.Title = "Index"; } <H2> Index </ h2>

JavaScript ViewModel'и

Тепер створюємо сутність для тесту (person), це той об'єкт, який ми будемо перевіряти на правильність введення на формі:

function Person (last, first, second, birth, weight) {return {lastName: ko.observable (last), firstName: ko.observable (first), secondName: ko.observable (second), birthDate: ko.observable (birth ), weight: ko.observable (weight)}; }

Тепер створюємо ViewModel для сторінки Index.cshtml:

$ (Function (parameters) { "use strict"; site.vm.viewModel = function () {var data = [new Person ( "Суходріщев", "Дормидонт", "Євлампійович", "03/03/1983", " 92.3 "), new Person (" Тіхобздеев "," Гавриїл "," Опанасович "," 13.03.1976 "," 90,8 ")], meta = new site.controls.Metadata (" Тестування валідації Knockout "," Перевіряємо як працює валідація Knockout, \ в тому числі локалізацію Knockout на російську мову: цифри, дати і т.д. "," http://www.calabonga.net "), clock = new site.controls.Clock (), person = data [0], person2 = data [1], errors = ko.validatedObservable (person), errors2 = ko.validatedObservable (person2), saveCommand = ko.asyncCommand ({execute: function (complete) {alert ( "Saved! "); complete ();}, canExecute: function (isExecuting) {return! isExecuting && errors.isValid;}}), saveCommand2 = ko.asyncCommand ({execute: function (complete ) {Alert ( "Saved 2!"); Complete ();}, canExecute: function (isExecuting) {return! IsExecuting && errors2.isValid;}}); return {meta: meta, clock: clock, person: person, person2: person2, saveCommand: saveCommand, saveCommand2: saveCommand2}; } (); ko.applyBindings (site.vm.viewModel); });

Пояснення ...

Рядок 3: включаємо "строгість".

Рядки 7-10: створюємо два об'єкти Person, один валідний для EN локалізації, інший валиден для RU валідації (дивитися треба на дату і вага).

Рядки 12-16: метадані для головній сторінці, до речі, клас метаданих "переїхав" в jssite в namespace "controls". У рядку 17: створюємо, як уже повелося, об'єкт Clock. Якщо при першому старті годинник підуть - скрипти встановлені правильно!

Рядки 17-18: створюємо дві змінних для зберігання на формі двох Person.

Рядки 22-30 і рядки 31-39: створюємо asyncCommand (якраз з того самого пакету kolite) для більш повної реалізації паттерна MVVM на формі.

Рядки 41-48: Виставляємо публічні властивості.

Рядок 51: Прив'язуємо дані до форми.

Форма (подання)

Форма більше не буде змінюватися, тому приведу її цілком:

@ {ViewBag.Title = "Index"; } <H2> Index </ h2> <div data-bind = "text: clock.time" id = "clock"> </ div> <h2 data-bind = "text: meta.title"> </ h2> <p data-bind = "text: meta.description"> </ p> <table> <thead> <tr> <th style = "width: 50%"> Globalization EN </ th> <th style = "width : 50% "> Globalization RU </ th> </ tr> </ thead> <tbody> <tr> <td data-bind =" css: { 'valid': person.isValid (), 'invalid':! person.isValid ()} "> <p> <span data-bind =" text: person.isValid () "> </ span> </ p> <div data-bind =" with: person "> <div class = "editor-label"> <label> Прізвище: </ label> </ div> <div class = "editor-field"> <input type = "text" data-bind = "value: lastName" /> </ div> <div class = "editor-label"> <label> Ім'я: </ label> </ div> <div class = "editor-field"> <input type = "text" data-bind = "value: firstName "/> </ div> <div class =" editor-label "> <label> батькові: </ label> </ div> <div class =" editor-field "> <input type =" text "data-bind = "value: secondName" /> </ div> <div class = "editor-label"> <label> Дата народження: </ label> </ div> <div class = "editor-fiel d "> <input type =" text "data-bind =" value: birthDate "/> </ div> <div class =" editor-label "> <label> Вага: </ label> </ div> <div class = "editor-field"> <input type = "text" data-bind = "value: weight" /> </ div> </ div> <p> <button data-bind = "command: saveCommand, text: 'зберегти' "> </ button> </ p> </ td> <td data-bind =" css: { 'valid': person2.isValid (), 'invalid':! person2.isValid ()} "> <p> <span data-bind = "text: person2.isValid ()"> </ span> </ p> <div data-bind = "with: person2"> <div class = "editor-label"> < label> Прізвище: </ label> </ div> <div class = "editor-field"> <input type = "text" data-bind = "value: lastName" /> </ div> <div class = "editor -label "> <label> Ім'я: </ label> </ div> <div class =" editor-field "> <input type =" text "data-bind =" value: firstName "/> </ div> < div class = "editor-label"> <label> батькові: </ label> </ div> <div class = "editor-field"> <input type = "text" data-bind = "value: secondName" /> </ div> <div class = "editor-label"> <label> Дата народження: </ label> </ div> <div class = "editor-field"> <input type = "text" data-bind = "value: birthDate" /> </ div> <div class = "editor-label"> <label> Вага: </ label> < / div> <div class = "editor-field"> <input type = "text" data-bind = "value: weight" /> </ div> </ div> <p> <button data-bind = "command : saveCommand2, text: 'зберегти' "> </ button> </ p> </ td> </ tr> </ tbody> </ table> @section scripts {<script src =" ~ / Scripts / app / site .vm.viewModel.js "> </ script>}

А ось як вона виглядає:


(Рис 1. Перед установкою локалізації)

час перевіряти

Але для початку руссіфіціруем валідацію у knockout. Для цього знаходимо на сайті Knockout-Validation папку з назвою Localization, там вже є ru-RU.js , Ось його-то і завантажити Щоб додати в проект. Таким чином, ми включаємо переклад на російську мову валідацію примітивних типів.

Тепер треба підключити локалізацію, я це зроблю в файлі site.core.js, там у мене знаходиться bootstrapper і все інше. Ось змінений файл:

// base namespace var site = site || {}; // config module site.cfg = site.cfg || {}; // model's module site.m = site.m || {}; // viewmodel's module site.vm = site.vm || {}; // services module site.services = site.services || {}; // utilites module site.utils = site.utils || {}; // controls module site.controls = site.controls || {}; // start engine var bootstrapper = function () {var root = this, initLibs = function () {// initialization for third-party libs site.amplify = root.amplify; site. $ = root.jQuery; site.logger = root.toastr; site._ = root._; }, InitValidation = function () {ko.validation.configure ({registerExtenders: true, // default is true messagesOnModified: true, // default is true insertMessages: true, // default is true parseInputAttributes: true, // default is false writeInputAttributes: true, // default is false messageTemplate: null, // default is null decorateElement: true // default is false. Applies the validationElement CSS class}); ko.validation.localize ({required: 'Необхідно заповнити це поле.', min: 'Значення має бути більше або дорівнює {0}.', max: 'Значення має бути менше або дорівнює {0}.', minLength: ' довжина поля повинна бути не менше {0} символів. ', maxLength:' довжина поля повинна бути не більше {0} символів. ', pattern:' Будь ласка перевірте це поле. ', step:' значення поле повинно змінюватися з кроком {0 } ', email:' Введіть в поле правильну адресу email ', date:' Будь ласка, введіть правильну дату ', dateISO:' Будь ласка, введіть правильну дату в форматі ISO ', number:' поле повинно містити число ', digit:' поле повинно містити цифри ', phoneUS:' Пол е повинно містити правильний номер телефону ', equal:' Значення повинні бути рівні ', notEqual:' Будь ласка виберіть інше значення. ', unique:' Значення має бути унікальним. '}); }, InitConfig = function () {// settings for site site.cfg.throttle = 600; site.cfg.busyIndicatorImageName = "/images/ms-loader.gif"; // pager site.cfg.pageSize = 10; site.cfg.groupSize = 10; site.cfg.pageSizes = ko.observableArray ([5, 10, 20, 30, 50, 100]); }, Init = function () {initLibs (); initConfig (); initValidation (); }; return {run: init}; } ();

Рядок 34-61: Налагодження та локалізація knockout.Validation, яку викликаємо в методі ініціалізації в рядку 77.

Запустивши проект, я все також бачу ту ж картинку - EN - зелений, RU - червоний. Значить валідація ще не налаштована.

Ключовий момент Localization або Globalize.culture

На щастя, чи на жаль, але все вже давно придумали за нас. Вже існує збірка (якщо так можна висловитися для js-файлу), яка реалізує весь необхідний для нас функціонал - globalize . На сайті добре розписано для чого призначена збірка. Підходить вона і для нашого випадку. Качаємо ... додаємо в проект:



(Рис. 2. Підключення глобалізації)

Не забудьте прописати скрипти в шаблоні _Layout.cshtml, щоб вони завантажувалися на всіх сторінках додатка, або там, де вам буде завгодно. Я додав у шаблон, для простоти.

Тепер у файлі site.core.js підключаємо "глобалізацію". У методі InitLibs (див. Рядки 26-33 попереднього лістингу) доведеться дописати кілька рядків:

initLibs = function () {// globalize Globalize.culture ( "ru"); // підміняємо парсинг чисел з плаваючою точкою // тому що в Globalize.parseFloat існує бага, // так як "точка" (.) Обробляється як частина числа // навіть якщо вона такою не є. // Я виправив це так: Globalize.orgParaseFloat = Globalize.parseFloat; Globalize.parseFloat = function (value) {value = String (value); var culture = this.findClosestCulture (); var seperatorFound = false; for (var i in culture.numberFormat) {if (culture.numberFormat [i] == ".") {seperatorFound = true; break; }} If (! SeperatorFound) {value = value.replace ( ".", "NaN"); } Return this.orgParaseFloat (value); }; // встановлюємо власні валідатори // knockout для "number" і для "data" ko.validation.rules.number.validator = function (value, validate) {return! (Value) || (Validate &&! IsNaN (Globalize.parseFloat (value))); }; ko.validation.rules.date.validator = function (value, validate) {return! (value) || (Validate && Globalize.parseDate (value)! = Null); }; // initialization for third-party libs site.amplify = root.amplify; site. $ = root.jQuery; site.logger = root.toastr; site._ = root._; }

Рядок 4: підключає локалізацію до javascript.

Зверніть увагу на те, що в Globalize.parseFloat існує деяка оказія, справа в тому, що "точка" (.) Приймається бібліотекою як частина числа, навіть якщо вона не є його частиною. Рядки 12-14 виправляють цю помилку.

Так само, треба не тільки підключити Globalize, виправивши багу, але ще і трохи перевизначити правила перевірки валідності у самого knockoutjs. І тут вже доведеться написати код самостійно. Я написав перевірку для DateTime і Number:

ko.validation.rules.number.validator = function (value, validate) {return! (value) || (Validate &&! IsNaN (Globalize.parseFloat (value))); }; ko.validation.rules.date.validator = function (value, validate) {return! (value) || (Validate && Globalize.parseDate (value)! = Null); };

Інших правил мені поки не потрібна ... Запускаємо! УРА !!!


(Рис. 3. Knockout.Validation "по-російськи")

Те що і було потрібно!

А як ви перевіряли введення дати і дрібних чисел?

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

Или позвоните нам по телефонам: (048) 823-25-64

Организация (обязательно) *

Адрес доставки

Объем

Как с вами связаться:

Имя

Телефон (обязательно) *

Мобильный телефон

Ваш E-Mail

Дополнительная информация: