ساخت بنرهشداردهنده با استفاده از Bootstrap و AngularUI Bootstrap در MVC

دراین مقاله،نحوه ساخت یک بنر هشداردهنده و یک Modal با قابلیت استفاده مجدد، درMVC به کمک jQuery، Web API، بوت استرپ، AngularJS و AngularUI Bootstrap را آموزش خواهیم داد.

ساخت بنرهشداردهنده با استفاده از Bootstrap و AngularUI Bootstrap در MVC

مقدمه

بعضی از کاربران بنر هشدار دهنده(warning banner) را با نام هایی همچون disclaimer banner، consent screen، پذیرش قوانین کار با سیستم، log-on warning banner، login policy، Logon Banner، Logon Notice و ... می شناسند ولی در اصل همه اینها، همان صفحه ایی است که وقتی کاربر برای بار اول وارد برنامه می شود، مشاهده می کند.

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

- نحوه ساخت بنر هشدار دهنده به کمک jQuery و Bootstrap

- نحوه ساخت بنر هشدار دهنده به کمک AngularJS و AngularUI Bootstrap

- نحوه ساخت یک Web API ساده

- نحوه دسترسی به Web API از داخل کنترلر برنامه MVC

- نحوه افزودن نشانه anti-forgery در درخواست های AJAX از نوع Post

- نحوه ساخت یک Modal با قابلیت استفاده مجدد در MVC به کمک partial view و jQuery و Bootstrap

- نحوه ساخت یک Modal با قابلیت استفاده مجدد به کمک AngularJS Template و AngularUI Bootstrap

- نحوه ساخت یک فیلتر احراز هویت

در شکل زیر مشاهده می کنید که برنامه شامل دو پروژه با نام های CommonApp و WarningBanner است. پروژه CommonApp یک Web API است که مسئول ارسال محتویات داخل بنر هشدار دهنده است.

شکل 1

View
در فهرست 1، کدهای Bootstrap modal را مشاهده می کنیم که در یک view با نام WarningPage قرار داده شده است. در این مثال محتویات بدنه modal به کمک ViewBag پر می شود. شما می توانید با توجه به نیازهای برنامه، بجای ViewBag از Model یا حتی hard-code استفاده کنید. مقدار صفت data-keyboard را برابر False قرار داده ایم تا وقتی کاربر دکمه ESC در کیبورد را زد، از بسته شدن بنر هشدار دهنده جلوگیری نماییم.

فهرست 1

@{ Html.RenderPartial("~/Views/Shared/_AntiforgeryToken.cshtml"); }  
div class="modal fade" id="myModal" role="dialog" data-keyboard="false" data-backdrop="static">  
    <div class="modal-dialog">  
    <div class="modal-content">  
    <div class="modal-header">  
    <button type="button" class="close" data-dismiss="modal">×</button>  
            </div>  
        @if (ViewBag.SystemWarningMessage != null)  
        {  
    <div class="modal-body"> @Html.Raw(ViewBag.SystemWarningMessage)</div>  
        }  
    <div class="modal-footer">  
    <button type="button" class="btn btn-default" id="btnAcceptPolicy" data-dismiss="modal">OK</button>  
            </div>  
        </div>  
    </div>  
</div>  

View Action

در زمان بارگذاری صفحه، اکشن متد WarningPage بررسی می کند که کاربر بر روی دکمه OK در صفحه بنر هشدار دهنده کلیک کرده است یا خیر. اگر جواب مثبت باشد، درخواست را به صفحه اصلی منتقل می کند و درغیر اینصورت بنر هشدار دهنده را در صفحه به کاربر نمایش می دهد.

فهرست 2

public ActionResult WarningPage()  
    {  
        if (Session["SessionOKClick"] != null)  
        {  
            return RedirectToAction("Index");  
        }  
        SetWarningBanner();  
        return View();  
    }  

