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

в 12:18, , рубрики: .net, api, asp.net mvc, kendo ui, odata, метки: , ,

Админка за 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

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

После этого я изменяю только действие 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, а Вам за внимание.

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

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

Автор: aleksey_bober

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js