• 0
M.B.O

تغيير خيارات قائمة منسدلة بدلالة قائمة منسدلة اخرى

سؤال

بسم الله الرحمن الرحيم والصلاة والسلام على سيدنا محمد وعلى اله وصحبه أجمعين

لاحظ كثرة الاستفسارات في عدة منتديات حول موضوع لو كان عندي قائمتين منسدلة select list كيف أغير مثلا ً محتويات القائمة الثانية عندما يحدد المستخدم عنصر معين في القائمة الأولى ، ومثال على ذلك هو الدول والمدن ، أي عندما يختار المستخدم دولة معينة تتغير محتويات المدن إلى مدن الدولة التي حددها المستخدم ، والأمثلة كثيرة على هذا الأمر .

[ مثال مباشر على الدرس اضغط هنا ]

الموضوع بسيط جدا ً فقط محتاج قليل من التركيز .

الامر لايمكن حصره على مثال معين او طريقة معينة الامثلة كثيره وكذلك ربما قد لا نتحتاج لاستخدام قواعد بيانات مثل MySQL ملف XML قد يفي بالغرض او حتى ملف txt لكن حتى تتضح الصورة اكثر بالنسبة للمبتدئين اخترت ان اعمل المثال على قاعدة بيانات MySQL ، ويمكن للشخص اختيار ما يناسبه ولا يقتصر الموضوع على طريقة واحدة .

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

سأبدأ أولا ً بتحليل قاعدة البيانات كيف سوف تكون ، رغم أنها بسيطة جدا ً لكن زيادة لزيادة الفهم أكثر وتفصيل الأمور .

العناصر الأساسية في هذا الموضوع هما عنصرين قد يزيدوا لكن في هذا الدرس سأفترض أنهم عنصرين فقط تسهيلا ً للفهم وسآخذ مثال الدول والمدن.

العنصر الأول مثلا ً وليكن هو الدولة countries والعنصر الثاني هي المدينة Cities، إذن سيكون لدي هناك جدول للدول وجدول أخر للمدن , نأخذ أولا ً جدول الدول وسأضع فيه ثلاثة حقول فقط هما رقم الدولة ID وكذلك اسم الدولة name و القيمة value هذه سنستخدمها مع الوسم select بإمكانك أن تضع حقول أكثر حسب رغبتك ، أما في جدول المدن سأضع اربعة حقول الأول رقم المدينة ID والثاني اسم المدينة name والثالث value والرابع countrie_id عبارة عن foreign key من جدول الدول لعمل العلاقة مابين جدول الدول وجدول المدن .

سيكون المخطط البياني للجداول بالشكل التالي :

0MXKQ.jpg

هذا هو المخطط البسيط للجدولين وهذا مثال أخر لبعض السجلات في الجدولين :

G9QAU.jpg

حسنا ً اعتقد أن الفكرة اتضحت الآن بالنسبة لتخطيط قاعدة البيانات , سننتقل إذن إلى تحليل آلية العمل .

سنحتاج إلى ملفين PHP الملف الأول نسميه form.php والملف الثانية Cities.php ايضا ً ننشى مجلد للملفات المؤقته بأسم tempCities كذلك لا ننسى مكتبة jQuery

- في البداية عند فتح الصفحة ينفذ استعلام على قاعدة البيانات لجلب الدول ووضعها في قائمة منسدلة مثلا ً لنسمي هذه القائمة بـ list1 ، ثم ينفذ استعلام آخر لجلب المدن المتعلقة بالدولة المحددة حاليا ً في list1 ثم يضعها في قائمة منسدلة أخرى ولنسميها list2 ، هذه الخطوة الأولى وهي الافتراضية عند دخول المستخدم إلى الموقع للمرة الأولى .

- الخطوة الثانية وهي عندما يقوم المستخدم باختيار عنصر من list1 تتغير القيم في list2 .

- سأضيف خطوة أخرى اختياريه لإضافة مزيد من المرونة ، وهي أن الاستعلام في قاعدة البيانات ينفذ مره واحده فقط ثم يتم حفظ القيم في ملف مؤقت على الخادم Server وفي المرة الثانية يتم اخذ البيانات من الملف المؤقت وليس من قاعدة البيانات ، هذا الأمر سيعطي أولا ً سرعة اكبر في جلب البيانات وثانيا ً سيخفف الضغط على الخادم.

حسنا ً بعد أن حللنا قاعدة البيانات وتصورنا آلية العمل نبدأ الآن بالتطبيق العملي باستخدام التقنيات التي ستساعدنا في هذه العملية .

