One way I often handle this is to just POST the form when the first selection is made. I do this by adding this small bit of code to the first SELECT tag.
onchange="this.form.submit()"
I build an array with categories and subcategories, so the Category is the Primary KEY followed by an array holding the Subcategories under this Category. It would look something like this.
Array
(
[a] => Array
(
[a1] => a1
[a2] => a2
[a3] => a3
)
[b] => Array
(
[b1] => b1
[b2] => b2
[b3] => b3
)
)
I would usually build this array within a WHILE query result loop something like this.
$select_options[$row['category']][$row['subcategory_id']] = $row['subcategoryname'];
You can them loop through the array while building the form and check for $_POST['category_id']
and if “NOT EMPTY” and “ARRAY KEY EXISTS” you can then loop through these Subcategories.
You’ll want to have a check for POST to set the the selected option as selected so it is still selected as the page reloads.
$selected_cat = (!empty($_POST['category_id']) && $_POST['category_id'] == $category ? ' selected="selected"' : '');
<div class="form-group">
<label class="col-md-12" for="category_id">{{LANG category}}</label>
<div class="col-md-12">
<select name="category_id" id="category_id" class="form-control" onchange="this.form.submit()">
<option value="Select">Select</option>
<?php
if(!empty($select_options)):
foreach($select_options as $category => $subcategories):
$selected_cat = (!empty($_POST['category_id']) && $_POST['category_id'] == $category ? ' selected="selected"' : '');
echo '<option value="'.$category.'"'.$selected_cat.'>'.$category.'</option>'."\r";
endforeach;
endif;
?>
</select>
</div>
<label class="col-md-12" for="subcategory_id">{{SUB category}}</label>
<div class="col-md-12">
<select name="subcategory_id" id="subcategory_id" class="form-control">
<option value="Select">Select</option>
<?php
if(!empty($select_options) && !empty($_POST['category_id']) && array_key_exists($_POST['category_id'],$select_options)):
foreach($select_options[$_POST['category_id']] as $subcategory_id => $subcategoryname):
echo '<option value="'.$subcategory_id.'">'.$subcategoryname.'</option>'."\r";
endforeach;
endif;
?>
</select>
</div>
</div>
If you really need both IDs and Names for both Categories and Subcategories you can ADD these hard coded Keys to your array build and adjust your form building to accommodate.
Array
(
[a] => Array
(
[name] => category a
[subcategories] => Array
(
[a1] => subcategory a1
[a2] => subcategory a2
[a3] => subcategory a3
)
)
[b] => Array
(
[name] => category b
[subcategories] => Array
(
[b1] => subcategory b1
[b2] => subcategory b2
[b3] => subcategory b3
)
)
)
You would build this array using 2 lines like this.
$select_options2[$row['category_id']]['name'] = $row['category'];
$select_options2[$row['category_id']]['subcategories'][$row['subcategory_id']] = $row['subcategoryname'];
The form build would then use these ‘name’ and ‘subcategories’ keys.
<div class="form-group">
<label class="col-md-12" for="category_id">{{LANG category}}</label>
<div class="col-md-12">
<select name="category_id" id="category_id" class="form-control" onchange="this.form.submit()">
<option value="Select">Select</option>
<?php
if(!empty($select_options2)):
foreach($select_options2 as $category_id => $subcategories):
$selected_cat = (!empty($_POST['category_id']) && $_POST['category_id'] == $category_id ? ' selected="selected"' : '');
echo '<option value="'.$category_id.'"'.$selected_cat.'>'.$select_options2[$category_id]['name'].'</option>'."\r";
endforeach;
endif;
?>
</select>
</div>
<label class="col-md-12" for="subcategory_id">{{SUB category}}</label>
<div class="col-md-12">
<select name="subcategory_id" id="subcategory_id" class="form-control">
<option value="Select">Select</option>
<?php
if(!empty($select_options2) && !empty($_POST['category_id']) && array_key_exists($_POST['category_id'],$select_options2)):
foreach($select_options2[$_POST['category_id']]['subcategories'] as $subcategory_id => $subcategoryname):
echo '<option value="'.$subcategory_id.'">'.$subcategoryname.'</option>'."\r";
endforeach;
endif;
?>
</select>
</div>
</div>
There are other ways to do this with jQuey and hiding options etc but I find this works well in a lot of cases.