صندوق بحث آبل- الجزء الثاني

في الكاتب: و مدرجة تحت التنصيف دروس.

بسم الله و الحمد لله و الصلاة و السلام على سيدنا رسول الله –صلى الله عليه و على آله و صحبه و من والاه بإحسان إلى يوم الدين –.

اليوم سنكمل –إن شاء الله- ما بدأناه في الدرس السابق وذلك بتفعيل صندوق البحث ليقوم بالبحث في قاعدة بيانات مجهزّة مسبقا ثم يقوم بعرض النتائج في المتصفح و كل ذلك يتم (أجاكسيّاً).

ما هي الفكرة الأساسية؟

الفكرة ببساطة هي البحث في قاعدة البيانات كلما كتب المستخدم حرفاً في صندوق البحث و عرض النتيجة مباشرة كما في الشكل:

ajax search

كيفية ظهور نتائج البحث

ولكن ما هو الأجاكس Ajax؟

نظرة تاريخية

“ليس له علاقة مع أجاكس أمستردام!”
إن “أجاكس” ليس تقنية في حد ذاته و إنما هو مصطلح يرمز لعدة تقنيات تعمل سوياً.فكلمة أجاكس Ajax  هي اختصار لـ (Asynchronous JavaScript and XML )  استخدم المصطلح أول مرة مطوّر المواقع Jesse James Garret  عام 2005 :

“كنت محتاجاً لشيء أبسط من جملة:

Asynchronous Javascript + CSS + DOM+ and XMLHttpRequest

لكي أستخدمه عند مناقشة هذا المفهوم مع العملاء.”

ما هو….عمليّا؟

بصورة مبدئية.. يكفي القول بأنه عمل طلب ( Http Request ) للخادم (السيرفر) و التعامل مع النتيجة من هذا الطلب بدون إعادة تحميل الصفحة أو الانتقال لصفحة أخرى. والأمثلة على ذلك كثيرة:

أمثلة لتطبيقات أجاكس

قوقل مليئة بتطبيقات الأجاكس... لاحظ أيضا ظهور التحديثات في تويتر.

 

أعتقد أن الصورة اتّضحت نوعاً ما!! الأجاكس موضوع ممتد و ربما سنتطرّق إليه لاحقاً بإذن الله.

الملفات المستخدمة:

 

إضافة إلى الدرس السابق فإن التعديلات شملت تعديل كود ملف الـ HTML و إضافة ملف PHP ليقوم بالبحث في قاعدة البيانات.بالإضافة إلى ملفين أحدها للاتصال و الآخر لفلترة مدخلات المستخدم.

الصفحة الرئيسية التي تحوي صندوق البحث والـ CSS والجافاسكريبت متمثلة في الجيكويري.و ملف البي اتش بي PHP الذي يحوي كود البحث في قاعدة البيانات.

الخطوات:

  1. الــ HTML و ال CSS .
  2. الـجيكويري JQuery والأجاكس Ajax.
  3. البي اتش بي PHP .

 

أولاً : HTML  و CSS :

إلى الأعلى
سنضيف أولا قائمة نتائج البحث مع الصور بمحتوى وهمي Dummy Content قبل بدء أي شيء وذلك لتسهيل تحديد شكل القائمة و موضعها بالنسبة لصندوق البحث عند عرض النتائج لاحقا.ثم سنقوم بحذف المحتوى الوهمي و من ثم إخفائها وذلك بالخاصية display:none في الــ CSS .

محتوى وهمي

تم إضافة بعض المحتوى الوهمي لضبط خصائص و أبعاد صندوق البحث

HTML :

كود الـ HTML لقائمة نتائج  البحث:

 
<div id="menu" class="r25">
 <img id="wait" src="imgs/wait.gif" alt="loading"/>
<input id="search" class="r25" type="text" />
<ul>
  <li> < img src="imgs/products/ipad.png"/ >
<h4>ipad</h4>
All-new thinner, lighter design. Faster A5 chip. FaceTime video calling. With the same 10-hour battery. It's not a tablet, it's iPad.</li>
</ul>
</div>

CSS :

