TechnoDiver Posted October 2, 2021 Share Posted October 2, 2021 Hello Freaks and Geeks, I hope the weekend is seeing you all healthy and happy. I've been debating the proper implementation of a task. Hoping to find someone sitting in front of the computers feeling helpful. I believe I need to JS/AJAX for this, so I hope I'm in the right forum I have a form. In that form there's a <select> dropdown for a 'category' and one for 'type' of contribution. I'd like to make it so that the options available in the category dropdown are conditional on what was chosen in the type dropdown. So if I had the following PHP -> <?php <div class="form-group"> <label>Category</label> <select class="form-control" name="cat_id" id="category"> <?php if(!$this) { echo $post->selectCat('top'); } else { echo $post->selectCat('actor'); } ?> </select> </div> the "(!this)" in the if condition is meant only as a placeholder to keep the error notis away in my IDE and does nothing, nor was ever expected to. So in this implementation I thought to have 2 methods. Create a JS boolean function and either call selectCat('top') or selectCat('actor') depending on what the JS returned. I could also, though not sure how yet, call the PHP methods directly from the JS. What would be the best way to complete this task? The way I started with, the other way I mentioned, another way I haven't thought about?? All advice, input and criticism welcome.. TIA and the best to you all during these messy times Quote Link to comment https://forums.phpfreaks.com/topic/313850-display-options-conditionally-in-element/ Share on other sites More sharing options...
Solution Barand Posted October 2, 2021 Solution Share Posted October 2, 2021 This example will repopulate the category menu depending on the selected type <html> <head> <title>Sample</title> <script type="text/javascript" src="https://code.jquery.com/jquery-3.3.1.min.js"></script> <script type='text/javascript'> // array of categories for each type var cat_types = JSON.parse('{"A":{"1":"Cat 1","2":"Cat 2","3":"Cat 3"},"B":{"4":"Cat 4","5":"Cat 5","6":"Cat 6"},"C":{"7":"Cat 7","8":"Cat 8","9":"Cat 9"}}'); $().ready(function() { // populate type menu $.each(cat_types, function(k,v) { $("#type").append($("<option>", {"val":k, "text":k})) }) // when type selected, populate cat menu $("#type").change( function() { $("#cat").html("<option value=''> - select category -</option"); var type = $(this).val() $.each(cat_types[type], function(k, v) { $("#cat").append($("<option>", {"val":k, "text":v})) }) }) }) </script> <style type='text/css'> </style> </head> <body> <form> Type <select name='type' id='type'> <option value=""> - select type -</option> </select> <br><br> Cat <select name='cat' id='cat'></select><br> </form> </body> </html> 1 Quote Link to comment https://forums.phpfreaks.com/topic/313850-display-options-conditionally-in-element/#findComment-1590618 Share on other sites More sharing options...
TechnoDiver Posted October 2, 2021 Author Share Posted October 2, 2021 Hay, Barand, Thanks for your answer. I'm playing around with it now. I've got it populating correctly in the actual project but realize I'll have an issue soon. The <select> menu for the categories was originally populated by a PHP method which used the cat id from the database as the value in the <option> element. I was the method I was calling in the OP is -> <?php public function selectCat($type) { $table = "categories"; $field = "type"; // $type = "top"; $rule = "ORDER BY id ASC"; $query = $this->_db->get($table, array($field, "=", $type), $rule); $this->_data = $query->all(); $str = ""; foreach($this->_data as $obj) { $cat_id = $obj->id; $category = $obj->category; $title = ucwords($category); $str .= " <option value='$cat_id'>$title</option> "; } return $str; } So I'm thinking I'll rewrite this method to return your JSON.parse($string) Quote '{"A":{"1":"Cat 1","2":"Cat 2","3":"Cat 3"},"B":{"4":"Cat 4","5":"Cat 5","6":"Cat 6"},"C":{"7":"Cat 7","8":"Cat 8","9":"Cat 9"}}' replacing "A", "B", "C" etc with the values from the type field; "1", "2", "3" etc keys with cat ids and "Cat 1", "Cat 2", "Cat 3" etc with the category names... you get the picture. In your very experienced opinion is this the best way to do this or would you suggest a different way? Quote Link to comment https://forums.phpfreaks.com/topic/313850-display-options-conditionally-in-element/#findComment-1590630 Share on other sites More sharing options...
Barand Posted October 3, 2021 Share Posted October 3, 2021 It's one way, and if I didn't have a database, it's as good a way as any. If I did have a DB I'd do it differently. But given no information to the contrary, I did it that way. A DB solution would use elements of that code, such as building the category menu. Quote Link to comment https://forums.phpfreaks.com/topic/313850-display-options-conditionally-in-element/#findComment-1590631 Share on other sites More sharing options...
TechnoDiver Posted October 3, 2021 Author Share Posted October 3, 2021 14 minutes ago, Barand said: It's one way, and if I didn't have a database, it's as good a way as any. If I did have a DB I'd do it differently. But given no information to the contrary, I did it that way. A DB solution would use elements of that code, such as building the category menu. Ok, thank you. I'm going to work on creating that string in a PHP method, I'm part way there as I type. I hope you can respond again if I have to readdress this issue lol Thanks again Quote Link to comment https://forums.phpfreaks.com/topic/313850-display-options-conditionally-in-element/#findComment-1590632 Share on other sites More sharing options...
Barand Posted October 3, 2021 Share Posted October 3, 2021 Using a DB, I'd do it this way (tables used are from my SQL tutorial). Select a house name and the pupils menu lists pupils from that house. <?php const HOST = 'localhost'; const USERNAME = '????'; const PASSWORD = '????'; const DATABASE = 'jointute'; // default db $db = pdoConnect(); //============================================================================== // HANDLE AJAX CALLS // if (isset($_GET['ajax'])) { if ($_GET['ajax']=='pupilopts') { exit( json_encode(pupilOptions($db, $_GET['hid']))); } exit('INVALID REQUEST'); } //============================================================================== function houseOptions($db) { $opts = "<option value=''>- select house -</option>\n"; $res = $db->query("SELECT houseID , house_name FROM house ORDER BY house_name "); foreach ($res as $r) { $opts .= "<option value='{$r['houseID']}'>{$r['house_name']}</option>\n"; } return $opts; } function pupilOptions($db, $hid) { $opts = []; $res = $db->prepare("SELECT pupilID , CONCAT(lname, ', ', fname) as name FROM pupil WHERE houseID = ? ORDER BY lname, fname "); $res->execute([$hid]); $pups = $res->fetchAll(); $opts = array_column($pups, 'name', 'pupilID'); sort($opts); return $opts; } function pdoConnect($dbname=DATABASE) { $db = new PDO("mysql:host=".HOST.";dbname=$dbname;charset=utf8",USERNAME,PASSWORD); $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $db->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); $db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); return $db; } ?> <!DOCTYPE html> <html lang='en'> <head> <title>Example</title> <meta charset='utf-8'> <script type="text/javascript" src="https://code.jquery.com/jquery-3.3.1.min.js"></script> <script type='text/javascript'> $().ready( function() { $("#houses").change( function() { var hid = $(this).val() $.get( "", // specify processing file on server (in this case it's same file) {"ajax":"pupilopts", "hid":hid}, // data to send in request function(resp) { // handle the response $("#pupils").html("<option value=''> - select pupil -</option"); $.each(resp, function(k, v) { $("#pupils").append($("<option>", {"val":k, "text":v})) }) }, "JSON" // response type ) }) }) </script> <style type='text/css'> body { font-family: calibri, sans-serif; font-size: 12pt; } div { margin: 16px; padding: 8px; border: 1px solid gray; } label { display: inline-block; background-color: black; color: white; width: 120px; padding: 8px; margin: 1px 8px; } </style> </head> <body> <div> <label>House</label> <select id="houses" > <?= houseOptions($db) ?> </select> </div> <div> <label>Pupil</label> <select id="pupils" > <!-- pupil options --> </select> </div> </body> </html> 2 Quote Link to comment https://forums.phpfreaks.com/topic/313850-display-options-conditionally-in-element/#findComment-1590634 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.