در فهرست 3، کدهای مربوط به قرار دادن محتویات در بنر هشدار دهنده را قرار داده ایم. در این مثال روش کار این است که محتوای داخل بنر هشدار دهنده را از طریق Web API و کلاس HttpClient دریافت نماییم. کدها بسیار واضح هستند ولی با این حال می توانیم به بهبود بیشتر این کدها بپردازیم. کدهای نوشته شده را می توانیم به شکلی ویرایش نماییم که Web API URI را از داخل فایل پیکربندی(configuration file) دریافت نماید و کاری کنیم که خروجی برنامه قبل از ارسال به سمت کاربر، بررسی شود و پاکسازی شود تا کاربر یک فایل JSON پاکسازی شده دریافت نماید. اگر قصد استفاده از Web API را نداشتید، می توانید کدها را طوری ویرایش نمایید که داده ها را از طریق دیتابیس یا فایل پیکربندی یا ... دریافت نماید. هدف اصلی استفاده از هدرهای cache-control در این روش این است که در صورت کلیک شدن دکمه بازگشت در مرورگر، از قرار گرفتن داده ها در حافظه موقت مرورگر جلوگیری نماییم. به عنوان مثال اگر کاربر بعد از پذیرفتن قوانین، بر روی دکمه بازگشت مروگر کلیک نماید، بنر هشدار دهنده دوباره نمایش داده خواهد شد و کاربر مجبور خواهد شد که قوانین را دوباره بپذیرد.

فهرست 3

internal void SetWarningBanner()  
{  
    Response.Cache.SetCacheability(HttpCacheability.NoCache);  
    Response.Cache.SetExpires(DateTime.UtcNow.AddHours(-1));  
    Response.Cache.SetNoStore();  
    //Content can be from the database/Entity, Web Services, hardcode here  
    using (var client = new HttpClient())  
    {  
        client.BaseAddress = new Uri("http://localhost:47503");  
        client.DefaultRequestHeaders.Accept.Clear();  
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));  
        var response = client.GetAsync("api/warningbanner/1").Result;  
        if (response.IsSuccessStatusCode)  
        {  
            string responseString = response.Content.ReadAsStringAsync().Result;  
            JObject json = JObject.Parse(responseString);  
        //you can update the code to sanitize the json output here  
            ViewBag.SystemWarningMessage = json["Content"].ToString();  
        }  
    }  
}  

Web API

در فهرست 4، کدهای مربوط به کنترلر web API را مشاهده می کنیم. این کلاس شامل یک شی WarningBanner است که در این شی چند داده اولیه قرار دارد و همچنین در این کلاس یک متد وجود دارد که با دریافت Id محتویات شی WarningBanner متناظر با آن Id  را برمی گرداند.

فهرست 4

public class WarningBannerController : ApiController  
{  
//sample data   
IList<WarningBanner> warningBanners = new List<WarningBanner>  
    {  
        new WarningBanner { Id = 1, Content = "<b> *** Warning Banner Content 1 ****</b>",  
            LastUpdatedDate = DateTime.Now},  
        new WarningBanner { Id = 2, Content = "<b> *** Warning Banner Content 2 ****</b>",                 
            LastUpdatedDate= DateTime.Now.AddDays(-30)}  
    };  
    public IHttpActionResult Get(int id)  
    {  
        var banner = warningBanners.FirstOrDefault((p) => p.Id == id);  
        if (banner == null)  
        {  
            return NotFound();  
        }  
        return Ok(banner);  
    }  
}  

رویداد کلیک برای کلید OK

در فهرست 5، می بینیم که در صورت کلیک بر روی دکمه OK، به کمک یک تابع Ajax و به روش Post، اکشن متد Home/AcceptPolicy را فراخوانی می نماییم. در این مثال درخواست شامل نشان anti-forgery و مقادیری به شکل کلید/مقدار است. اگر درخواست موفق بود، درخواست را به صفحه ایی که از آنجا آمده است برمی گردانیم.

فهرست 5

<script type="text/javascript">  
    $(window).load(function () {  
        $('#myModal').modal('show');  
    });  
    jQuery(document).ready(function () {  
        jQuery("#btnAcceptPolicy").click(function () {  
            jQuery.ajax({  
                type: "POST",  
                url: '@Url.Content("~/Home/AcceptPolicy")',  
                data: { rURL: 'someDummyValue' },  
                beforeSend: function (xhr) { xhr.setRequestHeader('RequestVerificationToken', $("#antiForgeryToken").val()); },  
                success: function (data) {  
                    window.location.href = data;  
                }  
            });  
        });  
    });  
