مطالب
پلاگین DataTables کتابخانه jQuery - قسمت اول
DataTables پلاگینی برای کتابخانه jQuery است. این پلاگین امکانات پیشرفته ای برای یک جدول html که حاوی داده‌ها است اضافه می‌کند، و همچنین عملیات صفحه بندی، جستجو، مرتب سازی داده‌ها را در سمت کاربر انجام می‌دهد.

به طور خلاصه می‌توانید امکانات متعدد این پلاگین را در زیر مشاهده کنید:
  • صفحه بندی داده‌ها با تعداد رکوردهای قابل تغییر در هر صفحه (variable length pagination)
  • فیلتر کردن داده‌های بایند شده به جدول (on-the-fly filtering)
  • مرتب سازی داده‌ها بر اساس ستون‌های مختلف با قابلیت تشخیص نوع داده ستون (Multi-column sorting with data type detection)
  • تغییر اندازه ستون‌ها به صورت هوشمند (Smart handling of column widths)
  • نمایش داده‌ها در جدول از اکثر data source‌ها (DOM، یک آرایه جاوا اسکریپتی، یک فایل، یا با استفاده از پردازش سمت سروری (سی شارپ، php و غیره) )
  • قابلیت جهانی شدن یا منطبق شدن با زبان‌های مختلف دنیا (Fully Internationalisable)
  • قابلیت تعویض theme آن با استفاده از jQuery UI ThemeRoller
  • وجود داشتن 2900 آزمون واحد برای آن (backed by a suite of 2900 unit test)
  • وجود داشتن پلاگین‌های متعدد برای آن
  • و رایگان بودن آن
در این مقاله شما را به طور مقدماتی با این پلاگین آشنا خواهم کرد.
برای استفاده از این پلاگین ابتدا به اینجا مراجعه کرده و آنرا به همراه مثالهای آن که در یک فایل فشرده هستند را دانلود کنید. بعد از دانلود و خارج کردن فایل دانلودی از حالت فشرده، وارد پوشه examples از آن که بشوید می‌توانید مثالهای متعدد در رابطه با این پلاگین را مشاهده نمائید.

  مثال‌های این پلاگین یکی از بهترین منابع یادگیری آن هستند. در این سری از مقالات هم از روی همین مثالها پیش میرویم. برای این کار، بعد از مراجعه به پوشه examples فایل index.html را باز کنید و مثال اول را (Zero Configuration) کلیک کنید.
 

نتیجه حاصل از اجرای مثال Zero Configuration چیزی شبیه تصویر زیر است: 
تصویر را شماره گزاری کرده ام تا بتوانم راحت‌تر آنرا برایتان تشریح کنم.
  1. داده‌های درون جدول (10 تای اول) که در قسمت tbody جدول قرار دارند
  2. قسمت thead جدول
  3. قسمت tfoot جدول
  4. اندازه صفحه (page size)
  5. کادر جستجو که در کلیه ستون‌های جدول جستجویی را انجام می‌دهد و داده‌ها بر اساس آن فیلتر می‌شوند.
  6. قابلیت مرتب سازی رکوردها بر اساس یک ستون خاص به صورت صعودی یا نزولی
  7. اطلاعات مربوط به رکوردهای جاری و تعداد کل رکوردها
  8. قابلیت تغییر صفحه با دکمه‌های previous و next

تشریح مثال Zero Configuration :

برای استفاده از این پلاگین، باید ارجاعی به کتابخانه jquery و نیز فایل jquery.dataTables.js  وجود داشته باشد. این دو فایل در زیر پوشه media/js قرار گرفته اند.
<script type="text/javascript" language="javascript" src="../../media/js/jquery.js"></script>
<script type="text/javascript" language="javascript" src="../../media/js/jquery.dataTables.js"></script>
و همچنین css‌های مربوطه به این پلاگین بدین صورت معرفی شده اند:
<style type="text/css" title="currentStyle">
    @import "../../media/css/demo_page.css";
    @import "../../media/css/demo_table.css";
</style>
در این مثال که ساده‌ترین مثال مربوط به این پلاگین است داده‌ها به صورت دستی در جدول قرار گرفته اند و روش‌های دیگر را به قسمت‌های بعد موکول می‌کنیم. اگر به source این مثال مراجعه کنید (از روی فایل اصلی و نه از طریق مرورگر) مشاهده می‌کنید که یک جدول html با id برابر با example وجود دارد که حاوی 57 سطر است (در قسمت tbody) که حاوی داده‌های جدول هستند. اما با مراجعه به source مثال از طریق مرورگر مشاهده می‌کنید تعداد این سطرها 10 تا هست و این بدین معنیه که پلاگین فقط تعداد رکوردهای مورد نیاز رو در قسمت tbody قرار می‌ده و از بقیه فاکتور می‌گیره و هر بار که کاربر به صفحه رو با دکمه‌های Previous و Next تغییر می‌ده این پلاگین قسمت tbody رو تغییر میده

این نکته هم جا نمونه که برای اعمال شدن پلاگین DataTables به یک جدول که به طور مثال id جدول example هست، به صورت زیر عمل می‌کنیم:
$(document).ready(function() {
    $('#example').dataTable();
} );


مطالب
آشنایی با WPF قسمت هفتم: DataContext بخش چهارم
تا قسمت قبلی کنترل لیست را پر نمودیم. در این مقاله قصد داریم آخرین کنترلT یعنی تقویم را بایند کرده و یک نکته از Binding را جهت تکمیل کردن بحث بیان کنیم.

تقویم
در دروس گذشته اطلاعات را از متدی به نام GetPerson دریافت می‌کردیم که اطلاعات آن به شرح زیر است:
  public static Person GetPerson()
        {

            return new Person()
            {
                Name = "Leo",
                Gender = true,
                ImageName = "man.jpg",
                Country = new Country()
                {
                    Id = 3, Name = "Angola" 
                },
                FieldOfWork = new FieldOfWork[] { test.FieldOfWork.Actor, test.FieldOfWork.Producer },
                Date = DateTime.Now.AddMonths(-3)
            };
        }

تاریخ ثبت شده در بالا، به سه ماه قبل از تاریخ فعلی بر می‌گردد و حالا این تاریخ را به خصوصیت DisplayDate تقویم انتساب می‌دهیم:
Calendar DisplayDate="{Binding Date}" Grid.Row="4" Grid.Column="1" HorizontalAlignment="Left" Margin="10">
اگر از برنامه اجرا بگیرد می‌بینید که تقویم روی سه ماه پیش قرار گرفته است؛ ولی تاریخی روی صفحه انتخاب نشده است و دلیل آن هم این است که این خصوصیت، تقویم را به جایی میبرد که آن تاریخ در آن ذکر شده است، ولی تاریخی روی صفحه انتخاب نمی‌کند. به همین علت در اکثر موارد در کنار خاصیت DisplayDate، از خاصیت SelectedDate هم استفاده می‌شود. این خاصیت بر خلاف خاصیت قبلی، تقویم را حرکت نمی‌دهد ولی تاریخ را انتخاب می‌کند. پس در این حالت ما هر دو گزینه را بایند می‌کنیم که هم تقویم به محل تاریخ حرکت کرده و هم تاریخ مد نظر انتخاب شود:
 <Calendar DisplayDate="{Binding Date}" SelectedDate="{Binding Date}" Grid.Row="4" Grid.Column="1" HorizontalAlignment="Left" Margin="10">

ادامه مفاهیم بایندینگ
در قسمت پنجم، دیدیم که چطور می‌توانیم با استفاده از متد OnPropertyName، برنامه را از تغییراتی که در سطح مدل می‌گذرد، آگاه کنیم و این تغییرات جدید را دریافت کرده و اطلاعات نمایش داده شده را به روز کنیم. در اینجا قصد داریم خلاف اینکار را با استفاده از همان متد انجام دهیم. یعنی مدل را از تغییراتی که در سطح UI می‌گذرد، آگاه کنیم.
این مثال را روی خصوصیت Name مدل اجرا می‌کنیم:
در Xaml Editor تگTextBox مربوط به نام شخص را به شکل زیر تغییر می‌دهیم:
  <TextBox Grid.Row="0" Grid.Column="1" Name="Txtname" Text="{Binding Path=Name,Mode=TwoWay}" HorizontalAlignment="Left" Margin="5" Width="200" ></TextBox>

تغییری که در این حالت رخ داده است، افزودن ویژگی به نام Mode است که روی گزینه TwoWay تنظیم شده است. در قسمت‌های قبلی تمامی بایندینگ‌ها به طور پیش فرض روی حالت یک طرفه OneWay قرار داشتند، ولی در اینجا ما بایندینگ را دو طرفه اعمال کرده‌ایم. حال به همین سادگی هر تغییری که در این TextBox رخ دهد به مدل هم اعمال خواهد شد.
حال برای تست این مورد، عنصر زیر را در کنار نام شخص به صفحه اضافه می‌کنیم. یک برچسب متنی که به خاصیت Name متصل است و از تغییراتی که در سطح مدل داده می‌شود، آگاه است:
 <TextBlock Grid.Column="1" Text="{Binding Path=Name}"  Grid.Row="0" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="210,10,0,13" RenderTransformOrigin="0.555,1.283" ></TextBlock>
