استفاده از modal بوت استرپ

در این مقاله میخوام با استفاده از Modal بوت استرپ فرم های ویرایش ، اضافه ، و حذف را در همان صفحه باز کنیم بدون اینکه صفحه ای جدا طراحی کنیم.

استفاده از modal بوت استرپ

این ایده ی نمایش مشاهده ی ویرایش استاندارد با ویرایشگرهای طبقه بندی شده ی استاندارد برای اشیای master و آرگومان های آن با لیستی از ویرایشگر ها که اجازه ی ویرایش لیستی از اشیای فرزندان را در همان صفحه دارند , است.

معمولا چیزی که ما از داخل جعبه از قالب های  VS2013 ASP.NET MVC طبقه بندی شده خارج میکنیم  مدل های ساده است.

به سرعت فهمیدم که این کار ساده ای نیست تا اینکه معجزه ی گسترش RenderAction Http را کشف کردم.

من سعی کردم که نمونه های بسیار آسان را به آن الحاق کنم اما پایه ی دانش ASP.NET MVC مورد نیاز است .

کد های اولیه :

در ابتدا اجازه دهید که یک پروژه ی ASP.NET استاندارد و جدیدی بنام TestAjax  با انتخاب قالب MVC با قراردادن مرجع اصلی MVC و بدون تصدیق بسازیم.

برای ساده نگه داشتن آن بیاید دو مدل بسازیم : اشخاص و لیست آدرس های مرتبط با هر شخص

"namespace TestAjax.Models
{
    public class Person
    {
        public int Id { get; set; }

        [Display(Name = "First Name")]
        [Required]
        [StringLength(255, MinimumLength = 3)]
        public string Name { get; set; }

        [Display(Name = "Last Name")]
        [Required]
        [StringLength(255, MinimumLength = 3)]
        public string  Surname { get; set; }

        public virtual ICollectionAddress Addresses { get; set; }
    }
}

namespace TestAjax.Models
{
    public class Address
    {
        public int Id { get; set; }

        [Required]
        [StringLength(255, MinimumLength = 3)]
        public string City { get; set; }
       
        [Display(Name = "Street Address")]
        public string Street { get; set; }

        [Phone]
        public string Phone { get; set; }

        public int PersonID { get; set; }
        public virtual Person Person  { get; set; }
    }
}

حال که مدل هایمان را سر جای خود دادیم  کنترلر ها را میسازیم.

بر روی فولدر کنترلر راست کلیک کنید و گزینه ی افزودن کنترلر را انتخاب کنید و از بخش دیالوگ ” MVC 5 Controller with views, using Entity Framework ” را انتخاب کنید.

حال شخص را به عنوان کلاس مدل انتخاب میکنیم , یک DataDb جدید میسازیم و همه chechbox های داخل دیالوگ را انتخاب میکنیم.

پروژه را بازسازی کنید و کنترلر دیگری برای انتخاب آدرس DataDb ساخته شده بیافزایید.

برای آماده سازی مرحله ی نهایی کنترلر خانه و فولدر خانه از بخش مشاهده را حذف کنید.

در مشاهده _Layout اشتراک گذاری شده آیتم های منوی استاندارد را با کلمه ی Index تعویض کنید , درباره ی Contact  با یکی که اشاره به People دارد :

"@Html.ActionLink("People","Index","People"),/pre

و در نهایت در App_Start\RouteConfig.cs ما باید کلمه Index را با People جایگزین کنیم که برنامه مان به طور پیش فرض به کنترلر People اشاره میکند.

حال که پروژه مان تکمیل و اجرا شده ما , تغییرات ارائه خواهند شد.

آیکون های Bootstrap در دکمه ها

برای زیباسازی دکمه های نمونه من تصمیم گرفتم که دکور آنها را به صورت Bootstarp glyphicons دربیاورم. به خاطر سینتکس های glyphicon ها :

