PHP dynamic options in select inside html - javascript

I have categories and sub-category taken from API json file, the API returns category objects with "parent" attribute, main category objects have parent attribute equals to 0, and the sub-category objects have the parent attribute equals to the main categories id.
the code of main categories is `
<label for="Category"> Main Category</label>
<select id="category">
<?php foreach ($obj as $category):?>
<?php if($category->parent==0) : ?>
<option value=<?=$category->id?>><?=$category->name?></option>
<?php endif; ?>
<?php endforeach; ?>
</select>
`
$obj is equals to the json decode taken from api.
How I can write the code of the sub-categories? I want make options where subcategory->parent equals to the id of the selected category"category->id" chosen above

So $obj is a list of all categories. Some are parents and some are children (subcategories)?
Is there a way to nest the categories on the API side so that it returns the children as a var on the parent object, or create a separate object for the children that you can access for each parent?
If those aren't an option, either format the categories prior to creating the select field so that you can more cleanly generate the children, or add a nested loop inside your current foreach that checks if a category is a child of the current category.
This is ugly and I haven't tested it, but you might be able to do something like this:
foreach ($obj as $category) {
if ($category->parent==0) {
echo "<option value='" . $category->id . "'>$category->name</option>"
foreach ($obj as $subCategory) {
if ($subCategory->parent != 0 && $subcategory->parent == $category->id) {
echo "<option value='" . $subcategory->id . "'>$subcategory->name</option>"
}
}
}
}

Related

Change select option with javascript based on PHP variable

I've read multiple threads here and still can't find a good answer for my question, so I'm sorry for this silly question but there are no words for how bad I am with Javascript.
So I'm currently trying to change the select options on a 2nd select tag based on the selected option from the first one.
<select name="category" id="category">
<option value="" disabled selected value>Cat1</option>
<?php
$stmt = $conn->query("SELECT * FROM cats");
while($row = $stmt->fetch()) {
echo "<option value='".$row['name']."'>".$row['text']."</option>";
}
?>
</select>
</div>
</div>
<div class="div3">
<div class="div4">
<label for="test">cat2</label>
</div>
<div class="div7">
<select name="sub" id="sub">
<?php
$stmt = $conn->query("SELECT * FROM cats WHERE name = $cat");
while($row = $stmt->fetch()) {
echo "<option value='".$row['subname']."'>".$row['subtext']."</option>";
}
?>
</select>
</div>
So I know that I somehow need to call a JavaScript with "onchange" which will get the $cat variable and then pass back the information from the SQL table. But I have absolute no idea how I can do this..
I don't wanna use either form or Ajax. If this is possible with pure Javascript, I would be really happy..
Then of course I don't expect you to solve the entire issue for me but I would be glad if someone could point me in the right direction (Don't think too much about the prepared statements with $stmt, this is just a first test)
If you don't want to use Ajax, you need to get all data for each main category and save them all into a pieced-together JS array.
Something like
$jstext = ''; //our pieced-together array definition for JS
$stmt = $conn->query("SELECT * FROM cats");
while($row = $stmt->fetch()) {
echo "<option value='".$row['name']."'>".$row['text']."</option>";
$stmt2 = $conn->query("SELECT * FROM cats WHERE name = {$row['name']}");
$jstext .= "subcategories['".$row['name']."'] = '";
$tmp = '';
while($row2 = $stmt2->fetch()) {
$tmp .= '<option>'.$row2['name'].'</option>'; //generate html for each subcategory
}
}
$jstext .= $tmp."';\r\n"; //add subcategories to array index, add line break
Then in your <script> tag, add:
<script>
var subcategories;
<?php echo $jstext ?>
</script>
This should generate an array with an index of each main category and the content is the respective sub-categories.
Example Output:
<script>
var subcategories;
subcategories['maincat1'] = '<option>subcat1</option><option>subcat3</option>';
subcategories['maincat2'] = '<option>subcat4</option><option>subcat6</option>';
</script>
Now you just need to replace the innerHTML of your "sub" select when the "category" select fires an onchange event.

Arrays from 2 MySQL queries to be used on 2 select using javascript

