ASP.NET MVC: MVVM на HTML или использование knockout при создании сайта (часть 2 из 2).
Доведем форму до ума
В первой части статьи была подготовлена основа для формы обратной связи, в этой части закончим начатое. Я добавил некоторое количество полей на форму. Теперь разметка формы выглядит так:
1: <h3data-bind="text: view.title"></h3>
2: <pdata-bind="text: sendResult"></p>
3: <divdata-bind="ifnot: isbusy, visible: sended">
4: <p>
5: <labelfor="Subject">Выберите тему сообщения</label>
6: <selectdata-bind="options: subjects, value: vm().Subject, optionsCaption:'выбрать тему'"id="Subject"></select>
7: <small>загружено тем: <spandata-bind="text: subjects().length"></span>шт.</small>
8: <br/>
9: <spandata-bind="visible: vm().Subject">Выбранная тема: <b>
10: <spandata-bind="text: vm().Subject"></span></b>
11: </span>
12: </p>
13: <p>
14: <labelfor="userName">Ваше имя</label>
15: <inputtype="text"data-bind="value: vm().UserName"id="userName"required/>
16: </p>
17: <p>
18: <labelfor="email">Ваш почтовый адрес для ответа</label>
19: <inputtype="email"data-bind="value: vm().Email"id="email"required/>
20: </p>
21: <p>
22: <labelfor="message">Тескт сообщения</label>
23: <textareaid="message"data-bind="value: vm().Message"rows="5"required></textarea>
24: </p>
25: <p>
26: <buttondata-bind="click: sendMessage">Отправить сообщение</button>
27: </p>
28: </div>
29:
30: @section scripts {
31: @Scripts.Render("~/bundles/koval")
32: <scriptsrc="@Scripts.Url("~/js/site.core.js")"></script>
33: <script src="@Scripts.Url("~/js/site.service.feedback.js")"></script>
34: <script src="@Scripts.Url("~/js/site.vm.feedback.js")"></script>
35: }
Поясню некоторые строки этого листинга:
- строка 2: сначала выводит приглашение заполнить все поля, при удачной попытке отправки отображает благодарность, при неудачной, соответственно, сообщение о неработоспособности сервера или вежливое напоминание, что поля надо заполнять правильно;
- строка 6: была доработана, добавлена дополнительная опция “выбрать тему”;
- строка 7-11: выбранная тема сообщения показывается именно тут.
Новый JsonResult
Напишем новый метод контролера Ajax, который как раз и должен будет отправлять сообщение администратору.
1: /// <summary>
2: /// Отправленная с формы модель
3: /// будет приходить сюда
4: /// </summary>
5: /// <param name="model"></param>
6: /// <returns></returns>
7: [HttpPost]
8: public JsonResult SendFeedback(FeedbackViewModel feedback) {
9: string message = "Простите ошибка. Не могу отправить сообщение. Возможно форма неверно заполнена или проблемы на сервере.";
10: bool sended = false;
11: if (ModelState.IsValid) {
12:
13: // реальная отправка сообщения
14: message = "Спасибо за ваше сообщение. Приходите еще!";
15: sended = true;
16: }
17: return Json(new { Message = message, Sended = sended });
18: }
Опять вернемся Javascript
А теперь на код изменившегося ViewModel’а для javascript:
1: ///////////////////////////////////////////////////////////////
2: // site.feedback
3: // Работает через dataService с объектами на форме
4: // Feedback
5: // автор: calabonga.net
6: ///////////////////////////////////////////////////////////////
7:
8: (function (site) {
9:
10: "use strict";
11:
12: site.vm.feedbackViewModel = function () {
13: var
14: view = {
15: title: "Отправка сообщения"
16: },
17: subjects = ko.observableArray([]),
18: sendResult = ko.observable("Заполните все поля формы, пожалуйста"),
19: isbusy = ko.observable(false),
20: cansended = ko.observable(true),
21: feedback = ko.observable({
22: "Subject": ko.observable(),
23: "UserName": ko.observable(),
24: "Email": ko.observable(),
25: "Message": ko.observable()
26: }),
27:
28: loadSubjects = function () {
29: isbusy(true);
30: site.services.feedbackForm.loadSubjects(callbackSubjects);
31: },
32: callbackSubjects = function (json) {
33: isbusy(false);
34: ko.mapping.fromJS(json, {}, subjects);
35: var total = subjects().length;
36: },
37: sendMessage = function () {
38: sendResult("Ждите. Идет отправка сообщения");
39: isbusy(true);
40: site.services.feedbackForm.sendFeedback(JSON.stringify(feedback), callbackMessage);
41: },
42: callbackMessage = function (json) {
43: isbusy(false);
44: cansended(json.Sended ? false : true)
45: sendResult(json.Message);
46: };
47:
48: loadSubjects();
49:
50: return {
51: view: view,
52: vm: feedback,
53: isbusy: isbusy,
54: sendResult: sendResult,
55: sended: cansended,
56: subjects: subjects,
57: sendMessage: sendMessage
58: }
59:
60: }();
61:
62: })(site);
Как не трудно заметить, добавились новые свойства и новый ViewModel для модели FeedbackViewModel:
1: ///////////////////////////////////////////////////////////////
2: // ViewModel для отправки feedback на сервер
3: // автор: calabonga.net
4: ///////////////////////////////////////////////////////////////
5:
6: function FeedbackViewModel(subject, userName, email, message) {
7: this.Subject = subject;
8: this.UserName = userName;
9: this.EmailAdrress = email;
10: this.Message = message;
11: };
Вот так теперь выглядит форма обратной связи:
А теперь опишу как это работает. Сейчас валидация объекта не предусмотрена. Как можно догадаться, проверку на правильность ввода пользователя проверяет метод контролера SendFeedback. У меня в планах показать, как можно использовать валидацию отправляемого объекта при помощи Knockout.Validation. И это я сделаю чуть позже, а пока посмотрите как работает текущий вариант формы.
Так выглядит форма если пользователь ввел неправильные данные. Подчеркнутое сообщение приходит как результат действия метода контроллера (то есть это серверная валидация):
Вот так форма отображается, если пользователь отправил верные данные:
Работает всё прекрасно, вот только пользователь, ни коим образом не знает о том, какую именно ошибку он совершил, а если бы форма была посложнее? Очень трудно было бы определить, в каком именно поле была допущена ошибка. Решить данную проблему поможет Knockout.Validation. Раз у ж мы используем ko, то и валидацию будем использовать на его основе, хотя нельзя забывать что существует еще и jquery.validation (и другие, сторонние разработки). Более того, существует вариант использовать jquery.validation в knockout.
Knockout.Validation в действии
Так как сборки (пакеты) уже все подключены. Мне остается немного подправить Javascript ViewModel’а чтобы заработала валидация. Вот измененные строки, которые немного дополнили объявление feedback:
1: feedback = ko.validatedObservable({
2: "Subject": ko.observable().extend({ required: true }),
3: "UserName": ko.observable().extend({ required: true, minLength: 4 }),
4: "Email": ko.observable().extend({ required: true, email: true }),
5: "Message": ko.observable().extend({ required: true, minLength: 10 })
6: }),
Обратите внимание, что сам объект feedback стал теперь не просто ko.observable(), а ko.validatedObservable(). И еще надо немного на форме подправить привязку формы отправки:
1: <p>
2: <buttondata-bind="click : sendMessage,
enable: vm().isValid()">Отправить сообщение</button>
3: </p>
Теперь кнопка отправки будет влючена, только если объект feedback будет валиден (правильно заполнен). Правда же ничего сложного? Если попробовать ввести некорректные данные, форм заартачится и вывалит кучу сообщений:
Дополнительная информация по типам валидации расширяемости свойств можно посмтреть на сайте плагина. Кстати, кажется не очень удачная идея отображать русскому пользователю сообщения на английском языке. Можно скачать локализацию положить ее в папку scripts под названием knockout.validation.ru-RU.js. Более ничего делать не надо, даже добавлять в пакет (Bundle), потому файл будет подключен автоматически из-за того, что виртуальный путь до пакета Knockout.Validation использует “*”.
1: bundles.Add(new ScriptBundle("~/bundles/koval").Include(
2: "~/Scripts/knockout.validation.*"
Обновив страницу, можно будет читать сообщения на русском языке.
Ну, и на последок, остается немного разукрасить выводимое сообщение, что они были более заметны. Нужно в CSS задать стиль validationMessage.
1: .validationMessage
2: {
3: background-color:red;
4: color:white;
5: padding:5px;
6: }
Вот окончательный вариант формы обратной связи:
Вместо заключения
Вот наверное и всё. Пишите комментарии. И ссылка на демонстрационный проект.
Подробнее: http://feedproxy.google.com/~r/blogmusor/~3/d14dgm8iOpo/94
Дайджест новых статей по интернет-маркетингу на ваш email
Новые статьи и публикации
- 2024-11-26 » Капитан грузового судна, или Как начать использовать Docker в своих проектах
- 2024-11-26 » Обеспечение безопасности ваших веб-приложений с помощью PHP OOP и PDO
- 2024-11-22 » Ошибки в Яндекс Вебмастере: как найти и исправить
- 2024-11-22 » Ошибки в Яндекс Вебмастере: как найти и исправить
- 2024-11-15 » Перенос сайта на WordPress с одного домена на другой
- 2024-11-08 » OSPanel 6: быстрый старт
- 2024-11-08 » Как установить PhpMyAdmin в Open Server Panel
- 2024-09-30 » Как быстро запустить Laravel на Windows
- 2024-09-25 » Next.js
- 2024-09-05 » OpenAI рассказал, как запретить ChatGPT использовать содержимое сайта для обучения
- 2024-08-28 » Чек-лист: как увеличить конверсию интернет-магазина на примере спортпита
- 2024-08-01 » WebSocket
- 2024-07-26 » Интеграция с Яндекс Еда
- 2024-07-26 » Интеграция с Эквайринг
- 2024-07-26 » Интеграция с СДЕК
- 2024-07-26 » Интеграция с Битрикс-24
- 2024-07-26 » Интеграция с Travelline
- 2024-07-26 » Интеграция с Iiko
- 2024-07-26 » Интеграция с Delivery Club
- 2024-07-26 » Интеграция с CRM
- 2024-07-26 » Интеграция с 1C-Бухгалтерия
- 2024-07-24 » Что такое сторителлинг: техники и примеры
- 2024-07-17 » Ошибка 404: что это такое и как ее использовать для бизнеса
- 2024-07-03 » Размещайте прайс-листы на FarPost.ru и продавайте товары быстро и выгодно
- 2024-07-01 » Профилирование кода в PHP
- 2024-06-28 » Изучаем ABC/XYZ-анализ: что это такое и какие решения с помощью него принимают
- 2024-06-17 » Зачем вам знать потребности клиента
- 2024-06-11 » Что нового в работе Яндекс Метрики: полный обзор обновления
- 2024-06-11 » Поведенческие факторы ранжирования в Яндексе
- 2024-06-11 » Скорость загрузки сайта: почему это важно и как влияет на ранжирование
Есть три способа отвечать на вопросы: сказать необходимое, отвечать с приветливостью и – наговорить лишнего Плутарх - (ок. 46 — ок.120) - древнегреческий писатель, историк |
Мы создаем сайты, которые работают! Профессионально обслуживаем и продвигаем их , а также по всей России и ближнему зарубежью с 2006 года!
Как мы работаем
Заявка
Позвоните или оставьте заявку на сайте.
Консультация
Обсуждаем что именно Вам нужно и помогаем определить как это лучше сделать!
Договор
Заключаем договор на оказание услуг, в котором прописаны условия и обязанности обеих сторон.
Выполнение работ
Непосредственно оказание требующихся услуг и работ по вашему заданию.
Поддержка
Сдача выполненых работ, последующие корректировки и поддержка при необходимости.