اینک برنامه را اجرا می‌کنیم و فیلد متنی نام را ویرایش می‌کنیم. اگر فوکوس را از این کنترل بگیریم، می‌بینید که فیلد متنی هم به مقدار جدید تغییر می‌کند. اتفاق جدیدی که در اینجا افتاد این بود که مدل از تغییراتی که در سطح UI رخ داده بود، آگاه شد و بعد از آن فیلد متنی همانطور که قبلا با آن آشنا شده‌ایم از تغییری که در مدل رخ داده است آگاه شده است.


 
از دیگر مقادیر Mode می‌توان به جدول زیر اشاره کرد:
OneWayToSource
در این حالت، مدل از تغییرات سطح UI آگاه می‌شود ولی بقیه کنترل‌ها یا المان‌ها را از تغییرات خود آگاه نمی‌کند. 
OneTime
 در این حالت تنها یکبار مدل داده‌های خود را کنترل کرده (همان پر کردن اولیه داده‌ها) و دیگر هیچ نوع تغییراتی را رصد نمی‌کند.
 
تا به اینجا یک سری پیش نیازها را یاد گرفتیم. ولی روشی را که تا به اینجا استفاده کرده‌ایم یک روش اشتباه و قدیمی است که در winform هم انجام می‌دادیم. یعنی هنوز وابستگی بین رابط کاربری و منطق برنامه وجود دارد. در قسمت بعدی در مورد M-V-VM صحبت خواهیم کرد و از طریق viewmodel ارتباط بین مدل و ویو را ایجاد خواهیم کرد. در این روش دیگر نیازی نیست که بدانید کنترلی به اسم textbox1 وجود دارد یا خیر یا حتی اصلا اسمی دارد یا خیر و این یعنی جدایی رابط کاربری و منطق برنامه و اصل هدف WPF.
دانلود مثال
مطالب دوره‌ها
اجزای جاوا اسکریپتی بوت استرپ 3
مباحث منوهای پایین افتادنی و برگه‌‌ها (tabs) در بوت استرپ 2 و 3 یکسان هستند و نکات آن‌ها در بحث «نگاهی به اجزای تعاملی Twitter Bootstrap» عنوان شده‌اند. در ادامه به اجزای جدیدی خواهیم پرداخت که مختص بوت استرپ 3 بوده و از تازه‌های آن به‌شمار می‌روند. همچنین اجزایی را که در بررسی بوت استرپ 2 به آن‌ها پرداخته نشد، مانند Carousels و Scroll spy، نیز بررسی می‌کنیم.


پنل‌ها و آکاردئون‌ها

پنل‌های آکاردئونی، بسیار شبیه به برگه‌ها عمل می‌کنند. با کلیک بر روی یک سربرگ، محتوای مخفی شده آن نمایش داده می‌شود. این اعمال نیز توسط اجزای جاوا اسکریپتی بوت استرپ، به کمک jQuery عمل می‌کنند.
یک مثال:
    <div class="container">
        <h4 class="alert alert-info">
            پنل آکاردئونی</h4>
        <div class="row">
            <div class="panel-group" id="accordion">
                <div class="panel panel-default">
                    <div class="panel-heading">
                        <h4 class="panel-title">
                            <a href="#vacc" class="accordion-toggle" data-toggle="collapse" data-parent="#accordion">
                                <span class="glyphicon glyphicon-pushpin"></span>اطلاعات یک</a>
                        </h4>
                    </div>
                    <div id="vacc" class="panel-collapse collapse in">
                        <div class="panel-body">
                            <p>
                                متن متن متن متن .......</p>
                            <p>
                                <a href="#" class="btn btn-info">بیشتر >></a></p>
                        </div>
                    </div>
                </div>
                <div class="panel panel-default">
                    <div class="panel-heading">
                        <h4 class="panel-title">
                            <a href="#checkups" class="accordion-toggle" data-toggle="collapse" data-parent="#accordion">
                                <span class="glyphicon glyphicon-ok"></span>اطلاعات 2</a>
                        </h4>
                    </div>
                    <div id="checkups" class="panel-collapse collapse">
                        <div class="panel-body">
                            <p>
                                متن متن متن متن .......</p>
                            <p>
                                <a href="#" class="btn btn-info">بیشتر >></a></p>
                        </div>
                    </div>
                </div>
            </div>
            <!-- end accordion -->
        </div>
        <!-- end row -->
    </div>
    <!-- /container -->

توضیحات:
- ابتدا کل ناحیه مدنظر باید در یک div با کلاس panel-group محصور شود؛ به همراه یک id دلخواه. از این id در ویژگی‌های data-parent عنوان‌های هر پنل این گروه استفاده می‌شود. به این ترتیب سیستم جاوا اسکریپتی آن متوجه خواهد شد که باید داخل چه ناحیه‌ای از صفحه عمل کند.
- پس از مشخص سازی آغاز پنل گروهی مدنظر، هر گروه، داخل یک div با کلاس panel panel-default قرار خواهد گرفت. به این ترتیب اولین پنل آکاردئونی مثال، شکل می‌گیرد.
- سپس داخل هر پنل مجزا، باید توسط panel-heading مشخص کنیم که عنوان این پنل و محتوای خاص این عنوان کجا باید قرار گیرند. همچنین به کمک panel-collapse collapse in، محتوایی را که با کلیک بر روی عنوان هر پنل به صورت خودکار ظاهر خواهد شد را معرفی می‌کنیم.
در ادامه می‌توان پنل‌های بیشتری را به این مجموعه و گروه افزود.
- پنلی که قرار است در ابتدای کار باز باشد، دارای کلاس collapse in خواهد بود؛ مابقی فقط collapse دارند.


بررسی کامپوننت Carousels

بوت استرپ به همراه کامپوننت اسلایدشو توکاری است به نام Carousel که بدون نیاز به حتی یک سطر کدنویسی جاوا اسکریپت اضافی، یک اسلاید شو بسیار حرفه‌ای را ارائه می‌دهد. مثالی را در این مورد در ادامه ملاحظه می‌کنید:
    <div class="container">
        <h4 class="alert alert-info">
            اسلاید شو</h4>
        <div class="row">
            <div id="myCarousel" class="carousel slide">
                <ol class="carousel-indicators">
                    <li data-target="#myCarousel" data-slide-to="0" class="active"></li>
                    <li data-target="#myCarousel" data-slide-to="1"></li>
                    <li data-target="#myCarousel" data-slide-to="2"></li>
                </ol>
                <!-- carousel-indicators -->
                <section class="carousel-inner">
                    <div class="active item">
                        <img src="images/01.jpg" alt="Photo 1"></div>
                    <div class="item">
                        <img src="images/02.png" alt="Photo 2"></div>
                    <div class="item">
                        <img src="images/03.jpg" alt="Photo 3"></div>
                </section><!-- carousel-inner -->
                <a href="#myCarousel" class="left carousel-control" data-slide="prev"><span class="glyphicon glyphicon-chevron-left">
                </span></a><a href="#myCarousel" class="right carousel-control" data-slide="next"><span
                    class="glyphicon glyphicon-chevron-right"></span></a>
            </div>
            <!-- myCarousel -->
        </div>
        <!-- end row -->
    </div>




توضیحات:
- در قسمت carousel-inner این کامپوننت، لیست تک تک تصاویر مورد نیاز قرار خواهند گرفت. تصویر آغازین دارای div ایی محصور کننده با کلاس active item است و مابقی کلاس item دارند.
- مرحله بعد، کار افزودن سیستم راهبری و حرکت بین تصاویر اضافه شده است. این سیستم چیزی نیست جز چند لینک مزین شده با کلاس‌های left carousel-control و همچنین right carousel-control. ویژگی‌های data-slide این لینک‌ها نیز مشخص کننده اعمالی هستند که کامپوننت جاوا اسکریپتی carousel قرار است انجام دهد. برای مثال حرکت به قبل یا بعد. همچنین باید دقت داشت که href این لینک‌ها به id مرتبط با div اصلی دربرگیرنده این قسمت از صفحه اشاره می‌کند. از یک سری گلیف آیکن نیز برای نمایش فلش رو به چپ و راست نیز در اینجا استفاده شده است.
- قسمت لیست مرتبط دارای کلاس carousel-indicators، در حقیقت مشخص کننده سه دایره کوچکی است که در تصویر فوق ملاحظه می‌کنید. به ازای هر تصویر، یک مورد را باید افزود. در اینجا data-target هر آیتم به id مرتبط با div محصور کننده کل اسلایدشو اشاره می‌کند. data-slide-toها به شماره تصویر متناظر هر آیتم متصل خواهند شد. ایندکس آغازین این آیتم‌ها از صفر شروع می‌شود.



بررسی کامپوننت Scroll spy

