![]() |
|
Snippets |
|
There are two multi-select box, the first one is parent list menu, the second one is child menu; when clicking item in first list, its submenu will appear in second list, then you can multi-select from 2nd list; and you can multi-select items in 1st list by clicking, double-click, ctrl+click, shift+click, all selected items in 1st list will display their children in 2nd list, all deselected items from 1st list will remove their children from 2nd list. This combo list can be used for select HOBBIES, TYPES, CATEGORIES etc.
*** in multiselSuccess.php:
<script type="text/javascript" src="/sf/js/prototype/prototype.js"></script> <body onload="new Ajax.Request('/news/select/level/province', {asynchronous:true, evalScripts:false, onComplete:function(request, json){updateJSON(request,json,1)}}); return false;" >
*** in multiselSuccess.php:
<?php echo select_tag("province",options_for_select(Array(''=>'-Select-')),'multiple=multiple size=10 onmousedown=GetCurrentListValues(this); onchange=javascript:loadCity(\''.sfConfig::get('app_site_url').'news/select/level/city\',this)'); echo select_tag('city[]',options_for_select(Array(''=>'-Select-')),'multiple=multiple size=10'); ?> <div id=statusTxt></div>
*** in view.yml:
selectSuccess: has_layout: off
*** javascript can be written in multiselSuccess.php, or in another javascript file multiselSuccess.js: if written in a seperate file multiselSuccess.js, put it under PROJECT_NAME\web\js\, and in ...\apps\APPLICATION_NAME\config:
javascripts: [multiselSuccess.js ]
<script language="javascript"> <!--// /** * ajax no refresh cascading 2-level menu * */ function loadCity(url,CONTROL) { //load city var strTmp=provinceChanged(CONTROL); //result format: +provinceId or -provinceId var provChg=strTmp.split(","); url=url+"/id/"+provChg[0]; //provChg[0]: item value of first menu; url: /news/select/level/city/id/ItemValueOfFirstMenu new Ajax.Request(url, {asynchronous:true, evalScripts:false, onComplete:function(request, json){updateJSON(request,json,2,provChg[1])}}); return false; } var arrOldValues; function GetCurrentListValues(CONTROL){ var strValues = ""; strValues = GetSelectValues(CONTROL); arrOldValues = strValues.split(",") } function GetSelectValues(CONTROL){ var strTemp = ""; for(var i = 0;i < CONTROL.length;i++){ if(CONTROL.options[i].selected == true){ strTemp += "1,"; } else{ strTemp += "0,"; } } return strTemp; } function provinceChanged(CONTROL){ var strTemp = GetSelectValues(CONTROL); arrNewValues = strTemp.split(","); var sum=0; for(var i=0;i<arrNewValues.length-1;i++){ sum+=eval(arrNewValues[i]); if (sum >= 2){ //more than 1 are selected break; } if (arrNewValues[i] == 1){ //when this condition is met, sum must be 1 var selectedPos=i; } } if (sum==0){ //deselect all by ^Click; remove all from 2nd menu provChg=""+",--"; } else if (sum==1){ //only one selected, click or ctrl+click if (arrOldValues[selectedPos] == 0){ //if this selcted one wasn't selected before, just add; //at this point,arrNewValues[selectedPos] must be 1 removeOptionAll("city"); provChg=CONTROL.options[selectedPos].value+",+"; } else{ //if this selcted one was selected before, remove all others but keep selected of this one removeOptionAll("city"); provChg=CONTROL.options[selectedPos].value+",+"; //???to simplify, just add, previously selected may be lost } } else{ // for(var i=0;i<arrNewValues.length-1;i++){ if (arrNewValues[i] != arrOldValues[i]){ if (arrNewValues[i]==1){ //add a new province provChg=CONTROL.options[i].value+",+"; } else{ //remove a new province provChg=CONTROL.options[i].value+",-"; } } } } return provChg; } /** * ajax no refresh 2-level cascading menu * */ function addOption(objSelectNow,txt,val) { //using W3C syntax add Options for SELECT var objOption = document.createElement("OPTION"); objOption.text= txt; objOption.value=val; objSelectNow.options.add(objOption); } function addOptionGroup(selectId,optGroup) { var objSelect = document.getElementsByTagName("SELECT"); var objSelectNow = objSelect[selectId]; if (selectId=="province"){ objSelectNow.length = 1; } /// add Options group for (i=0; i<optGroup.length; i++) { addOption(objSelectNow, optGroup[i][1], optGroup[i][0]); } } function removeOptionGroup(selectId,optGroup) //optGroup: array of 2nd menu corresponding to deselected item of 1st menu; categoryId=>categoryName { var objSelect = document.getElementsByTagName("SELECT"); var objSelectNow = objSelect[selectId]; for (i=0;i<objSelectNow.length;i++){ if (objSelectNow.options[i].value==optGroup[0][0]){ //the first position to be removed var bgn=i; break; } } /// remove Options for (i=0;i<optGroup.length;i++){ objSelectNow.options.remove(bgn); } } function removeOptionAll(selectId) { var objSelect = document.getElementsByTagName("SELECT"); var objSelectNow = objSelect[selectId]; for (i=1;i<objSelectNow.options.length;){ objSelectNow.options.remove(1); } } function updateJSON(request, json,level,operation){ var responses = json; if (!json){ //if you don't use the json tips then evaluate the renderedText instead var responses = eval('(' + request.responseText + ')'); } if (level==1) //for 1st menu addOptionGroup("province",responses); else if (level==2){ //for 2nd menu if (operation=="+"){ addOptionGroup("city",responses); } else if (operation=="-"){ removeOptionGroup("city",responses); } else if (operation=="--"){ removeOptionAll("city"); } } } --> </script>
*** in actions.classs.php:
public function executeSelect(){ /** * ajax no refresh 2-level cascading menu back-end * */ //load data: $c=new Criteria(); $c->add(CategoryPeer::PARENT_ID,NULL); //get contents for 1st menu $categories=CategoryPeer::doSelect($c); $parent=""; if ($categories){ $i=0; $parent='['; foreach ($categories as $category){ $name=$category->getName(); $id=$category->getId(); $parent=$parent.'["'.$id.'","'.$name.'"],'; //format for 1st menu: [["1","German"],["2","France"],["3","Argentina"]] //retrive records whose parent_id is.. $c=new Criteria(); $c->add(CategoryPeer::PARENT_ID,$category->getId()); $categories_sub=CategoryPeer::doSelect($c); $city[$id]='['; //index of $city[] is category id; format of $city[]:[["48","Team1.Fr"],["49","Team2.Fr"],["50","Team3.Fr"],["51","Team4.Fr"],["52","Team5.Fr"]] foreach ($categories_sub as $category_sub){ $city[$id]=$city[$id].'["'.$category_sub->getId().'","'.$category_sub->getName().'"],'; } $city[$id]=rtrim($city[$id],","); $city[$id].=']'; $i++; } } $parent=rtrim($parent,","); $parent.=']'; $level=$this->getRequestParameter('level'); if($level=="province"||$level==""){ //level=province, output contents for first menu $this->output=$parent; } else if($level=="city"){ //level=city, output contents for second menu $id=$this->getRequestParameter('id'); $this->output=$city[$id]; } else{ //false $this->output="error when getting data"; } return sfView::SUCCESS; }
*** in selectSuccess.php:
<?php echo $output; ?>
Comments on this snippet
I don't get it...