Wednesday, June 26, 2013

asp.net mvc4, razor, telerik grid, model, popup window using

Admin/CountryController.cs

using HiimelOyun.Core.Domain.Directory;
using HiimelOyun.Core.Infrastructure;
using HiimelOyun.Framework.Controllers;
using HiimelOyun.Services.Common;
using HiimelOyun.Services.Directory;
using HiimelOyun.Services.Localization;
using HiimelOyun.Framework.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Telerik.Web.Mvc;
using HiimelOyun.Core;
using HiimelOyun.Admin.Models.Directory;
using HiimelOyun.Core.Domain.Common;

namespace HiimelOyun.Admin.Controllers
{
    [BorAdminAuthorize]
    public class CountryController : BaseAdminController
    {
        private readonly ICountryManager _countryManager;
        private readonly IStateProvinceManager _stateProvinceManager;
        private readonly ILocalizationManager _localizationManager;
        private readonly IAddressManager _addressManager;
        private readonly ILocalizedEntityManager _localizedEntityManager;
        private readonly ILanguageManager _languageManager;
        private readonly AdminAreaSettingModel _adminAreaSettings;

        public CountryController()
        {
            IEngine engine = EngineContext.Current;
            _countryManager = engine.Resolve<ICountryManager>();
            _stateProvinceManager = engine.Resolve<IStateProvinceManager>();
            _localizationManager = engine.Resolve<ILocalizationManager>();
            _addressManager = engine.Resolve<IAddressManager>();
            _localizedEntityManager = engine.Resolve<ILocalizedEntityManager>();
            _languageManager = engine.Resolve<ILanguageManager>();
            _adminAreaSettings = engine.ResolveSettings<AdminAreaSettingModel>();
        }

        public ActionResult Index()
        {
            return View();
        }
       
        #region Countries
       
        public ActionResult List()
        {
            ViewBag.AdminAreaSettings = _adminAreaSettings;

            var countries = _countryManager.GetAllCountries(true);
            var model = new GridModel<CountryInfo>
            {
                Data = countries.ToList(),
                Total = countries.Count
            };
            return View(model);
        }

        [HttpPost, GridAction(EnableCustomBinding = true)]
        public ActionResult CountryList(GridCommand command)
        {
            var countries = _countryManager.GetAllCountries(true);
            var model = new GridModel<CountryInfo>
            {
                Data = countries.ToList(),
                Total = countries.Count
            };

            return new JsonResult
            {
                Data = model
            };
        }

        public ActionResult Create()
        {
            return View();
        }

        [HttpPost, ParameterBasedOnFormNameAttribute("save-continue", "continueEditing")]
        public ActionResult Create(CountryInfo country, bool continueEditing)
        {
            if (ModelState.IsValid)
            {
                _countryManager.InsertCountry(country);
                SuccessNotification("Амжилттай хадгаллаа!");
                return continueEditing ? RedirectToAction("Edit", new { id = country.Id }) : RedirectToAction("List");
            }

            //If we got this far, something failed, redisplay form
            return View(country);
        }

        public ActionResult Edit(int id)
        {
            var country = _countryManager.GetCountryById(id);
            if (country == null) return RedirectToAction("List");
            return View(country);
        }

        [HttpPost, ParameterBasedOnFormNameAttribute("save-continue", "continueEditing")]
        public ActionResult Edit(int id, FormCollection form, bool continueEditing)
        {
            var country = _countryManager.GetCountryById(id);

            if (TryUpdateModel(country))
            {
                if (ModelState.IsValid)
                {
                    _countryManager.UpdateCountry(country);
                    SuccessNotification("Амжилттай засварлалаа!");
                    return continueEditing ? RedirectToAction("Edit", new { id = country.Id }) : RedirectToAction("List");
                }
            }

            return View(country);
        }

