مطالب
نمایش خودکار مقدار یکDropDownList با کمک jQuery

نیاز بود هنگام انتخاب یک آیتم دراپ داون لیست در کل برنامه و تمامی دراپ داون‌های آن، مقدار آن‌ها نیز به صورت یک برچسب در کنار آن نمایش داده شود.
برای مثال در لیست زیر:

<asp:DropDownList ID="ddlActive" runat="server">
<asp:ListItem Value="Active">فعال</asp:ListItem>
<asp:ListItem Value="Inactive">غیرفعال</asp:ListItem>
</asp:DropDownList>
اگر آیتم فعال انتخاب شد، مقدار active نیز کنار آن نمایش داده شود و الی آخر.

راه حل اول:
در تمام صفحات به ازای تک تک دراپ داون‌ها یک label اضافه کنیم و همچنین کدهای تمام قسمت‌های برنامه را نیز اصلاح کنیم تا این مورد را لحاظ کند.

راه دوم:
یک کنترل دراپ داون سفارشی را با خاصیت مورد نظر (همراه بودن با یک لیبل) ایجاد کرده و سپس تمام فرم‌ها را باید اصلاح کرد تا از این کنترل جدید استفاده کنند.

راه سوم:
استفاده از jQuery برای اعمال این مهم به کل برنامه بدون نیاز به تغییرات اساسی در آن (و همچنین سازگاری با تمام مرورگرها):

//فقط در این محدوده
$("#mainFormReq select").change(function() {
var currentId = $(this).attr("id"); //آی دی شیء جاری
var val = $(this).val(); //مقدار
var text = $('#' + currentId + ' option:selected').text(); //متن
$("#lbl" + currentId).remove(); //اگر نمونه‌ی قبلی موجود است حذف شود
if (val && (val.length > 0) && (text != val)) {
//اگر متن و مقدار یکی نیست نمایش داده شود
$(this).after('<label id="lbl' + currentId + '">' + val + '</label>');
}
});
توضیحات:
در یک محدوده مشخص شده با ID مساوی mainFormReq (مثلا استفاده از master page ها و نسبت دادن این ID به content آن)، به دنبال تمام select های موجود در آن ناحیه می‌گردیم (اگر mainFormReq حذف شود، این جستجو در کل صفحه صورت خواهد گرفت) و تغییرات آن‌ها را تحت نظر قرار خواهیم داد.
سپس آی دی این کنترل انتخابی را دریافت می‌کنیم (از این ID برای تولید ID برچسب مورد نظر استفاده خواهیم کرد).
در ادامه مقدارهای text و value گزینه انتخابی دریافت می‌شوند (+).
سپس بررسی خواهیم کرد که آیا برچسبی با ID مشخص شده ما وجود دارد (در صورت انتخاب آیتم‌های دیگر، نباید برچسبی غیر منحصربفرد و تکراری در صفحه ایجاد کرد)
در ادامه اگر این مقدار null نبود و همچنین مقدار text و value هم یکی نبودند (اگر یکی بودند لزوم وجود این برچسب بی معنا است)، با استفاده از متد after کتابخانه jQuery یک برچسب را تولید و مقدار مورد نظر را پس از محل نمایش دراپ داون خود، نمایش خواهیم داد.

بهبود کد:
صورت مساله: اکنون نیاز است بجز ناحیه mainFormReq، به سه ناحیه دیگر نیز این تغییرات اعمال گردد. آیا باید همین مقدار کد را سه بار دیگر copy/paste کرد؟
روش صحیح انجام اینکار در jQuery ، نوشتن یک افزونه بر اساس کدهای فوق است که روش انجام آن به صورت زیر می‌باشد (+):

//<![CDATA[
(function($) {
$.fn.dropdownlabel = function() {
return this.change(function() {
var obj = $(this);
var currentId = obj.attr("id"); //آی دی شیء جاری
var val = obj.val(); //مقدار
var text = $('#' + currentId + ' option:selected').text(); //متن
$("#lbl" + currentId).remove(); //اگر نمونه‌ی قبلی موجود است حذف شود
if (val && (val.length > 0) && (text != val)) {
//اگر متن و مقدار یکی نیست نمایش داده شود
obj.after('<label id="lbl' + currentId + '">' + val + '</label>');
}
});
};
})(jQuery);
//]]>
و در نهایت نحوه استفاده از آن (فایلی به نام jquery.dropdownlabel.js ) به صورت زیر خواهد بود:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="TestDropdownlabel.aspx.cs"
Inherits="testWebForms87.TestDropdownlabel" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>

