سلام
توی این پست تصمیم دارم نحوه پیاده سازی autosuggest search رو آموزش بدم. توی اینترنت آموزشایی دیدم که یا خیلی پیچیده توضیح داده بودن یا برای پیاده سازی از ابزارای آماده ای مث ابزاری موجود توی ajax control toolkit استفاده کرده ولی من به شخصه خیلی اعتقادی به استفاده از این ابزارا ندارم. چون هم صفحه رو سنگین میکنن هم کاستمایز کردنشون خیلی سخته.
برای نمونه میتونید سایت دیجیکالا رو ببینید. وقتی توی کادر سرچش شروع به تایپ میکنید زیرش نتیجه سرچ رو نمایش میده. یه همچین چیزی رو قراره پیاده سازی کنیم.
من با استفاده از jQuery ajax این کارو انجام میدم. خیلی راحت و البته سریع و کاربردی.
خب برای شروع اول باید فایل جی کوئری رو به صفحه تون الحاق کنید:
<script src='<%= ResolveUrl("~/js/jquery-2.1.1.min.js") %>'></script>
توی مرحله بعدی تابعی که عمل سرچ رو انجام میده رو مینویسیم. من این تابع رو توی فایل index.aspx.cs می نویسم:
[System.Web.Services.WebMethod]
public static string Search(string keywords)
{
DataTable dt = Product.Search(keywords);
string html = "";
for (int i = 0; i < dt.Rows.Count; i++)
{
html += "<li><a href='/product/" + dt.Rows[i]["ProductId"] + "/" +
dt.Rows[i]["ProductName"].ToString() +"'><img class='img-thumbnail img-polaroid' src='" + dt.Rows[i]["picName"] + "?w=40&h=43&mode=crop'><h5 class='pTitle'>" + dt.Rows[i]["ProductName"] + "</h5></a></li>";
}
return html;
}
اما توضیح کد بالا:
از اونجایی که ما میخوایم از این متد توی جی کوئری استفاده کنیم پس باید اونو از نوع WebMethod در نظر بگیریم.
نکته دیگه اینکه حتما این متد باید public و static باشه. خروجی این متد هم string هست که در واقع برای ما کد html خروجی رو تولید میکنه. یه پارامتر ورودی هم داره که در واقع همون عبارتی هست که کاربر برای جست وجو وارد میکنه و از نوع رشته ست.
اما خط بعدی:
DataTable dt = Product.Search(keywords);
توی این خط من تابع Search که توی کلاس Product هست رو فراخوانی کردم که توی این تابع استاتیک کار جست وجو توی جدولی که مد نظر من هست انجام میشه و نتیجه به صورت DataTable برگردونده میشه. دیگه از توضیح بدنه این تابع صرف نظر میکنم چون طولانی میشه و بحث ما هم روی این مباحث نیست.
اما اصل بحث ما روی ادامه هست. معمولا توی جی کوئری ای جکس کاری که می کنیم اینه که کد اچ تی ام ال رو میسازیم و بعد با استفاده از جی کوئری اون رو توی بخشی که مد نظرمون هست نمایش میدیم. منم توی ادامه این متد همین کارو کردم. شما با توجه به پروژه خودتون کد اچ تی ام ال مورد نظر خودتون رو میسازید. من با توجه به پروژه خودم اون چیزی که قراره نمایش بدم به صورت لیست هست برای همین از li استفاده کردم و لابه لاش هرجا که نیاز داشتم اطلاعات رو از دیتاتیبل خوندم و توی کد اچ تی ام الم قرار دادم.
در نهایت هم این کد اچ تی ام الی که توی متغیر رشته ای html ریختم رو return میکنم.
حالا میریم سراغ استفاده از این خروجی و نمایش اون توی سایت. من از اونجاییکه کادر سرچم توی مسترپیجم هست پس کدهای جی کوئری رو هم همونجا مینویسم. البته میتونید توی یه فایل js قرار بدید و بعد اونو توی صفحه تون الحاق کنید. پس میریم سراغ صفحه مسترپیج.
تکست باکسی که قراره توش تایپ بشه:
کد HTML:
<input autocomplete="off" type="text" id="schBox" placeholder="جستجو" />
<div class="instant-search">
<ul id="product-items"></ul>
</div>
دوستان دقت کنید هیچ نیازی نیس از کنترل TextBox استفاده کنید. پس من از input اچ تی ام ال استفاده کردم. در ادامه هم یه تگ div گذاشتم که در حالت عادی نمایش داده نمیشه (display:none) و به محض تایپ توی تکست باکس به نمایش در میاد و نتیجه سرچ توش نشون داده میشه.
اما کدهای جی کوئری:
$(function () {
$('#schBox').keyup(function (event) {
var text = $(this).val();
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "/index.aspx/Search",
data: "{'keywords':'" + text + "'}",
dataType: "json",
success: function (response) {
if (response.d == '') {
$("#product-items").html('<li class="empty">هیچ موردی یافت نشد.</li>');
$('.instant-search').fadeIn(200);
return;
}
$("#product-items").html(response.d);
$('.instant-search').fadeIn(200);
}
});
});
});
در ادامه کدهای بالا رو توضیح میدم:
برای اینکه با شروع تایپ توی تکست باکس عمل جست وجو انجام بشه من از رویداد keyup استفاده کردم. پس تکست باکس رو با id که قبلا براش تعریف کردم انتخاب میکنم و رویداد keyup رو براش فراخوانی میکنم:
$('#schBox').keyup(function (event) {
});
حالا میریم سراغ کدای درون این قسمت:
توی خط اول مقداری که کاربر توی تکست باکس وارد کرده رو داخل یه متغیر به نام text میریزیم تا بعدا راحت تر ازش استفاده کنیم:
var text = $(this).val();
حالا وقتش رسیده که عملیات ای جکسی رو شروع کنیم. کاری که باید بکنیم اینه که مقداری که الان کاربر وارد کرده رو بفرستیم به تابع Search که قبلا توی فایل index.aspx.cs نوشته بودیم. پس میریم سراغ متد $.ajax()
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "/index.aspx/Search",
data: "{'keywords':'" + text + "'}",
dataType: "json",
success: function (response) {
if (response.d == '') {
$("#product-items").html('<li class="empty">هیچ موردی یافت نشد.</li>');
$('.instant-search').fadeIn(200);
return;
}
$("#product-items").html(response.d);
$('.instant-search').fadeIn(200);
}
});
داخل متد $.ajax() چندتا پارامتر تعریف شده که به صورت name:value هستش. من فقط اونایی رو که مهمه و باهاش کار داریم رو توضیح میدم. بقیش برای ما مهم نیست. بذارید به همین شکلی که هست باشه.
یکی از پارامترایی که مهمه پارامتر url هست که باید آدرس تابع Search رو بهش بدیم. چون این تابع رو توی صفحه index.aspx.cs نوشتیم پس مقدار پارامتر url به شکل زیر میشه:
url: "/index.aspx/Search"
دقت کنید که نباید آدرس صفحه index.aspx.cs رو بدید.
پارامتر بعدی که خیلی هم مهمه پارامتر data هست که کارش اینه که ما آرگومانهای تابعی که نوشتیم رو بهش پاس بدیم. تابع Search یه پارامتر به نام keywords داشت که باید مقدار وارده شده توی تکست باکس رو بهش ارسال کنیم.
data: "{'keywords':'" + text + "'}"
متغیر text که بالاتر تعریف کردیم و مقدار وارد شده توسط کاربر رو توش ذخیره کردیم اینجا استفاده میشه. دقت کنید که کوتیشن و دابل کوتیشن ها رو دقیقا به همین شکل بذارید.
خب یه پارامتر دیگه به نام success داریم که یه تابع براش تعریف میشه. در صورتی که کد ما خطایی نداشته باشه تابع پارامتر success اجرا میشه.
همونطور که گفتم این پارامتر یه تابع میگیره.
success: function (response) {
if (response.d == '') {
$("#product-items").html('<li class="empty">هیچ موردی یافت نشد.</li>');
$('.instant-search').fadeIn(200);
return;
}
$("#product-items").html(response.d);
$('.instant-search').fadeIn(200);
}
این تابع یه پارامتر میگیره که اسمش هرچیزی میتونه باشه. من اسمش رو response گذاشتم. خروجی تابع Search به صورت json هست که یه آبجکت به نام d داره. پس ما هم از طریق همین آبجکت به صورت response.d به خروجی اچ تی ام ال دسترسی پیدا میکنیم.
ابتدا بررسی میکنیم اگه نتیجه جست وجو هیچی نبوده پیام مناسب به کاربر نشون داده بشه. پس توی div که قبلا توی کد اچ تی ام ال تعریف کرده بودیم و به صورت پیش فرض مخفی بود (با سی اس اس) و داخل ul با استفاده از متد html پیام رو به کاربر نشون میدیم و بعد div رو هم با متد fadeout() نمایش میدیم:
if (response.d == '') {
$("#product-items").html('<li class="empty">هیچ موردی یافت نشد.</li>');
$('.instant-search').fadeIn(200);
return;
}
و در ادامه اگر جست وجو نتیجه ای داشته پس خروجی تابع Search رو توی ul با id=product-items نمایش میدیم. و div رو نمایش میدیم.
اما چندتا نکته:
- سعی کردم تقریبا تمامی جزئیات رو توضیح بدم تا اگر کسی هم مبتدی هست به دردش بخوره.
- تنها کاری که میمونه نحوه نمایش المانها هست که این دیگه با سی اس اس انجام میشه. اینکه اون Div دقیقا زیر تکست باکس نشون داده بشه و ...
- هرجایی رو که متوجه نشدید بپرسید، اگه بلد بودم توضیح میدم.
- من یه سری کدها رو از این آموزش حذف کردم که خیلی شلوغ نشه. مثلا اون چیزی که من خودم نوشتم این امکانات رو هم داره:
- تا زمانی که تعداد کاراکترهای واردشده توسط کاربر کمتر از 3تا باشه عمل سرچ انجام نمیشه.
- عملکرد دکمه اینتر رو غیرفعال کردم که اگه کاربر اینتر رو زد صفحه رفرش نشه
- اگه کاربر دکمه escape رو زد کادر نتیجه سرچ بسته بشه.
- کاربر اگه بیرون از div کلیک کرد، div مخفی بشه.
- و اینکه چون منطقی نیس با تایپ هرکاراکتر بلافاصله عمل سرچ انجام بشه، من یه delay خیلی کوتاه در حد یه ثانیه ایجاد کردم که تعداد requestها کمتر بشه.
- امیدوارم این آموزش به دردتون خورده باشه.
- این اولین پست آموزشی من هست و مطمئنا ایراداتی توش هست. خوشحال میشم ایراداتش رو هم بگید.
موفق باشید.