        [HttpPost]
        public ActionResult Delete(int id)
        {
            var country = _countryManager.GetCountryById(id);
            if (country == null) return RedirectToAction("List");

            try
            {
                if (_addressManager.GetAddressTotalByCountryId(country.Id) > 0)
                    throw new BorException("The country can't be deleted. It has associated addresses");

                _countryManager.DeleteCountry(country);

                SuccessNotification(string.Format("{0} дугаартай мэдээлэл утслаа!", id));
                return RedirectToAction("List");
            }
            catch (Exception exc)
            {
                ErrorNotification(exc);
                return RedirectToAction("Edit", new { id = country.Id });
            }
        }

        #endregion

        #region States / provinces

        [HttpPost, GridAction(EnableCustomBinding = true)]
        public ActionResult States(int countryId, GridCommand command)
        {
            var states = _stateProvinceManager.GetStateProvincesByCountryId(countryId, true);
            var model = new GridModel<StateProvinceInfo>
            {
                Data = states.ToList(),
                Total = states.Count()
            };
            return new JsonResult
            {
                Data = model
            };
        }
       
        //create
        public ActionResult StateCreatePopup(int countryId)
        {
            var model = new StateProvinceModel();
            model.CountryId = countryId;
            return View(model);
        }

        [HttpPost]
        public ActionResult StateCreatePopup(string btnId, string formId, StateProvinceModel model)
        {
            var country = _countryManager.GetCountryById(model.CountryId);
            if (country == null) return RedirectToAction("List");

            if (ModelState.IsValid)
            {
                var stateProvince = model.ToEntity<StateProvinceInfo>();

                _stateProvinceManager.InsertStateProvince(stateProvince);
               
                ViewBag.RefreshPage = true;
                ViewBag.btnId = btnId;
                ViewBag.formId = formId;
               
                return View(model);
            }
           
            return View(model);
        }

        //edit
        public ActionResult StateEditPopup(int id)
        {
            var stateProvince = _stateProvinceManager.GetStateProvinceById(id);
            if (stateProvince == null) return RedirectToAction("List");

            var model = stateProvince.ToModel<StateProvinceModel>();
           
            return View(model);
        }

        [HttpPost]
        public ActionResult StateEditPopup(string btnId, string formId, StateProvinceModel model)
        {
            var stateProvince = _stateProvinceManager.GetStateProvinceById(model.Id);
            if (stateProvince == null) return RedirectToAction("List");

            if (TryUpdateModel(stateProvince))
            {
                if (ModelState.IsValid)
                {
                    _stateProvinceManager.UpdateStateProvince(stateProvince);

                    ViewBag.RefreshPage = true;
                    ViewBag.btnId = btnId;
                    ViewBag.formId = formId;
                    return View(model);
                }
            }

            return View(model);
        }

        [GridAction(EnableCustomBinding = true)]
        public ActionResult StateDelete(int id, GridCommand command)
        {
            var state = _stateProvinceManager.GetStateProvinceById(id);
            if (state == null) throw new ArgumentException("No state found with the specified id");

            if (_addressManager.GetAddressTotalByStateProvinceId(state.Id) > 0)
                return Content("Мэдээлэл ашиглалтанд байгаа тул устгах боломжгүй!");

            int countryId = state.CountryId;
            _stateProvinceManager.DeleteStateProvince(state);

            return States(countryId, command);
        }

        #endregion

        [AcceptVerbs(HttpVerbs.Get)]
        public ActionResult GetStatesByCountryId(string countryId,
            bool? addEmptyStateIfRequired, bool? addAsterisk)
        {
            //permission validation is not required here


            // This action method gets called via an ajax request
            if (String.IsNullOrEmpty(countryId))
                throw new ArgumentNullException("countryId");

            var country = _countryManager.GetCountryById(Convert.ToInt32(countryId));
            var states = country != null
                ? _stateProvinceManager.GetStateProvincesByCountryId(true, false, country.Id, true).ToList()
                : new List<StateProvinceInfo>();
            var result = (from s in states select new { id = s.Id.ToString(), name = s.Name }).ToList();
            if (addEmptyStateIfRequired.HasValue && addEmptyStateIfRequired.Value && result.Count == 0)
                result.Insert(0, new { id = "0", name = MessageUtil.GetHtmlSelectFirstItem() });
            else
            {
                if (result.Count == 0) result.Insert(0, new { id = "", name = MessageUtil.GetHtmlSelectEmptyItem() });
            }
            if (addAsterisk.HasValue && addAsterisk.Value)
                result.Insert(0, new { id = "0", name = "*" });
            return Json(result, JsonRequestBehavior.AllowGet);
        }
    }
}
 



 