</script>  

Action method برای کلید Ok

اکشن متد AcceptPolicy ، دارای صفت HttpPost  و AjaxValidateAntiForgeryToken است. هدف اصلی این متد این است که به client اعلام کند پس از کلیک شدن کلید Ok درخواست به کدام URL ارسال شود. کدهای این متد در فهرست 6 قرار داده شده است. می توان حرکت های خلاقانه ایی در این بخش انجام داد، مثلا افزودن دستوراتی برای لاگ گیری از جواب های کاربران. این متد یک پارامتر ورودی با نام rURL دارد که این متغییر توسط کدهای ما استفاده نمی شود. هدف اصلی از قرار دادن این پارامتر در متد این است که نشان دهیم می توان از طریق AJAX post، پارامتر هم به اکشن متد ارسال کرد. هدف اصلی از ایجاد متغییر از نوع session با نام SessionOKClick، این است که اگر کاربر بر روی کلید Ok کلیک کرد، اطلاعات کلیک کردن کاربر را نگه داریم. دیگر متغییر session که نام آن SessionReturnUrl است، وظیفه نگهداری آدرسی که درخواست از آنجا ایجاد شده است را دارد. این آدرس در متد AuthorizeAttribute.OnAuthorization قرار داده می شود که در مورد این متد در بخش بعد توضیح خواهیم داد.

فهرست 6

[HttpPost]  
[AjaxValidateAntiForgeryToken]  
public ActionResult AcceptPolicy(string rURL)  
{  
    Session["SessionOKClick"] = "1";  
    string decodedUrl = string.Empty;  
    //return url to redirect after user accepted the policy  
    if (Session["SessionReturnUrl"] != null)  
    {  
        decodedUrl = Server.UrlDecode(Session["SessionReturnUrl"].ToString());  
    }  
    if (Url.IsLocalUrl(decodedUrl))  
    {  
        return Json(decodedUrl);  
    }  
    else  
    {  
        return Json(Url.Action("Index", "Home"));  
    }  
}  

سفارشی سازی فیلتر احراز هویت

در فهرست 7، نحوه سفارشی سازی فیلتر احراز هویت برای بررسی اینکه آیا لازم است قبل از ارسال کاربر به بخش کاربرهای احراز هویت شده، ابتدا کاربر را به صفحه حاوی بنر هشدار دهنده، منتقل کند یا خیر. در این مثال متد OnAuthorization فقط شامل کدهایی برای مدیریت قواعد بنر هشدار دهنده است. در واقع، برنامه شما ممکن است دستورات دیگری برای ارزیابی احراز هویت هم داشته باشد. به راحتی می توانیم کدهای موجود در فهرست 7 را به کدهای فیلتر احراز هویت برنامه شما اضافه کنیم. متدهای PageToShowPolicyNotification و PageToSkipPolicyNotification به ما اجازه می دهد که صفحات خاصی را مشخص نماییم که بنر هشدار دهنده در آنها نمایش داده شوند یا نمایش داده نشوند. متد OnAuthorization ، درخواست را به سمت یک صفحه هشدار منتقل می کند اگر

- این اکشن متد از سمت کلید Ok (بخش قبول قوانین) ارسال نشده باشد و

- کاربر باید قوانین را قبل از مشاهده صفحات موردنظرش، قبول کند و

- کاربر قبلا بر روی کلید Ok (بخش قبول قوانین) کلیک نکرده است.

همانطور که قبلا اشاره کرده ایم، متغییر session با نام SessionOKClick زمانی مقدار دهی می شود که اکشن متد AcceptPolicy در صفحه WarningPage فراخوانی شود. هدف اصلی SessionReturnUrl نگه داری URL ایجاد کننده درخواست است. ما نمی توانیم مطمعن باشیم که همه کابران از طریق صفحه /home وارد سایت ما شوند، ممکن است کاربری وارد آدرس /home/contact یا /home/about یا ... شود. مثلا اگر کاربر از طریق آدرس /home/contact وارد سایت شود، پس از قبول کردن قوانین سایت، دوباره به همان صفحه /home/contact منتقل خواهند شد. اگر می خواهید بنر هشداردهنده را به کمک AngularJS  ببینید، باید در عنصر appSettings که در فایل web.config قرار دارد، مقدار WaningBannerAngular را برابر با 1 قرار دهید.

