Reputation: 687
I am trying to populate the dropdown menu based on the selection of the first menu. using the code below it will just make the next dropdown to be empty
$(\".category_id\").change(function(){
$(\"#account_id > option\").remove();
$(\"#item_name_id > option\").remove();
var category_id={'category_id':$(this).val()};
$.ajax({
type: \"POST\",
url: 'getCategory1/',
dataType: \"json\",
data: category_id,
success: function(category_ids){
// category_ids = {"0":"Choose Account Name","2":"OfficeEquipment","3":"IT Equipment"}
$.each(category_ids,function(account_id,name){
var opt = $('<option />');
opt.val(account_id);
opt.text(name);
$(this).closest('td').next().find('select').append(opt);
});
}
});
});
The controller function I used:
public function actionGetCategory1(){
//Get all the sub categories a the main category
$cat_id = $_POST['category_id'];
$subCategory = Item::model()->getCategory1($cat_id);
echo(json_encode($subCategory));
}
The model function
public function getCategory1($cat_id){
$where = "WHERE category_id = $cat_id";
$select = "SELECT * FROM tbl_account $where";
$query = Yii::app()->db->createCommand($select)->queryAll();
$subCat = array();
$subCat[0] = "Choose Account Name";
if($query){
foreach($query as $row){
$subCat[$row['account_id']] = $row['account_name'];
}
return $subCat;
}
else{ return FALSE; }
}
The data to be loop in the $.each will be coming form the controller in json format. I used var_dump to display i.
string(189) "{"0":"Choose Account Name","2":"Information and Communication Technology Equipment","3":"Office Equipment","4":"Furniture and Fixtures","5":"Communication Equipment","6":"Other Equipments"}"
Upvotes: 2
Views: 253
Reputation: 1484
Should be something like this. You will need to use a better selector for getting your < select > tag.
$.each(category_ids,function(account_id,name){
var x = document.createElement('option');
x.setAttribute('value', account_id);
var y = document.createTextNode(name);
$(x).append(y);
$('#selectId').append(x)
});
EDIT After further discussion this looks like a better answer:
$(\".category_id\").change(function(){
var _this = this;
$(\"#account_id > option\").remove();
$(\"#item_name_id > option\").remove();
var category_id={'category_id':$(this).val()};
$.ajax({
type: \"POST\",
url: 'getCategory1/',
dataType: \"json\",
data: category_id,
success: function(category_ids){
// category_ids = {"0":"Choose Account Name","2":"OfficeEquipment","3":"IT Equipment"}
$.each(category_ids,function(account_id,name){
var opt = $('<option />');
opt.val(account_id);
opt.text(name);
$(_this).closest('td').next().find('select').append(opt);
});
}
});
});
This is something that trips up a lot of people. Here is a good quick read on "this" scope that should make this clearer to understand.http://javascriptplayground.com/blog/2012/04/javascript-variable-scope-this/
Upvotes: 1
Reputation: 4064
It looks like you want to build up cascading dropdown menus. A user has to select the category first, account name next, and so on... am I right?
If that's what you want. Your code is not right unless those cascading dropdownmenus are going to have only one option each.
$.ajax({
type: \"POST\",
url: 'getCategory1/',
dataType: \"json\",
data: category_id,
success: function(category_ids){
// assume that your category_ids will be a string array.
// ex: ["#cate01", "#cate02", "#cate03", "#cate04", "#cate05"]
$.each(category_ids, function(account_id,name) {
// first loop,
// be account_id = 0, name = "#cate01"
var opt = $('<option />');
opt.val(account_id);
opt.text(name);
// <option value="0">#cate01</option> is created.
// this will be "#cate01", it is the same with the name value.
// actually, you don't need to use this keyword here.
$(this).closest('td').next().find('select').append(opt);
// it will look up #cate01 and find its parent, its td and
// moves to td right next to it, and finally settles on the select element inside it.
});
}
});
With this code, the options will not stack up on a select element because the target selecbox keeps changing during the whole each loop. I suspect that there's more on category_ids
. But even if `category_ids consist of more than a string array, it's not the way to do it. I feel uncertain to continue my answer, because it seems that you are smart enough to know already how to tweak this kind of code.
Anyway..
$.ajax({
type: \"POST\",
url: 'getCategory1/',
dataType: \"json\",
data: category_id,
success: function(category_ids){
$.each(category_ids, function(account_id,name) {
// you need a list of option data here,
// fetching it though AJAX or something ( it's your call )
// Let's say you get a set of option data like this at this point.
/*
optData : {
cate01 : ["option01", "option02", "option03" ··· , "option10" ]
}
*/
// I'm declaring this variable for improving readability.
var targetDropdown = $(name).closest('td').next().find('select');
$.each(optData.cate01, function(val, optionName) {
var opt = $('<option />');
opt.val(val);
opt.text(optionName).appendTo(targetDropdown);
}
});
}
});
FYI
I don't know what kind of data you are trying to put into each select boxes and what kind of data you actually have, but the point is that your current code is not able to pile up the options on a single select box.
I just suggested the way to acheive the goal. If you provide me the exact set of data, I mean the options, I can help you more precisely. I guess this is enough for you by the way.
Upvotes: 1
Reputation: 3305
Try something like this,
$.each(category_ids,function(account_id,name){
var opt = $('<option />');
opt.val(account_id);
opt.text(name);
$(this).closest('td').next().find('select').append(opt);
});
$(this).closest('td').next().find('select option:first').attr('selected', 'selected');
Upvotes: 1