اگر به مستندات رسمی بوت استرپ مراجعه کنید، منوی کنار صفحه با لغزش صفحه به سمت پایین ثابت است؛ اما به ازای هر سرفصل جدیدی در صفحه، آیتم فعال این منو نیز به صورت خودکار تغییر می‌کند. این قابلیت توسط کامپوننت Scroll spy ایجاد شده است. یک مثال:
<body id="articles" data-spy="scroll" data-target=".scrollspy">
    <div class="container">
        <h4 class="alert alert-info">
            Scroll spy</h4>
        <div id="articlesindex" class="row">
            <section class="scrollspy clearfix col col-lg-3 hidden-sm">
                <ul class="nav nav-list affix">
                    <li><a href="#item1"><span class="glyphicon glyphicon-user"></span>Item 1</a></li>
                    <li><a href="#item2"><span class="glyphicon glyphicon-user"></span>Item 2</a></li>
                    <li><a href="#item3"><span class="glyphicon glyphicon-user"></span>Item 3</a></li>
                </ul>
                <!-- nav-list -->
            </section><!-- scrollspy -->
            <section class="col col-lg-9">
                <article id="item1" class="media">
                    <h2>
                        item1</h2>
                    <div class="media-body">
                        <p>
                            متن متن متن ............متن متن متن ............متن متن متن .............</p>
                        <p>
                            متن متن متن ............متن متن متن ............متن متن متن .............</p>
                        <p>
                            متن متن متن ............متن متن متن ............متن متن متن .............</p>
                        <p>
                            متن متن متن ............متن متن متن ............متن متن متن .............</p>
                        <p>
                            متن متن متن ............متن متن متن ............متن متن متن .............</p>
                        <p>
                            متن متن متن ............متن متن متن ............متن متن متن .............</p>
                        <p>
                            متن متن متن ............متن متن متن ............متن متن متن .............</p>
                        <p>
                            متن متن متن ............متن متن متن ............متن متن متن .............</p>
                        <p>
                            متن متن متن ............متن متن متن ............متن متن متن .............</p>
                        <p>
                            متن متن متن ............متن متن متن ............متن متن متن .............</p>
                        <p>
                            متن متن متن ............متن متن متن ............متن متن متن .............</p>
                        <p>
                            متن متن متن ............متن متن متن ............متن متن متن .............</p>
                        <p>
                            متن متن متن ............متن متن متن ............متن متن متن .............</p>
                    </div>
                </article>
                <article id="item2" class="media">
                    <h2>
                        item2</h2>
                    <div class="media-body">
                        <p>
                            متن متن متن ............متن متن متن ............متن متن متن .............</p>
                        <p>
                            متن متن متن ............متن متن متن ............متن متن متن .............</p>
                        <p>
                            متن متن متن ............متن متن متن ............متن متن متن .............</p>
                        <p>
                            متن متن متن ............متن متن متن ............متن متن متن .............</p>
                        <p>
                            متن متن متن ............متن متن متن ............متن متن متن .............</p>
                        <p>
                            متن متن متن ............متن متن متن ............متن متن متن .............</p>
                        <p>
                            متن متن متن ............متن متن متن ............متن متن متن .............</p>
                        <p>
                            متن متن متن ............متن متن متن ............متن متن متن .............</p>
                        <p>
                            متن متن متن ............متن متن متن ............متن متن متن .............</p>
                        <p>
                            متن متن متن ............متن متن متن ............متن متن متن .............</p>
                        <p>
                            متن متن متن ............متن متن متن ............متن متن متن .............</p>
                        <p>
                            متن متن متن ............متن متن متن ............متن متن متن .............</p>
                        <p>
                            متن متن متن ............متن متن متن ............متن متن متن .............</p>
                    </div>
                </article>
                <article id="item3" class="media">
                    <h2>
                        item3</h2>
                    <div class="media-body">
                        <p>
                            متن متن متن ............متن متن متن ............متن متن متن .............</p>
                        <p>
                            متن متن متن ............متن متن متن ............متن متن متن .............</p>
                        <p>
                            متن متن متن ............متن متن متن ............متن متن متن .............</p>
                        <p>
                            متن متن متن ............متن متن متن ............متن متن متن .............</p>
                        <p>
                            متن متن متن ............متن متن متن ............متن متن متن .............</p>
                        <p>
                            متن متن متن ............متن متن متن ............متن متن متن .............</p>
                        <p>
                            متن متن متن ............متن متن متن ............متن متن متن .............</p>
                        <p>
                            متن متن متن ............متن متن متن ............متن متن متن .............</p>
                        <p>
                            متن متن متن ............متن متن متن ............متن متن متن .............</p>
                        <p>
                            متن متن متن ............متن متن متن ............متن متن متن .............</p>
                        <p>
                            متن متن متن ............متن متن متن ............متن متن متن .............</p>
                        <p>
                            متن متن متن ............متن متن متن ............متن متن متن .............</p>
                        <p>
                            متن متن متن ............متن متن متن ............متن متن متن .............</p>
                    </div>
                </article>
            </section><!-- artistinfo -->
        </div>
        <!-- end row -->
    </div>
    <!-- /container -->
    <script type="text/javascript" src="Scripts/jquery-1.10.2.min.js"></script>
    <script type="text/javascript" src="Scripts/bootstrap-rtl.js"></script>
</body>


توضیحات:
- کار با ایجاد یک section جدید که حاوی منوی ثابت کنار صفحه است، شروع می‌شود. این section دارای کلاس scrollspy می‌باشد. داخل این section لیست عناوین منو قرار می‌گیرند که ul آن دارای کلاس nav nav-list affix خواهد بود. affix سبب می‌شود تا این لیست در کنار صفحه ثابت نمایش داده شود و همواره نمایان باشد.
- نکته مهم لیست آیتم‌های منو، مقادیر href لینک‌های آن است. این مقادیر باید به id محتوای متناظر اشاره کنند. این محتواها را در ادامه‌ی کار ملاحظه می‌کنید.
- به علاوه اگر به تگ body در ابتدای کار دقت کرده باشید، ویژگی‌های data-spy و هدفی که قرار است تحت نظر قرار گیرد به آن اضافه شده‌است.
- تا اینجا این سیستم کار می‌کند؛ اما اگر صفحه را به بالا و پایین حرکت دهید، پس زمینه آیتم فعال، تغییر رنگ نمی‌دهد. برای این منظور نیاز است، به CSS سفارشی خود، چند سطر ذیل را اضافه کرد:
.scrollspy .nav > li.active{
   background: lightgray;
}


فایل‌های نهایی این قسمت را از اینجا نیز می‌توانید دریافت کنید:
bs3-sample04.zip
 
مطالب
داستانی از Unicode
یکی از مباحثی که به نظرم هر دانشجوی رشته کامپیوتر، فناوری اطلاعات و علاقمند به این حوزه باید بداند بحث کاراکترهاست؛ جدا از اینکه همه ما در مورد وجود ascii یا UTF-8 و ... و توضیحات مختصر آن اطلاع داریم ولی عده‌ای از دوستان مثل من هنوز اطلاعات پایه‌ای‌تر و جامع‌تری در این باره نداریم؛ در این مقاله که برداشتی از وب سایت smashing magazine  و W3 است به این مبحث می‌پردازیم.
کامپیوترها تنها با اعداد سر و کار دارند نه با حروف؛ پس این بسیار مهم هست که همه کامپیوترها بر روی یک سری اعداد مشخص به عنوان نماینده‌ای از حروف به توافق برسند. این توافق یکسان بین همه کامپیوترها بسیار مهم هست و باید طبق یک استاندارد مشترک استفاده شود تا در همه سیستم‌ها قابل استفاده و انتقال باشد؛ برای همین در سال 1960 اتحادیه استاندارهای آمریکا، یک سیستم رمزگذاری 7 بیتی را ایجاد کرد؛ به نام American Standard Code for Information Interchange یا کد استاندارد سازی شده آمریکایی برای تبادل اطلاعات یا همان ASCII. این هفت بیت به ما اجازه می‌داد تا 128 حرف را کدگذاری کنیم. این مقدار برای حروف کوچک و بزرگ انگلیسی و هم چنین حروف لاتین، همراه با کدگذاری ارقام و یک سری علائم نگارشی و کاراکترهایی از قبیل space ، tab و موارد مشابه و نهایتا کلیدهای کنترلی کافی بود. در سال 1968 این استاندارد توسط رییس جمهور وقت آمریکا لیندون جانسون به رسمیت شناخته شده و همه سیستم‌های کامپیوتری ملزم به رعایت و استفاده از این استاندارد شدند.
برای لیست کردن و دیدن این کدها و نمادهای حرفیشان می‌توان با یک زبان برنامه نویسی یا اسکریپتی آن‌ها را لیست کرد. کد زیر نمونه‌ای از کد نوشته شده در جاوااسکریپت است.
 <html> 

<body>
 <style type="text/css">p {float: left; padding: 0 15px; margin: 0;}</style> 

<script type="text/javascript">
 for (var i=0; i<128; i++) document.writeln ((i%32?'':'<p>') + i + ': ' + String.fromCharCode (i) + '<br>'); 

</script>
</body>
 </html>