نأخذ أول خطوة وهي كتابة الهيكلة الأساسية لكودHTML في ملف form.php :


<html>
<head>
<title>Change List</title>
</head>

<body>
<form method="POST" action="#">
<select name="list1" id="Countries">

</select>


<select name="list2" id="Cities">

</select>

<input type="submit" value="go" />
<form>
<div id="loading" style="display:none">Loading</div>
</body>
</html>

لاحظ الكود بسيط جدا ً سأوضح ابرز الأمور فقط .

أنشأت نموذج بداخلة قائمتين منسدلة الأولى اسمها list1 والثانية list2 بالإضافة إلى id لكل قائمة هذا الـ id فائدته ستتضح فيما بعد ، لاحظ أنني لم أضع أي خيارات على القائمة والسبب آن هذه الخيارات سيتم جلبها من قاعدة البيانات، أيضا ً أضفت div بداخله نص لكنه غير ظاهر يظهر فقط في فترة تغيير القائمة , هذا الأمر اختياري فقط لإضافة بعض الجماليات بإمكانك الاستغناء عنه ، وسيتضح هذا الأمر لنا في السطور القادمة .

حسنا ً الخطوة التالية وهي جلب أسماء الدول ووضعها في list1 ، عن طريق الكود التالي :

<select name="list1" id="Countries">
<?php
$query = mysql_query("SELECT id,name,value FROM countries");
while($rows = mysql_fetch_array($query))
{
echo '<option value="'.$rows['value'].'">'.$rows['name'].'</option>';
}
?>
</select>

إلى هنا اعتقد انه لا جديد الاكواد مألوفة للكل ، نتقل الآن إلى الخطوة الأهم في هذا الموضوع وهي القائمة المنسدلة الخاصة بالمدن والتي أسميناها list2

القائمة المنسدلة للمدن تأخذ احتمالين ، الاحتمال الأول وهو عند استعراض الصفحة لأول مره تظهر مدن الدولة المحدد افتراضيا ً في القائمة المنسدلة الأولى ، والاحتمال الثاني هو عندما يقوم المستخدم بتغيير الدولة تتغير معها الدولة .

سنأخذ أولا ً الاحتمال الأول وهو عند استعراض الصفحة لأول مره .

بما أن القائمة المنسدلة للمدن مرنه وغير ثابتة أي تتغير حسب الخيار الموجود في القائمة المنسدلة الأولى وكذلك حسب اختيار المستخدم إذن في هذه الحالة سأستخدم لغة من نوع Client-side حتى تفي بالغرض , سأستخدم لغة الجافاسكربت Javascript واختصارا ً للوقت والجهد سأستخدم مكتبة jQuery كونها ستسهل علينا الأمر خصوصا ً عند التعامل مع تقنية الاجاكس Ajax.

بعد تضمين مكتبة jQuery الى مشروعنا سأبدأ بتعريف دالة بلغة الجافاسكربت باسم getCities هذه الدالة هي المسئولة عن تغيير محتويات القائمة المنسدلة للمدن list2 ، تقوم بإرسال قيمة الدولة الى ملف Cities.php ثم يتم الاستعلام عن مدن الدولة في ملف Cities.php بعد المعالجة تقوم دالة getCities بأخذ القيم المرجعة بعد الاستعلام من ملف Cities.php ووضعها في القائمة المنسدلة للمدن list2 ، كود الدالة سيكون كا التالي :

function getCities()
{
// جلب قيمة الخيار المفعل حاليا ً في القائمة المنسدلة للدول
var countryValue = $("#Countries").val();

// مسار مجلد الملفات المؤقته
var temCity = "tempCities/";

// مسار الملف المؤقت للدولة المحددة في القائمة المنسدلة للدول
var tempURL = temCity + countryValue + ".txt";

// يتم استخدام هذا المتغير في حالة لم يكن هناك ملف مؤقت للدولة
// يتم ارسال البيانات الى ملف البي اتش بي عن طريق المصفوفة بوست
var dataPost = "co_val=" + countryValue;

// اظهار رسالة التحميل للمستخدم مابين اختيار الدولة وعرض المدن
$("#loading").fadeIn(100);

// استخدام تقنية الاجاكس عن طريق مكتبة الجيكوري لجلب مدن الدولة
$.ajax(
{
url : tempURL,

// اذا لم يتم العثور على الملف المؤقت لمدن الدولة
error : function()
{
$.ajax({
url : "Cities.php",
type : "POST",
data : dataPost,
success : function(result)
{
$("#loading").fadeOut(100);
// اخفاء القائمة المنسدلة للمدن في حالة لم يتم ادخال اي مدن للدولة
(result == "null") ? $("#Cities").hide(0) : $("#Cities").show(0);

// اضافة المدن للقائمة المنسدلة للمدن
$("#Cities").html(result);
}

})
},

// جلب البيانات من الملف المؤقت للدولة
success : function(result)
{
$("#loading").fadeOut(100);
(result == "null") ? $("#Cities").hide(0) : $("#Cities").show(0);
$("#Cities").html(result);
}
})

}