فهرست 7

public class RequireAcceptPolicy : AuthorizeAttribute, IAuthorizationFilter  
{  
    internal static bool PageToSkipPolicyNotification(HttpContext ctx)  
    {  
        string[] pagesToExclude = { "/home/testwarningpage", "/home/warningpage"};  
        string pageToCheck = ctx.Request.Path.ToString().ToLower().TrimEnd('/');  
        return pagesToExclude.Contains(pageToCheck) ? true : false;  
    }  
    internal static bool PageToShowPolicyNotification(HttpContext ctx){ ….}  
    public override void OnAuthorization(AuthorizationContext filterContext)  
    {  
        //Other Authorization logic ….  
            ….  
        //don't prompt if the action is from acceptpolicy, and pages to exclude and SessionOKClick != null (user already accepted policy)  
        if (!filterContext.ActionDescriptor.ActionName.ToLower().Contains("acceptpolicy") && !PageToSkipPolicyNotification(HttpContext.Current) &&  
                            HttpContext.Current.Session["SessionOKClick"] == null)  
        {  
            //track the request url, include the query string  
            HttpContext.Current.Session["SessionReturnUrl"] = filterContext.HttpContext.Request.Url.PathAndQuery;  
            //redirect to policy page  
            if (System.Configuration.ConfigurationManager.AppSettings["WaningBannerAngular"] == "1")  
            {  
                filterContext.Result = new RedirectResult("~/home/WarningPageNg");  
            }  
            else  
            {  
                filterContext.Result = new RedirectResult("~/home/WarningPage");  
            }  
        }  
    }  
}  

کلاس FilterConfig

فهرست 8، نحوه افزودن صفت فیلتر احراز هویت که به صورت سفارشی با نام RequireAcceptPolicy ساخته ایم را در مجموعه فیلتر های  global نشان می دهد.

فهرست 8

public class FilterConfig  
{  
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)  
    {  
        filters.Add(new RequireAcceptPolicy());  
    }  
}  

ارزیابی Anti-Forgery به صورت Ajax

کدهای مربوط به Anti-Forgery را می توانید در وبلاگ مایکروسافت ببینید. بجای آنکه کدهای سمت client را در هر صفحه ایی قرار دهیم، این کد را در یک partial view با نام _AntiforgeryToken.cshtml قرار می دهیم و سپس می توانیم هرجا که به Anti-Forgery نیاز بود این partial view را در آن صفحه قرار دهیم یا که می توانیم این partial view را در layout قرار دهیم تا در همه صفحه ها وجود داشته باشد. در فهرست شماره 9، کدهای مربوط به _AntiforgeryToken.cshtml قرار داده شده است. این partial view شامل دو hidden field با نام های antiForgeryToken و antiForgeryTokenNg است که antiForgeryToken وظیفه نگه داری Token که توسط متد GetAntiForgeryToken ساخته می شود را دارد و antiForgeryTokenNg توسط AngularJS مورد استفاده قرار خواهد گرفت.

فهرست 9

@functions{  
    public string GetAntiForgeryToken()  
    {  
        string cookieToken, formToken;  
        AntiForgery.GetTokens(null, out cookieToken, out formToken);  
        return cookieToken + "," + formToken;  
    }  
}  
<input type="hidden" id="antiForgeryToken" value="@GetAntiForgeryToken()" />  
<input id="antiForgeryTokenNg" data-ng-model="antiForgeryToken" type="hidden"  
    data-ng-init="antiForgeryToken='@GetAntiForgeryToken()'" />  

در فهرست شماره 10، تابع jQuery AJAX، مقدار نشانه Anti-Forgery را به روش Post به اکشن متد داخل کنترلر ارسال می نماید. کد های جاوا اسکریپت را به صورت کامل می توانید در فهرست شماره 5 مشاهده نمایید.

فهرست 10

beforeSend: function (xhr) { xhr.setRequestHeader('RequestVerificationToken', $("#antiForgeryToken").val()); }  