يكتمل الشكل النهائي لقائمة النتائج زائداً مؤشر جاري البحث (الصورة الصغيرة أقصى يسار الصندوق) بإضافة كود الـ CSS .. سنركز على كود قائمة نتائج البحث وصورة (جاري البحث) لأن الباقي تم المرور عليه في الدرس السابق:

 
#results{ /*    تنسيق صندوق البحث   */
width: 360px;
background: #fff;/* #fff=white */
list-style: none;/* منع عرض نقط أو مربعات بجانب كل نتيجة */
text-align: center;
display: none;/* لن يتم عرض صندوق البحث إلا عند الكتابة على صندوق البحث */
position: absolute;
margin-top:0px;
padding: 0px;
border:1px solid #e2e2e2; /* #e2e2e2 = pretty light gray*/
/* the radius */
-moz-border-radius:5px;
-webkit-border-radius: 5px;
border-radius:  5px;
/* the box shadows  إضافة ظل على صندوق البحث...بحيث يكون خفيف الظل */
-moz-box-shadow: 0px 5px 10px black;
-webkit-box-shadow:0px 5px 10px black;
box-shadow: 0px 5px 10px black;
}

#results li{ /* تنسيق نتائج البحث */
height: 64px;
border-bottom: 1px solid #e2e2e2;
padding:5px;
}