كل سطر برمجي به تعليق للتوضيح , لا مشكلة إذا لم تفهم الكود بشكل كامل سيتضح إن شاء الله في الأسطر القادمة .

سأوضح الفكرة العامة للكود بشكل مختصر , مثل ما ذكرت في الاعلى الكود في الأعلى عبارة عن دالة هذه الدالة مهمتها الأساسية هي جلب البيانات من قاعدة البيانات آو من الملف المؤقت , ترسل قيمة الحقل المحدد في القائمة الأولى عن طريقة تقنية الاجاكس باستخدام POST هذا في حالة لم يكن هناك ملف مؤقت , في حالة هناك ملف مؤقت لمدن الدولة يتم جلب البيانات من الملف المؤقت .

بعد أن عرفنا الدالة سنقوم الآن باستخدامها ، مثل ما ذكرت في الأعلى آن هناك احتمالين للقائمة المنسدلة الأولى , الاحتمال الأول وضحته بالأعلى وهو عند استعراض الصفحة لأول مره والاحتمال الثاني هو عندما يقوم المستخدم بتغيير الدولة في القائمة الأولى , واختصارا ً للجهد قمت بتعريف الدالة التي بالأعلى وهي التي سنستخدمها في الاحتمالين أي عند البداية وعند تغيير خيارات الدول , وكود استخدام الدالة سيكون بالشكل التالي :

$(document).ready(function()
{

getCities();

$("#Countries").change(function()
{
getCities();
})
})

قد تلاحظ آن الاكواد غريبة بعض الشيء إذا لم تكن لديك خلفية مسبقة عن مكتبة jQuery أو الجافا سكربت , لذلك أي شي غير واضح لا تنسى أن تسأل عنه حتى أوضحه لك أن شاء الله

إلى هنا نكون قد انتهينا من ملف form.php والكود النهائي لهذا الملف يفترض أن يكون بالشكل التالي :


<html>
<head>
<title>Change List</title>
<script type="text/javascript" src="jQuery.js"></script>
<script type="text/javascript">

function getCities()
{
// جلب قيمة الخيار المفعل حاليا ً في القائمة المنسدلة للدول
var countryValue = $("#Countries").val();

// مسار مجلد الملفات المؤقته
var temCity = "tempCities/";

// مسار الملف المؤقت للدولة المفعلة في القائمة المنسدلة للدول
var tempURL = temCity + countryValue + ".txt";

// يتم استخدام هذا المتغير في حالة لم يكن هناك ملف مؤقت للدولة
// يتم ارسال البيانات الى ملف البي اتش بي عن طريق المصفوفة بوست
var dataPost = "co_val=" + countryValue;


$("#loading").fadeIn(100);

// استخدام تقنية الاجاكس عن طريق مكتبة الجيكوري لجلب مدن الدولة
$.ajax(
{
url : tempURL,

// اذا لم يتم العثور على الملف المؤقت لمدن الدولة
error : function()
{
$.ajax({
url : "Cities.php",
type : "POST",
data : dataPost,
success : function(result)
{
$("#loading").fadeOut(100);
// اخفاء القائمة المنسدلة للمدن في حالة لم يتم ادخال اي مدن للدولة
(result == "null") ? $("#Cities").hide(0) : $("#Cities").show(0);

// اضافة المدن للقائمة المنسدلة للمدن
$("#Cities").html(result);
}

})
},

// جلب البيانات من الملف المؤقت للدولة
success : function(result)
{
$("#loading").fadeOut(100);
(result == "null") ? $("#Cities").hide(0) : $("#Cities").show(0);
$("#Cities").html(result);
}
})

}


/*
-----------------------
*/


$(document).ready(function()
{

getCities();

$("#Countries").change(function()
{
getCities();
})
})
</script>
</head>

