function resetSearch(progressId, form, pagerId, container, sortId, sortOrderId, pageSizeId) { $(pagerId).closest('.row').hide(); $(progressId).css("display", "block"); $(pagerId).data("page", 2); $(sortId).val($(sortId + " option:first").val()); $(sortOrderId).val($(sortOrderId + " option:first").val()); $(pageSizeId).val($(pageSizeId + " option:first").val()); $(form).find("input[type=text], textarea").val(""); $(form).find("select").each(function(key, val) { $(this).val($(this).find('option:first').val()); }); $(form).find('#PageIndex').val(1); $(form).find('#PageSize').val($(pageSizeId).val()); $(form).find('#CurrentSort').val($(sortId).val()); $(form).find('#SortDirection').val($(sortOrderId).val()); $(form).find('#PageIndex').val(1); $(container).html(""); $(form).submit(); }
اگر از شیرپوینت 2016 استفاده میکنید به آدرس زیر بروید:
C:\Program Files\Common Files\microsoft shared\Web ServerExtensions\16\TEMPLATE\CONTROLTEMPLATES
واگر از شیرپوینت 2013 استفاده میکنید به آدرس زیر بروید:
C:\Program Files\Common Files\microsoft shared\Web ServerExtensions\15\TEMPLATE\CONTROLTEMPLATES
و از آدرس مذکور به دنبال فایلی به نام welcome.ascx بگردید.
به منظور اضافه کردن آیتم " ورود با حساب کاربری دیگر " باید همین فایل را ویرایش کنیم. جهت ویرایش فایل میتوانید از یک ویرایشگر متن ساده ( Text Editor ) همانند Notepad++ یا ویژوال استودیو استفاده نمایید.
تنها کاری که باید انجام دهید اینست که کدهای زیر را به فایل مذکور اضافه نمایید:
<SharePoint:MenuItemTemplate runat="server" ID="ID_LoginAsDifferentUser" Text="<%$Resources:wss,personalactions_loginasdifferentuser%>" Description="<%$Resources:wss,personalactions_loginasdifferentuserdescription%>" MenuGroupId="100" Sequence="100" UseShortId="true" />
در فایل welcome.ascx باید به دنبال تگ "ID_RequestAcess" بگردید و کد بالا را قبل از آن اضافه نمایید. اما توجه بفرمایید که مکان دقیق اضافه کردن این قطعه کد، دقیقا با ترتیب آیتم منویی که تصمیم دارید در آن جایگاه قرار گیرد، رابطه مستقیم دارد؛ بدین معنا که اگر تمایل دارید ترتیب نمایش جایگاه این آیتم منو را عوض نمایید، براحتی میتوانید در جایگاه مناسب کد بالا را کپی نمایید:
بلافاصله پس از ذخیره کردن فایل welcome.ascx، با فشردن کلیدهای Ctrl+F5 میتوانید نتیجه تغییراتتان را مشاهده نمایید. در صورت لزوم میتوانید کش مرورگر را خالی نمایید.
bower یک فناوری منسوخ شدهاست و اگر بخواهیم bower.json ذکر شدهی در این مطلب را با package.json مربوط به npm جایگزین کنیم، به یک چنین محتوایی خواهیم رسید:
{ "name": "testwebapp", "version": "1.0.0", "description": "", "scripts": {}, "author": "", "license": "ISC", "dependencies": { "bootstrap": "^3.3.7", "jquery": "^2.2.4", "jquery-ajax-unobtrusive": "^3.2.4", "jquery-validation": "^1.17.0", "jquery-validation-unobtrusive": "^3.2.8" } }
سپس بر اساس مسیرهای پوشهی node_modules جدید، فایل bundleconfig.json چنین محتوایی را پیدا میکند:
[ { "outputFileName": "wwwroot/css/site.min.css", "inputFiles": [ "node_modules/bootstrap/dist/css/bootstrap.min.css", "wwwroot/css/site.css" ] }, { "outputFileName": "wwwroot/js/site.min.js", "inputFiles": [ "node_modules/jquery/dist/jquery.min.js", "node_modules/jquery-validation/dist/jquery.validate.min.js", "node_modules/jquery-validation-unobtrusive/dist/jquery.validate.unobtrusive.min.js", "node_modules/jquery-ajax-unobtrusive/jquery.unobtrusive-ajax.min.js", "node_modules/bootstrap/dist/js/bootstrap.min.js", "wwwroot/js/site.js" ], "minify": { "enabled": true, "renameLocals": true }, "sourceMap": false } ]
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>@ViewData["Title"] - DNTCommon.Web.Core.TestWebApp</title> <link href="~/css/site.min.css" rel="stylesheet" asp-append-version="true" /> </head> <body> <div> @RenderBody() </div> <script src="~/js/site.min.js" type="text/javascript" asp-append-version="true"></script> @RenderSection("Scripts", required: false) </body> </html>
<Project Sdk="Microsoft.NET.Sdk.Web"> <Target Name="PrecompileScript" BeforeTargets="BeforeBuild"> <Exec Command="dotnet bundle" /> </Target> <ItemGroup> <DotNetCliToolReference Include="BundlerMinifier.Core" Version="2.6.362" /> </ItemGroup> </Project>
ASP.NET MVC #13
@model Models.Account @{ Layout = null; ViewBag.Title = "ورود به سیستم"; } <script src="@Url.Content("~/Scripts/jquery-1.7.1.min.js")" type="text/javascript"></script> <script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script> <script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script> @using (Html.BeginForm()) { @Html.ValidationSummary(true) <fieldset> <legend>Login</legend> <table style="font-size: 8pt"> <tr> <td style="width: 100px; text-align: left">نام کاربری :</td> <td>@Html.EditorFor(model => model.Username)</td> </tr> <tr> <td></td> <td style="color: red">@Html.ValidationMessageFor(model => model.Username)</td> </tr> <tr> <td style="width: 100px; text-align: left">کلمه عبور :</td> <td>@Html.EditorFor(model => model.Password)</td> </tr> <tr> <td></td> <td style="color: red">@Html.ValidationMessageFor(model => model.Password)</td> </tr> <tr> <td></td> <td> <input type="submit" value="ورود به سیستم" /></td> </tr> </table> </fieldset> }
public class Account { [Required(ErrorMessage = "نام کاربری باید وارد شود.")] [StringLength(20)] public string Username { get; set; } [Required(ErrorMessage = "کلمه عبور باید وارد شود.")] [DataType(DataType.Password)] public string Password { get; set; } }
[HttpGet] public ActionResult LogOn(string returnUrl) { if (User.Identity.IsAuthenticated) //remember me { if (shouldRedirect(returnUrl)) { return Redirect(returnUrl); } return Redirect(FormsAuthentication.DefaultUrl); } return View(); // show the login page }
[HttpPost] public ActionResult LogOn(Account loginInfo, string returnUrl) { if (this.ModelState.IsValid) { List<User> users = _userService.GetUser(loginInfo.Username, loginInfo.Password); if (users != null && users.Count == 1) { FormsAuthentication.SetAuthCookie(loginInfo.Username,false);// loginInfo.RememberMe); //-- کاربر برنامه ریزی if (users.First().UserType_Id == 1) { return RedirectToAction("Index", "Programming", new { u = loginInfo.Username }); } else if (users.First().UserType_Id == 2) { } else if (users.First().UserType_Id == 3) { } else if (users.First().UserType_Id == 4) { } } } this.ModelState.AddModelError("", "نام کاربری یا کلمه عبور اشتباه وارد شده اند."); ViewBag.Error = ""; return View(loginInfo); }
<appSettings> <add key="webpages:Version" value="2.0.0.0" /> <add key="webpages:Enabled" value="false" /> <add key="PreserveLoginUrl" value="true" /> <add key="ClientValidationEnabled" value="true" /> <add key="UnobtrusiveJavaScriptEnabled" value="true" /> </appSettings>
@model IEnumerable<FsWeb.Models.Book> <!DOCTYPE html> <html> <head> <title>@ViewBag.Title</title> <meta name="viewport" content="width=device-width, initial-scale=1" /> <link rel="stylesheet" href="http://code.jquery.com/mobile/1.0.1/jquery.mobile-1.0.1.min.css" /> </head> <body> <div data-role="page" data-theme="a" id="booksPage"> <div data-role="header"> <h1>Guitars</h1> </div> <div data-role="content"> <ul data-role="listview" data-filter="true" data-inset="true"> @foreach(var x in Model) { <li><a href="#">@x.Name</a></li> } </ul> </div> </div> <script src="http://code.jquery.com/jquery-1.6.4.min.js"> </script> <script src="http://code.jquery.com/mobile/1.0.1/jquery.mobile-1.0.1.min.js"> </script> <script> $(document).delegate("#bookPage", 'pageshow', function (event) { $("div:jqmData(role='content') > ul").listview('refresh'); }); </script> </body> </html>
برای ساخت کنترلر جدید، در پروژه #F ساخته شده یک Source File ایجاد نمایید و کدهای زیر را در آن کپی نمایید:
namespace FsWeb.Controllers open System.Web.Mvc open FsWeb.Models [<HandleError>] type BooksController() = inherit Controller() member this.Index () = seq { yield Book(Name = "My F# Book") yield Book(Name = "My C# Book") } |> this.View
اما نکته ای که در مثال بالا وجود دارد این است که دو نمونه از نوع Book را برای ساخت seq وهله سازی میکند. در نتیجه باید Book Type را به عنوان مدل تعریف کنیم. به صورت زیر:
namespace FsWeb.Models type Book = { Id : Guid; Name : string }
namespace FsWeb.Models type Book() = member val Name = "" with get, set
اگر همچون پروژههای #C قصد دارید با استفاده از Attributeها مدل خود را اعتبارسنجی نمایید میتوانید به صورت زیر اقدام نمایید:
open System.ComponentModel.DataAnnotations type Book() = [<Required>] member val Name = "" with get, set
namespace FsWeb.Models open System open System.ComponentModel.DataAnnotations type Book() = [<Key>] member val Id = Guid.NewGuid() with get, set [<Required>] member val Name = "" with get, set
نکته: دستور open معادل با using در #C است.
بررسی ساختار ویجتهای وب Kendo UI
<script src="js/kendo.web.min.js" type="text/javascript"></script>
<script type="text/javascript" src='<%: ResolveClientUrl("~/path....") %>'></script>
<script type="text/javascript"> $(document).ready(function () { PopupForm.ShowForm({ renderFormUrl : "/postreply/renderreplyform", ..... }); }); </script>
در پست قبل به بررسی انتخاب عناصر بر اساس موقعیت پرداختیم، در این پست به بحث "استفاده از انتخاب کنندههای سفارشی jQuery" خواهیم پرداخت.
4-1- استفاده از انتخاب کنندههای سفارشی jQuery
در پستهای قبلی (^ و ^ ) تعدادی از انتخاب کنندههای CSS که هر کدامشان موجب قدرت و انعطاف پذیری انتخاب اشیا موجود در صفحه میشوند را بررسی کردیم. با این وجود فیلترهای انتخاب کننده قدرتمندتری وجود دارند که توانایی ما را برای انتخاب بیشتر میکنند.
به عنوان مثال اگر بخواهید از میان تمام چک باکس ها، گزینه هایی را که تیک خورده اند انتخاب نمایید، از آنجا که تلاش برای مطابقت حالتهای اولیه کنترلهای HTML را بررسی میکنیم، jQuery انتخابگر سفارشی checked: را پیشنهاد میکند، که مجموعه از عناصر را که خاصیت checked آنها فعال باشد را برای ما برمی گرداند. براس مثال انتخاب کننده input تمامی المانهای <input> را انتخاب میکند، و انتخاب کننده input:checked تمامی inputهایی را انتخاب میکند که checked هستند. انتخاب کننده سفارشی checked:یک انتخاب کننده خصوصیت CSS عمل میکند (مانند [foo=bar]). ترکیب این انتخاب کنندهها میتواند قدرت بیشتری به ما بدهد، انتخاب کننده هایی مانند radio:checked: و checkbox:checked: .
همانطور هم که قبلا بیان شد، jQuery علاوه بر پشتیبانی از انتخاب کنندههای CSS تعدادی انتخاب کننده سفارشی را نیز شامل میشود که در جدول 3-2 شرح داده شده است.
توضیح | انتخاب کننده |
عناصری را انتخاب میکند که تحت کنترل انیمیشن میباشند. در پستهای بعدی انیمیشنها توضیح داده میشوند. | animated: |
عناصر دکمه را انتخاب میکند، عناصری مانند (input[type=submit]، input[type=reset]، input[type=button]، یا button) | button: |
عناصر Checkbox را انتخاب میکند، مانند ([input[type=checkbox). | checkbox: |
عناصر checkboxها یا دکمههای رادیویی را انتخاب میکند که در حالت انتخاب باشند. | checked: |
عناصری ر انتخاب میکند که دارای عبارت foo باشند. | contains(foo) //c: |
عناصر در حالت disabled را انتخاب میکند. | disabled: |
عناصر در حالت enabledرا انتخاب میکند. | enabled: |
عناصر فایل را انتخاب میکند، مانند ([input[type=file). | file: |
عناصر هدر مانند h1 تا h6 را انتخاب میکند. | header: |
عناصر مخفی شده را انتهاب میکند. | hidden: |
عناصر تصویر را انتخاب میکند، مانند ([input[type=image). | image: |
عناصر فرم مانند input ، select، textarea، button را انتخاب میکند. | input: |
انتخاب کنندهها را برعکس میکند. | not(filter)//c: |
عناصری که فرزندی دارند را انتخاب میکند. | parent: |
عناصر password را انتخاب میکند، مانند ([input[type=password). | password: |
عناصر radio را انتخاب میکند، مانند ([input[type=radio). | radio: |
دکمههای reset را انتخاب میکند، مانند ([input[type=reset یا [button[type=reset). | raset: |
عناصری (عناصر option) را انتخاب میکند که در وضعیت selected قراردارند. | selected: |
دکمههای submit را انتخاب میکند، مانند ([input[type=submit یا [button[type=submit). | submit: |
عناصر text را انتخاب میکند، مانند ([input[type=text). | text: |
عناصری را که در وضعیت visibleباشند انتخاب میکند. | visible: |
:checkbox:checked:enabled
این فیلترها و انتخاب کنندهها کاربردهای وسیعی در صفحات اینترنتی دارند، آیا آنها حالت معکوسی نیز دارند؟
استفاده از فیلتر not:
برای آنکه نتیجه انتخاب کنندهها را معکوس کنیم میتوانیم از این فیلتر استفاده کنیم. برای مثال دستور زیر تمام عناصری را که checkBox نیستند را انتخاب میکند:
input:not(:checkbox)
استفاده از فیلتر has:
در اینجا دیدیم که CSS انتخاب کننده قدرتمندی را ارایه کرده است که فرزندران یک عنصر را در هر سطحی که باشند (حتی اگر فرزند مستقیم هم نباشند) انتخاب میکند. برای مثال دستور زیر تمام عناصر span را که در div معرفی شده باشند را انتخاب میکند:
div span
اما اگر بخواهیم انتخابی برعکس این انتخاب داشته باشیم، باید چه کنیم؟ برای این کار باید تمام divهایی که دارای عنصر span میباشد را انتخاب کرد. برای چنین انتخابی از فیلتر has: استفاده میکنیم. به دستور زیر توجه نمایید، این دستور تمام عناصر div را که در آنها عنصر span معرفی شده است را انتخاب میکند:
div:has(span)
برای برخی انتخابهای پیچیده و مشکل، این فیلتر و مکانیزم بسیار کارا میباشد و به سادگی ما را به هدف دلخواه میرساند. فرض کنید میخواهیم آن خانه از جدول که دارای یک عنصر عکس خاص میباشد را پیدا کنیم. با توجه به این نکته که آن عکس از طریق مقدار src قابل تشخیص میباشد، با استفاده از فیلتر has: دستوری مانند زیر مینویسیم:
$('tr:has(img[src$="foo.png"])')
این دستور هر خانه از جدول را که این عکس در آن قرار گرفته باشد را انتخاب میکند.
همانگونه که دیدیم jQuery گزینههای بسیار متعددی را به منظور انتخاب عناصر موجود در صفحه برای ما مهیا کرده است که میتوانیم هر عنصری از صفحه را انتخاب و سپس تغییر دهیم که تغییر این عناصر در پستهای آینده بحث خواهد شد.
موفق و موید باشید.
در برنامههای وب امروز نیازی به فراخوانی ثوابت که در طول حیات برنامه انگشت شمار تغیر میکنند نیست و با توجه به استفاده از فرامین و متدهای سمت کلاینت احتیاج هست تا این ثوابت بار اول لود صفحه به کلاینت پاس داده شوند.
میتوان در این گونه موارد از قابلیتهای گوناگونی استفاده کرد که در اینجا ما با استفاده از یک فیلد مخفی و json مقدار را به کلاینت پاس میدهیم و در این مثال در سمت کلاینت نیز دراپ دان را با این مقادیر پر میکنیم:
public enum PersistType { Persistable = 1, NotPersist = 2, AlwaysPersist = 3 }
لیست را باید قبل از پر کردن در فیلد مخفی به json بصورت serialize شده تبدیل کرد، برای این منظور از JavaScriptSerializer موجود در اسمبلیهای دات نت در متد زیر استفاده شده:
public static string ConvertEnumToJavascript(Type t) { if (!t.IsEnum) throw new Exception("Type must be an enumeration"); var values = System.Enum.GetValues(t); var dict = new Dictionary<int, string>(); foreach (object obj in values) { string name = System.Enum.GetName(t, obj); dict.Add(Convert.ToInt32(System.Enum.Format(t, obj, "D")), name); } return new JavaScriptSerializer().Serialize(dict); }
با توجه به اینکه در سمت کلاینت مقدار json ذخیره شده در فیلد مخفی را میتوان به صورت آبجکت برخورد کرد پس یک متد در سمت کلاینت این آبجکت را در loop قراد داده و درمتغییری در فایل جاوا اسکریپت نگهداری میکنیم:
var Enum_PersistType = null; function SetEnumTypes() { Enum_PersistType = JSON.parse($('#hfJsonEnum_PersistType').val()); }
و در هر قسمت که نیاز به مقدار enum بود با توجه به ایندکس مقدار را برای نمایش ازاین متغییر بیرون میکشیم:
function GetPersistTypeTitle_Concept(enumId) { return Enum_PersistType[enumId]; }
برای مثال در dropdown در سمت کلاینت این نوع استفاده شده و در حالتی از صفحه فقط برای نمایش عنوان آن احتیاج به دریافت آن از سمت سرور باشد میتوان از این روش کمک گرفت
و یا در سمت javascript میتوان با استفاده از jQuery مقادیر متغییر را در dropdown پر کرد.
function FillDropdown() { $("#ddlPersistType").html(""); $.each(Enum_PersistType, function (key, value) { $("#ddlPersistType").append($("<option></option>").val(key).html(value)); }); }