در فهرست شماره 11، به طور خلاصه، نحوه ارسال Anti-Forgery Token توسط AngularJS به اکشن متد داخل کنترلر را می بینیم. لطفا سورس کد این مقاله را دانلود کنید و حتما بررسی کنید چرا که ممکن است به یک سری قسمت های این بخش، به طور کامل نپردازیم و سریع از روی آنها عبور کنیم. در زمان بارگذاری صفحه، کنترلر، مقدار داخل hidden field را دریافت می کند و این مقدار را در آرایه ایی از متغییر ها با نام Items ذخیره می کند. وقتی که کاربر روی کلید Ok کلیک می کند و قوانین را قبول می کند، سرویس AngularJS $http به همراه هدرهای property ها، به سمت سرور Post می شود. در این مثال هدر property، شامل پارامتر RequestVerificationToken و مقدار $scope.items[0] است. آرایه موجود در این مثال فقط یک Item دارد به همین دلیل است که از عدد 0 در آرایه استفاده کرده ایم.

فهرست 11

// modal controller  
$scope.items = [$scope.antiForgeryToken];  
// OK click  
$http({  
    method: 'POST',  
    url: '/home/AcceptPolicy',  
    params: Indata,  
    headers: {  
        'RequestVerificationToken': $scope.items[0]  
    }  
…  

View در AngularJS

در فهرست شماره 12 کدهای مربوط به WarningPageNg را مشاهده می کنیم که در View از AngularUI Bootstrap modal و AngulatJS استفاده شده است. مانند صفحه WarningPage، محتویات داخل Modal از طریق ViewBag پر می شود. شما می توانید کدها را متناسب با نیازهایتان جوری ویرایش کنید که اطلاعات را از دیتابیس یا روش های دیگر دریافت نماید. محتویات داخل modal به صورت کپسوله شده در قالب script directive قرار می گیرند. در صورت کلیک شدن بر روی کلید Ok، تابع ok()  فراخوانی می شود و تابع openModal() در زمان بارگزاری صفحه فراخوانی می شود.

فهرست 12

<div ng-controller="modalcontroller">  
    <script type="text/ng-template" id="myModal.html">  
    <div class="modal-header"></div>  
    <div class="modal-body">  
        @if (ViewBag.SystemWarningMessage != null)  
        {  
            <div class="modal-body"> @Html.Raw(ViewBag.SystemWarningMessage)</div>  
        }  
    </div>  
    <div class="modal-footer">  
        <button class="btn btn-default" type="button" ng-click="ok()">OK</button>  
    </div>  
    </script>  
    @{ Html.RenderPartial("~/Views/Shared/_AntiforgeryToken.cshtml"); }  
    <span ng-init="openModal()"></span>  
</div>  
@section scripts{  
    <script src="~/ControllersNg/ModalController.js"></script>  
}  

در فهرست شماره 13، محتویات فایل ModalController.js نمایش داده شده است. در ابتدا این کدها یک ماژول با نام TestAngularApp ساخته شده که این ماژول وابسته به ماژول ui.bootstrap خواهد بود. کدهای نوشته شده، از تابع Config برای تزریق $httpProvider به داخل ماژول پیکربندی برنامه، استفاده می کند. Provider به ماژول اجازه افزودن هدرهای نوع X-Requested-With را به فراخوانی های انجام شده، می دهد. این هدر برای کار با صفت AjaxValidateAntiForgeryToken مورد نیاز است و باعث برطرف شدن خطای "required anti-forgery cookie \’__RequestVerificationToken\’ is not present." می شود. شما می توانید لیستی از خصوصیات و تعاریف AngularUI Modal را در این لینک مشاهده نمایید. کدهای مربوطه به کلید Ok بسیار شبیه فهرست شماره 5 است. اگر بر روی کلید، کلیک شود، اطلاعات صفحه به علاوه Anti-Forgery token به اکشن متد home/AcceptPolicy به روش Post ارسال می شود.

فهرست 13

  var app = angular.module('TestAngularApp', ['ui.bootstrap']);  
app.config(['$httpProvider', function ($httpProvider) {  
    $httpProvider.defaults.headers.common["X-Requested-With"] = 'XMLHttpRequest';  
}]);  
app.controller('modalcontroller', function ($scope, $uibModal) {  
    $scope.animationsEnabled = true;  
    $scope.openModal = function (size) {  
        $scope.items = [$scope.antiForgeryToken];  
        var ModalInstance = $uibModal.open({  
            animation: $scope.animationsEnabled,  
            templateUrl: 'myModal.html',  
            controller: 'InstanceController',  
            backdrop: false,  
            resolve: {  
                items: function () { return $scope.items; }  
            }  
        });  
    };  
});  
app.controller('InstanceController', function ($scope, $uibModalInstance, $http, $window, items) {  
    $scope.items = items;  
    $scope.ok = function () {       
        var Indata = { rURL: 'dummyTestParam' };  
        $http({  
            method: 'POST',  
            url: '/home/AcceptPolicy',  
            params: Indata,  
            headers: {'RequestVerificationToken': $scope.items[0] }  
        }).then(function successCallback(response) {  
            $scope.status = response.status;  
            $scope.data = response.data;  
            $window.location.href = response.data;  
        }, function errorCallback(response) {  
        });  
        $uibModalInstance.close();  
    };  
    $scope.cancel = function () {  
        //it dismiss the modal   
        $uibModalInstance.dismiss('cancel');  
    };  
});  

Modal با قابلیت استفاده مجدد به کمک jQuery و Bootstrap

در فهرست شماره 14، کدهای HTML داخل _ModalDialog را می بینیم که در این partial view بخش های مربوط به عنوان و بدنه Modal قرار دارد. همچنین این partial view علاوه بر Modal، شامل چند button نیز است.

فهرست 14

<div class="modal fade" id="SharedModalDialog" role="dialog" data-keyboard="false" data-backdrop="static">  
    <div class="modal-dialog">  
        <div class="modal-content">  
            <div class="modal-header">  
                <button type="button" class="close" data-dismiss="modal">×</button>  
                <h4 class="modal-title">[Title]</h4>  
            </div>  
            <div class="modal-body">[Body] </div>  
            <div class="modal-footer">  
                <button type="button" class="btn btn-default"   
                        id="SharedModalDialogBtnOk" data-dismiss="modal">OK</button>  
                <button type="button" class="btn btn-default"   
                        id="SharedModalDialogBtnCancel" data-dismiss="modal">Cancel</button>  
            <div>  
        </div>  
    </div>  
</div>  

در فهرست شماره 15 یک ماژول جی کوئری با نام ModalDialog وجود دارد که این ماژول وظیفه نمایش dialog در _ModalDialog را دارد. این پلاگین 5 پارامتر ورودی دارد که شما می توانید با توجه به نیازهایتان این پلاگین را ویرایش نمایید. پارامتر های Title و Body مربوط به عنوان و محتوای داخل بدنه dialog هستند. پارامتر های OkButtonText و CancelButtonText نیز مخصوص مشخص کردن نوشته و visibility دکمه Ok و Cancel هستند. اگر برای OkClickRedirect مقدار خاصی قرار داده شود، در صورت کلیک بر روی کلید Ok، درخواست به این آدرس منتقل خواهد شد.

فهرست 15

$(document).ready(function () {  
    (function ($) {  
        // jQuery plugin definition  
        $.fn.ModalDialog = function (params) {  
            // merge default and user parameters  
            params = $.extend({ title: '', body: '', OkButtonText: '', OkClickRedirect: '', CancelButtonText: '' }, params);  
            if (params.title != '') {  
                $(".modal-title").text(params.title);  
            }  
            if (params.title != '') {  
                $(".modal-body").html(params.body);  
            }  
            if (params.OkButtonText != '') {  
                $("#SharedModalDialogBtnOk").text(params.OkButtonText);  
                $("#SharedModalDialogBtnOk").show();  
            }  
            else {  
                $("#SharedModalDialogBtnOk").hide();  
            }  
            if (params.CancelButtonText != '') {  
                $("#SharedModalDialogBtnCancel").text(params.CancelButtonText);  
                $("#SharedModalDialogBtnCancel").show();  
            }  
            else {  
                $("#SharedModalDialogBtnCancel").hide();  
            }  
            if (params.OkClickRedirect != '') {  
                $("#SharedModalDialogBtnOk").click(function () {  
                    window.location.replace(params.OkClickRedirect);  
                });  
            }  
            $('#SharedModalDialog').modal('show');  
            // allow jQuery chaining  
            return false;  
        };  
    })(jQuery);  
});  

در فهرست شماره 16، نحوه استفاده از partial view که تازه ساخته ایم و پلاگین جی کوئری برای نمایش modal dialog را می بینیم. متد RenderPartial را می توانیم در صفحه Layout قرار دهیم. اینکار در صورتی که برنامه ما نیاز به نمایش notification یا alert message به کاربر داشته باشد، بسیار مفید است. در سه کلید جداگانه، نحوه استفاده از این پلاگین نمایش داده شده است.

فهرست 16

<input type="button" id="btn1" value="Test Bootstrap Modal - OK button/Redirect" />  
<input type="button" id="btn2" value="Test Bootstrap Modal - multiple button" />  
<input type="button" id="btn3" value="Test Bootstrap Modal - no button" />  
@section scripts {  
    @{  
        Html.RenderPartial("~/Views/Shared/_ModalDialog.cshtml");  
    }  
    <script type="text/javascript">  
        $("#btn1").click(function () {  
            $('#SharedModalDialog').ModalDialog({  
                title: 'Test - modal',  
                body: '<b>Do you agree with the term?</b>',  
                OkButtonText: 'Accept',  
                OkClickRedirect: '/Home/Index/?test=1'  
            });  
        });  
        $("#btn3").click(function () {  
            $('#SharedModalDialog').ModalDialog({  
                title: 'Test - modal 2 ',  
                body: 'This is ANOTHER test <b>content 2222 </b> more <br/> contents .....'  
            });  
        });  
        $("#btn2").click(function () {  
            $('#SharedModalDialog').ModalDialog({  
                title: 'Test Bootstrap Dialog - multiple button',  
                body: 'Are you sure you want to delete this record?',  
                CancelButtonText: 'Cancel',  
                OkButtonText: 'Yes',  
                OkClickRedirect: '/Home/Index/?test=2'  
            });  
        });  
    </script>  
}  

فهرست شماره 17 نحوه نمایش dialog بدون نیاز به کلیک، پس از بارگزاری صفحه را نشان می دهد.

فهرست 17

$(document).ready(function () {  
    $('#SharedModalDialog').ModalDialog({  
        title: 'Test - Page Load',  
        body: 'Display on page load !!!!'  
    });  
});  

Modal با قابلیت استفاده مجدد به کمک AngularJS و AngularUI Bootstrap

در فهرست شماره 18، قالب کلی modal dialog که در فایل _ModalDialogNg.html قرار دارد را نمایش داده ایم. نمایش یا عدم نمایش کلید بر اساس عبارات موجود در صفت های ngShow مثل showX، showOK و showCancel است. عنوان و نوشته کلید ها از طریق property های موجود در این کلاس قابل تغییر هستند. دستورالعمل(directive) AngularJS ng-bind-html برای نمایش محتویات HTML به صورت امن در یک عنصر Div به کار می رود اما همچنان باید مقادیر ورودی کاربر ابتدا چک شوند که مشکلی نداشته باشند تا بتوانیم آنها را نمایش دهیم.

فهرست 18

<div class="modal-header">  
    <button type="button" class="close" ng-show="showX" ng-click="cancel()">×</button>  
    <h3 class="modal-title">{{title}}</h3>  
</div>  
<div class="modal-body">  
    <div data-ng-bind-html="htmlBind"></div>  
</div>  
<div class="modal-footer">  
    <button class="btn btn-default" ng-show="showOK" type="button" ng-click="ok()">{{btnOkText}}</button>  
    <button class="btn btn-default" ng-show="showCancel" type="button" ng-click="cancel()">{{btnCancelText}}</button>  
</div>  

در فهرست شماره 19، محتویات فایل ModalPartialController.js نمایش داده شده است. سرویس AngularJS $sce توسط کنترلر استفاده می شود تا یک نسخه امن از مقداری HTML ساخته شود. سرویس $uibModal برای ساخت modal استفاده می شود. هدف اصلی استفاده از سرویس $window ، انتقال درخواست به یک URL خاص پس از کلیک بر روی کلید Ok است. کدهای مربوط به نمایش یا عدم نمایش کلید و تنظیمات نوشته عناصر و ... در فهرست شماره 19 نمایش داده شده است.

فهرست 19

    var app = angular.module('TestAngularApp', ['ui.bootstrap']);  
app.controller('modalcontroller', function ($scope, $uibModal, $window) {  
    $scope.openModal = function (title, body, okBtnText, okClickRedirect, cancelBtnText) {  
        $scope.items = [title, body, okBtnText, okClickRedirect, cancelBtnText];  
        var ModalInstance = $uibModal.open({  
            animation: true,  
            templateUrl: '/TemplatesNg/_ModalDialogNg.html',  
            controller: 'InstanceController',  
            backdrop: false,  //disables modal closing by click on the background  
            keyboard: true,     //disables modal closing by click on the ESC key  
            resolve: {  
                items: function () {  
                    return $scope.items;  
                }  
            }  
        });  
        ModalInstance.result.then(function (btn) {  
            if (btn == "OK") {  
                $window.location.href = okClickRedirect;  
            }  
        }, function () { });  
    };  
});  
app.controller('InstanceController', function ($scope, $uibModalInstance, $sce, items) {  
    $scope.items = items;  
    $scope.title = $scope.items[0];  
    $scope.body = $scope.items[1];  
    $scope.btnOkText = $scope.items[2];  
    $scope.btnCancelText = $scope.items[4];  
    var returnUrl = $scope.items[3];  
    //allow html  
    $scope.htmlBind = $sce.trustAsHtml($scope.items[1]);  
    //hide or close the X close button on the top, you can write extra logic here to hide or show it  
    $scope.showX = false;  
    $scope.showOK = true;  
    if ($scope.btnOkText == '') {  
        //hide OK button  
        $scope.showOK = false;  
    }  
    //cancel button  
    $scope.showCancel = true;  
    if ($scope.btnCancelText == '') {  
        $scope.showCancel = false;  
    }  
    //OK clicked  
    $scope.ok = function () {  
        if (returnUrl == '') {  
            $uibModalInstance.close('');  
        } else {  
            $uibModalInstance.close('OK');  
        }  
    };  
    $scope.cancel = function () {  
        //it dismiss the modal   
        $uibModalInstance.dismiss();  
    };  
});  

در فهرست شماره 20، نحوه فراخوانی AngularUI Bootstrap Modal به همراه ارسال چند پارامتر، نمایش داده شده است. ابتدا ModalPartialController.js را به برنامه اضافه می کنیم. کنترلر های AngularJS مورد نظرمان در این فایل که در فهرست 19 نمایش داده بودیم، قرار دارند. سپس یک عنصر Div می سازیم و ng-controller directive را به آن اضافه می کنیم و نام کنترلر را modalcontroller قرار می دهیم. یک کلید به این Div اضافه می کنیم و برای رویداد ng-click این کلید از متد openModal که در ModalPartialController.js ساخته ایم، استفاده می کنیم.

فهرست 20

<div ng-controller="modalcontroller">  
    <button class="btn btn-default" type="button"  
            ng-click="openModal('AngularUI Model','Click on <b>Ok</b> to Redirect to Contact page.', 'OK', '/home/Contact', 'Close')">  
                Modal with redirect</button>  
</div>  
<div ng-controller="modalcontroller">  
    <button class="btn btn-default" type="button"  
            ng-click="openModal('@ViewBag.Something','This is the content<b>body 2</b>', '','', 'Close It')">   
                Modal with close button only</button>  
</div>  
<div ng-controller="modalcontroller">  
    <button class="btn btn-default" type="button"  
            ng-click="openModal('AngularUI Model 2','This is a notification!', '','', 'Ok')">  
        Modal with OK button only  
    </button>  
</div>  
@section scripts{  
    <script src="~/ControllersNg/ModalPartialController.js"></script>  
}  

در فهرست 21، نحوه نمایشdialog  بدون نیاز به کلیک و در زمان بارگذاری صفحه، را قرار داده ایم.

فهرست 21

<div ng-controller="modalcontroller"  
         ng-init="openModal('AngularUI Model Onload','Display on page load!', '','', 'Ok')">  
</div>  

خروجی برنامه

آموزش asp.net mvc

آموزش بوت استرپ

فایل های ضمیمه
دانلود نسخه ی PDF این مطلب