#results li:hover{/* تنسيق النتائج عند مرور مؤشر الماوس فوقها */
background-image: -webkit-gradient(linear, left top, left bottom, from(#e2e2e2), to(#fff)); /* Saf4+, Chrome */
background-image: -webkit-linear-gradient(top, #e2e2e2, #fff); /* Chrome 10+, Saf5.1+ */
background-image:    -moz-linear-gradient(top, #e2e2e2, #fff); /* FF3.6 */
background-image:     -ms-linear-gradient(top, #e2e2e2, #fff); /* IE10 */
background-image:      -o-linear-gradient(top, #e2e2e2, #fff); /* Opera 11.10+ */
background-image:         linear-gradient(top, #e2e2e2, #fff);
filter: progid:DXImageTransform.Microsoft.gradient(startColorStr='#e2e2e2', EndColorStr='#fff'); /* IE6–IE9 */
}
#results li h4,p{
padding: 0px;
margin: 0px;
}

#results li p{/* تنسيق وصف كل منتج من المنتجات */
color:gray;
font-size:12px;
margin-left:5px;
}
#results img{/*  تنسيق الصور المعروضة في نتائج البحث */
float:left;
}

#wait{/*   هذا هو الجزء المتعلق بمؤشر البحث و هي صورة صغيرة متحركة في أقصى يسار صندوق البحث الغرض منها إظهار وجود عملية جارية حالياً */
display: none;/*  لن يتم عرضه حتى تتم الكتابة في صندوق البحث */
position: absolute; /* */
margin-top: 3px;
margin-left: 3px;
}

مهلاً مهلاً من أين يأتي كل هذا الـ CSS!!؟؟

البعض تعوّدت كتابته مباشرة و لكن من أفضل المواقع لتعلّم الــ CSS هو CSS3PLEASE.com قم بتطبيق خصائص الـ CSS مباشرة ثم انسخها إلى صفحتك..الأمر بسيط!!


ثانياً : الجافا سكربت (مكتبة الجيكويري) والأجاكس :

إلى الأعلى

الأجاكس

ميكانيكية العمل ببساطة على التسلسل الآتي:
عند التركيز بالماوس على صندوق البحث يكون محرك الحدث هنا هو الــتركيز focus والذي يفعّل الدالة animate التي تقوم بتحريك الصندوق.وقد قمنا بإعدادها مسبقاً.

كتابة الكلمة المراد البحث عنها :محرك الحدث هنا هو الضغط على لوحة المفاتيح keyup  والذي بدوره ينادي الدالة $.ajax() لتقوم بعملها.

سنقوم الآن بإعداد الجزء من الجافاسكربت الذي يستمع للوحة المفاتيح Keyboard Event .و يقوم بتنفيذ ما بداخله – كود الأجاكس – عند الضغط على لوحة المفاتيح keyUp.

 
//onKeyUp
$('#search').keyup(function(){// سيقوم البحث بتنفيذ الدوال والأوامر التالية عند رفع الأصبع عن أحد ازرار لوحة الفاتيح
  

  if($(this).attr('value')!="")//اختبر ما إذا كان صندوق البحث يحوي نصاً أم لا ..إذا كان يحوي نصاً سيقوم بإظهار مؤشر (جاري البحث) سم يقوم بتنفيذ دالة الأجاكس،أما إذا كان لا يحوي شيئا فسوف يتخطى جميع الكود الآتي و يقوم بعرض رسالة (أكتب للبحث).
  {
  $('#wait').css('display','block');//أظهر مؤشر جاري البحث إذا كان  هنالك محتوى في صندوق البحث
/********************************************/
//يتم وضع كود دالة الأجاكس هنا...بحيث يقوم  بالتنفيذ مع كل ضغطة على لوحة المفاتيح
$.ajax()
{
}
/********************************************/

}//end if
  else 
  $('#results').html("<h4>أكتب للبحث</h4>");//اطبع هذه الرسالة في حالة عدم و جود نص في صندوق البحث

});//end keyup

نستخدم الآن الدالة $.ajax() وكما ذكرنا سنضعه داخل الكود أعلاه:

 
  $.ajax({
                type: 'POST',//طريقة الطلب إما post و get
                url: 'ajax_search.php',//ملف البي اتش بي الذي سيتم مناداته و ارسال مفردة البحث إليه و الذي بدورة سيقوم بالبحث في قاعدة البيانات
                data:'search='+$(this).attr('value'),//المتغيرات التي سيتم ارسالها
        success: function(html) {
      
          $('#results').fadeIn();  // أظهر قائمة النتائج،لاحظ أنها حتى هذه اللحظة لا يحوي شيئاً
        
        if(html=="")//قم بعرض رسالة تفيد عدم وجود نتيجة إذا كانت النتيجة (لا شيء)
          $('#results').html("< h4 >لا توجد نتيجة..حاول استخدام كلمة مفتاحية أخرى</ h4 >");
    
        else 
          $('#results').html(html);// اعرض النتيجة المرسلة من ملف البي اتش بي
        
    
        $('#wait').fadeOut();//قم بإخفاء مؤشّر جاري التحميل بعد استقبال المحتوى من ملف البي اتش بي
                }
        
        });

السطر الأول type يوضح طريقة إرسال البيانات باستخدام GET  أو POST .

السطر الثاني url وفيه يتم تحديد وجهة طلب الأجاكس والملف الموضوع هنا هو ajax_search.php و هو الذي سيبحث في قاعدة البيانات و يقوم بإعادة النتيجة باستخدام الدالة echo .

في السطر الثالث data نقوم بتحديد المتغيرات التي نودّ إرسالها إلى صفحة الـ PHP وقد أرسلنا هنا المتغير search و أسندنا إليه النص الموجود في صندوق البحث.

دالة success يتم تنفيذها حينما يكون طلب الأجاكس ناجحاً.. وظيفتها استقبال البيانات القادمة من ملف الـPHP وعرضها في المتصفح. لاحظ المتغير html : يمثِّل البيانات القادمة من ملف الــPHP.

التحكم في حركة الصندوق :

كان هذا في الدرس السايق..و لكن تم تعديل تنفيذ الدالة Blur لتقوم بإخفاء قائمة النتائج أولاً ثم تصغير صندوق البحث بعد ذلك.

 
//onBlur   
$("#search").blur(function(){

  $("#results").fadeOut({ //قم بإخفاء قائمة صندوق البحث
    duration: "slow", // ببطىء
    complete: function(){ //وعند الانتهاء من عمليه الإخفاء..قم بتنفيذ هذه الدالة
  
    $('#search').animate({ //قم بتصغير صندوق البحث
       "width": "90px",//تصغير العرض
      "backgroundColor": "#a2a2a2",//تغيير اللون إلى الرمادي
      "-webkit-box-shadow": "0px 0px 0px gray",//إلغاء ظل الصندوق
      "-moz-box-shadow": "0px 0px 0px gray" ,//إلغاء ظل الصندوق
      "box-shadow": "0px 0px 0px gray",//إلغاء ظل الصندوق
      "border":"1px solid #a2a2a2"  //تعيين خط رمادي يحيط بالصندوق
       
      }, 300 ),//وليكن هذا الحدث خلال فترة 300 ملليثانية
    

     $('#search').css({
      "background-image":"url(imgs/white_magn.png)"
      }),
     

    $('#search').attr("value","");//تنظيف صندوق البحث من أي نص بداخله
  
  
    }//end function
  });//end fadeout

});//end blur



ثالثا البي اتش بي PHP:

إلى الأعلى

طريقة عمل PHP هي كالآتي: نتصل بقاعدة البيانات.. نستقبل الكلمة المراد البحث عنها ثم نتأكد من صلاحيتها.. نقوم بعملية البحث..ثم نرسل البيانات على شكل HTML باستخدام الدالة echo إلى الجيكويري مرة أخرى ليعرض النتائج في صفحة الــ HTML.

(من الجدير بالذكر هنا أن PHP يرسل المتغيرات إلى ملفات الفلاش أيضا عن طريق الدالة echo).

سنقوم في البداية بإنشاء جدول البيانات وتتكون من 3 حقول رئيسية وهي اسم المنتج واسم صورته و وصفه .

 

CREATE TABLE `apple` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `product_name` varchar(50) CHARACTER SET latin1 NOT NULL,
  `image` varchar(50) CHARACTER SET latin1 NOT NULL,
  `description` text COLLATE latin1_general_ci NOT NULL,
  PRIMARY KEY (`id`)
);

ملف الاتصال connection.php:
والذي يقوم بالاتصال مع قاعدة البيانات.

 
//incs/connection.php
// الاتصال مع قاعدة البيانات
$connection = mysql_connect("localhost","username","password"); 
  if (!$connection) {
    die("  فشل الاتصال: " . mysql_error());
  }

  $db_select = mysql_select_db("db-name",$connection);
  if (!$db_select) {
    die("فشل اختيار قاعدة البيانات : " . mysql_error());
  }


ثم ملف الدوال:
ملف الدوال functions.php
يحوي على الدالة mysql_prep التي تقوم بتنظيف ما أدخله المستخدم وتزيل أي إدخال مشبوه : Code Injection

هذه هي الـsnippet المفضّلة لدي لتنظيف إدخال المستخدم وإعدادها للإستخدام الآمن.
 
//incs/functions.php
  function mysql_prep( $value ) {
    $magic_quotes_active = get_magic_quotes_gpc();
    $new_enough_php = function_exists( "mysql_real_escape_string" ); // i.e. PHP >= v4.3.0
    if( $new_enough_php ) { // PHP v4.3.0 or higher
      // undo any magic quote effects so mysql_real_escape_string can do the work
      if( $magic_quotes_active ) { $value = stripslashes( $value ); }
      $value = mysql_real_escape_string( $value );
    } else { // before PHP v4.3.0
      // if magic quotes aren't already on then add slashes manually
      if( !$magic_quotes_active ) { $value = addslashes( $value ); }
      // if magic quotes are active, then the slashes already exist
    }
    return $value;
  }



أخيرا نعود إلى الملف الـ PHP الرئيسي:
 
  
        header ('Content-type: text/html; charset=utf-8');
  require_once('incs/functions.php');//يتم مناداة الملف  التالي لاستخدام الدالة الموجود فيه
  require_once("incs/connection.php");//يتم مناداة هذا الملف للاتصال بقاعدة البيانات

// The search stuff  

//استقبال المتغير الذي يحوي كلمة البحث و تنظيفه من أي كود إدخال مشبوه
$search=mysql_prep($_POST['search']);

  $data="";
  if($search!="")
  {
          $query = "SELECT * ";
      $query .= "FROM apple ";
      $query .= "WHERE product_name like '%". $search ."%' LIMIT 6";
      
      $result_set = mysql_query($query,$connection) or  die("Database query failed: " . mysql_error());
      
        if(mysql_num_rows ($result_set)>0)//إذا هناك نتائج...
        {    

          while ($row = mysql_fetch_array($result_set)) //التعامل مع نتيجة البحث سطراً سطراً و تقسيم كل سطر إلى مصفوفة للحصول على قيمة كل حقل على حده.
          {
            $image=$row['image'];//تخزين اسم الصورة
            $pname=$row['product_name'];//تخزين اسم المنتج
            $desc=$row['description'];//تخزين الوصف

//يتم إسناد المحتوى الأساسي لقائمة النتائج الصور و اسم المنتج و وصفه في المتغير التالي والذي سيتم إرساله فيما بعد أجاكسيّا ليقوم الجي كويري بعرضه
            $data.="<li><img src='imgs/products/$image' /><h4>$pname</h4><p>$desc</p></li>";
          }//end while loop
          
        
        }//end if
    
      

  
  }//end if
        
  echo $data; // قم بارجاع النتيجة إلى الجيكويري ليقوم بعرضها..إذا كانت تحوي شيئا سيعرضها..و إذا كانت فارغة سيعرض رسالة تفيد بعدم وجود نتيجة..



كان بالإمكان أن وضع كل الكود بي بما فيه ملفي الاتصال connection.php و الدوال functions.php داخل ملف البي اتش بي الرئيسي و لكن من الأفضل فصل المحتوى لعدة أسباب..منها تسهيل إصلاح الأخطاء..التنظيم ،على سبيل المثال قد تحتاج إلى استخدام كود الاتصال أو دالة الإعداد mysql_prep مرة أخرى في ملف آخر..فليس هناك حوجة لإعدادة كتابة الدالة مرة أخرى..عليك فقط مناداة ملف البي اتش بي ثم منادات الدالة المطلوبة…التنظيم شيء جيد :)