I already have the first HTML select populated by the result of the first query.
Now what I need or want to do is put the results from the second query on a Json file (maybe) or an XML (don't care) and then using javascript (not jquery) populate the second HTML select based on the first HTML select option selected.
This is my current code:
<?php
# Get all brands id and brand name to populate brands HTML select 1
$q1=mysqli_query($conect,"SELECT id, brand FROM brands ORDER BY brand ASC");
$brand_select="";
while($brand=mysqli_fetch_assoc($q1)){
$brand_select=$brand_select.'<option value="'. $brand['id'] .'">'. $brand['brand'] .'</option>';
}
# Get all models id and model name to populate models HTML select based on the brands ID from html select 1
$q2=mysqli_query($conect,"SELECT id, brand_id, model FROM models ORDER BY model ASC");
$models_select="";
while($model=mysqli_fetch_assoc($q2)){
$models_select=$models_select.'<option value="'. $model['id'] .'">'. $model['modelo'] .'</option>';
}
?>
<select name="brand" id="brands" class="s1" onchange="populate(this.id,'modelos')">
<option value="">Select Brand</option>
<?= $brand_select ?>
</select>
<br>
<select name="models" id="models" class="s1">
<option value="">Select Model</option>
<?= $models_select ?>
</select>
The id from the brands table is related to the brand_id on the models table for relational purposes.
The brands HTML select are displaying the brands just perfect as it should and the options as is, are showing the full list of models of all brands.
I'm sure that an onChange event should be used on the first HTML select, that is as far as I can get without Javascript.
Of course I've looked other Similar Questions but can't find one that matches my idea about this.
Any suggestion from You the real genius :-)
Here is one way of doing it. PHP is used to produce an array of model options sorted by brand - this makes things easier for the JavaScript. An event listener is added to the brands select which updates the models select appropriately.
PHP
$q1=mysqli_query($conect,"SELECT id, brand FROM brands ORDER BY brand ASC");
$brand_select="";
while($brand=mysqli_fetch_assoc($q1)){
$brand_select=$brand_select.'<option value="'. $brand['id'] .'">'. $brand['brand'] .'</option>';
}
# Get all models id and model name to populate models HTML select based on the brands ID from html select 1
$q2=mysqli_query($conect,"SELECT id, brand_id, model FROM models ORDER BY brand_id, model ASC");
$models_select="";
while($model=mysqli_fetch_assoc($q2)){
$models_select[$model['brand_id']][] = '<option value="'. $model['id'] .'">'. $model['model'] .'</option>';
}
echo "<script type=\"text/javascript\">\nvar models = {};\n";
foreach ($models_select as $b => $m) {
echo "models['$b'] = '" . implode('', $m) . "';\n";
}
echo '</script>';
Javascript
window.addEventListener('load', function () {
document.getElementById('brands').addEventListener('change', function () {
if (this.value != '') {
document.getElementById('models').innerHTML = '<option value="">Select Model</option>' + models[this.value];
}
});
});
HTML
<select name="brand" id="brands" class="s1">
<option value="">Select Brand</option>
<?= $brand_select ?>
</select>
<br>
<select name="models" id="models" class="s1">
<option value="">Select Model</option>
</select>
Easy solution is:
Create a php array with all the models that you then write into a javascript array:
$models = [];
while($model=mysqli_fetch_assoc($q2)){
$models_select=$models_select.'<option value="'. $model['id'] .'">'. $model['modelo'] .'</option>';
$models[] = $model;
}
?>
<script>
var moduls = <?php echo json_encode($models); ?> // this makes a JSON string out of the php array, which js can interpret as javascript array/object.
function populateModels(brandId) {
// TODO:
// filter the models that have the right brandId
// generate the options of the fitting models
// write the options to select #models
}
</script>
A better (because you don't have massive data lying around that you possibly don't use) solution would be to use ajax, as you can find in many questions/answers for "Dynamic selects"

multiselect filter using javascript