button type="button" class="btn btn-default btn-lg"
  span class="glyphicon glyphicon-star"/span Star
/button

من یک  HtmlHelper نیز افزوده ام تا خروجی صحیح Html  را از کمک کننده ی ActionLink بدست آورد.

در داخل پروژه فولدر های HtmlHelper بسازید و داخل آنها کلاس MyHelper.cs

کد کمک کننده :

// As the text the: "span class='glyphicon glyphicon-plus'/span" can be entered
        public static MvcHtmlString NoEncodeActionLink(this HtmlHelper htmlHelper,
                                             string text, string title, string action,
                                             string controller,
                                             object routeValues = null,
                                             object htmlAttributes = null)
        {
            UrlHelper urlHelper = new UrlHelper(htmlHelper.ViewContext.RequestContext);

            TagBuilder  builder = new TagBuilder("a");
            builder.InnerHtml = text;
            builder.Attributes["title"] = title;
            builder.Attributes["href"] = urlHelper.Action(action, controller, routeValues);
            builder.MergeAttributes(new RouteValueDictionary(HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes)));

            return MvcHtmlString.Create(builder.ToString());
        }

حال برای دکمه ی glyphed خروجی با استفاده از ActionLink از این سینتکس استفاده میکنیم :

"@Html.NoEncodeActionLink("span class='glyphicon glyphicon-plus'/span", "Add new Person", "Create", "People", routeValues: null, htmlAttributes: new { @class = "btn btn-primary" })

در داخل شاخص کنترلر مشاهده ی Pepalle@using TextAjax را بیافزایید. Helper ها ,هدایتگر بالای صفحه میباشند. بعد از آن جای @Html.ActionLink(“Create New” , “Create”) را با متن زیر تغییر دهید :

"div class="pull-right"
 @Html.NoEncodeActionLink("span class='glyphicon glyphicon-plus'/span", "Add new Person", "Create", "People", routeValues: null, htmlAttributes: new { @class = "btn btn-primary" })
/div

وویرایش , جزئیات ,  ساختن ActionLink با :

"div class="pull-right"
    @Html.NoEncodeActionLink("span class='glyphicon glyphicon-pencil'/span", "Edit", "Edit", "People", routeValues: new { id = item.Id }, htmlAttributes: new { data_modal = "", @class = "btn btn-default" })
     
    @Html.NoEncodeActionLink("span class='glyphicon glyphicon-search'/span", "Details", "Details", "People", routeValues: new { id = item.Id }, htmlAttributes: new { data_modal = "", @class = "btn btn-default" })
     
    @Html.NoEncodeActionLink("span class='glyphicon glyphicon-trash'/span", "Delete", "Delete", "People", routeValues: new { id = item.Id }, htmlAttributes: new { data_modal = "", @class = "btn btn-danger" })
/div

حال ما باید آیکون های خودمان را در جای مناسب قرار دهیم.

لیست ها

یک تصویر برای درک بهتر براتون قرار میدم.

استفاده از modal بوت استرپ

RenderAction خروجی را از کار های مختلف بر مشاهده تزریق میکند.

تنها چیزی که باید به خاطر داشته باشیم این است که کنترلر فرزند نباید اجازه “فرار” از مشاهده داشته باشد.

به همین  دلیل ما تمام مشاهدات فرزندان را به عنوان بخش های ویرایش شده در مکان با مدل ها اجرا میکنیم.

برای شروع کنترلر ویرایش مشاهده ی Pepale را ویرایش میکنیم.

درست قبل از “برگشت به لیست” تکه ی زیر را وارد نمایید :

"div class="row"
    div class="col-md-offset-2 col-md-10"
        @{ Html.RenderAction("Index", "Addresses", new { id = Model.Id }); }
    /div
/div

حال ما باید کنترلر آدرس را تعیین کنیم زیرا مشاهده ی استاندارد در شاخص Action را بازمیگرداند.

