چند روز پیش همکاران عزیز تو شرکت جادوی فکر ازم خواستن چند جلسه آموزش جاوا اسکریپت براشون برگزار کنم. اولین جلسه رو همون روز برگزار کردیم و طبق درخواست بچه ها قرار شد یک سری اطلاعات رو با استفاده از Ajax از سرور بخونیم و در یک پنجره مدال بوت استرپ نشون بدیم.

برای فرمت بندی اطلاعات در پنجره از قالب های کندو (Kendo UI Template) استفاده کردم. من عاشق ابزارهای Kendo هستم و تو همه پروژه هام ازشون استفاده می کنم.

خوب. کدهای زیاد پیچیده ای اینجا وجود نداره. ساختار پروژه به این شکله:

قالب پیش فرض پروژه وب در ویژوال استودیو 2013، شامل فایل های jQuery و Bootstrap هست و نیازی نیست که اونا رو اضافه کنم.

یک پوشه به اسم jslib درست کردم و کامپوننتهای جاوااسکریپت رو توش گذاشتم. و یک پوشه به اسم app که اسکریپتهای مربوط به صفحات رو توش میذارم. بعد از مدتها کار کردن و چیدن ساختار پروژه هام به شکلهای مختلف، به این نتیجه رسیدم که این شکل چیدن اسکریپت ها بهتره و نیازی نیست که حتما فایلهای جاوااسکریپت رو در پوشه Scripts و فایل های css رو در پوشه Content قرار بدیم.

این کد اولیه مربوط به صفحه Index.cshtml هست:


<!-- Button trigger modal -->
<button class="btn btn-primary btn-lg showDataBtn" id="showData" data-toggle="modal" data-target="#myModal" data-id="1">
    Launch demo modal
</button>
<!-- Modal -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button>
                <h4 class="modal-title" id="myModalLabel">Modal title</h4>
            </div>
            <div class="modal-body">
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
                <button type="button" class="btn btn-primary">Save changes</button>
            </div>
        </div>
    </div>
</div>
این کد رو عینا از راهنمای بوت استرپ کپی کردم که شامل بخش های زیره:
<button class="btn btn-primary btn-lg" id="showData" data-toggle="modal" data-target="#myModal" data-id="1">
    Launch demo modal
</button>
یک دکمه که چند تا خصیصه داره که رفتارش رو کنترل می کنن: 
data-toggle="modal"
مشخص می کنه که این دکمه کارش باز و بسته کردن یک پنجره مداله.
data-target="#myModal"
شناسه ی پنجره ای که باید باز بشه رو مشخص میکنه. بعد از اون هم کد مربوط به خود پنجره وجود داره. 
همین دو قسمت برای اینکه بتونیم یک مدال دیالوگ باز بکنیم کافین و نیازی نیست که هیچ کد جاوا اسکریپتی نوشته بشه. نتیجه کار تا اینجا میشه این:


اسکریپ های بوت استرپ که تو صفحه ما قرار دارن به صورت خودکار عملیات لازم رو انجام میدن (با استفاده از خصیصه هایی که رو تگ ها گذاشتیم).

حالا فرض کنین که می خوایم وقتی پنجره مون باز می شه اطلاعاتی رو از سرور بگیریم و توش نشون بدیم.
فرض کنین کلاسی به اسم Person داریم که اطلاعاتش از بانک اطلاعاتی خونده میشه:

    public class Person
    {
        public int Id { get; set; }
        public string FName { get; set; }
        public string LName { get; set; }
        public int Random { get; set; }
    }
 برای دریافت اطلاعات یک کنترلر درست می کنم که اطلاعات رو به ما بده:
    public class DataController : Controller
    {
public ActionResult GetData(int id) { var person = GetSampleData().Single(p => p.Id == id); return Json(person, JsonRequestBehavior.AllowGet); } [NonAction] public Person[] GetSampleData()         {
            return new Person[]{
                new Person(){
                    Id=1,
                    FName="Mahmood",
                    LName = "Dehghan",
                    Random = new Random().Next() 
                },
                new Person(){
                    Id=2,
                    FName="Mehdi",
                    LName = "Miri",
                    Random = new Random().Next() 
                }
            };
        }
    }
تابع GetSampleData داده فرضی تولید میکنه. تو نرم افزار واقعی این کد با کد خوندن از بانک اطلاعاتی جایگزین میشه.

برای اینکه اطلاعات دریافت شده از سرور رو تو پنجره نشون بدیم از قالب کندو (Kendo Template) استفاده کردم.

