Админка за 10 минут

от автора

Здравствуйте, уважаемое Хабрасообщество!

Я занимаюсь разработкой веб-сайтов. Как правило, это решения под индивидуальные потребности заказчиков. Поэтому я не использую готовые CMS, а предпочитаю складывать кирпичики самостоятельно. Конечно и админскую часть приходиться писать самостоятельно, поскольку она должна выполнять те функции, которые нужны заказчику, но и ничего лишнего не должно быть. И если написать несколько методов для редактирования данных это пол беды, то приходилось ещё и верстать приятный и удобный интерфейс.

Долгое время я использовал Twitter Bootstrap, но он не мог удовлетворить все потребности. Приходилось верстать дополнительные кнопочки и писать скрипты. Но вот однажды, я познакомился с замечательным UI-фреймворком KendoUI от Telerik. Что из этого получилось под катом.


О самом фреймворке уже писалась статья на Хабре. Мы будем использовать библиотеку Web-контролов KendoUI Web. Чтобы понимать, что можно создавать с её помощью можно посетить страничку с демо. Для построения контролов можно использовать как хелперы для ASP.NET, JSP или PHP, так и javascript-виджеты. Последние распространяются по лицензии GPL v3 License, поэтому я использовал именно их. Скачать тот или иной пакет можно здесь. На серверной стороне я использую ASP.NET MVC 4 с пакетом Microsoft ASP.NET Web API OData 4.0.0, уставить который можно с помощью команды PM> Install-Package Microsoft.AspNet.WebApi.OData

Для демонстрации создадим простой класс Article, и добавим ему три свойства разного типа

    public class Article 	{ 		public int ID { get; set; } 		public string Title { get; set; } 		public bool Hidden { get; set; } 	} 

Далее создадим ApiController для работы с данными. В своем примере я использую Entity Framework, поэтому сразу указываю Scaffolding options

После этого я изменяю только действие GetArticles, так показано в примере ниже. Прежде всего теперь оно возвращает ODataResult. А в качестве параметра принимает ODataQueryOptions, это коллекция сериализованных параметров строки запроса. В самом действии мы получаем коллекцию и общее количество элементов в ней. А после применяем к ней входящие параметры. В результате мы возвращаем коллекцию после применение к ней параметров и общее количество, оно необходимо для пагинации.

    public class ArticlesController : ApiController     {         private Storage db = new Storage();          // GET api/Articles 		public ODataResult<Article> GetArticles(ODataQueryOptions options) 		{ 			var items = db.Articles; 			var count = items.Count();             var res = (IEnumerable<Article>)options.ApplyTo(items);  			return new ODataResult<Article>(res, null, count); 		}          // GET api/Articles/5         public Article GetArticle(int id)         {             Article article = db.Articles.Find(id);             if (article == null)             {                 throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound));             }              return article;         }          // PUT api/Articles/5         public HttpResponseMessage PutArticle(int id, Article article)         {             if (ModelState.IsValid && id == article.ID)             {                 db.Entry(article).State = EntityState.Modified;                  try                 {                     db.SaveChanges();                 }                 catch (DbUpdateConcurrencyException)                 {                     return Request.CreateResponse(HttpStatusCode.NotFound);                 }                  return Request.CreateResponse(HttpStatusCode.OK);             }             else             {                 return Request.CreateResponse(HttpStatusCode.BadRequest);             }         }          // POST api/Articles         public HttpResponseMessage PostArticle(Article article)         {             if (ModelState.IsValid)             {                 db.Articles.Add(article);                 db.SaveChanges();                  HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.Created, article);                 response.Headers.Location = new Uri(Url.Link("DefaultApi", new { id = article.ID }));                 return response;             }             else             {                 return Request.CreateResponse(HttpStatusCode.BadRequest);             }         }          // DELETE api/Articles/5         public HttpResponseMessage DeleteArticle(int id)         {             Article article = db.Articles.Find(id);             if (article == null)             {                 return Request.CreateResponse(HttpStatusCode.NotFound);             }              db.Articles.Remove(article);              try             {                 db.SaveChanges();             }             catch (DbUpdateConcurrencyException)             {                 return Request.CreateResponse(HttpStatusCode.NotFound);             }              return Request.CreateResponse(HttpStatusCode.OK, article);         }     } 

Вот и все. Самое время переходить к клиентской части. Для начала подключим KendoUI и JQuery на страницу.

    <link href="~/Content/kendo/kendo.common.min.css" rel="stylesheet" /> 	<link href="~/Content/kendo/kendo.default.min.css" rel="stylesheet" /> 	<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script> 	<script src="~/Scripts/kendo/kendo.web.min.js"></script> 

После этого установим и настроим виджет. Подробнее о настройках виджета можно прочитать здесь.

<div id="grid"></div> 	<script> 		$(document).ready(function () { 			$("#grid").kendoGrid({ 				dataSource: { 					pageSize: 3, 					serverSorting: true, 					serverFiltering: true, 					serverPaging: true, 					type: 'odata', 					transport: { 						read: { 							url: "/api/articles", 							dataType: "json", 							type: "GET" 						}, 						create: { 							url: "/api/articles", 							dataType: "json", 							type: "POST" 						}, 						update: { 							url: function (article) { 								return "/api/articles/" + article.ID 							}, 							dataType: "json", 							type: "PUT" 						}, 						destroy: { 							url: function (article) { 								return "/api/articles/" + article.ID 							}, 							dataType: "json", 							type: "DELETE" 						} 					}, 					schema: { 						data: function (data) { 							return data.Items; 						}, 						total: function (data) { 							return data.Count; 						}, 						model: { 							id: "ID", 							fields: { 								ID: { editable: false }, 								Title: { type: "string", editable: true, nullable: false, validation: { required: true } }, 								Hidden: { type: "boolean", editable: true } 							} 						} 					} 				}, 				height: 250, 				filterable: true, 				sortable: true, 				pageable: true, 				toolbar: ["create"], 				editable: "popup", 				columns: [ 					{ field: "ID", filterable: false, width: 50 }, 					{ field: "Title", title: "Название", width: 300 }, 					{ field: "Hidden", title: "Скрыт", width: 100 }, 					{ command: ["edit", "destroy"], title: " ", width: "210px" } 				] 			}); 		}); 	</script> 

Готово! Теперь можно запускать и проверять. Менее чем за 10 минут мы создали полноценный интерфейс для управления данными, с возможностью пагинации, сортировки и фильтрации. Удобный и приятный. Спасибо KendoUI и формату OData, а Вам за внимание.




Р.S. Кстати есть возможность локализации виджетов. Для этого необходимо подключить соответствующий скрипт из папки js/cultures, который поставляется в архиве с фреймворком.

ссылка на оригинал статьи http://habrahabr.ru/post/175457/