<body>
<form method="POST" action="gg.php">
<select name="list1" id="Countries">
<?php
$query = mysql_query("SELECT id,name,value FROM countries");
while($rows = mysql_fetch_array($query))
{
echo '<option value="'.$rows['value'].'">'.$rows['name'].'</option>';
}
?>
</select>


<select name="list2" id="Cities">

</select>

<input type="submit" value="go" />
<form>
<div id="loading" style="display:none">Loading</div>
</body>
</html>

نتقل الآن إلى ملف Cities.php هذا الملف دورة الأساسي في جلب المدن من قاعدة البيانات , طبعا ً لا نتعامل معه بشكل مباشر إنما عن طريق الاجاكس من ملف form.php

كود ملف Cities.php سيكون بالشكل التالي :

$couVal = $_POST['co_val'];

if($couVal)
{

$queryTown = mysql_query("SELECT name,value FROM cities WHERE country_value = '$couVal'");
$num = mysql_num_rows($queryTown);

if($num > 0)
{
while($rows = mysql_fetch_array($queryTown))
{
echo '<option value="'.$rows['value'].'">'.$rows['name'].'</option>';

$fp = fopen("tempCities/".$couVal.".txt","a");
fwrite($fp,'<option value="'.$rows['value'].'">'.$rows['name'].'</option>');
}
fclose($fp);
}else
{
echo 'null';
}

}

شرح الكود :

أولا ً قمت بتعريف متغير محتواه عبارة عن المصفوفة POST

لو رجعنا إلى الخلف قليلا ً سنلاحظ أننا استخدامنا تقنية الاجاكس وكذلك استخدمنا POST لإرسال البيانات إلى ملف Cities.php ، مرننا البيانات عبر قيمة co_val

البيانات التي أرسلناها هي عبارة عن قيمة الخيار المحدد حاليا ً في القائمة المنسدلة للدول , نرسل هذه القيمة إلى ملف Cities.php ثم نستعلم عن المدن المتعلقة بهذه الدولة , إذن المتغير couVal يحتوي على قيمة Value للمدينة المحدد في القائمة المنسدلة للدول .

في السطر التالي قمت بوضع شرط لاختبار أن هناك فعلا ً قيم مرسلة ، هذه القيمة هي عبارة عن رمز الدولة ليتم الاستعلام عنه

ثم في الأسطر التالية قمت بعملية استعلام عادية وطباعة القيم , الأمر المهم الأخر في هذا الكود هو أنني قمت بتنفيذ دالة fopen لعمل ملف مؤقت في مجلد tempCities هذا الملف حتى لا يتم الاستعلام مره أخرى من قاعدة البيانات ويتم اخذ البيانات من الملف المؤقت للتخفيف على الخادم وكذلك للسرعة .

إلى هنا انتهى الدرس , اعذروني إذا كانت هناك أي أخطاء أو لم أقم بإيصال المعلومة بشكل صحيح ، أسعد باستقبال أسئلتكم واستفساراتكم .

دمتم بود M.B.O

تم تعديل بواسطه M.B.O
3

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

6 إجابة على هذا السؤال .

  • 0

بعد التحية

الاخ / محمد

إسكريبت رائع وكنت ابحث عنه ، لكن واجهتني بعض المشاكل ف تطبيقة

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

كما ارجو منك المساعدة لو توافر لديك الوقت

حيث انني ابحث عن سكريبت خاص يقوم بعمل

Multiple Dropdwon checkbox list

و ف نفس الوقت يقوم بعمل فيلتر للقائمة المنسدلة الثانية بعد الاختيار من القائمة المنسدلة الاولى

مثال على هذا الاسكريبت

عملية البحث على موقع فابريكا للسيارات

http://www.fabreka.com

تماما كما اشرت بموضوعك لكن مع زيادة فكرة multiple checkbox

اتمنى يكون عندك الوقت ويتوافر لديك هذا النوع من الاسكريبت

مع خالص تحياتي وتقديري

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

من فضلكم افيدونى عايز استعلم عن المدينة واسم داخل المدينة فى جدول واحد وكيفية عمل قائمة منسدلة الاختيار المدينة وبعد ابحث فى المدينة عن الاسم

التصميم بالدريم ويفر وقاعدة البيانات بـ mysql

تم تعديل بواسطه محمد الطاهر
0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

مضى وقت طويل على كتابتي للموضوع واعتذر على عدم متابعة الموضوع وقراءة الردود

اخي sameh89 اذا كانت لازلت بحاجة لهذا الكود يمكنك مراسلتي على الخاص وسأرسل لك الكود بشكل كامل.

 