<script src="jquery.min.js" type="text/javascript"></script>
<script src="jquery.dropdownlabel.js" type="text/javascript"></script>

<script type="text/javascript">
$(document).ready(function() {
$("#mainFormReq select").dropdownlabel();
});
</script>

</head>
<body>
<form id="form1" runat="server">
<div id="mainFormReq">
<asp:DropDownList ID="ddlActive" runat="server">
<asp:ListItem Value=""></asp:ListItem>
<asp:ListItem Value="Active">فعال</asp:ListItem>
<asp:ListItem Value="Inactive">غیرفعال</asp:ListItem>
</asp:DropDownList>
</div>
</form>
</body>
</html>

مطالب
استفاده از دیتابیس Sqlite در الکترون (قسمت اول)
یکی از مهمترین بخش‌های هر برنامه، بخش ذخیره و بازیابی دیتا است. برای ذخیره سازی از طریق وب و مرورگر، راه‌های مختلف زیادی چون webStorage ,Indexed DB ,Sqlite ,NeDB, و ... وجود دارند.

Sqlite دیتابیس مناسبی برای برنامه‌های چندسکویی است و عموما به عنوان اولین گزینه استفاده می‌شود. برای کار با این دیتابیس، ما از ماژول sql.js که یکی از ماژول‌های معروف در جاوااسکریپت است، استفاده می‌کنیم. برای نصب آن از طریق npm، به شکل زیر اقدام می‌کنیم:
npm install sql.js --save
سپس کد همیشگی زیر را برای آغاز، در فایل index.js وارد می‌کنیم:
const{app,BrowserWindow}=require("electron");

let win;
function onLoad()
{
  win=new BrowserWindow({
    width:800,
    height:600
  });
  win.loadURL(`file://${__dirname}/index.html`);
}

app.on("ready",onLoad());
  ابتدا باید بررسی کنیم که آیا دیتابیس از قبل موجود است یا خیر و اگر موجود نبود، برای اولین بار آن را بسازیم. برای بررسی وجود یک فایل نیز می‌توانیم از چند دستور مختلف استفاده کنیم. path.exists و fs.exists، دو عدد از آن‌ها می‌باشند که هر دوی آنان به صورت غیرهمزمان هستند و پارمتر اولشان نام فایل، به همراه مسیر (یا تنها مسیر) است و پارامتر دوم هم یک تابع callback است که به عنوان پارامتر، جواب را بر می‌گرداند. برای استفاده از حالت همزمان، عبارت Sync را به انتهای نام متدها اضافه کنید. نحوه استفاده از آن به شکل زیر است:
var path=require("path");
path.exists('filepath",(status)=>
{
....
});
var status=path.existsSync("file");
//===============================
var fs=require("fs");
fs.exists('filepath",(status)=>
{
....
});
var status=path.existsSync("file");
ولی بهتر است بدانید که تاریخ انقضای دو دستور بالا سر آمده است و الان از دستور fs.stat استفاده می‌شود. این متد هم به دو شکل همزمان و غیرهمزمان وجود دارد:
fs.stat('foo.txt', function(err, stat) {
    if(err == null) {
        console.log('فایل موجوده');
    } else if(err.code == 'ENOENT') {
        // فایل وجود نداره
        fs.writeFile('log.txt', 'Some log\n');
    } else {
        //خطای دیگری رخ داده است
    }
});
برای استفاده از حالت همزمان هم کد را به شکل زیر بنویسید:
try {
  stats = fs.statSync(path);
  console.log("File exists.");
}
catch (e) {
  console.log("File does not exist.");
}
سپس کد زیر را در فرآیند اصلی وارد می‌کنیم:
const fs = require('fs');
const sql = require('sql.js');

  dbPath = './mydb.sqlite';
  dbExists=false;

try {
  dbExists = fs.statSync(dbPath);
}
catch (e) {
}