CreateOrUpdate.cshtml

@model CountryInfo

@using Telerik.Web.Mvc.UI;
@Html.ValidationSummary(true)
@if (Model != null && Model.Id > 0)
{
    Html.HiddenFor(model => model.Id);
}
@Html.Telerik().TabStrip().Name("country-edit").Items(x =>
{
    x.Add().Text("Үндсэн мэдээлэл").Content(TabInfo().ToHtmlString()).Selected(true);
    x.Add().Text("Аймаг/хот").Content(TabStates().ToHtmlString());
})
@helper TabInfo()
{       
    <table class="adminContent">
        <tr>
            <td class="adminTitle">
                @Html.BorLabelFor(model => model.Name):
            </td>
            <td class="adminData">
                @Html.EditorFor(model => model.Name)
                @Html.ValidationMessageFor(model => model.Name)
            </td>
        </tr>
    </table>
    <table class="adminContent">
        <tr>
            <td class="adminTitle">
                @Html.BorLabelFor(model => model.TwoLetterIsoCode):
            </td>
            <td class="adminData">
                @Html.EditorFor(model => model.TwoLetterIsoCode)
                @Html.ValidationMessageFor(model => model.TwoLetterIsoCode)
            </td>
        </tr>
        <tr>
            <td class="adminTitle">
                @Html.BorLabelFor(model => model.ThreeLetterIsoCode):
            </td>
            <td class="adminData">
                @Html.EditorFor(model => model.ThreeLetterIsoCode)
                @Html.ValidationMessageFor(model => model.ThreeLetterIsoCode)
            </td>
        </tr>
        <tr>
            <td class="adminTitle">
                @Html.BorLabelFor(model => model.NumericIsoCode):
            </td>
            <td class="adminData">
                @Html.EditorFor(model => model.NumericIsoCode)
                @Html.ValidationMessageFor(model => model.NumericIsoCode)
            </td>
        </tr>
        <tr>
            <td class="adminTitle">
                @Html.BorLabelFor(model => model.DisplayOrder):
            </td>
            <td class="adminData">
                @Html.EditorFor(model => model.DisplayOrder)
                @Html.ValidationMessageFor(model => model.DisplayOrder)
            </td>
        </tr>
        <tr>
            <td class="adminTitle">
                @Html.BorLabelFor(model => model.Published):
            </td>
            <td class="adminData">
                @Html.EditorFor(model => model.Published)
                @Html.ValidationMessageFor(model => model.Published)
            </td>
        </tr>
    </table>
}
@helper TabStates()
{
    if (Model.Id > 0)
    {
    <table class="adminContent">
        <tr>
            <td>
                @(Html.Telerik().Grid<StateProvinceInfo>()
                    .Name("states-grid")
                    .DataKeys(x =>
                    {
                        x.Add(y => y.Id).RouteKey("Id");
                    })
                    .Columns(columns =>
                    {
                        columns.Bound(x => x.CentreName);
                        columns.Bound(x => x.Name);
                        columns.Bound(x => x.Abbreviation).Width(100);
                        columns.Bound(x => x.DisplayOrder).Width(100).Centered();
                        columns.Bound(x => x.IsCentre)
                            .Template(@<text>@Html.HintStateImageTag(item.IsCentre)</text>)
                            .ClientTemplate(string.Format(Html.HintStateImageTag(), "<#= IsCentre #>"))
                            .Centered()
                            .Width(100);
                        columns.Bound(x => x.IsWeather)
                            .Template(@<text>@Html.HintStateImageTag(item.IsWeather)</text>)
                            .ClientTemplate(string.Format(Html.HintStateImageTag(), "<#= IsWeather #>"))
                            .Centered()
                            .Width(100);
                        columns.Bound(x => x.Published)
                            .Template(@<text>@Html.HintStateImageTag(item.Published)</text>)
                            .ClientTemplate(string.Format(Html.HintStateImageTag(), "<#= Published #>"))
                            .Centered()
                            .Width(100);
                        columns.Bound(x => x.Id)
                            .Width(50)
                            .Centered()
                            .ClientTemplate("<input type='submit' value='Засах' onclick=\""
                                + "javascript:OpenWindow('" + @Url.Action("StateEditPopup")
                                + "/<#= Id #>?btnId=btnRefresh&formId=country-form', 800, 250, true); return false;\" class='t-button' />")
                            .Title("Засах");
                        columns.Command(commands =>
                        {
                            commands.Delete().Text("Устгах");
                        }).Title("Устгах").Width(50);

                    })
                    .DataBinding(dataBinding =>
                    {
                        dataBinding.Ajax()
                            .Select("States", "Country", new { countryId = Model.Id })
                            .Delete("StateDelete", "Country");
                    })
                    .ClientEvents(x => x.OnError("grid_onError"))
                    .EnableCustomBinding(true))
            </td>
        </tr>
        <tr>
            <td>
                @{
        var popupUrl = "javascript:OpenWindow('"
            + Url.Action("StateCreatePopup", "Country"
            , new { countryId = Model.Id, btnId = "btnRefresh", formId = "country-form" })
            + "', 800, 250, true); return false;";
                }
                <input type="submit" id="btnAddNewState" name="btnAddNewState" value="Нэмэх"
                    onclick="@popupUrl" class="t-button" />
                <input type="submit" id="btnRefresh" name="btnRefresh" style="display: none" />
                <script type="text/javascript">
                    $(document).ready(function () {
                        $('#btnRefresh').click(function () {
                            var optionsGrid = $("#states-grid");
                            optionsGrid.data('tGrid').ajaxRequest();
                            return false;
                        });
                    });
                </script>
            </td>
        </tr>
    </table>
    <script type="text/javascript">
        function grid_onError(e) {
            alert(e.XMLHttpRequest.responseText);
            e.preventDefault();
        }
    </script>
    }
    else
    {
        @:Хадгалсаны дараа нэмэлт мэдээлэл дээр засвар хийх боломжтой болно.
    }
}


