21 августа 2012 г.

Знакомство с Kendo UI Window для ASP.Net

На сегодняшний день, на поприще веба, представлена целая куча разнообразных UI фреймворков, для быстрой разработки красивого и удобного интерфейса своих проектов. Действительно, это снимает огромную проблему с разработчика, экономит время, и позволяет лишний раз не связываться с дизайнерами\верстальщиками (уж простите если обидел кого).
По моему скромному мнению, одним из самых удобных и перспективных UI-пакетов, является Kendo UI. Да-да, это именно та штука, ради которой Telerik "зарезал" свой Telerik Extensions for ASP.NET MVC, о котором я собирался написать десяток постов...

Для тех, кто не в курсе, немного расскажу о Kendo.
Вообще, Kendo UI состоит из трех пакетов:
  • Web (для всех обычных сайтов);
  • Mobile (компоненты для мобильных платформ);
  • DataViz (специальный набор для красивого представления данных: таблицы, графики, диаграммы и прочее.)
Каждый пакет включает стандартные Javascript библиотеки для работы набора, плюс компоненты/контролы для WebForms и MVC.
Вот тут и приходит самое главное разочарование - все это добро, как всегда, платное. Причем стоит ооочень хороших денег. Но мелкая радость все же имеется - бесплатно (GPL v3) предоставляется только пакет Web, хотя и без специальных контролов под asp.net, а лишь имея скриптовую реализацию.

Понятное дело, что работать мы будем с бесплатной версией пакета.
Итак, сегодня у нас первое знакомство с Kendo UI, и первым его компонентом - Window.

Window - это попап, всплывающее окошко, диалоговое окно... Называть можно па-разному, но суть одна и та же. В JQuery UI, его аналогом является Dialog.

Обычно, при использовании всплывающих окон, применяется всего 2 сценария:
  • вызов попапа с статическим контентом, который уже находится на странице, просто скрыт от пользователя;
  • вызов попапа, с подгрузкой в него контента ajax-запросом;
Испробуем Kendo UI Window для обоих вариантов поведения.

Но для начала, необходимо скачать сам пакет, и включить его в проект:
И, конечно же, подключить в _Layout.cshtml, чтобы KendoUI был доступен по всему проекту:

<link href="@Url.Content("/KendoUI/styles/kendo.common.min.css")" rel="stylesheet" type="text/css" />
<link href="@Url.Content("/KendoUI/styles/kendo.default.min.css")" rel="stylesheet" type="text/css" />
<script src="@Url.Content("/KendoUI/js/kendo.web.min.js")" type="text/javascript"></script>

Сценарий 1. Локальный контент для попапа

Пусть на нашей странице есть скрытый див, содержимое которого нужно выносить в всплывающее окно, а также кнопка, по клику на которую должен произойти вызов окошка:

<div id="window1">
    Content of the Window
</div>
<button id="openButton1">
    Open Window</button>

Если контент изначально уже должен лежать на странице, так почему бы не сформировать окошко сразу после полной загрузки HTML, и потом, при необходимости, просто его показать. Все это дело реализуем в javascript:

   1:  <script type="text/javascript">
   2:      $(function () {
   3:          var win = $("#window1").kendoWindow({
   4:              height: "200px",
   5:              title: "Centered Window",
   6:              visible: false,
   7:              width: "300px"
   8:          });
   9:   
  10:          $("#openButton1").click(function () {
  11:              var win = $("#window1").data("kendoWindow");
  12:              win.center();
  13:              win.open();
  14:          });
  15:      });
  16:  </script>

Сначала мы привязываем Kendo Window к нужному диву с контеном, и задаем начальные настройки попапа. С полным списком возможных настроек можно ознакомиться в официальной документации. Мы же зацепим лишь некоторые.
Далее, мы привязываем к событию нажатия кнопки получение нужного экземпляра окна, его центрирование, и показ пользователю.

По-сути, всего написанного уже достаточно для работы всплывающего окна Kendo:

Попап получился довольно простенький. Давайте попробуем его немного приукрасить с функциональной точки зрения. А именно, добавим дополнительные управляющие кнопки. Делается это одной строкой в настройке окна:

   1:  var win = $("#window1").kendoWindow({
   2:      height: "200px",
   3:      title: "Centered Window",
   4:      visible: false,
   5:      width: "300px",
   6:      actions: ["Minimize", "Maximize", "Close"]
   7:  });

А вот и результат:

Но можно пойти еще дальше, и добавлять не только стандартные командные кнопки, но и создавать свои собственные, с конкретными обработчиками. Давайте попробуем:

   1:  var win = $("#window1").kendoWindow({
   2:      height: "200px",
   3:      title: "Centered Window",
   4:      visible: false,
   5:      width: "300px",
   6:      actions: ["Custom", "Minimize", "Maximize", "Close"],
   7:  }).data("kendoWindow").wrapper.find(".k-i-custom").click(function(e) {
   8:      alert("Custom action button clicked");
   9:      e.preventDefault();
  10:  });

Мы добавили в верхнюю панель свою, новую кнопку Custom, и написали обработчик для клика по ней. Вот что получилось:


Стоит заметить, что название кнопки в "actions", должно отвечать второй части класса "k-i-*". Для чего это нужно? Во-первых, для того, чтобы иметь возможность добавить больше одной кастомной кнопки. А во-вторых, для возможности выбора необходимой иконки по стилю.

Для примера, давайте добавим к этому окошку еще одну кнопку для поиска чего-то, а заодно немного упростим синтаксис:

   1:  $("#window1").kendoWindow({
   2:      height: "200px",
   3:      title: "Centered Window",
   4:      visible: false,
   5:      width: "300px",
   6:      actions: ["Custom", "Search", "Minimize", "Maximize", "Close"],
   7:  });
   8:   
   9:  $("#window1").data("kendoWindow").wrapper.find(".k-i-custom").click(function(e) {
  10:      alert("Custom action button clicked");
  11:      e.preventDefault();
  12:  });
  13:   
  14:  $("#window1").data("kendoWindow").wrapper.find(".k-i-search").click(function(e) {
  15:      alert("Search button clicked");
  16:      e.preventDefault();
  17:  });

Ну и результат:

Думаю, что на этом, с первым типом окошка, можно закончить.

Сценарий 2. Контент, подгружаемый ajax-запросом

Я добавил на страницу еще одну кнопку, для вызова такого окошка, а также еще один див, который скрыт, и будет выступать контейнером для подгружаемого контента:

   1:  <div id="window2" style="display: none;">
   2:  </div>
   3:  <button id="openButton2">
   4:      Open Window With AJAX-Content</button>

Также обработчик нажатия кнопки:

   1:  $("#openButton2").click(function () {
   2:      $("#window2").kendoWindow({
   3:          content: "@Url.Action("SomeAction", "Home")",
   4:          title: "Async Window Content",
   5:          actions: ["Refresh", "Minimize", "Maximize", "Close"],
   6:          width: "300px",
   7:          modal: true
   8:      }).data("kendoWindow").center().open();
   9:  });

Как видимо из настроек, контент для окна будет браться по адресу /home/someaction. А оттуда  мы будем возвращать простенький контрол, с текущей серверной датой.
Контроллер HomeController:

   1:  public ActionResult SomeAction()
   2:  {
   3:      ViewBag.MyDate = DateTime.Now;
   4:      return PartialView("_userControl");
   5:  }

Контрол _userControl:

   1:  <div>
   2:      I'm user control!
   3:      <br />
   4:      Datetime is: @ViewBag.MyDate
   5:      <br />
   6:      <div style="float: right;">
   7:          <input type="button" value="Ok" onclick="Okay();" />
   8:      </div>
   9:  </div>
  10:  <script type="text/javascript">
  11:      function Okay() {
  12:          // Do some actions
  13:          $("#window2").data("kendoWindow").close();
  14:      };
  15:  </script>

Вот и все. Ничего сложного.
Вот и результат работы:

Напоследок еще посмотрим на работу с событиями самого окна. Давайте отлавливать событие открытия попапа после выполнения ajax-запроса. Для этого нужно немного дополнить настройки окна в javascript-е:

   1:  $("#openButton2").click(function () {
   2:      $("#window2").kendoWindow({
   3:          content: "@Url.Action("SomeAction", "Home")",
   4:          title: "Async Window Content",
   5:          actions: ["Refresh", "Minimize", "Maximize", "Close"],
   6:          width: "300px",
   7:          modal: true,
   8:          open: onOpen
   9:      }).data("kendoWindow").center().open();
  10:  });
  11:   
  12:  function onOpen(e) {
  13:      alert('ajax window is loaded!');
  14:  };

Как результат, после нажатия кнопки выполняется запрос на сервер (за контентом для окна), но перед показом самого попапа отрабатывает событие open:
И только после закрытия alert-а, мы увидим наш долгожданный попап:

На этом, пожалуй, все.
_____
Исходники