چیزی که ما به جای آن نیاز داریم مشاهده ی بخشی است.

پس من تلاش میکنم که این قطعه کد را برای شاخص Action وارد کنم :

 "// GET: Addresses
[ChildActionOnly]
public async TaskActionResult Index(int id)
{
    ViewBag.PersonID = id;
    var addresses = db.Addresses.Where(a = a.PersonID == id);

    return PartialView("_Index", await addresses.ToListAsync());
}

بعد از راه اندازی این خطا را دریافت کردم “HttpServerUtility.Exexute was blocked by waiting for the end of an asynchronous operation.”

بعد از کمی تحقیق و جستجو در اینترنت متوجه شدم که عملیات های ناهمگام در اکشن فرزندان در ورژن MVC مجاز نمیباشد.

پس به عنوان یه تعمیر سریع ,کنترلر آدرس و فولدر آدرس ها در بخش مشاهده را حذف کنید . سپس دوباره کنترلر آدرس ها را طبقه بندی کنید اما تیک بخش ” Use async controller action ” را اینبار بردارید.

شاخص ویرایش شده حال باید به صورت زیر باشد :

[ChildActionOnly]
public ActionResult Index(int id)
{
    ViewBag.PersonID = id;
    var addresses = db.Addresses.Where(a = a.PersonID == id);

    return PartialView("_Index", addresses.ToList());
}

سپس باید نام “Index.cshtml ” را به “_Index.cshtml” در مشاهده ی آدرس ها تغییر دهید سپس از آن اجرا بگیرید.

من دوراسیون شاخص اکشن را با خاصیت “فقط اکشن فرزندان” قرار دادم زیرا نمیخواهیم این متد مستقیما فراخوانی شود .

پارامتر ID به ما اجازه میدهد تا آدرسی که برای شخص داده شده است را دریافت کنیم.

ViewBag.PersonID برای خواندن ساخت آدرس در شاخص مفید خواهد بود.

برنامه اکنون اجرا میشود اما، ما هنوز ویرایش در مکان آدرس ها را اجرا نکرده ایم. پس کلیک بر روی ساخت لینک ما را به مشاهده ی دیگری میبرد.

شما میتوانید با حذف موقتی خاصیت “تنها اکشن فرزندان” و کلیک بر لینکش آن را امتحان کنید.

برای جلوگیری از فرار از مشاهده ما از مودال های Bootstrap با کمی کمک از جاوا سکریپت استفاده میکنیم.

مودال های Bootstrap

من اسکریپت های زیر را به مودال هایbootstrap  تبدیل کردم.

// modalform.js

$(function () {

    $.ajaxSetup({ cache: false });

    $("a[data-modal]").on("click", function (e) {

        // hide dropdown if any
        $(e.target).closest('.btn-group').children('.dropdown-toggle').dropdown('toggle');

       
        $('#myModalContent').load(this.href, function () {
           

            $('#myModal').modal({
                /*backdrop: 'static',*/
                keyboard: true
            }, 'show');

            bindForm(this);
        });

        return false;
    });

});

function bindForm(dialog) {
   
    $('form', dialog).submit(function () {
        $.ajax({
            url: this.action,
            type: this.method,
            data: $(this).serialize(),
            success: function (result) {
                if (result.success) {
                    $('#myModal').modal('hide');
                    //Refresh
                    location.reload();
                } else {
                    $('#myModalContent').html(result);
                    bindForm(dialog);
                }
            }
        });
        return false;
    });
}

تابع ا سکریپت به سه چیز احتیاج دارد :

۱-    در مشاهده این ترتیب از مکان نگه دارنده ها :

!-- modal placeholder--
div id='myModal' class='modal fade in'
    div class="modal-dialog"
        div class="modal-content"
            div id='myModalContent'/div
        /div
    /div
/div

۲- در مشاهده ای که میخواهیم این نوع علامت را در جایش قرار دهیم :