در سال‌های بعدی، با قوی‌تر شدن پردازش‌گرها و 8 بیت شدن یک بایت به جای ذخیره 128 عدد توانستند 256 عدد را ذخیره کنند ولی استاندارد اسکی تا 128 کد ایجاد شده بود و مابقی را به عنوان ذخیره نگاه داشتند. در ابتدا کامپیوترهای IBM از آن‌ها برای ایجاد نمادهای اضافه‌تر و همچنین اشکال استفاده می‌کرد؛ مثلا کد 200 شکل  ╚ بود که احتمالا برنامه نویسان زمان داس، این شکل را به خوبی به خاطر میاورند یا مثلا حروف یونانی را اضافه کردند که با کد 224 شکل آلفا  α بود و بعد‌ها به عنوان  code page 437  نامگذاری شد. هر چند که هرگز مانند اسکی به یک استاندارد تبدیل نشد و بسیاری از کشورها از این فضای اضافی برای استانداردسازی حروف خودشان استفاده می‌کردند و در کشورها کدپیج‌های مختلفی ایجاد شد. برای مثال در روسیه کد پیچ 885 از کد 224 برای نمایش Я بهره می‌برد و در کد پیچ یونانی 737 برای نمایش حرف کوچک امگا ω استفاده می‌شد. این کار ادامه داشت تا زمانیکه مایکروسافت در سال 1980 کد پیچ Windows-1251 الفبای سریلیک را ارئه کرد. این تلاش تا سال 1990 ادامه پیدا کرد و تا آن زمان 15 کدپیج مختلف استاندارسازی شده برای الفبایی چون سیریلیک، عربی، عبری و ... ایجاد شد که این استانداردها از ISO-8859-1 شروع و تا  ISO-8859-16 ادامه داشت و موقعی که فرستنده پیامی را ارسال می‌کرد، گیرنده باید از کدپیج مورد نظر مطلع می‌بود تا بتواند پیام را صحیح بخواند.
بیایید با یک برنامه علائم را در این 15 استاندارد بررسی کنیم. تکه کدی که من در اینجا نوشتم یک لیست را که در آن اعداد یک تا 16 لیست شده است، نشان میدهد که با انتخاب هر کدام، کدها را از 0 تا 255 بر اساس هر استاندارد به ترتیب نمایش می‌دهد. این کار توسط تعیین استاندارد در تگ متا رخ میدهد.
در زمان بارگذاری، استانداردها با کد زیر به لیست اضافه می‌شوند.در مرحله بعد لیستی که  postback را در آن فعال کرده‌ایم، کد زیر را اجرا می‌کند. در این کد ابتدا charset انتخاب شده ایجاد شده و سپس یکی یکی کدها را به کاراکتر تبدیل می‌کنیم و رشته نهایی را درج می‌کنیم: ( دانلود فایل‌های زیر )
 private String ISO = "ISO-8859-";
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                for (int i = 1; i < 16; i++)
                {
                    ListItem item = new ListItem();
                    item.Text = ISO + i.ToString();
                    item.Value = i.ToString();
                    DropDownList1.Items.Add(item);
                }
                ShowCodes(1);
            }
           
        }

     
        protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (DropDownList1.SelectedItem != null)
            {
                int value = int.Parse(DropDownList1.SelectedValue);
                ShowCodes(value);
            }
            
        }

        private void ShowCodes(int value)
        {
            Response.Charset = ISO + value;
            string s = "";
            for (int i = 0; i < 256; i++)
            {
                char ch = (char)i;
                s += i + "-" + ch;
                s += "<br/>";//br tag
            }
            Label1.Text = s;
        }

تقریبا سال 1990 بود که بسیاری از اسناد به همین شیوه‌ها نوشته و ذخیره شد. ولی باز برای بسیاری از زبان‌ها، حتی داشتن یکی دو حرف بیشتر مشکلاتی را به همراه داشت. مثلا حروف بعضی زبان‌ها مثل چینی و ژاپنی که 256 عدد، پاسخگو نبود و با آمدن شبکه‌ای چون اینترنت و بحث بین المللی شدن و انتقال اطلاعات، این مشکل بزرگتر از آنچه بود، شد.

یونیکد نجات بخش
اواخر سال 1980 بود که پیشنهاد یک استاندارد جدید داده شد و در آن به هر حرف و یا نماد در هر زبانی یک عدد یکتا نسبت داده میشد و باید بیشتر از 256 عدد می‌بود که آن را یونیکد نامیدند. در حال حاضر یونیکد نسخه 601 شامل 110 هزار کد می شود. 128 تای آن همانند اسکی است. از 128 تا 255 مربوط به علائم و علامت‌هاست که بیشتر آن‌ها از استاندارد ISO-8859-1 وام گرفته شده‌اند. از 256 به بعد هم بسیاری از علائم تلفظی و ... وجود دارد و از کد 880 زبان یونایی آغاز شده و پس از آن زبان‌های سیریلیک، عبری، عربی و الی آخر ادامه می‌یابند. برای نشان دادن یک کد یونیکد به شکل هگزادسیمال U+0048 نوشته می‌شود و برای تبدیل آن به دسیمال 4*16+8=72 استفاده می‌شود. به هر کد یونیکد، کد پوینت code point گفته میشود.
در ویکی پدیای فارسی، یونیکد اینگونه توضیح داده شده است: "نقش یونیکد در پردازش متن این است که به جای یک تصویر برای هر نویسه یک کد منحصر به فرد ارایه می‌کند. به عبارت دیگر، یونیکد یک نویسه را به صورت مجازی ارایه می‌کند و کار ساخت تصویر (شامل اندازه، شکل، قلم، یا سبک) نویسه را به عهده نرم‌افزار دیگری مانند مرورگر وب یا واژه‌پرداز می‌گذارد. "
یونیکد از 8 بیت یا 16 بیت استفاده نمی‌کند و با توجه به اینکه دقیقا 110 ،116 کد را حمایت می‌کند به 21 بیت نیاز دارد. هر چند که کامپیوترها امروزه از معمار‌های 32 بیتی و 64 بیتی استفاده می‌کنند، این سوال پیش می‌آید که ما چرا نمی‌توانیم کاراکترها را بر اساس این 32 بیت و 64 بیت قرار بدهیم؟ پاسخ این سوال این‌است که چنین کاری امکان پذیر است و بسیاری از نرم افزارهای نوشته شده در زبان سی و سی ++ از wide character حمایت می‌کنند. این مورد یک کاراکتر 32 بیتی به نام wchar_t است که نوعی داده char توسعه یافته هشت بیتی است و بسیاری از مرورگرهای امروزی از آن بهره مند هستند و تا 4 بیلیون کاراکتر را حمایت می‌کنند.
شکل زیر دسته بندی از انواع زبان‌های تحت حمایت خود را در نسخه 5.1 یونیکد نشان می‌دهد:


کد زیر در جاوااسکریپت کاراکترهای یونیکد را در مرز معینی که برایش مشخص کرده‌ایم نشان می‌دهد:
 <html> 

<body>
 <style type="text/css">p {float: left; padding: 0 15px; margin: 0;}</style> 

<script type="text/javascript">
for (var i=0; i<2096; i++)
   document.writeln ((i%256?'':'<p>') + i + ': ' + String.fromCharCode (i) + '<br>'); 

</script>
</body>
 </html>