این کد رو تو صفحه Index.cshtml بعد از تک مربوط به پنجره قرار بدین.
<script id="mdoelDataTemplate" type="text/x-kendo-template">
<div class="panel panel-warning">
<div class="panel-heading">
My template
</div>
<div class="panel-body">
<b>Id:</b> #=Id#<br />
<b>FName:</b> #=FName#<br />
<b>LName:</b> #=LName#<br />
<p>Random number from server: #=Random#</p>
</div>
</div>
</script>
این تگ اسکریپت برای مرورگر هیچ معنی نداره چونکه نوع اون رو text/x-kendo-template گذاشتیم. پس مرورگر اون رو نادیده میگیره.
حالا تو پوشه app یک فایل جاوااسکریپت درست می کنم به اسم home.js و این کد رو توش می نویسم:
$(function () {
    var dataTemplate = kendo.template($("#mdoelDataTemplate").html());
    $("#showData").click(function () {
        $.getJSON(getUrl("Data/GetData") + "?id=" + $(this).data("id"), function (res) {
            $("#myModal .modal-body").html(dataTemplate(res));
        });
    });
});

زیاد وارد جزئیات این کد نمی شم. تابع getUrl که می بینین رو تو فایل _Layout.cshtml تعریف کردم:
    <script>
        var baseUrl = "@Url.Content("~")";
        function getUrl(url) {
            return baseUrl + url;
        }
    </script>
این تابع باعث میشه بتونم آدرس هاس سروری رو تو کد جاوااسکریپت بدست بیارم.

حالا برنامه قابل اجراست:



با زدن دکمه، پنجره باز میشه و اطلاعات رو از سرور نشون میده.
اگه دقت کرده باشین ما یک Id هم به سرور ارسال می کنیم و سرور اطلاعات رو بر اساس اون فیلتر میکنه:
        public ActionResult GetData(int id)
        {
            var person = GetSampleData().Single(p => p.Id == id);
            return Json(person, JsonRequestBehavior.AllowGet);
        }
این Id از خصیصه data-id که به دکمه دادیم خونده می شه:
        $.getJSON(getUrl("Data/GetData") + "?id=" + $(this).data("id"), function (res) {
با این کار میتونیم دکمه های مختلف برای نشون دادن اطلاعات مختلف داشته باشیم.
 یک دکمه دیگه با این کد به صفحه Index.cshtml اضافه می کنم:
<button class="btn btn-primary btn-lg showDataBtn" data-toggle="modal" data-target="#myModal" data-id="2">
    Show me the second row
</button>
یک تغییر کوچک هم تو فایل home.js میدم تا به جای استفاده از id دکمه، واقعه کلیک رو برای همه دکمه هایی که کلاس showDataBtn رو دارن رجیستر کنه:
    $(".showDataBtn").click(function () {
حالا با اجرای برنامه دو تا دکمه داریم:

و با زدن دکمه دوم پنجره ی باز شده اطلاعات دومین شخص رو به ما نشون می ده:


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

پا نوشت 1:
بعضی جاها از معادل فارسی اسامی، مثل بوت استرپ و کندو استفاده کردم. اگه فکر می کنین بهتره همه جا از اسامی انگلیسی (Bootstrap, Kendo) استفاده کنم بهم بگین.

پانوشت 2:
در ابتدا هدفم از ایجاد این وبلاگ، انتشار تجربه های شخصیم در دست و پنجه نرم کردن با مشکلات برنامه نویسی در پروژه هام بود. که شاید راه حل هایی که پیدا می کنم به درد دیگران هم بخوره.
این پست (که اولین مطلبم هم هست) در مقایسه با هدف اولیم، شامل مطالب ساده تریه و مفصل تر هم هست. ولی خب دیگه. همین طور یهویی حسش اومد که بنویسمش. انشاالله شروعی باشه برای پست های غنی تر و سنگین تر.

پانوشت 3:
نوشتن وب لاگ کار سخت و وقت گیریه. نوشتن این مطلب تا اینجا دقیقا 3 ساعت و 6 دقیقه طول کشیده. مدت زیادیه که دوست دارم مطلب بنویسم. ولی فرصت نمی کنم. نوشتن این پست رو دقیقا بعد از دیدن این سایت شروع کردم: keysleft.com. این سایت مال آقای اسکات هنسلمنه. (ممنون از دوست عزیزم فرید بکران که باعث شد به این سایت سر بزنم)