div class="modal-header"
    button type="button" class="close" data-dismiss="modal" aria-hidden="true"times;/button
    h4 class="modal-title" id="myModalLabel"Add new Address/h4
/div

@using (Html.BeginForm())
{
    div class="modal-body"
        // Place Form  editors here
    /div
    /div
    div class="modal-footer"
        button class="btn" data-dismiss="modal"Cancel/button
        input class="btn btn-primary" type="submit" value="Add" /
    /div
}

۳- مشاهده ی حمایتی اکشن در مدل باید Json(new { success = true}); را به جای View(); بازگزداند.

یادداشت : لطفا به یاد داشته باشید که اسکریپت به خاصیت مدل داده در ساخت اکشن لینک احتیاج دارد.

یادداشت : خوب است که یک خاصیت از نوع دکمه به دکمه ی منتصل کردن داده – شما از مشکلات با مودال هایbootstrap  زمانی که کاربر دکمه ی کلید بازگشت را میفشارد برای دریافت دیالوگ . در بعضی از مودال های مرورگر ها بدون این خاصیت فقط بسته میشوند .

برای کامل کردن bootstrap مودال های ۳.۱.۱ در MVC 5 به نمونه دقت کنید.

در پروژه ما من یک modalform.js به فولدر سکریپت و bundles.Add(new ScriptBundle(“~/bundles/modalform”).Include(“~/Scripts/modalform.js”)); اضافه کردم.خط به AppStart\BundleConfig.cs.حال با ویرایش ” “_Index.schtml به لایه زیر میرسیم :

@using TestAjax.Helpers
@model IEnumerableTestAjax.Models.Address

!-- modal placeholder--
div id='myModal' class='modal fade in'
    div class="modal-dialog"
        div class="modal-content"
            div id='myModalContent'/div
        /div
    /div
/div

div class="panel panel-default"
    div class="panel-heading"
        strongAddress List/strong
    /div

    table class="table table-hover"
        tr
            th
                @Html.DisplayNameFor(model = model.City)
            /th
            th
                @Html.DisplayNameFor(model = model.Street)
            /th
            th
                @Html.DisplayNameFor(model = model.Phone)
            /th
            th@Html.NoEncodeActionLink("span class='glyphicon glyphicon-plus'/span", "Add", "Create", "Addresses", routeValues: new { PersonId = ViewBag.PersonID }, htmlAttributes: new { data_modal = "", @class = "btn btn-primary pull-right" })/th
        /tr

        @foreach (var item in Model)
        {
            tr
                td
                    @Html.DisplayFor(modelItem = item.City)
                /td
                td
                    @Html.DisplayFor(modelItem = item.Street)
                /td
                td
                    @Html.DisplayFor(modelItem = item.Phone)
                /td
                td
                    div class="pull-right"
                        @Html.NoEncodeActionLink("span class='glyphicon glyphicon-pencil'/span", "Edit", "Edit", "Addresses", routeValues: new { id = item.Id }, htmlAttributes: new { data_modal = "", @class = "btn btn-default" })
                         
                        @Html.NoEncodeActionLink("span class='glyphicon glyphicon-trash'/span", "Delete", "Delete", "Addresses", routeValues: new { id = item.Id }, htmlAttributes: new { data_modal = "", @class = "btn btn-danger" })
                       
                    /div
                /td
            /tr
        }
    /table
/div

افزودن حمایت کننده برای مودال ها در “Edit.cshtml” Pepale در بخش متن ها:

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
    @Scripts.Render("~/bundles/modalform")
}

برای کار کردن با مودال ها در کنترلر آدرس ها ما باید متد ” Create ” را تغییر دهیم.

public ActionResult Create(int PersonID)
{
    Address address = new Address();
    address.PersonID = PersonID;

    return PartialView("_Create", address);
}

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "Id,City,Street,Phone,PersonID")] Address address)
{
    if (ModelState.IsValid)
    {
        db.Addresses.Add(address);
        db.SaveChanges();
        return Json(new { success = true });
    }

    return PartialView("_Create");
}

