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>
Related
Hello I want to achieve is to make "Select Form HTML" dynamic using JavaScript, What I mean by that is I expect every time I select a dropdown must be selected the value that I set to that tag.
The data from tag is from database I loop the data using php
ex. 1 src: Get selected value/text from Select on change
This example is 100% working correct but what I need is not to get the value but to assign like sample below next example 2
function handleSelectChange(event) {
var selectElement = event.target;
var value = selectElement.value;
alert(value);
}
<select onchange="handleSelectChange(event)">
<option value="1">one</option>
<option value="2">two</option>
</select>
ex 2 Those function will alert or run everytime I select/Click each of them F1 or F2
<table>
<tr>
<td onclick="myFunction1()">F1</td>
<td onclick="myFunction2()">F2</td>
</tr>
</table>
<script>
// Function 1 will run when I click the F1
function myFunction1() { alert('myFunction1'); }
// Function 2 will run when I click the F2
function myFunction2() { alert('myFunction2'); }
In example 1 As you can see the first example select form html will grab the the value of option tag, right?.
Now In example number 2 it will run the function when I click each of the F1 or F2
So what I need to the program is pass a value from my database to my javaScript function and run it like in alert or example 1 but in "Select tag" HTML version
ex. 3 Here's my query
<form action="">
<select name="customers" id="myId" class="form-control">
<option value="">Select a customer:</option>
<?php
$user_id = 1;
$sql = "SELECT * FROM `myTable` WHERE user_id = '$user_id' Order by create_at DESC";
$result = $mysqli->query($sql);
if ($result->num_rows > 0) {
// output data of each row
while($row = $result->fetch_assoc())
{ ?>
<!-- appsFunction('<?php echo $row['colName2']; ?>') << will be the value that should run in console.log -->
<option value="<?php echo $row['id']; ?>" onclick="appsFunction('<?php echo $row['colName2']; ?>')"><?php echo $row['colName1']; ?></option>
<?php }
} else { return false; }
?>
</select>
</form>
ex. 3 part 2 javascript
<script>
function appsFunction(passVar) {
colose.log(passVar);
}
</script>
As you can see in my first example a "Select Tag" HTML when I select dropdown it returns to me a value right?, in second example when I click F1 or F2 it will run the function then return alert, What I need here is When I select the dropdown it will accept the value I pass in function "appsFunction(passVar)" appsFunction('<?php echo $row['colName2']; ?>') from select tag which the value is from my database.. so I need help idea how to do that properly..
NOTE: The function must be run when I select the dropdown, the function must be accept the value I set which from my database it's like totally example number 2 but in Select tag HTML version not just text or html table.
Thanks in advance for solving my problem.
If you register an event handler on the select element itself that listens for change events you will be able to process the selected OPTION and access any value/property associated with it. You cannot assign an event handler directly to an OPTION element as you are trying to do here. You can add as many dataset attributes as you need to the OPTION elements however which you can easily access in the Javascript event handler.
If the value you pass into the SQL statement is to be dynamic ( from a GET or POST request most usually ) you really need to use a Prepared Statement to help mitigate SQL Injection attacks.
As your select menu is making use of only 3 columns from the mytable table you should limit the returned fields to those columns which in turns helps when using a Prepared Statement as you can easily assign the results as variables.
<form name='geronimo'>
<select name="customers" class="form-control">
<option selected hidden disabled>Select a customer:
<?php
$user_id = 1;
$sql="select `id`, `colName1`, `colName2` from `mytable` where user_id = ? order by create_at desc";
$stmt=$mysqli->prepare($sql);
$stmt->bind_param('s',$user_id);
$res=$stmt->execute();
if( $res ){
$stmt->bind_result($id,$col1,$col2);
while( $stmt->fetch() ){
printf('<option value="%s" data-col="%s">%s', $id, $col2, $col1 );
}
$stmt->free_result();
$stmt->close();
}
?>
</select>
</form>
<script>
document.forms.geronimo.customers.addEventListener('change',function(e){
let id=this.value;
let col2=this.dataset.col;
let col1=this.options[this.options.selectedIndex].text;
alert( id + ' ' + col2 + ' ' + col1 )
});
</script>
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.
I have the following drop down list and I would like to use it in several pages
<form action = "Unser Team.php" method = "post" name = "test">
<div class = "custom-select">
<div class = "select">
<select id ="custom-select" name = "custom-select" style="width:200px;" onchange = " this.form.submit();">
<option <?php if ($_POST['custom-select'] == 'Abteilung auswählen') print 'selected '; ?>value="Abteilung auswählen">Abteilung auswählen</option>
<option <?php if ($_POST['custom-select'] == 'TL-311') print 'selected '; ?> value="TL-311">TL-311</option>
<option <?php if ($_POST['custom-select'] == 'TP-271') print 'selected '; ?> value="TP-271">TP-271</option>
<option <?php if ($_POST['custom-select'] == 'TP-310') print 'selected '; ?> value="TP-310">TP-310</option>
<option <?php if ($_POST['custom-select'] == 'TP-270') print 'selected '; ?> value="TP-270">TP-270</option>
</select>
</div>
</div>
when the user selects an option I save it and I would like to see in the next page the option that has been selected is preselected and for its use the following code
in the home page:
var file;
function myFunction()
{
var mylist = document.getElementById("custom-select");
var mytext = mylist.options[mylist.selectedIndex].text;
window.file = mytext;
return window.file;
}
window.onload = function() {
var getInput = window.file;
localStorage.setItem("files",getInput);
}
for the other pages:
var myFile = localStorage.getItem("files");
window.onload = function() {
var ddValue= localStorage.getItem('files');
var dd= document.getElementById('custom-select');
for(var i = 0;i < dd.options.length;i++){
if(dd.options[i].value == ddValue ){
dd.options[i].selected = true;
break;
}
}
}
with this the selected value in the home page is preselected in the next pages but the problem is that with this code I can not change the selected value i the drop down list in other pages. can please somebody help me?
I am new in web programming.
First of all, welcome to Stackoverflow!
As pointed out by misorude, it might be wise to utilize the PHP session. When you switch from one page to another, without a form's submit, you will lose the $_POST variable. Which I believe is your problem here?
What happens when you you use sessions however, is that the client saves an ID as cookie. Every time it communicates with your server, it supplies this "session_id". This way the server will be able to grab the right session variables for that client.
Using sessions is fairly easy, call session_start(); at the top of your script. From there on you can use $_SESSION["var_name"] = "value";
For more details on the topic, you might want to read this article on w3Schools.
I need to get the value of the selected items on the first dropdown because on the second drop down the list that will be shown will depend on the value from the first drop down. Here's my coding. By the way I am using PHP.
In here I am displaying the list of region, then when region is already selected the province that are only under that region should be displayed in the second drop down.
First drop down:
<p><b>Region:</b>
<select class="w3-select" name="region" id="region_value"
onChange="myFunction()" required>
<option value="">--- Select Region ---</option>
<?php
$Region = $FormModel->RegionList();
foreach($Region as $RegionList) {
?>
<option id="option" value="<?php echo $RegionList['region_code']?>"><?php
echo $RegionList['region_name'] ?> </option> </p>
<?php } ?>
</select>
Second drop down:
<p><b>Province:</b>
<select class="w3-select" name="province" id="demo" required>
<option value="">--- Select Province ---</option>
<?php
$Province = $FormModel->ProvinceList();
foreach($Province as $ProvinceList) {
?>
<option value="<?php echo $ProvinceList['prov_code']?>"> <?php echo
$ProvinceList['prov_name'] ?> </option> </p>
<?php } ?>
</select>
I have a java script here getting the value of the selected items but I don't know how to pass it as an attribute to set the value as the region code.
I have a setter and getter in which I will set first the region code and in my query I am getting the value of the region code. But it's not working.
<script>
function myFunction() {
var x = document.getElementById("region_value").value;
$FormModel = new Form(x);
}
</script>
Here's my query where I get the list of province.
public function ProvinceList(){
$region = $this->getRegion();
$sql = "SELECT prov_code,psgc_prv, prov_name FROM lib_provinces WHERE
region_code='$region' ORDER BY prov_name";
$this->openDB();
$this->prepareQuery($sql);
$result = $this->executeQuery();
$recordlist = array();
$trash = array_pop($recordlist);
foreach($result as $i=>$row){
$row_data = array(
"prov_code"=>$row["prov_code"],
"psgc_prv"=>$row["psgc_prv"],
"prov_name"=>$row["prov_name"]
);
$recordlist[$i] = $row_data;
}
$this->closeDB();
return $recordlist;
}
I would be a great help if someone can answer me in this work around.Thanks!
If fetching all the provinces at once is an option you should do this via javascript.
You need to have all the items in a javascript variable and fill you select with these values.
OnChange you should filter the values using only the ones that applies
<script>
var optionItems;
var values = <?php echo json_encode($ProvinceList) ?>;
refreshOptions(values);
function refreshOptions(listItems, x) {
x = x || 0;
var sel = document.getElementById('demo');
sel.innerHTML = "";
for(var i = 0; i < listItems.length; i++) {
if ((x == 0) || (listItems[i].psgc_prv == x)) {
var opt = document.createElement('option');
opt.innerHTML = listItems[i].prov_name;
opt.value = listItems[i].prov_code;
sel.appendChild(opt);
}
}
}
function myFunction() {
var x = document.getElementById("region_value").value;
refreshOptions(values, x);
}
</script>
The second drop down would be just
<select class="w3-select" name="province" id="demo" required>
</select>
This implies stop filtering in the php query to the database
$sql = "SELECT prov_code,psgc_prv, prov_name FROM lib_provinces ORDER BY prov_name";
See this feedle with a working example (without the php)
https://fiddle.jshell.net/7k18euhw/3/
Edit since there is a new request of having another select level
If you have a lot o municipalities the approach of getting all of them in the same way as in Provinces is not a good idea. In that case you will need use ajax to fetch them.
This is what you need to do:
Having an accesible url that receives a province id as param and returns a json with the list of municipaties
Depending on how are you using php are many ways to do this for example if you have a framework you should have a controller is is just vainilla php should be something like this.
mun-list.php
echo json_encode($FormModel->ProvinceList($_GET['prov_id']));
get the onChange event for provinces (in the same way that you are doing with regions) and make a ajax call to the service that you jus created.
As already Kaja suggested you should use jquery to do this (http://jquery.com/)
function onProvChange() {
var prov_id = $("#prov_select").val();
$.ajax({
url: 'mun-list.php?prov_id='+prov_id,
type: 'GET',
success: function(data) {
//without a lot of detail this should populate in the way you did before
refreshMunicipalities(data);
}
});
}
You can do it without it but is harder, take a look at this post.How to make an AJAX call without jQuery?
By using Ajax you can fix. I have used jquery and php
For an example
$("#region_value").change(function() {
region_value= $("#region_value").val();
$.ajax({
url: 'ProvinceList URL',
data: { region_value: region_value },
type: 'POST',
success: function(data) {
var json = JSON.parse(data); \\ I have used JSON to parse data
$('#demo').empty(); // clear the current elements in select box
$('#demo').append('<option value=>Select province</option>');
for (row in json) {
$('#demo').append('<option value='+json[row].prov_code+'>'+json[row].prov_name+'</option>');
}
}
});
});
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>