HtmlExtensions.cs

public static class HtmlExtensions
    {
        public static string HintStateImageTag(this HtmlHelper helper)
        {
            return "<img alt=\"\" src=\""
                + ResolveUrl(helper, "~/Administration/Content/images/active-{0}.gif").ToHtmlString()
                + "\" />";
        }

        public static string HintStateImageTag(this HtmlHelper helper, bool value)
        {
            return "<img alt=\"\" src=\""
                + ResolveUrl(helper, "~/Administration/Content/images/active-" + value.ToString().ToLowerInvariant() + ".gif").ToHtmlString()
                + "\" />";
        }

        public static string HintStateImageUrl(this HtmlHelper helper, bool value)
        {
            return ResolveUrl(helper
                , "~/Administration/Content/images/active-" + value.ToString().ToLowerInvariant() + ".gif").ToHtmlString();
        }

        public static MvcHtmlString ResolveUrl(this HtmlHelper htmlHelper, string url)
        {
            var urlHelper = new UrlHelper(htmlHelper.ViewContext.RequestContext);
            return MvcHtmlString.Create(urlHelper.Content(url));
        }

        public static MvcHtmlString Hint(this HtmlHelper helper, string value)
        {
            // Create tag builder
            var builder = new TagBuilder("img");

            // Add attributes
            builder.MergeAttribute("src", ResolveUrl(helper, "~/Administration/Content/images/ico-help.gif").ToHtmlString());
            builder.MergeAttribute("alt", value);
            builder.MergeAttribute("title", value);

            // Render tag
            return MvcHtmlString.Create(builder.ToString());
        }

        public static MvcHtmlString DeleteConfirmation<T>(this HtmlHelper<T> helper, string buttonsSelector = null) where T : BaseBorEntityModel
        {
            return DeleteConfirmation<T>(helper, "", buttonsSelector);
        }
        public static MvcHtmlString DeleteConfirmation<T>(this HtmlHelper<T> helper, string actionName, string buttonsSelector = null) where T : BaseBorEntityModel
        {
            if (String.IsNullOrEmpty(actionName))
                actionName = "Delete";

            var modalId = MvcHtmlString.Create(helper.ViewData.ModelMetadata.ModelType.Name.ToLower() + "-delete-confirmation").ToHtmlString();

            //there's an issue in Telerik (ScriptRegistrar.Current implemenation)
            //it's a little hack to ensure ScriptRegistrar.Current is loaded
            helper.Telerik();

            #region Write click events for button, if supplied

            if (!string.IsNullOrEmpty(buttonsSelector))
            {
                var textWriter = new StringWriter();
                IClientSideObjectWriter objectWriter = new ClientSideObjectWriterFactory()
                    .Create(buttonsSelector, "click", textWriter);
                objectWriter.Start();
                textWriter.Write("function(e){e.preventDefault();openModalWindow(\"" + modalId + "\");}");
                objectWriter.Complete();
                var value = textWriter.ToString();
                ScriptRegistrar.Current.OnDocumentReadyStatements.Add(value);
            }

            #endregion

            var deleteConfirmationModel = new DeleteConfirmationModel
            {
                Id = helper.ViewData.Model.Id,
                ControllerName = helper.ViewContext.RouteData.GetRequiredString("controller"),
                ActionName = actionName
            };

            var window = helper.Telerik().Window().Name(modalId)
                .Title("Та мэдээллийг устгахдаа итгэлтэй байна уу?")
                .Modal(true)
                .Effects(x => x.Toggle())
                .Resizable(x => x.Enabled(false))
                .Buttons(x => x.Close())
                .Visible(false)
                .Content(helper.Partial("Delete", deleteConfirmationModel).ToHtmlString()).ToHtmlString();

            return MvcHtmlString.Create(window);
        }

        public static MvcHtmlString BorLabelFor<TModel, TValue>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TValue>> expression, bool displayHint = true)
        {
            var result = new StringBuilder();
            var metadata = ModelMetadata.FromLambdaExpression(expression, helper.ViewData);
            var hintResource = string.Empty;
            object value = null;
            if (metadata.AdditionalValues.TryGetValue("Display", out value))
            {
                var resourceDisplayName = value as DisplayAttribute;
                if (resourceDisplayName != null && displayHint)
                {
                    hintResource = resourceDisplayName.Name;
                }
            }
            if (string.IsNullOrEmpty(hintResource) && !string.IsNullOrEmpty(metadata.DisplayName) && metadata.IsRequired)
            {
                hintResource = metadata.DisplayName + "*";
            }

            result.Append(helper.Hint(hintResource).ToHtmlString());
            result.Append(helper.LabelFor(expression, new { title = hintResource }));
            return MvcHtmlString.Create(result.ToString());
        }

        public static MvcHtmlString RequiredHint(this HtmlHelper helper, string additionalText = null)
        {
            // Create tag builder
            var builder = new TagBuilder("span");
            builder.AddCssClass("required");
            var innerText = "*";
            //add additinal text if specified
            if (!String.IsNullOrEmpty(additionalText))
                innerText += " " + additionalText;
            builder.SetInnerText(innerText);
            // Render tag
            return MvcHtmlString.Create(builder.ToString());
        }

        public static string FieldNameFor<T, TResult>(this HtmlHelper<T> html, Expression<Func<T, TResult>> expression)
        {
            return html.ViewData.TemplateInfo.GetFullHtmlFieldName(ExpressionHelper.GetExpressionText(expression));
        }
        public static string FieldIdFor<T, TResult>(this HtmlHelper<T> html, Expression<Func<T, TResult>> expression)
        {
            var id = html.ViewData.TemplateInfo.GetFullHtmlFieldId(ExpressionHelper.GetExpressionText(expression));
            // because "[" and "]" aren't replaced with "_" in GetFullHtmlFieldId
            return id.Replace('[', '_').Replace(']', '_');
        }

        /// <summary>
        /// Creates a days, months, years drop down list using an HTML select control.
        /// The parameters represent the value of the "name" attribute on the select control.
        /// </summary>
        /// <param name="html">HTML helper</param>
        /// <param name="dayName">"Name" attribute of the day drop down list.</param>
        /// <param name="monthName">"Name" attribute of the month drop down list.</param>
        /// <param name="yearName">"Name" attribute of the year drop down list.</param>
        /// <param name="beginYear">Begin year</param>
        /// <param name="endYear">End year</param>
        /// <param name="selectedDay">Selected day</param>
        /// <param name="selectedMonth">Selected month</param>
        /// <param name="selectedYear">Selected year</param>
        /// <param name="localizeLabels">Localize labels</param>
        /// <returns></returns>
        public static MvcHtmlString DatePickerDropDowns(this HtmlHelper html,
            string dayName, string monthName, string yearName,
            int? beginYear = null, int? endYear = null,
            int? selectedDay = null, int? selectedMonth = null, int? selectedYear = null, bool localizeLabels = true)
        {
            var daysList = new TagBuilder("select");
            var monthsList = new TagBuilder("select");
            var yearsList = new TagBuilder("select");

            daysList.Attributes.Add("name", dayName);
            monthsList.Attributes.Add("name", monthName);
            yearsList.Attributes.Add("name", yearName);

            var days = new StringBuilder();
            var months = new StringBuilder();
            var years = new StringBuilder();

            string dayLocale, monthLocale, yearLocale;
            if (localizeLabels)
            {
                dayLocale = "Өдөр";
                monthLocale = "Сар";
                yearLocale = "Он";
            }
            else
            {
                dayLocale = "Day";
                monthLocale = "Month";
                yearLocale = "Year";
            }

            days.AppendFormat("<option value='{0}'>{1}</option>", "0", dayLocale);
            for (int i = 1; i <= 31; i++)
                days.AppendFormat("<option value='{0}'{1}>{0}</option>", i,
                    (selectedDay.HasValue && selectedDay.Value == i) ? " selected=\"selected\"" : null);


            months.AppendFormat("<option value='{0}'>{1}</option>", "0", monthLocale);
            for (int i = 1; i <= 12; i++)
            {
                months.AppendFormat("<option value='{0}'{1}>{2}</option>",
                                    i,
                                    (selectedMonth.HasValue && selectedMonth.Value == i) ? " selected=\"selected\"" : null,
                                    CultureInfo.CurrentUICulture.DateTimeFormat.GetMonthName(i));
            }


            years.AppendFormat("<option value='{0}'>{1}</option>", "0", yearLocale);

            if (beginYear == null)
                beginYear = DateTime.UtcNow.Year - 100;
            if (endYear == null)
                endYear = DateTime.UtcNow.Year;

            for (int i = beginYear.Value; i <= endYear.Value; i++)
                years.AppendFormat("<option value='{0}'{1}>{0}</option>", i,
                    (selectedYear.HasValue && selectedYear.Value == i) ? " selected=\"selected\"" : null);

            daysList.InnerHtml = days.ToString();
            monthsList.InnerHtml = months.ToString();
            yearsList.InnerHtml = years.ToString();

            return MvcHtmlString.Create(string.Concat(daysList, monthsList, yearsList));
        }

        public static MvcHtmlString Widget(this HtmlHelper helper, string widgetZone)
        {
            return helper.Action("WidgetsByZone", "Widget", new { widgetZone = widgetZone });
        }
    }