و در نهایت آدرس ” _Creat.chtml ”  تغییر نام یافته باید به فرم زیر تبدیل شود :

@model TestAjax.Models.Address

div class="modal-header"
    button type="button" class="close" data-dismiss="modal" aria-hidden="true"×/button
    h4 class="modal-title" id="myModalLabel"Add new Address/h4
/div

@using (Html.BeginForm())
{
    div class="modal-body"

        @Html.AntiForgeryToken()
        div class="form-horizontal"
            @Html.ValidationSummary(true, "", new { @class = "text-danger" })

            div class="form-group"
                @Html.LabelFor(model = model.City, htmlAttributes: new { @class = "control-label col-md-2" })
                div class="col-md-10"
                    @Html.EditorFor(model = model.City, new { htmlAttributes = new { @class = "form-control" } })
                    @Html.ValidationMessageFor(model = model.City, "", new { @class = "text-danger" })
                /div
            /div

            div class="form-group"
                @Html.LabelFor(model = model.Street, htmlAttributes: new { @class = "control-label col-md-2" })
                div class="col-md-10"
                    @Html.EditorFor(model = model.Street, new { htmlAttributes = new { @class = "form-control" } })
                    @Html.ValidationMessageFor(model = model.Street, "", new { @class = "text-danger" })
                /div
            /div

            div class="form-group"
                @Html.LabelFor(model = model.Phone, htmlAttributes: new { @class = "control-label col-md-2" })
                div class="col-md-10"
                    @Html.EditorFor(model = model.Phone, new { htmlAttributes = new { @class = "form-control" } })
                    @Html.ValidationMessageFor(model = model.Phone, "", new { @class = "text-danger" })
                /div
            /div

        /div
    /div
    div class="modal-footer"
        button class="btn" data-dismiss="modal"Cancel/button
        input class="btn btn-primary" type="submit" value="Add" /
    /div
}

حال ما میتوانیم خط آدرس جدید را بدون فرار از از قسمت ” مشاهده ی ویرایش شخص ” بیافزاییم.

استفاده از modal بوت استرپ

استفاده از modal بوت استرپ

از الگوی مشابه برای ساخت بخش های _Edit و _Delete استفاده میشود .

علاوه بر این میتوانیم یک بخش بنام _List بسازیم تا که در جزئیات مشاهده ی شخص نمایش داده شود.

برای سایر بخش ها لطفا به دانلود های الحاقی مراجعه کنید که شامل سورس کامل برای برای پروژه میباشد.

نکته : برای به روز رسانی بسته های Nuget در الحاقی ها برنامه را بازسازی کنید.

شما باید هردو گزینه ی ” اجازه به Nuget برای دانلود بسته های گمشده ” و ” به صورت اتوماتیک به دنبال بسته های گمشده گشتن در طول ساخت در ویژوال استودیو ” را در تنظیمات NuGet تیک بزنید.

امید وارم استفاده کنید.

جزئیات فایل

زبان پروژه : MVC
حجم فایل پیوست : 200 KB

دانلود فایل

دانلود با لینک مستقیم
پسورد فایل : www.mspsoft.com
داریوش فرخی

داریوش فرخی هستم از سال 92 شروع به یادگیری برنامه نویسی و از سال 93 در بخش برنامه نویسی و تولید محتوای سایت mspsoft.com مشغول هستم. فعالیتم نیز بیشتر در زمینه های برنامه نویسی با سی شارپ و asp.net بوده است. اوقات فراغتم را هم غالبا با تماشای فیلم یا بازی های کامپیوتری پر میکنم .

نوشته‌های مرتبط

دیدگاه‌ها

*
*

این سایت از اکیسمت برای کاهش هرزنامه استفاده می کند. بیاموزید که چگونه اطلاعات دیدگاه های شما پردازش می‌شوند.