if(!dbExists)
{
  //create Database
var sqlStr=fs.readFileSync("./sql.txt");
var db = new sql.Database();
db.run(String(sqlStr));

//write to disk
var data=db.export();
var buffer=new Buffer(data);
fs.writeFileSync(dbPath,buffer);
}
else{
  var buffer = fs.readFileSync(dbPath);
  var db = new sql.Database(buffer);
}
ابتدا بررسی می‌کنیم که آیا فایلی با نام test.sqlite در مسیر جاری است یا خیر. در صورتی که نباشد، کد داخل شرط اجرا می‌شود. در اولین خط شرط، فایلی را با نام sql.txt که شامل محتوای زیر است، می‌خوانیم:
CREATE TABLE numbers (
    id     INT          PRIMARY KEY
                        UNIQUE
                        NOT NULL,
    fname  VARCHAR (20) NOT NULL,
    lname  VARCHAR (30) NOT NULL,
    number VARCHAR (15) NOT NULL
);
insert into numbers values(1,'ali','yeganeh','03111223344');
insert into numbers values(2,'xxx','yyy','45454555');
سپس در خطوط بعدی دیتابیس جدیدی را ایجاد می‌کنیم و دستور sql را با متد run اجرا می‌کنیم. دستوراتی که متد run اجرا می‌کند، شامل خروجی نیستند. پس دستوراتی را که نیاز به خروجی ندارند، به این متد بسپارید. سپس از این دیتابیس، یک شیء خروجی را دریافت میکنم و با بافر کردن، آن را در یک فایل ذخیره می‌کنیم. در صورتی هم که از قبل دیتابیس وجود داشته باشد، بافر خوانده شده را مستقیما به سازنده Database می‌دهیم.
بعد از آن نیاز است تا دیتابیس در دسترس Render Process‌ها قرار بگیرد که در مقاله "شیوه کدنویسی در الکترون " در مورد global صحبت کرده‌ایم و نحوه استفاده از آن را فرا گرفتیم:
global.db=db;

در پایان اجرای برنامه لازم است که دیتابیس توسط دستور close بسته شود. سپس کد زیر را در رویداد windows-all-closed می‌نویسیم:
app.on('window-all-closed', () => {
  db.close();
  if (process.platform !== 'darwin') {
    app.quit();
  }
});
در این کد گفته‌ایم که موقعی که تمام پنجره‌های برنامه بسته شدند، دیتابیس را نیز ببند.
(چند مورد خارج از بحث): کد بعدی که مورد استفاده قرار گرفته است و در مقالات قبلی در مورد آن صحبت نکرده‌ایم این است که در سیستم‌های مک، وضعیت به این قرار است که اگر شما برنامه را ببیندید، آن برنامه بسته نشده و در پس زمینه فعال است و می‌توانید آن را از طریق dock اطراف صفحه، مجددا فعال کنید. ولی با نوشتن کد بالا، ما این وضعیت را اعلام کرده‌ایم که اگر تمامی پنجره‌ها بسته شدند، کل برنامه را ببند.

همچنین بسیار خوب است که کد زیر را هم همیشه اضافه کنید:
win.on('closed', () => {
    win = null;
  });
موقعی که پنجره مربوطه بسته شود، متغیری که به پنجره اشاره می‌کند، در حافظه می‌ماند. پس بهتر است که این مقدار حافظه را رها کنید تا Garbage Collector اقدام به حذف آن در حافظه کند.
پس اگر این کد را نوشتید، وضعیت سیستم عامل مک را به خاطر داشته باشید و مجبور هستید کد زیر را نیز اضافه کنید:
app.on('activate', () => {
  if (win === null) {
    createWindow();
  }
});
در این صورت اگر کاربر پنجره را از طریق Dock مجددا فعال کرد، پنجره برنامه شما نیز مجددا نمایش داده خواهدشد.

بعد از اینکه دیتابیس را به شیء global دادیم، در صفحه html کد زیر را وارد می‌کنیم:
<html>
  <head>
    <script src="./jquery.min.js"></script>
    <link href="./bootstrap-3.3.6-dist/css/bootstrap.min.css" rel="stylesheet"></link>
    <meta charset="utf-8">
    <title></title>
    <script>
    const {remote}=require("electron");
    let db=remote.getGlobal("db");
    </script>
  </head>
  <body>

<table id="people" class="table table-hover table-striped">
<th>
  <tr>
    <td>First Name</td>
    <td>last Name</td>
    <td>Phone Number</td>
  </tr>
</th>
<tbody>

</tbody>
</table>
  </body>
