استفاده از ImageButton به جای PushButton
ساخت ربات تلگرامی با #C
pm> Install-Package Telegram.Bot
https://api.telegram.org/bot[bot-token]/setwebhook
https://api.telegram.org/bot[bot-token]/setwebhook?url=https://yourdomain.example/api/webhook
Owin چیست ؟ قسمت اول
خواندنیهای 29 مرداد
اس کیوال سرور
الگوهای طراحی برنامه نویسی شیءگرا
توسعه وب
دات نت فریم ورک
دبلیو پی اف و سیلور لایت
سی و مشتقات
متفرقه
محیطهای مجتمع توسعه
مرورگرها
پی اچ پی
npm install -g @angular/cli
ng new HowToKeepAngularSizeSmall
ng serve --open --prod
"@agm/core": "^1.0.0-beta.5", "@angular/flex-layout": "^7.0.0-beta.23", "@angular/material": "^7.3.3", "@angular/platform-browser": "~7.2.0", "@asymmetrik/ngx-leaflet": "^5.0.1", "@ngx-loading-bar/router": "1.3.1", "@ngx-translate/core": "^11.0.1", "@ngx-translate/http-loader": "^4.0.0", "@progress/kendo-angular-buttons": "^4.3.3", "@progress/kendo-angular-dateinputs": "^3.6.0", "@progress/kendo-angular-dialog": "^3.10.1", "@progress/kendo-angular-dropdowns": "^3.5.1", "@progress/kendo-angular-excel-export": "^2.3.0", "@progress/kendo-angular-grid": "^3.13.0", "@progress/kendo-angular-inputs": "^4.2.0", "@progress/kendo-angular-intl": "^1.7.0", "@progress/kendo-angular-l10n": "^1.3.0", "@progress/kendo-angular-layout": "^3.2.0", "@progress/kendo-data-query": "^1.5.0", "@progress/kendo-drawing": "^1.5.8", "@progress/kendo-theme-default": "^3.3.1", "@swimlane/ngx-datatable": "^14.0.0", "angular-calendar": "0.23.7", "angular-tree-component": "7.0.1", "bootstrap": "^3.4.0", "chart.js": "2.7.2", "d3": "4.13.0", "dragula": "3.7.2", "hammerjs": "2.0.8", "intl": "1.2.5", "leaflet": "1.3.1", "moment": "2.21.0", "ng2-charts": "1.6.0", "ng2-dragula": "1.5.0", "ng2-file-upload": "1.3.0", "ng2-validation": "4.2.0", "ngx-perfect-scrollbar": "5.3.5", "ngx-quill": "2.2.0", "screenfull": "3.3.2", "font-awesome": "^4.7.0", "jalali-moment": "^3.3.1", "jquery": "^3.3.1", "ng-snotify": "^4.3.1", "normalize.css": "^8.0.1",
@import "~bootstrap/dist/css/bootstrap.css"; @import "~@progress/kendo-theme-default/scss/all"; @import '@angular/material/prebuilt-themes/pink-bluegrey.css'; @import '~perfect-scrollbar/css/perfect-scrollbar.css'; @import "~ng-snotify/styles/material";
"scripts": [ "node_modules/jquery/dist/jquery.js", "node_modules/bootstrap/dist/js/bootstrap.min.js", "node_modules/hammerjs/hammer.min.js" ],
import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; // Import Material import { MatFormFieldModule, MatInputModule, MatButtonModule, MatButtonToggleModule, MatDialogModule, MatIconModule, MatSelectModule, MatToolbarModule, MatDatepickerModule, DateAdapter, MAT_DATE_FORMATS, MAT_DATE_LOCALE, MatTableModule, MatCheckboxModule, MatRadioModule, MatCardModule, fadeInContent, MatListModule, MatProgressBarModule, MatTabsModule, MatSidenavModule, MatSlideToggleModule, MatMenuModule } from '@angular/material'; // Import kendo angular ui import { ButtonsModule } from '@progress/kendo-angular-buttons'; import { GridModule, ExcelModule } from '@progress/kendo-angular-grid'; import { DropDownsModule } from '@progress/kendo-angular-dropdowns'; import { InputsModule } from '@progress/kendo-angular-inputs'; import { DateInputsModule } from '@progress/kendo-angular-dateinputs'; import { DialogsModule } from '@progress/kendo-angular-dialog'; import { RTL } from '@progress/kendo-angular-l10n'; import { LayoutModule } from '@progress/kendo-angular-layout'; import { WindowService, WindowRef, WindowCloseResult, DialogService, DialogRef, DialogCloseResult } from '@progress/kendo-angular-dialog'; import { SnotifyModule, SnotifyService, SnotifyPosition, SnotifyToastConfig, ToastDefaults } from 'ng-snotify'; import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; @NgModule({ declarations: [ AppComponent ], imports: [ BrowserModule, AppRoutingModule, // material MatSidenavModule, MatSlideToggleModule, MatInputModule, MatFormFieldModule, MatButtonModule, MatButtonToggleModule, MatDialogModule, MatIconModule, MatSelectModule, MatToolbarModule, MatDatepickerModule, MatCheckboxModule, MatRadioModule, MatCardModule, MatMenuModule, MatListModule, MatProgressBarModule, MatTabsModule, // kendo-angular ButtonsModule, GridModule, ExcelModule, DropDownsModule, InputsModule, DateInputsModule, DialogsModule, LayoutModule, SnotifyModule, ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }
همانطور که میبینید بدون افزودن کامپوننت جدیدی، حجم خروجی از 222KB به 582KB رسیدهاست. معمولا در هر پروژه نیاز به تعدادی دایرکتیو و سرویس پایه نیز میباشد که کم کم به حجم خروجی صفحات میافزاید. در نظر بگیرید که هنوز هیچ قالب خاصی برای صفحه مورد نظرمان استفاده نشده و به حجم 582KB رسیدهایم. برای نمونه میتوانیم سری به سایت madewithangular.com بزنیم و حجم خروجی تعدادی از سایتهای نوشته شدهی با انگیولار را بررسی کنیم. سایتهای زیر خروجی بالای 1.5MB دارند. همچنین سایتی را که خودم تقریبا یک سال پیش شروع کرده بودم، حجم خروجی آن 2.7MB است:
دلیل بالا رفتن حجم خروجی، اضافه شدن فایلهای JavaScript و style-sheet به bundle اصلی پروژه است. برای مثال حجم فایل main.js را در نمونههای ذکر شده بررسی کنید.
در قسمتهای بعدی، به نحوهی کار صحیح با انگیولار میپردازیم و حجم صفحات را بررسی میکنیم.
http://en.هشام.com/post/build-customizable-language-switcher-tag-helper-with-bootstrap
WebRequest wr = WebRequest.Create(uri); using (WebResponse response = wr.GetResponse()) { }
The remote name could not be resolved: 'en.هشام.com'
البته ممکن است کد فوق را بر روی ویندوزهای جدید بدون مشکل اجرا کنید. علت اینجا است که اگر از ویندوزهای قبل از ویندوز سرور 2012 استفاده میکنید، دات نت فریم ورک از RFC 3490 استفاده میکند؛ در غیراینصورت از RFC 5891 (فقط برای Windows 8, Windows 8.1, Windows 10, or Windows Server 2012)، با این تفاوتها.
روش رفع آن هم فعال سازی پردازش این نوع دامنهها (بر روی تمام ویندوزها) در فایلهای app.config و یا web.config به صورت زیر است:
<configuration> <uri> <idn enabled="All" /> <iriParsing enabled="true" /> </uri> </configuration>
var unicode = @"en.هشام.com"; var mapping = new IdnMapping(); // IDN = Internationalizing Domain Names var ascii = mapping.GetAscii(unicode); Console.WriteLine(ascii); string convertedBackToUnicode = mapping.GetUnicode(ascii); Console.WriteLine(convertedBackToUnicode);
اصول نمایش Tooltip در Bootstrap
Tooltip یکی دیگر از کامپوننتهای جاوا اسکریپتی Bootstrap است.
<a rel="tooltip" title="یک سری توضیحات در اینجا" href="#">اطلاعات</a> <script type="text/javascript"> $(document).ready(function () { $("[rel='tooltip']").tooltip({placement:'top', trigger : 'hover'}); }); </script>
برای المان مورد نظر، یک title تعریف کردهایم. برای اینکه tooltip پیش فرض مرورگر در این حالت ظاهر نشود، یک rel=tooltip را در اینجا به المان اضافه کرده و سپس افزونه tooltip بوت استرپ، بر روی کلیه المانهایی با rel=tooltip فراخوانی شده است.
placement، محل قرارگیری tooltip را مشخص میکند؛ مانند بالا، پایین، چپ و راست. trigger مشخص میکند که این tooltip در چه زمانی ظاهر شود. برای مثال در حالت hover یا در حالت focus یک المان.
در اینجا بجای title، از ویژگی data-original-title نیز میتوان استفاده کرد.
تبدیل خطاهای اعتبارسنجی ASP.NET MVC به Tooltip
هدف ما در اینجا، نهایتا رسیدن به شکل زیر میباشد:
همانطور که ملاحظه میکنید، اینبار بجای نمایش خطاها در یک برچسب مقابل کنترل متناظر، این خطا صرفا در حالت فوکوس کنترل، به شکل یک Tooltip در بالای آن ظاهر شده است.
کدهای کامل View برنامه
@model Mvc4TwitterBootStrapTest.Models.User @{ ViewBag.Title = "تعریف کاربر جدید"; } @using (Html.BeginForm()) { @Html.ValidationSummary(true, null, new { @class = "alert alert-error alert-block" }) <fieldset class="form-horizontal"> <legend>تعریف کاربر جدید</legend> <div class="control-group"> @Html.LabelFor(model => model.Name, new { @class = "control-label" }) <div class="controls"> @Html.EditorFor(model => model.Name) @*@Html.ValidationMessageFor(model => model.Name, null, new { @class = "help-inline" })*@ </div> </div> <div class="control-group"> @Html.LabelFor(model => model.LastName, new { @class = "control-label" }) <div class="controls"> @Html.EditorFor(model => model.LastName) @*@Html.ValidationMessageFor(model => model.LastName, null, new { @class = "help-inline" })*@ </div> </div> <div class="form-actions"> <button type="submit" class="btn btn-primary"> ارسال</button> </div> </fieldset> } @section JavaScript { <script type="text/javascript"> $.validator.setDefaults({ showErrors: function (errorMap, errorList) { this.defaultShowErrors(); //اگر المانی معتبر است نیاز به نمایش تولتیپ ندارد $("." + this.settings.validClass).tooltip("destroy"); //افزودن تولتیپها for (var i = 0; i < errorList.length; i++) { var error = errorList[i]; $(error.element).tooltip({ trigger: "focus" }) // فقط در حالت فوکوس نمایش داده شود .attr("data-original-title", error.message); } }, // همانند قبل برای رنگی کردن کل ردیف در صورت عدم اعتبار سنجی و برعکس highlight: function (element, errorClass, validClass) { if (element.type === 'radio') { this.findByName(element.name).addClass(errorClass).removeClass(validClass); } else { $(element).addClass(errorClass).removeClass(validClass); $(element).closest('.control-group').removeClass('success').addClass('error'); } $(element).trigger('highlited'); }, unhighlight: function (element, errorClass, validClass) { if (element.type === 'radio') { this.findByName(element.name).removeClass(errorClass).addClass(validClass); } else { $(element).removeClass(errorClass).addClass(validClass); $(element).closest('.control-group').removeClass('error').addClass('success'); } $(element).trigger('unhighlited'); } }); //برای حالت پست بک از سرور عمل میکند $(function () { $('form').each(function () { $(this).find('div.control-group').each(function () { if ($(this).find('span.field-validation-error').length > 0) { $(this).addClass('error'); } }); }); }); </script> }
توضیحات
- با توجه به اینکه دیگر نمیخواهیم خطاها به صورت برچسب در مقابل کنترلها نمایش داده شوند، کلیه Html.ValidationMessageFor به صورت کامنت درآورده شدهاند.
- تغییر دوم مطلب جاری، اضافه شدن متد showErrors به تنظیمات پیش فرض jQuery Validator است. در این متد، اگر المانی معتبر بود، Tooltip آن حذف میشود؛ یا در سایر حالات، المانهایی که نیاز به اعتبارسنجی سمت کلاینت دارند، یافت شده و سپس ویژگی data-original-title با مقداری معادل خطای اعتبارسنجی متناظر، به این المان افزوده شده و سپس متد tooltip بوت استرپ بر روی آن فراخوانی میگردد.
به عبارتی زمانیکه یک input box در ASP.NET MVC به همراه مقادیر مرتبط با اعتبارسنجی آن رندر میشود، چنین شکلی را خواهد داشت:
<input class="text-box single-line" data-val="true" data-val-required="لطفا نام را تکمیل کنید" id="Name" name="Name" type="text" value="" />
<input class="text-box single-line input-validation-error" data-val="true" data-val-required="لطفا نام را تکمیل کنید" id="Name" name="Name" type="text" value="" data-original-title="لطفا نام را تکمیل کنید" title="">