CSS & Unicode
یکی از جذاب‌ترین خصوصیات در css، خصوصیت Unicode-range است. شما میتوانید برای هر کاراکتر یا حتی رنج خاصی از کاراکترها، فونت خاصی را اعمال کنید. به دو نمونه زیر دقت کنید:
/* cyrillic */
@font-face {
  font-style: normal;
  src: local('Roboto Regular'), local('Roboto-Regular'), url(http://fonts.gstatic.com/s/roboto/v14/mErvLBYg_cXG3rLvUsKT_fesZW2xOQ-xsNqO47m55DA.woff2) format('woff2');
  unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek-ext */
@font-face {
  font-style: normal;
  src: local('Roboto Regular'), local('Roboto-Regular'), url(http://fonts.gstatic.com/s/roboto/v14/-2n2p-_Y08sg57CNWQfKNvesZW2xOQ-xsNqO47m55DA.woff2) format('woff2');
  unicode-range: U+1F00-1FFF;
}
/* greek */
@font-face {
  font-style: normal;
  src: local('Roboto Regular'), local('Roboto-Regular'), url(http://fonts.gstatic.com/s/roboto/v14/u0TOpm082MNkS5K0Q4rhqvesZW2xOQ-xsNqO47m55DA.woff2) format('woff2');
  unicode-range: U+0370-03FF;
}
/* vietnamese */
@font-face {
  font-style: normal;
  src: local('Roboto Regular'), local('Roboto-Regular'), url(http://fonts.gstatic.com/s/roboto/v14/NdF9MtnOpLzo-noMoG0miPesZW2xOQ-xsNqO47m55DA.woff2) format('woff2');
  unicode-range: U+0102-0103, U+1EA0-1EF1, U+20AB;
}
/* latin-ext */
@font-face {
  font-style: normal;
  src: local('Roboto Regular'), local('Roboto-Regular'), url(http://fonts.gstatic.com/s/roboto/v14/Fcx7Wwv8OzT71A3E1XOAjvesZW2xOQ-xsNqO47m55DA.woff2) format('woff2');
  unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;
}
در صورتی که در Unicode-range، تنها یک کد مانند U+20AD نوشته شود، فونت مورد نظر فقط بر روی کاراکتری با همین کد اعمال می‌شود. ولی اگر بین دو کد از علامت - استفاده شود، فونت مورد نظر بر روی کاراکترهایی که بین این رنج هستند اعمال می‌شود U+0025-00FF و حتی می‌توان اینگونه نوشت ??U+4 روی کاراکترهایی در رنج U+400 تا U+4FF اعمال می‌شوند. برای اطلاعات بیش‌تر به اینجا و اینجا  مراجعه کنید.
به 65536 کد اول یونیکد Basic Multilingual Plan یا به اختصار BMP می‌گویند و شامل همه کاراکترهای رایجی است که مورد استفاده قرار می‌گیرند. همچنین یونیکد شامل یک فضای بسیار بزرگ خالی است که به شما اجازه توسعه دادن آن را تا میلیون‌ها کد می‌دهد. به کاراکترهایی که در این موقعیت قرار می‌گیرند supplementary characters یا کاراکترهای مکمل گویند. برای اطلاعات بیشتر می‌توانید به سایت رسمی یونیکد مراجعه کنید. در اینجا هم مباحث آموزشی خوبی برای یونیکد دارد، هر چند کامل‌تر آن در سایت رسمی برای نسخه‌های مختلف یونیکد وجود دارد.


UTF-8 نجات بخش می‌شود
بسیاری از مشکلات ما حل شد. همه حروف را داریم و مرورگر‌ها نیز همه حروف را میشناسند؛ ولی برای ما دو مشکل ایجاد کرده است:
  • بسیاری از نرم افزارها و پروتکل‌ها هنوز 8 بیتی کار می‌کنند.
  • اگر یک متن انگلیسی ارسال کنید، 8 بیت هم کافی است ولی در این حالت 32 بیت جابجا می‌شود؛ یعنی 4 برابر و در ارسال و دریافت و پهنای باند برایمان مشکل ایجاد می‌کند.
برای حل این مشکل استاندارهای زیادی چون USC-2 یا UTF-16 ایجاد شدند ولی در سال‌های اخیر برنده رقابت، UTF-8 بود که مخفف عبارت Universal Character Set Transformation Format 8 bit می‌باشد. این کدگذاری بسیار هوشمندانه عمل می‌کند. موقعی که شما کاراکتری را وارد می‌کنید که کدش بین 0 تا 255 است، 8 بیت به آن اختصاص می‌دهد و اگر در محدوده‌ای است که بتوان دو بایت را به آن اختصاص داد، دوبایت و اگر بیشتر بود، سه بایت و اگر باز بیشتر بود 4 بایت به آن اختصاص میدهد. پس با توجه به محدوده کد، تعداد بایت‌ها مشخص می‌شوند. بنابراین یک متن نوشته شده انگلیسی که مثلا از کدهای بین 0تا 128 استفاده می‌کند و فرمت ذخیره آن UTF-8 باشد به ازای هر کارکتر یک بایت ذخیره می‌کند.

مقایسه‌ای بین نسخه‌های مختلف :

همانطور که می‌بینید UTF-8 برای کاراکترهای اسکی، از یک بایت و برای دیگر حروف از دوبایت و برای بقیه BMP‌ها از سه بایت استفاده میکند و در صورتی که کاراکتری در ناحیه مکمل supplementary باشد، از چهار بایت استفاده خواهد کرد. UTF-16 از دو بایت برای نمایش کاراکترهای BMP و از 4 بایت برای نمایش کاراکترهای مکمل استفاده می‌کند و در UTF-32 از 4 بایت برای همه کاراکترها یا کد پوینت‌ها استفاده می‌شود.

نظرات اشتراک‌ها
قرار دادن سامانه دانشگاه بروی یک Private IP Address
اگه صحبت اینترانت باشه خب وبسایت رو هم روی اینترانتشون راه بندازن. فکر نمیکنم منطقی باشه که بیان یه لینک به اینترانت خودشون بروی اینترنت قرار بدن در حالی که نصف ملت روی اون کلیک میکنن و سردر گم میشن. یا اینکه لینک رو برای دسترسی‌های داخل شبکه ای نمایش بدن.
مطالب
بررسی ساختار ویجت‌های وب Kendo UI
ویجت‌های وب Kendo UI کدامند؟

ویجت‌های وب Kendo UI مجموعه‌ای از کنترل‌های سفارشی HTML 5 هستند که برفراز jQuery تهیه شده‌اند. این کنترل‌ها برای برنامه‌های وب و همچنین برنامه‌های دسکتاپ لمسی طراحی شده‌اند.
بهترین روش برای مشاهده‌ی این مجموعه، مراجعه به فایل examples\index.html پوشه‌ی اصلی Kendo UI است که لیست کاملی از این ویجت‌ها را به همراه مثال‌های مرتبط ارائه می‌دهد. تعدادی از اعضای این مجموعه شامل کنترل‌های ذیل هستند:
Window, TreeView, Tooltip, ToolBar, TimePicker, TabStrip, Splitter, Sortable, Slider, Gantt, Scheduler, ProgressBar, PanelBar, NumericTextBox, Notification, MultiSelect, Menu, MaskedTextBox, ListView, PivotGrid, Grid, Editor, DropDownList, DateTimePicker, DatePicker, ComboBox, ColorPicker, Calendar, Button, AutoComplete


نحوه‌ی استفاده کلی از ویجت‌های وب Kendo UI

با توجه به اینکه کنترل‌های Kendo UI مبتنی بر jQuery هستند، نحوه‌ی استفاده از آن‌ها، مشابه سایر افزونه‌های جی‌کوئری است. ابتدا المانی به صفحه اضافه می‌شود:
 <input id="pickDate" type="text"/>
سپس این المان را در رویداد document ready، به یکی از کنترل‌های Kendo UI مزین خواهیم کرد. برای مثال تزئین یک TextBox معمولی با یک Date Picker:
 <script type="text/javascript">
  $(function() {
        $("#pickDate").kendoDatePicker();
  });
</script>
روش دیگری به نام declarative initialization نیز برای اعمال ویجت‌های وب Kendo UI قابل استفاده است که از ویژگی‌های *-data مرتبط با HTML 5 کمک می‌گیرد. برای نمونه، کدهای جاوا اسکریپتی فوق را می‌توان با ویژگی data-role ذیل جایگزین کرد:
 <input id="dateOfBirth" type="text" data-role="datepicker" />
اگر در این حالت برنامه را اجرا کنید، تفاوتی را مشاهده نخواهید کرد.
برای فعال سازی حالت declarative initialization باید به دو نکته‌ی مهم دقت داشت:
الف) در مطلب معرفی Kendo UI اسکریپت‌های ذیل برای آماده سازی Kendo Ui معرفی شدند:
 <!--KendoUI: Web-->
<link href="styles/kendo.common.min.css" rel="stylesheet" type="text/css" />
<link href="styles/kendo.default.min.css" rel="stylesheet" type="text/css" />
<script src="js/jquery.min.js" type="text/javascript"></script>
<script src="js/kendo.web.min.js" type="text/javascript"></script>

<!--KendoUI: DataViz-->
<link href="styles/kendo.dataviz.min.css" rel="stylesheet" type="text/css" />
<script src="js/kendo.dataviz.min.js" type="text/javascript"></script>

<!--KendoUI: Mobile-->
<link href="styles/kendo.mobile.all.min.css" rel="stylesheet" type="text/css" />
<script src="js/kendo.mobile.min.js" type="text/javascript"></script>
باید دقت داشت که در آن واحد نمی‌توان تمام این بسته‌ها را با هم بکار برد؛ چون برای مثال فایل‌های جداگانه ویجت‌های وب و موبایل با هم تداخل ایجاد می‌کنند. بجای اینکار بهتر است از فایل‌های kendo.all.min.js (که حاوی تمام اسکریپت‌های لازم است) و css‌های عنوان شده استفاده کرد:
 <link href="styles/kendo.common.min.css" rel="stylesheet" type="text/css" />
<link href="styles/kendo.default.min.css" rel="stylesheet" type="text/css" />
<script src="js/jquery.min.js" type="text/javascript"></script>
<script src="js/kendo.all.min.js" type="text/javascript"></script>
ب) data-roleها توسط متد kendo.init فعال می‌شوند.
یک مثال کامل:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>

    <link href="styles/kendo.common.min.css" rel="stylesheet" type="text/css" />
    <link href="styles/kendo.default.min.css" rel="stylesheet" type="text/css" />
    <script src="js/jquery.min.js" type="text/javascript"></script>
    <script src="js/kendo.all.min.js" type="text/javascript"></script>

    <script type="text/javascript">
        $(function () {
            $("#pickDate").kendoDatePicker();
        });

        $(function () {
            // initialize any widgets in the #container div
            kendo.init($("#container"));
        });
    </script>
</head>
<body>
    <span>
        Pick a date: <input id="pickDate" type="text" />
    </span>

    <div id="container">
        <input id="dateOfBirth" type="text" data-role="datepicker" />
        <div id="colors"
             data-role="colorpalette"
             data-columns="4"
             data-tile-size="{ width: 34, height: 19 }"></div>
    </div>
</body>
</html>
- در این مثال نحوه‌ی پیوست تمام فایل‌های لازم Kendo UI را به صورت یکجا ملاحظه می‌کنید که در ابتدای head صفحه ذکر شده‌اند.
- در اینجا pickDate به صورت معمولی فعال شد‌ه‌است.
- اما در قسمت kendo.init نام یک ناحیه یا نام یک کنترل را می‌توان ذکر کرد. برای مثال در اینجا کل ناحیه‌ی مشخص شده توسط یک div با id مساوی container به صورت یکجا با تمام کنترل‌های داخل آن فعال گردیده‌است.

بنابراین برای اعمال declarative initialization، یک ناحیه را توسط kendo.init مشخص کرده و سپس توسط data-roleها، نام ویجت وب مورد نظر را به صورت lower case مشخص می‌کنیم. همچنین فایل‌های اسکریپت مورد استفاده نیز نباید تداخلی داشته باشند.


تنظیمات ویجت‌های وب Kendo UI

تاکنون نمونه‌ی ساده‌ای از بکارگیری ویجت‌های وب Kendo UI را بررسی کردیم؛ اما این ویجت‌ها توسط تنظیمات پیش بینی شده برای آن‌ها بسیار قابل تنظیم و تغییر هستند. تنظیمات آن‌ها نیز بستگی به روش استفاده و آغاز آن‌ها دارد. برای مثال اگر این ویجت‌ها را توسط کدهای جاوا اسکریپتی آغاز کرده‌اید، در همانجا توسط پارامترهای افزونه‌ی جی‌کوئری می‌توان تنظیمات مرتبط را اعمال کرد:
 <script type="text/javascript">
  $(function () {
      $("#pickDate").kendoDatePicker({
              format: "yyyy/MM/dd"
        });
  });
</script>
که در اینجا توسط پارامتر format، نحوه‌ی دریافت تاریخ نهایی مشخص می‌شود.
در حالت declarative initialization، پارامتر format تبدیل به ویژگی data-format خواهد شد:
<input id="dateOfBirth" type="text"
          data-role="datepicker"
          data-format="yyyy/MM/dd" />


تنظیمات DataSource ویجت‌های وب

بسیاری از ویجت‌های وب Kendo UI با داده‌ها سر و کار دارند مانند Grid، Auto Complete، Combo box و غیره. این کنترل‌ها داده‌های خود را از طریق خاصیت DataSource دریافت می‌کنند. برای نمونه در اینجا یک combo box را در نظر بگیرید. در مثال اول، خاصیت dataSource کنترل ComboBox در همان افزونه‌ی جی‌کوئری تنظیم شده‌است:
    <input id="colorPicker1" />
    <script type="text/javascript">
        $(document).ready(function () {
            $("#colorPicker1").kendoComboBox({
                dataSource: ["Blue", "Green", "Red", "Yellow"]
            });
        });
    </script>
و در مثال دوم، نحوه‌ی مقدار دهی ویژگی data-source را در حالت declarative initialization مشاهده می‌کنید. همانطور که عنوان شد، در این حالت ذکر متد kendo.init بر روی یک ناحیه و یا یک کنترل ویژه، جهت آغاز فعالیت آن ضروری است:
    <input id="colorPicker2" data-role="combobox" data-source='["Blue", "Green", "Red", "Yellow"]' />
    <script type="text/javascript">
        $(document).ready(function () {
            kendo.init($("#colorPicker2"));
        });
    </script>


کار با رویدادهای ویجت‌های وب

نحوه‌ی کار با رویدادهای ویجت‌های وب نیز بر اساس نحوه‌ی آغاز آن‌ها متفاوت است. در مثال‌های ذیل، دو حالت متفاوت تنظیم رویداد change را توسط خواص افزونه‌ی جی‌کوئری:
    <input id="colorPicker3" />
    <script type="text/javascript">
        function onColorChange(e) {
             alert('Color Change!');
        }

        $(document).ready(function () {
            $("#colorPicker3").kendoComboBox({
                dataSource: ["Blue", "Green", "Red", "Yellow"],
                change: onColorChange
            });
        });
    </script>
و همچنین توسط ویژگی data-change مشاهده می‌کنید:
    <input id="colorPicker4" data-role="combobox"
           data-source='["Blue", "Green", "Red", "Yellow"]'
           data-change="onColorChange" />

    <script type="text/javascript">
        function onColorChange(e) {
            alert('Color Change!');
        }

        $(document).ready(function () {
            kendo.init($("#colorPicker4"));
        });
    </script>
در هر دو حالت، انتخاب یک گزینه‌ی جدید combo box، سبب فراخوانی متد callback ایی به نام onColorChange می‌شود.


تغییر قالب ویجت‌های وب

Kendo UI همیشه یک جفت CSS را جهت تعیین قالب‌های ویجت‌های خود، مورد استفاده قرار می‌دهد. برای نمونه در مثال‌های فوق، kendo.common.min.css حاوی اطلاعات محل قرارگیری و اندازه‌ی ویجت‌ها است. شیوه نامه‌ی دوم همیشه به شکل kendo.[skin].min.css تعریف می‌شود که دارای اطلاعات رنگ و پس زمینه‌ی ویجت‌ها خواهد بود؛ مانند kendo.black.min.css، kendo.blueopal.min.css و امثال آن که در پوشه‌ی styles قابل مشاهده هستند.
همچنین باید دقت داشت که همیشه common باید پیش از skin ذکر شود؛ زیرا در تعدادی از حالات، شیوه نامه‌ی skin، اطلاعات common را بازنویسی می‌کند.
علاوه بر skinهای پیش فرض موجود در پوشه‌ی styles، امکان استفاده از یک theme builder آنلاین نیز وجود دارد: kendo-ui-themebuilder
مطالب
صفحه بندی، مرتب سازی و جستجوی پویای اطلاعات به کمک Kendo UI Grid
پس از آشنایی مقدماتی با Kendo UI DataSource، اکنون می‌خواهیم از آن جهت صفحه بندی، مرتب سازی و جستجوی پویای سمت سرور استفاده کنیم. در مثال قبلی، هر چند صفحه بندی فعال بود، اما پس از دریافت تمام اطلاعات، این اعمال در سمت کاربر انجام و مدیریت می‌شد.



مدل برنامه

در اینجا قصد داریم لیستی را با ساختار کلاس Product در اختیار Kendo UI گرید قرار دهیم:
namespace KendoUI03.Models
{
    public class Product
    {
        public int Id { set; get; }
        public string Name { set; get; }
        public decimal Price { set; get; }
        public bool IsAvailable { set; get; }
    }
}


پیشنیاز تامین داده مخصوص Kendo UI Grid

برای ارائه اطلاعات مخصوص Kendo UI Grid، ابتدا باید درنظر داشت که این گرید، درخواست‌های صفحه بندی خود را با فرمت ذیل ارسال می‌کند. همانطور که مشاهده می‌کنید، صرفا یک کوئری استرینگ با فرمت JSON را دریافت خواهیم کرد:
 /api/products?{"take":10,"skip":0,"page":1,"pageSize":10,"sort":[{"field":"Id","dir":"desc"}]}
سپس این گرید نیاز به سه فیلد، در خروجی JSON نهایی خواهد داشت:
{
"Data":
[
{"Id":1500,"Name":"نام 1500","Price":2499.0,"IsAvailable":false},
{"Id":1499,"Name":"نام 1499","Price":2498.0,"IsAvailable":true}
],
"Total":1500,
"Aggregates":null
}
فیلد Data که رکوردهای گرید را تامین می‌کنند. فیلد Total که بیانگر تعداد کل رکوردها است و Aggregates که برای گروه بندی بکار می‌رود.

می‌توان برای تمام این‌ها، کلاس و Parser تهیه کرد و یا ... پروژه‌ی سورس بازی به نام  Kendo.DynamicLinq نیز چنین کاری را میسر می‌سازد که در ادامه از آن استفاده خواهیم کرد. برای نصب آن تنها کافی است دستور ذیل را صادر کنید:
 PM> Install-Package Kendo.DynamicLinq
Kendo.DynamicLinq به صورت خودکار System.Linq.Dynamic را نیز نصب می‌کند که از آن جهت صفحه بندی پویا استفاده خواهد شد.


تامین کننده‌ی داده سمت سرور

همانند مطلب کار با Kendo UI DataSource ، یک ASP.NET Web API Controller جدید را به پروژه اضافه کنید و همچنین مسیریابی‌های مخصوص آن‌را به فایل global.asax.cs نیز اضافه نمائید.
using System.Linq;
using System.Net.Http;
using System.Web.Http;
using Kendo.DynamicLinq;
using KendoUI03.Models;
using Newtonsoft.Json;

namespace KendoUI03.Controllers
{
    public class ProductsController : ApiController
    {
        public DataSourceResult Get(HttpRequestMessage requestMessage)
        {
            var request = JsonConvert.DeserializeObject<DataSourceRequest>(
                requestMessage.RequestUri.ParseQueryString().GetKey(0)
            );

            var list = ProductDataSource.LatestProducts;
            return list.AsQueryable()
                       .ToDataSourceResult(request.Take, request.Skip, request.Sort, request.Filter);
        }
    }
}
تمام کدهای این کنترلر همین چند سطر فوق هستند. با توجه به ساختار کوئری استرینگی که در ابتدای بحث عنوان شد، نیاز است آن‌را توسط کتابخانه‌ی JSON.NET تبدیل به یک نمونه از DataSourceRequest نمائیم. این کلاس در Kendo.DynamicLinq تعریف شده‌است و حاوی اطلاعاتی مانند take و skip کوئری LINQ نهایی است.
ProductDataSource.LatestProducts صرفا یک لیست جنریک تهیه شده از کلاس Product است. در نهایت با استفاده از متد الحاقی جدید ToDataSourceResult، به صورت خودکار مباحث صفحه بندی سمت سرور به همراه مرتب سازی اطلاعات، صورت گرفته و اطلاعات نهایی با فرمت DataSourceResult بازگشت داده می‌شود. DataSourceResult نیز در Kendo.DynamicLinq تعریف شده و سه فیلد یاد شده‌ی Data، Total و Aggregates را تولید می‌کند.

تا اینجا کارهای سمت سرور این مثال به پایان می‌رسد.


تهیه View نمایش اطلاعات ارسالی از سمت سرور

اعمال مباحث بومی سازی
<head>
    <meta charset="utf-8" />
    <meta http-equiv="Content-Language" content="fa" />
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

    <title>Kendo UI: Implemeting the Grid</title>

    <link href="styles/kendo.common.min.css" rel="stylesheet" type="text/css" />
    <!--شیوه نامه‌ی مخصوص راست به چپ سازی-->
    <link href="styles/kendo.rtl.min.css" rel="stylesheet" />
    <link href="styles/kendo.default.min.css" rel="stylesheet" type="text/css" />
    <script src="js/jquery.min.js" type="text/javascript"></script>
    <script src="js/kendo.all.min.js" type="text/javascript"></script>

    <!--محل سفارشی سازی پیام‌ها و مسایل بومی-->
    <script src="js/cultures/kendo.culture.fa-IR.js" type="text/javascript"></script>
    <script src="js/cultures/kendo.culture.fa.js" type="text/javascript"></script>
    <script src="js/messages/kendo.messages.en-US.js" type="text/javascript"></script>

    <style type="text/css">
        body {
            font-family: tahoma;
            font-size: 9pt;
        }
    </style>

    <script type="text/javascript">
        // جهت استفاده از فایل: kendo.culture.fa-IR.js
        kendo.culture("fa-IR");
    </script>
</head>
- در اینجا چند فایل js و css جدید اضافه شده‌اند. فایل kendo.rtl.min.css جهت تامین مباحث RTL توکار Kendo UI کاربرد دارد.
- سپس سه فایل kendo.culture.fa-IR.js، kendo.culture.fa.js و kendo.messages.en-US.js نیز اضافه شده‌اند. فایل‌های fa و fa-Ir آن هر چند به ظاهر برای ایران طراحی شده‌اند، اما نام ماه‌های موجود در آن عربی است که نیاز به ویرایش دارد. به همین جهت به سورس این فایل‌ها، جهت ویرایش نهایی نیاز خواهد بود که در پوشه‌ی src\js\cultures مجموعه‌ی اصلی Kendo UI موجود هستند (ر.ک. فایل پیوست).
- فایل kendo.messages.en-US.js حاوی تمام پیام‌های مرتبط با Kendo UI است. برای مثال«رکوردهای 10 تا 15 از 1000 ردیف» را در اینجا می‌توانید به فارسی ترجمه کنید.
- متد kendo.culture کار مشخص سازی فرهنگ بومی برنامه را به عهده دارد. برای مثال در اینجا به fa-IR تنظیم شده‌است. این مورد سبب خواهد شد تا از فایل kendo.culture.fa-IR.js استفاده گردد. اگر مقدار آن‌را به fa تنظیم کنید، از فایل kendo.culture.fa.js کمک گرفته خواهد شد.

راست به چپ سازی گرید
تنها کاری که برای راست به چپ سازی Kendo UI Grid باید صورت گیرد، محصور سازی div آن در یک div با کلاس مساوی k-rtl است:
    <div class="k-rtl">
        <div id="report-grid"></div>
    </div>
k-rtl و تنظیمات آن در فایل kendo.rtl.min.css قرار دارند که در ابتدای head صفحه تعریف شده‌است.

تامین داده و نمایش گرید

در ادامه کدهای کامل DataSource و Kendo UI Grid را ملاحظه می‌کنید:
    <script type="text/javascript">
        $(function () {
            var productsDataSource = new kendo.data.DataSource({
                transport: {
                    read: {
                        url: "api/products",
                        dataType: "json",
                        contentType: 'application/json; charset=utf-8',
                        type: 'GET'
                    },
                    parameterMap: function (options) {
                        return kendo.stringify(options);
                    }
                },
                schema: {
                    data: "Data",
                    total: "Total",
                    model: {
                        fields: {
                            "Id": { type: "number" }, //تعیین نوع فیلد برای جستجوی پویا مهم است
                            "Name": { type: "string" },
                            "IsAvailable": { type: "boolean" },
                            "Price": { type: "number" }
                        }
                    }
                },
                error: function (e) {
                    alert(e.errorThrown);
                },
                pageSize: 10,
                sort: { field: "Id", dir: "desc" },
                serverPaging: true,
                serverFiltering: true,
                serverSorting: true
            });

            $("#report-grid").kendoGrid({
                dataSource: productsDataSource,
                autoBind: true,
                scrollable: false,
                pageable: true,
                sortable: true,
                filterable: true,
                reorderable: true,
                columnMenu: true,
                columns: [
                    { field: "Id", title: "شماره", width: "130px" },
                    { field: "Name", title: "نام محصول" },
                    {
                        field: "IsAvailable", title: "موجود است",
                        template: '<input type="checkbox" #= IsAvailable ? checked="checked" : "" # disabled="disabled" ></input>'
                    },
                    { field: "Price", title: "قیمت", format: "{0:c}" }
                ]
            });
        });
    </script>
- با تعاریف مقدماتی Kendo UI DataSource پیشتر آشنا شده‌ایم و قسمت read آن جهت دریافت اطلاعات از سمت سرور کاربرد دارد.
- در اینجا ذکر contentType الزامی است. زیرا ASP.NET Web API بر این اساس است که تصمیم می‌گیرد، خروجی را به صورت JSON ارائه دهد یا XML.
- با استفاده از parameterMap، سبب خواهیم شد تا پارامترهای ارسالی به سرور، با فرمت صحیحی تبدیل به JSON شده و بدون مشکل به سرور ارسال گردند.
- در قسمت schema باید نام فیلدهای موجود در DataSourceResult دقیقا مشخص شوند تا گرید بداند که data را باید از چه فیلدی استخراج کند و تعداد کل ردیف‌ها در کدام فیلد قرار گرفته‌است.
- نحوه‌ی تعریف model را نیز در اینجا ملاحظه می‌کنید. ذکر نوع فیلدها در اینجا بسیار مهم است و اگر قید نشوند، در حین جستجوی پویا به مشکل برخواهیم خورد. زیرا پیش فرض نوع تمام فیلدها string است و در این حالت نمی‌توان عدد 1 رشته‌ای را با یک فیلد از نوع int در سمت سرور مقایسه کرد.
- در اینجا serverPaging، serverFiltering و serverSorting نیز به true تنظیم شده‌اند. اگر این مقدار دهی‌ها صورت نگیرد، این اعمال در سمت کلاینت انجام خواهند شد.

پس از تعریف DataSource، تنها کافی است آن‌را به خاصیت dataSource یک kendoGrid نسبت دهیم.
- autoBind: true سبب می‌شود تا اطلاعات DataSource بدون نیاز به فراخوانی متد read آن به صورت خودکار دریافت شوند.
- با تنظیم scrollable: false، اعلام می‌کنیم که قرار است تمام رکوردها در معرض دید قرارگیرند و اسکرول پیدا نکنند.
- pageable: true صفحه بندی را فعال می‌کند. این مورد نیاز به تنظیم pageSize: 10 در قسمت DataSource نیز دارد.
- با sortable: true مرتب سازی ستون‌ها با کلیک بر روی سرستون‌ها فعال می‌گردد.
- filterable: true به معنای فعال شدن جستجوی خودکار بر روی فیلدها است. کتابخانه‌ی Kendo.DynamicLinq حاصل آن‌را در سمت سرور مدیریت می‌کند.
- reorderable: true سبب می‌شود تا کاربر بتواند محل قرارگیری ستون‌ها را تغییر دهد.
- ذکر columnMenu: true اختیاری است. اگر ذکر شود، امکان مخفی سازی انتخابی ستون‌ها نیز مسیر خواهد شد.
- در آخر ستون‌های گرید مشخص شده‌اند. با تعیین "{format: "{0:c سبب نمایش فیلدهای قیمت با سه رقم جدا کننده خواهیم شد. مقدار ریال آن از فایل فرهنگ جاری تنظیم شده دریافت می‌گردد. با استفاده از template تعریف شده نیز سبب نمایش فیلد bool به صورت یک checkbox خواهیم شد.


کدهای کامل این مثال را از اینجا می‌توانید دریافت کنید:
KendoUI03.zip
مطالب
بهینه سازی فایلهای js و css در برنامه‌های ASP.NET با استفاده از Combres - قسمت اول
 یکی از مواردی که در توسعه وب نقش مهمی دارد، بهینه سازی فایلهای js  و css است که با فشرده سازی و کش کردن آنها می‌توان سرعت بارگذاری را تا حد چشمگیری افزایش داد. برای درک بهتر، به مثال زیر توجه کنید.
یک پروژه ساده را ایجاد می‌کنیم و فایل‌های CSS و js  را مانند شکل زیر، به آن اضافه می‌کنیم:


طبق تصویر فایل‌ها را به صفحه‌ای که ساختیم اضافه می‌کنیم:


پروژه را اجرا کرده و توسط افزونه‌ی firebug درخواست‌هایی را که از سرور شده‌است، بررسی می‌کنیم. مشاهده خواهید کرد که به ازای هر فایل، یک درخواست به سرور ارسال شده و هیچکدام از فایل‌ها توسط  وب سرور فشرده سازی نشده‌اند و اطلاعاتی در مورد کش، به هدر آنها اضافه نشده است.

برای رفع این موارد، روشهای گوناگونی وجود دارد که امروز قصد داریم این کار را توسط  کتابخانه Combress انجام دهیم !
نصب کتابخانه Combres
شما می‌توانید با استفاده از nuget این کتابخانه را به پروژه خود اضافه کنید. 
ایجاد فایل تنظیمات
پس از نصب کتابخانه، فایلی با نام combres.xml در فولدر app_data ساخته می‌شود که تمامی فعالیت‌های کتابخانه براساس آن انجام می‌شود و ساختار آن بصورت زیر است:
<?xml version="1.0" encoding="utf-8" ?>
<combres xmlns='urn:combres'>
  <filters>
    <filter type="Combres.Filters.FixUrlsInCssFilter, Combres" />
  </filters>
  <resourceSets url="~/combres.axd"
                defaultDuration="30"
                defaultVersion="auto"
                defaultDebugEnabled="false"
                defaultIgnorePipelineWhenDebug="true"
                localChangeMonitorInterval="30"
                remoteChangeMonitorInterval="60">
    <resourceSet name="siteCss" type="css">
      <resource path="~/content/Site.css" />
      <resource path="~/content/anotherCss.css" />
      <resource path="~/scripts/yetAnotherCss.css" />
    </resourceSet>
    <resourceSet name="siteJs" type="js">
      <resource path="~/scripts/jquery-1.4.4.js" />
      <resource path="~/scripts/anotherJs.js" />
      <resource path="~/scripts/yetAnotherJs.js" />
    </resourceSet>
  </resourceSets>
</combres>
ResourceSet: با استفاده از هر ResourceSet می‌توانید آن مجموعه فایل را در یک درخواست از سرور دریافت کنید.
پارامتر url : برای تولید لینک فایل‌ها از آن استفاده میکند.
پارامتر defaultDuration : این عدد به تعداد روزهای پیشفرض برای کش کردن فایلها اشاره میکند.
پارامتر defaultVersion :در صورتی که مقدار آن auto باشد به ازای هر تغییر، آدرس جدیدی برای فایل موردنظر ایجاد میشود.
پارامتر defaultDebugEnabled :با استفاده از آن میتوانید debug mode را مشخص کنید. در صورتیکه مقدار آن auto باشد، این مقدار مستقیما از وب‌کانفیگ خوانده میشود.
مقادیر پیش فرض برای تمامی ResourceSet‌ها استفاده می‌شود و در صورت نیاز میتوان این مقادیر را برای هر ResourceSet بازنویسی کرد. فیلترها برای اعمال تغییراتی در فایل js و CSS استفاده می‌شوند که باید به این شکل معرفی شوند. در قسمت بعد با فیلترها بیشتر آشنا میشویم.
فایل cobmres.xml  را به منظور استفاده در پروژه به صورت زیر تغییر می‌دهیم.
<?xml version="1.0" encoding="utf-8" ?>

<combres xmlns='urn:combres'>
  <filters>
    <filter type="Combres.Filters.FixUrlsInCssFilter, Combres" />
  </filters>
  <resourceSets url="~/combres.axd"
                defaultDuration="30"
                defaultVersion="auto"
                defaultDebugEnabled="false"
                defaultIgnorePipelineWhenDebug="true"
                localChangeMonitorInterval="30"
                remoteChangeMonitorInterval="60">
    <resourceSet name="siteCss" type="css">
      <resource path="~/Styles/Site.css" />
    </resourceSet>
    <resourceSet name="siteJs" type="js">
      <resource path="~/Scripts/jquery-1.10.2.js" />
      <resource path="~/Scripts/jquery-1.10.2.min.js" />
    </resourceSet>
  </resourceSets>
</combres>
اگر از نیوگت برای نصب کتابخانه استفاده کرده باشید تغییرات مورد نیاز در فایل وب کانفیگ به صورت خودکار اعمال می‌شود؛ در غیر اینصورت باید قسمتهای زیر را به آن اضافه کنید.
<configuration>
  <configSections>
    <section name="combres" type="Combres.ConfigSectionSetting, Combres, Version=2.2, Culture=neutral, PublicKeyToken=1ca6b37997dd7536" />
  </configSections>
  <system.web>
    <pages>
      <namespaces>
        <add namespace="Combres" />
      </namespaces>
    </pages>
  </system.web>
  <combres definitionUrl="~/App_Data/combres.xml" />
  <appSettings>
    <add key="CombresSectionName" value="combres" />
  </appSettings>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="AjaxMin" publicKeyToken="21ef50ce11b5d80f" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-4.84.4790.14405" newVersion="4.84.4790.14405" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>
حال باید Route  مربوط به Combres را به RouteTable اضافه کنیم. در صورتیکه از نیوگت استفاده کرده باشید، کلاسی به فولدر app_start  اضافه شده است که با استفاده از WebActivator اینکار را در Application_Start انجام میدهد؛ در غیر اینصورت باید به صورت زیر این کار را انجام دهیم.
protected void Application_Start(object sender, EventArgs e)
        {
            RouteTable.Routes.AddCombresRoute("Combres Route");
        }
بعد از انجام مراحل قبل، نوبت به آن رسیده است که از لینکهای combres در صفحات خود استفاده کنیم. شیوه استفاده از آن در وب فرم به این صورت است:
<%@ Import Namespace="Combres" %>
<head runat="server">
    <%= WebExtensions.CombresLink("siteCss") %>
    <%= WebExtensions.CombresLink("siteJs") %>
</head>
و در MVC به صورت زیر می‌باشد:
<%= Url.CombresLink("siteCss") %>
<%= Url.CombresLink("siteJs") %>
در هر دو مورد نام ResourceSet برای تولید لینک به متد CombresLink ارسال میشود. پس از اجرای مجدد برنامه و با استفاده از firebug خواهیم دید که به ازای هر ResourceSet، یک درخواست به سرور ارسال شده است و حجم فایلها به صورت چشمگیری کاهش یافته است و اطلاعات مربوط به کش هم به آن اضافه شده است.

در ادامه می‌توانید فایل site.css قبلی و فعلی را مقایسه کنید!

در قسمت بعد با سازوکار combres و روش استفاده از فیلترها، بیشتر آشنا میشویم.

CombresProject-67bd3b7299f24c5484edc35537fa990b.zip 

نظرات مطالب
پرسش و پاسخ‌های متداول ایجاد یک وبلاگ بلاگری
قرار بود فقط دو تا سؤال بپرسید :)
- فرمت قالب‌ها xml است و با فرانت پیج قدیمی یا expression web جدید قابل ویرایش نیست و اصلا ادیتوری هم ندارد (یا جایی منتشر نشده تا جایی که اطلاع دارم). دستی باید روی آن کار شود.
- برای قرار دادن عکس در بک گراند، شما فقط کافی است عکس مورد نظر را در یک سایت دیگر آپلود کنید، سپس یک css تعریف کرده و آن‌را اعمال نمائید. به سلکتور body یا تگ body قابل اعمال است. اطلاعات بیشتر:
http://www.w3schools.com/css/pr_background-image.asp
- برای تعیین رنگ و اندازه تاریخ، باز هم باید css‌ سایت را در همان قسمت ویرایش html سایت ویرایش کنید. برای مثال این موارد باید اضافه شود:
h1, h2, h3 {
font-family: Tahoma;
direction: rtl;
font-size:8pt;
color:green;
text-align: right;
}
- تاریخ آرشیو هم در همان مقاله هست و باید اعمال شده باشد.

در کل شکل و شمایل این قالب‌ها با ویرایش css آن تا حد قابل قبولی قابل تغییر است (بدون نیاز به دستکاری قسمت‌های دیگر که مربوط به تعریف ویجت‌ها است)