اخي محمد الطاهر الدرس يشرح ما تريده ارجوا مراجعته ويمكن تطبيقه على الدريم ويفر او غيره

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

انا متشكر جدا

الحمد لله تمت الاستفادة من الدرس

وتم العمل بنجاح

ولكن عندى مشكلة فى صفحة نتائج عملية البحث عايز اعرض نتائج البحث

قمت بعمل صفحتين الصفحة الاولى city.php وصفحة ثانية لكود الاجكسى csa_ajax.php

هذا هو كود city.php

<!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><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><title>Untitled Document</title> <script type="text/javascript">    <!--    var request = false;	/*@cc_on @*/	/*@if (@_jscript_version >= 5)	try {	request = new ActiveXObject("Msxml2.XMLHTTP");	} catch (e) {	try {	request = new ActiveXObject("Microsoft.XMLHTTP");	} catch (e2) {	request = false;	}	}	@end @*/	if (!request && typeof XMLHttpRequest != 'undefined') {	request = new XMLHttpRequest();	}	function fillSelect(country) {		var url = "csa_ajax.php?country=" + escape(country);		request.open("GET", url, true);		request.onreadystatechange = go;		request.send(null);	}	function go() {		if (request.readyState == 4) {			if (request.status == 200) {				var response = request.responseText;				var list=document.getElementById("city");				var cities=response.split('|');				/* for (i=1; i<cities.length; i++) { */				for (i in cities) {				   if(i > 0){				   var x=document.createElement('option');				   var y=document.createTextNode(cities[i]);				   x.value = i;				   x.appendChild(y);				   list.appendChild(x);				   }				}			}		}	}	function initCs() {		var country=document.getElementById('country');		country.onchange=function() {			if(this.value!="") {				var list=document.getElementById("city");				while (list.childNodes[0]) {					list.removeChild(list.childNodes[0])				}				fillSelect(this.value);			}		}		fillSelect(country.value);	}    //-->    </script>  </head><body><script><!--window.onload=initCs; //--></script><form method="post" action="#"><p>   	<label>		country:		<select id="country" name="country">          <option value="1">ارمنت</option>          <option value="2">البياضية</option>          <option value="3">اسنا</option>          <option value="4">القرنة</option>          <option value="5">الاقصر</option>          <option value="6">طيبة</option>          <option value="7">الطود</option>          <option value="8">الزنية</option>        </select></label>	<label>		city: <select id="city" name="city"></select>	</label></p></form></body></html>
0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

صفحة كود الاجكسى csa_ajax.php

عايز اعمل كومب بوست للبحث عن اسم العميل داخل الفرع

<?phpfunction doIt($country) {switch ($country) {case "":return array('اختر الفرع');break;case "1":return array(1 => 'الرزيقات', 2 => 'الرياينة', 3 => 'ارمنت الحيط', 4 => 'المحاميد', 5 => 'ارمنت الوابورات');break;case "2":return array('البياضية','الحبيل','البغدادى');break;case "3":return array('اصفون','الدير','النمسا 1', 'النمسا 2','اسنا بحرى','اسنا قبلى','توماس','النجوع','الشغب','الحلة','الكيمان');break;case "4":return array('القبلى قمولا','الغربى قمولا','الضبعية','حاجر الضبعية','المريس','الاقالتة','القرنة','القرنة','البعيرات','جزيرة ارمنت');break;case "5":return array('الاولى - أ','الاولى - ب / 1','الاولى - ب / 2','الاولى - ج','الثانية و الثالثة','الرابعة و الخامسة','السادسة','السابعة و الثامنة','التاسعة - أ','التاسعة - ب','التاسعة ج والمساكن','منشأة العمارى','النجوع','العوامية','الكرنك - أ','الكرنك - ب','الكرنك - ج . د');break;case "6":return array('مدينة طيبة');break;case "7":return array('العديسات قبلى','العديسات بحرى','الطود غرب','الطود شرق','الطود','منشية النوبة');break;case "8":return array('الزنية 1','الزنية 2','الزنية 3','الزنية 4','الزنية 5');break; }}[email protected]$_GET['country'];$cities=doIt($country);foreach ($cities as $city) {echo '|'.$city;}?>

جزاكم الله عنا خير الجزاء

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

من فضلك سجل دخول لتتمكن من التعليق

ستتمكن من اضافه تعليقات بعد التسجيل



سجل دخولك الان

  • يستعرض القسم حالياً   0 members

    لا يوجد أعضاء مسجلين يشاهدون هذه الصفحة .