I have option tag and it works fine with single filter and I want to make it multi select....following is my code:-
$('#version_no').change(function () {
var version_no = $('#version_no').val();
if (version_no != null) {
showAll(version_no);
} else {
showAll();
}
});
showAll() is a function that returns data after filtering. if no filter is selected then everything is shown.
following is the view code:-
<select multiple="multiple" style="margin-top:15px;" name="version_no" id="version_no">
<option value="">Select Version No</option>
<?php if (count($get_version_no)): ?>
<?php foreach ($get_version_no as $version): ?>
<option value=<?php echo $version->version_no; ?>><?php echo $version->version_no; ?></option>
<?php endforeach; ?>
<?php else: ?>
<?php endif; ?>
$get_version_no is generating the dropdown value like 1,1.1,1.2 etc.....
SO I want to make it multi select any help will be appreciated. I'm using codeigniter 3.
You need to make version_no array in name for multiple select
<select multiple="multiple" style="margin-top:15px;" name="version_no[]" id="version_no">
In jquery
var version_no= [];
$.each($("#version_no option:selected"), function(){
version_no.push($(this).val());
});
var version = version_no.join(", ");
version will be the string with all selected values seperated by comma
Your Javascript code just needs to be refactored so that version_no is an array instead of a single value. You can use the ':selected' selector to get the selected options.
(see https://api.jquery.com/selected-selector/)
You will also need to refactor the showAll() function so that it parses an array instead of a single value. I would also have the showAll() function perform null checks instead of doing that if...then/else.

Sending a different column instead of this.value in php to javascript function (Query)

I've made a select list and filled it with info from a DB. Now i'm trying to make it so whenever you select a different item in the list it calls a javascript function that checks if the selected item/entity (or whatever it's supposed to be called) has a comment or not, and reacts accordingly.
So far I have this, which does work, and only shows the paragraph if the ID of the selected item sent is over 5. However, I don't know how to send the comment that is in the query as the parameter, so that it can then check the length and react.
This is what I have so far:
// Create connection
$conn = mysql_connect("localhost", "root", "admin")
or die("Could not connect: " . mysql_error());
// Selecting the DB
mysql_select_db("tickets") or die("Could not connect: " . mysql_error());
$query = mysql_query("SELECT * FROM tickets order by ID");
$numrows = mysql_num_rows($query);
//I want to change this.value to be the selected item's comment
echo '<select name="Tick" size='.$numrows.' onChange="checkSelectedValue(this.value)">';
while ($row = mysql_fetch_array($query)) {
echo '<option value="'.$row['ID'].'">Comment: '.$row['comments'].' </option>';
}
echo '</select>';
echo '<p id="commentNotifier" style='display:none;'> Selected item has a comment. </p>';
How would I modify this so the parameter of onChange="checkSelectedValue(this.value)" would be the selected item's comment instead of this.value which is, in my case, the ID.
Note that I don't want to change the value of each option to be comments instead of ID.
This is the javascript functon that works with the ID sent, and if it is over 5 it shows the paragraph that's otherwise hidden:
<script type="text/javascript">
function checkSelectedValue(val){
var element=document.getElementById('commentNotifier');
if(val > 5) //I would change this to val.length > 0 to check if comments exists or not
element.style.display='block';
else
element.style.display='none';
}
</script>
Pretty straightforward function. Cheers in advance!
In a pure javascript solution the best answer of this stack would helps : Get selected value in dropdown list using JavaScript?
You can use this to select the comment from the dropdown:
$('#mySelect').find(":selected").text()
But it requires you to use jQuery
Working fiddle: https://jsfiddle.net/b1qjw214/
In pure javascript:
function findElem() {
var elem = document.getElementById("mySelect");
var elemTxt = elem.options[elem.selectedIndex].text;
}
Fiddle: https://jsfiddle.net/dsy3tgmy/
Use data-* attributes and instead of this.value, pass this as argument so that you can deal with element and all its attributes.
Element.dataset returns the object of all the data-* attributes of the element
Try this:
function checkSelectedValue(elem) {
console.log('Value: ' + elem.value);
console.log('Comment: ' + elem.options[elem.selectedIndex].dataset.comment);
}
<script src="http://gh-canon.github.io/stack-snippet-console/console.min.js"></script>
<select onChange="checkSelectedValue(this)">
<option data-comment='Comment goes here' value="volvo">Volvo</option>
<option data-comment='Comment goes here' value="saab">Saab</option>
<option data-comment='Comment goes here' value="mercedes">Mercedes</option>
<option data-comment='Comment goes here' value="audi">Audi</option>
</select>

Multiple dependent dynamic select boxes in form

There is a model A that has_many B and a form where one can create a new A and
add/remove Bs. I.e. there is a link Add new B that runs some Javascript to insert another partial where one fills in values for B. All works fine.
The problem
Specifying a B is done through selecting the values using a couple of select
boxes. The problem is that depending on a value selected in one, the
collections used in the other selects should be scoped to only show relevant options. It's the classic case
with dynamic select boxes (think country - state select boxes), only with more
select boxes and I'd like all the select boxes to appear initially, so the
user can start from anywhere (select state first and country select box
narrows down its collection to the ones that can be chosen for that state).
Current approach
The Bs are rendered in a table, one B per row and I was thinking that I could
use AJAX to replace the table row (content) after fetching the new collections
from the server. This obviously needs a couple of things in place.
tr tag must have a unique id attribute, so replace_html can be used.
need to have a trigger on change for each select box
need to pass all select boxes' values (for that row) to the server
I'm stuck here, because of the following:
adding a B needs to have something unique to identify the tr tag as well
as all the selects on that row. I can use Time.now.to_i but that won't
work for the Javascript run by the link to add a new B because that will
hardcode the value and all use the same.
not sure if I should go with observe_field or a remote call in the select
form field helper.
how to pick up the values of all selects in one row and pass that remotely
to the server when triggered?
The project I'm working on is Rails 1.2.3 and uses Prototype. Please feel free to post "newer" solutions too, because I'm curious to see different solutions.
Any help on this is highly appreciated. Thanks in advance!
This doesn't answer your entire question but it might get you started. I handle it like this... this is for playlist entry, where the user can add new forms in a div #playlist-entry, and each form is .new_song_form with a hidden field .form_num (which I use in the create.js.erb file to tell it which form to hide/warn of validation errors, which isn't really relevant for you I guess).
var form_counter = 1;
function addSongFields() {
playlistEntry = $('#playlist-entry');
playlistEntry.append("<%= escape_javascript(render :partial => 'playlist_entry_form', :locals => { :schedule_event => #schedule_event, :playlist_entry => PlaylistEntry.new }) %>");
playlistEntry.find('.new_song_form:last').attr('id', 'new_song_form_'+form_counter);
playlistEntry.find('.form_num:last').val('new_song_form_'+form_counter);
}
$(document).ready(function() {
$('#add-song-link').click(function(event) {
event.preventDefault();
addSongFields();
form_counter++;
});
});
This form is a little different because there's no one "major" form to submit, it's a bunch of forms all on one page, but this basic idea might help you. It's not perfect programming - for example I should be passing form_counter as an argument to the function... but it works perfectly.
Dynamic Dependent Select Boxes
How to create dependent drop down list in php? I have searched a lot then implemented this one. This is created using HTML, JS, PHP simple dependent drop down boxes.
I knew it was possible to create a dynamic dependent drop down form using PHP, MySQL, and JavaScript,
but I had never had an excuse to use one before I need to teach to my students.
<?php
$region = $country = $state = $city = null; //declare vars
$conn = mysql_connect('localhost', 'username', 'password');
$db = mysql_select_db('selects',$conn);
if(isset($_GET["region"]) && is_numeric($_GET["region"]))
{
$region = $_GET["region"];
}
if(isset($_GET["country"]) && is_numeric($_GET["country"]))
{
$country = $_GET["country"];
}
if(isset($_GET["state"]) && is_numeric($_GET["state"]))
{
$state = $_GET["state"];
}
if(isset($_GET["city"]) && is_numeric($_GET["city"]))
{
$city = $_GET["city"];
}
?>
<script language="JavaScript">
function autoSubmit()
{
var formObject = document.forms['theForm'];
formObject.submit();
}
</script>
<form name="theForm" method="get">
<!-- REGION SELECTION -->
<select name="region" onChange="autoSubmit();">
<option value="null"></option>
<option VALUE="1" <?php if($region == 1) echo " selected"; ?>>East</option>
<option VALUE="2" <?php if($region == 2) echo " selected"; ?>>West</option>
</select>
<br><br>
<!-- COUNTRY SELECTION BASED ON REGION VALUE -->
<?php
if($region != null && is_numeric($region))
{
?>
<select name="country" onChange="autoSubmit();">
<option VALUE="null"></option>
<?php
//POPULATE DROP DOWN MENU WITH COUNTRIES FROM A GIVEN REGION
$sql = "SELECT COUN_ID, COUN_NAME FROM COUNTRY WHERE RE_ID = $region";
$countries = mysql_query($sql,$conn);
while($row = mysql_fetch_array($countries))
{
echo ("<option VALUE=\"$row[COUN_ID]\" " . ($country == $row["COUN_ID"] ? " selected" : "") . ">$row[COUN_NAME]</option>");
}
?>
</select>
<?php
}
?>
<br><br>
<?php
if($country != null && is_numeric($country) && $region != null)
{
?>
<select name="state" onChange="autoSubmit();">
<option VALUE="null"></option>
<?php
//POPULATE DROP DOWN MENU WITH STATES FROM A GIVEN REGION, COUNTRY
$sql = "SELECT STAT_ID, STAT_NAME FROM states WHERE COUN_ID = $country ";
$states = mysql_query($sql,$conn);
while($row = mysql_fetch_array($states))
{
echo ("<option VALUE=\"$row[STAT_ID]\" " . ($state == $row["STAT_ID"] ? " selected" : "") . ">$row[STAT_NAME]</option>");
}
?>
</select>
<?php
}
?>
<br><br>
<?php
if($state != null && is_numeric($state) && $region != null && $country != null)
{
?>
<select name="city" onChange="autoSubmit();">
<option VALUE="null"></option>
<?php
//POPULATE DROP DOWN MENU WITH CITIES FROM A GIVEN REGION, COUNTRY, STATE
$sql = "SELECT CIT_ID, CITY_NAME FROM CITY WHERE STAT_ID = $state ";
$cities = mysql_query($sql,$conn);
while($row = mysql_fetch_array($cities))
{
echo ("<option VALUE=\"$row[CIT_ID]\" " . ($city == $row["CIT_ID"] ? " selected" : "") . ">$row[CITY_NAME]</option>");
}
?>
</select>
<?php
}
?>
</form>

Categories

Resources