</html>
در این کد یک جدول داریم و قصد ما این است که آن دو سطر را که در ابتدا اضافه کردیم، در آن نمایش دهیم. چیزی که در این کدها قابل ملاحظه است، این است که ما از بسته‌های بوت استرپ و جی کوئری استفاده می‌کنیم. در ادامه کدهای زیر را در تگ اسکریپت  وارد می‌کنیم:
$(document).ready(()=>
{
  //show data
var tableBody=$("#people");

db.each("select * from numbers",(row)=>{
  let rowTemplate=`<tr><td>${row.fname}</td><td>${row.lname}</td><td>${row.number}</td></tr>`;
  tableBody.append(rowTemplate);
});
متد each برای مواقعی مناسب است که شما تعدادی سطر را برای بازگشت دارید و callback آن، به ازای هر سطر اجرا می‌شود و با استفاده از یک template string سطر سازی را انجام داده و آن را با استفاده از توابع جی کوئری به انتهای جدول اضافه می‌کنیم.
حال وقت آن رسیده است که خروجی کار را ببینیم. پس کد npm start را اجرا می‌کنیم. همانطور که می‌بینید خروجی به راحتی نمایش داده می‌شود. در مقاله بعدی بیشتر در این مورد صحبت می‌کنیم.
بازخوردهای دوره
نگاهی به انواع Aspects موجود در کتابخانه PostSharp
- لینک مستقیمی ندارم. جهت تست از بسته NuGet آن استفاده کنید.
- SQL Server هم تجاری است. Windows هم از بنیان تجاری است. احتمالا از هر دوی این‌ها استفاده می‌کنید. تجاری بودن دلیلی برای سرکوب اشتیاق به یادگیری مطلبی نیست و نخواهد بود.
- ضمن اینکه در قسمت‌های بعدی نمونه‌های سورس باز هم معرفی شده‌اند.
نظرات اشتراک‌ها
SQL CE در Visual Studio 2013
- SQL Server CE یک بانک اطلاعاتی قابل حمل است. به این صورت فایل‌های native اصلی آن در پوشه‌ی bin برنامه اضافه می‌شوند. با توزیع آن‌ها برنامه کار می‌کند و نیاز به نصاب دیگری ندارد.
- درایورهای آن هم برای EF موجود هستند.
اشتراک‌ها
SQL Server مایکروسافت، برای سومین سال پیاپی، بالاتر از اوراکل، در رتبه ی بهترین سیستم مدیریت پایگاه داده عملیاتی قرار گرفت
طبق آخرین رده بندی گارتنر، معتبرترین رده بندی جهانی حوزه‌ی آی تی، SQL Server مایکروسافت، برای سومین سال پیاپی، بالاتر از اوراکل، در رتبه‌ی بهترین سیستم مدیریت پایگاه داده عملیاتی قرار گرفت.

SQL Server مایکروسافت، برای سومین سال پیاپی، بالاتر از اوراکل، در رتبه ی بهترین سیستم مدیریت پایگاه داده عملیاتی قرار گرفت
اشتراک‌ها
تهیه بکاپ روزانه از پایگاه داده توسط ابزار SQL Server Management Studio Job

اگر مالک وب سایت شخصی هستید که در VPS و یا سرور اختصاصی آن را هاست نموده اید، حتما به بکاپ روزانه و حتی ساعتی از پایگاه داده نیاز خواهید داشت. ابزار SQL Server Job، این کار را برای شما به سادگی و ظرف چند دقیقه انجام خواهد داد.

ضمنا اگر به این نیاز دارید که بکاپ‌های خود را به صورت فایلی شامل تاریخ و ساعت ذخیره کنید، از این مطلب می‌توانید کمک بگیرید.

تهیه بکاپ روزانه از پایگاه داده توسط ابزار SQL Server Management Studio Job
اشتراک‌ها
نصب Net Framework 3.5. به صورت آفلاین

در صورت نصب ابزارهای جدید که توسط فریم ورک دات نت 3.5 پشتیبانی می‌شوند نیاز است این فریم ورک را نصب نماید از جمله این برنامه‌ها که در زمان نصب شما را ملزم به نصب نسخه دات نت 3.5 خواهند کرد SQL Server Manangement Studio و ... خواهند بود. عمدتا دو راه موجود است...

نصب Net Framework 3.5. به صورت آفلاین