أشهر أنواع المتصفحات

تمت تجربة هذا الكود في المتصفحات أعلاه.



أتمنى أن يكون الشرح وافياً و الكود واضحاً…في انتظار ردودكم…و دمتم :)
وصلى اللهم و سلم و بارك على سيدنا محمد و على آله و صحبه و سلم تسليما كثيرا إلى يوم الدين و الحمدلله رب العالمين

wdalhaj

مصمم و مطور ويب حر..يعشق شرب القهوة السوداء.. يمكنكم متابعته على التويتر [email protected]

More Posts

11 Responses to “كيفية عمل صندوق بحث بنكهة آبل – الجزء الثاني”

  1. محمد العباس مصطفى

    عمل ممتاز وأتمنى لك دوام التوفيق

    • wdalhaj

      تسلم يا ودالعباس وليك كل التوفيق كمان إن شاء الله :)

  2. sara

    مشكوووووووووووووور على هذا العمل الرائع انا من فتره ابحث عن هذا الكود والحمدلله اني لقيته
    بس في مشكلة صغيرة ومهمة انا اخذت الكود وطبقته على قاعدة البيانات الخاصة بي واشتغلت عال العال بس المشكلة انها ماتبحث بالبيانات العربي وانا شغلي كلة عربي كيييييييييف اعمل الله يحفظك كمل جميلك وشوف لي حل الله يجزيك الجنة

    • wdalhaj

      يسعدنا أنه أفادك.. بتطبيق العمليات الآتية سيعمل بإذن الله:
      يجب أن تكون قاعدة البيانات و الجداول من نوع utf8_general_ci:
      (mysql) CHARACTER SET utf8 COLLATE utf8_general_ci

      بالنسبة للhtml هذا هو كود الميتا والذي يوضع في وسم head :

       
      <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
      

      المصدر

      أيضا يجب إضافة هذا الكود إلى صفحة البي اتش بي في ملف الاتصال connection.php

       
      mysql_query("SET NAMES 'utf8'"); 
      mysql_query('SET CHARACTER SET utf8'); 
      

      المصدر
      المعذرة إذا لم يسعفني الوقت لحل المشكلة بالتفصيل.
      دوام التوفيق.

    • wdalhaj

      تسلم يا أبوعمار لك التحية ويسعدنا مرورك يا غالي.. و إن شاء الله نقدم شغل أحسن من ليندا زاتو :)

  3. محمد

    درس جميل :) بارك الله فيك

    ملاحظة بسيطة: حاول استخدام shorthands لأنها ستكون مختصر كثيرا للوقت مثل
    $(this).attr(‘value’)
    استعمل
    $(this).val()

    • wdalhaj

      بارك الله فيك أخ محمد و جزاك الله خيرا على التوضيح :)

أضف تعليقاً

  • (لن يتم نشره)