Forum Moderators: open

Message Too Old, No Replies

Populate pull-down menu based on current selection?

         

chutes

11:07 am on Jul 1, 2010 (gmt 0)

10+ Year Member



What would I have to do to achieve this effect; is it even possible?


Once I select supplier id 24, all other similarly-named SELECT fields should be populated with 24. (They all have the same ID, only the suffix/number is different.)


Form name: new_pro
Select Name: supplier[24] (24 is a varying number that's populated by a database)


Example (the source of the menu is written in php, if that makes any difference):
<form name="new_pro" method="post" onsubmit="return validate_form(this)" method="post" enctype="multipart/form-data">

<select name="supplier[3]">
<option value="" selected="selected">--none--</option><option value="23">23</option>
<option value="24">24</option></select>

<select name="supplier[4]">
<option value="" selected="selected">--none--</option><option value="23">23</option>
<option value="24">24</option></select>

It is the "supplier" field that I would like to have all turn to "24" once the 24 option is selected on a "select all" pull-down at the top of the menu, if possible.


Note: onsubmit="return validate_form(this) is from a different javascript function that's already in operation.


I've been battling with this script all evening and I can't seem to get it to work properly, any suggestions?

subexpression

9:37 pm on Jul 1, 2010 (gmt 0)

10+ Year Member



Hi chutes,

It was a bit difficult trying to figure out what you were asking.
I still might be wrong about interpreting your question, but here's something you could try:

<script type="text/javascript">
function changeindex(thisselect){
var dropdown = document.getElementsByTagName('select');
for(var i = 0; i < dropdown.length; i++){
if(dropdown[i].name != thisselect.name){
for(var j = 0; j < dropdown[i].options.length; j++){
if(dropdown[i].options[j].value == thisselect.options[thisselect.selectedIndex].value){
dropdown[i].options[j].selected = true;
}
}
}
}
}
</script>

<form name="new_pro" method="post" onsubmit="return validate_form(this)"
method="post" enctype="multipart/form-data">

<select name="supplier[1]" onchange="changeindex(this);">
<option value="" selected="selected">--none--</option>
<option value="23">23</option>
<option value="24">24</option>
</select>

<select name="supplier[2]" onchange="changeindex(this);">
<option value="" selected="selected">--none--</option>
<option value="23">23</option>
<option value="24">24</option>
</select>

<select name="supplier[3]" onchange="changeindex(this);">
<option value="" selected="selected">--none--</option>
<option value="23">23</option>
<option value="24">24</option>
</select>

<select name="supplier[4]" onchange="changeindex(this);">
<option value="" selected="selected">--none--</option>
<option value="23">23</option>
<option value="24">24</option>
</select>

</form>


Selecting a value from any one of the dropdowns locates the same value in the others and selects them.
You can have any number of <select> dropdowns since the script recursively iterates through the select elements to find options and their respective values.

- s

chutes

1:28 am on Jul 2, 2010 (gmt 0)

10+ Year Member



Thank you, subexpression!

Exactly what I wanted. However, is it possible to make a -separate- pulldown; the only pull-down that controls the "select all" option for the rest of the page?

Basically, most of the time I will need all fields populated to the same option; but there are instances where I'll need to change fields to other values.. so if there was 1 pull-down that controlled the others, it would allow for easier access to specify when the pull-down options are duplicated across the board and when they can be offered their own values.

Example:
"Use this pull-down if you want to select "24" for all options:"

Otherwise, if you don't make use of that pull-down, you'll have to populate all of the fields manually.

subexpression

2:32 am on Jul 2, 2010 (gmt 0)

10+ Year Member



chutes,

Try this:

<script type="text/javascript">
var supplier = new function(){
self = this;
self.select = {
'dropdown': [],
'which': '',
'mode': false,
'load': function(){
this.dropdown = document.getElementsByTagName('select');
this.reset();
this.mode = false;
},
'change': function(select){
this.which = select.options[select.selectedIndex];
if(select.name == 'mode'){
this.mode = (this.which.value == 'manual') ? false : true;
}
if(!this.mode){return}
this.changeindex();
},
'changeindex': function(){
for(var i = 0; i < this.dropdown.length; i++){
if(this.dropdown[i].name == 'mode'){
i++;
}
if(this.dropdown[i].name != this.which.name){
for(var j = 0; j < this.dropdown[i].options.length; j++){
if(this.dropdown[i].options[j].value == this.which.value){
this.dropdown[i].options[j].selected = true;
}
}
}
}
},
'reset': function(){
for(var i = 0; i < this.dropdown.length; i++){
this.dropdown[i].options[0].selected = true;
}
}
};
};
window.onload = function(){
supplier.select.load();
}
</script>

<form name="new_pro" method="post" onsubmit="return validate_form(this)"
method="post" enctype="multipart/form-data">

<select name="mode" onchange="supplier.select.change(this);">
<option value="manual">Manual Mode</option>
<option value="automatic">Automatic Mode</option>
</select>

<select name="supplier[1]" onchange="supplier.select.change(this);">
<option value="" selected="selected">--none--</option>
<option value="23">Combat Robot</option>
<option value="24">Servant Robot</option>
</select>

<select name="supplier[2]" onchange="supplier.select.change(this);">
<option value="" selected="selected">--none--</option>
<option value="23">Laser Rifle</option>
<option value="24">Drink Dispenser</option>
</select>

<select name="supplier[3]" onchange="supplier.select.change(this);">
<option value="" selected="selected">--none--</option>
<option value="23">Sonic Disrupter</option>
<option value="24">Back Scratcher</option>
</select>

<select name="supplier[4]" onchange="supplier.select.change(this);">
<option value="" selected="selected">--none--</option>
<option value="23">Tactical Nuke</option>
<option value="24">Food Replicator</option>
</select>

</form>

I had to modify the original function and used a bit of JSON to organize it better.
Try it out and let me know how it works for you.

- s

subexpression

2:42 am on Jul 2, 2010 (gmt 0)

10+ Year Member



chutes,

I noticed a superfluous assignment on line 11 in the 'load' method:
this.mode = false;

Since it's already initialized to false on line 7:
'mode': false,

...it doesn't need to be re-initialized in the 'load' method.
Anyway, it works the same. It was just an unnecessary line.

- s

chutes

4:07 am on Jul 2, 2010 (gmt 0)

10+ Year Member



Giving it a shot now; I'm not sure if I pasted something incorrectly but Firefox is giving me this in the error console:
Error: Error: supplier is not defined
Source File: http://www.example.com/page.php?cPath=640&pID=12378&action=new_pro
Line: 1

[edited by: chutes at 4:42 am (utc) on Jul 2, 2010]

subexpression

4:32 am on Jul 2, 2010 (gmt 0)

10+ Year Member



chutes,

If you are already using the onload="" event handler for the <body> tag, or another onload function, then it's very possible that this is getting overridden:
window.onload = function(){
supplier.select.load();
}

You'll need to either add that to your onload event handler, or use something like this:
// ONLOAD
function addOnload(func) {
var oldonload = window.onload;
if(typeof window.onload != 'function'){
window.onload = func;
}
else {
window.onload = function(){
oldonload();
func();
}
}
}
function loader(){
supplier.select.load();
}
addOnload(loader);

You can also add it to the supplier object in it's own object:
    self.event = {
'addonload': function(func){
var oldonload = window.onload;
if(typeof window.onload != 'function'){
window.onload = func;
}
else {
window.onload = function(){
oldonload();
func();
}
}
}
};


And then, you can call it externally like this to add this function to the window.onload event handler:
supplier.event.addonload(
function(){
supplier.select.load();
}
);

The reason you need to utilize onload is because the supplier.select.load() method must be called after the page is fully loaded.

- s

subexpression

4:42 am on Jul 2, 2010 (gmt 0)

10+ Year Member



chutes,

Actually, upon closer examination, it's probably not the onload event handler.
I'm not exactly sure what it could be since I can't see your source code.

Did it work "outside" of your project? Meaning, when you copied & pasted it into it's own html file and run in the browser, did it work?

Let me know if you have any progress.

- s

subexpression

4:46 am on Jul 2, 2010 (gmt 0)

10+ Year Member



chutes,

Oh, I located it.
You need to update the form and select elements, not just the Javascript:
<form name="new_pro" method="post" onsubmit="return validate_form(this)" 
method="post" enctype="multipart/form-data">

<select name="mode" onchange="supplier.select.change(this);">
<option value="manual">Manual Mode</option>
<option value="automatic">Automatic Mode</option>
</select>

<select name="supplier[1]" onchange="supplier.select.change(this);">
<option value="" selected="selected">--none--</option>
<option value="23">Combat Robot</option>
<option value="24">Servant Robot</option>
</select>

<select name="supplier[2]" onchange="supplier.select.change(this);">
<option value="" selected="selected">--none--</option>
<option value="23">Laser Rifle</option>
<option value="24">Drink Dispenser</option>
</select>

<select name="supplier[3]" onchange="supplier.select.change(this);">
<option value="" selected="selected">--none--</option>
<option value="23">Sonic Disrupter</option>
<option value="24">Back Scratcher</option>
</select>

<select name="supplier[4]" onchange="supplier.select.change(this);">
<option value="" selected="selected">--none--</option>
<option value="23">Tactical Nuke</option>
<option value="24">Food Replicator</option>
</select>

</form>

chutes

4:48 am on Jul 2, 2010 (gmt 0)

10+ Year Member



I think initially got the "Error: changeindex is not defined" because I did not paste the function (I snipped it out by accident):
<script type="text/javascript">
function changeindex(thisselect){
var supplier = new function(){


After fixing that, I get the following:
Error: missing } after function body
Source File: http://www.example.com/page.php?cPath=640&pID=12378&action=new_pro
Line: 109, Column: 1
}

and
Error: supplier is not defined
Source File: http://www.example.com/page.php?cPath=640&pID=12378&action=new_pro
Line: 1


I am trying out some of your new suggestions right now.

chutes

4:59 am on Jul 2, 2010 (gmt 0)

10+ Year Member



Alright, tried all of your suggestions and even tried moving some code; no dice.

Did it work "outside" of your project? Meaning, when you copied & pasted it into it's own html file and run in the browser, did it work?

Pasted everything to a .html file and it did indeed work.
I will paste some of my source code showing where I placed the edits, I'm certain I did something wrong. (I'm very new to javascript)

chutes

5:06 am on Jul 2, 2010 (gmt 0)

10+ Year Member



1st portion of js code:
<script type="text/javascript">
function changeindex(thisselect){
var supplier = new function(){
self = this;
self.select = {
'dropdown': [],
'which': '',
'mode': false,
'load': function(){
this.dropdown = document.getElementsByTagName('select');
this.reset();
},
'change': function(select){
this.which = select.options[select.selectedIndex];
if(select.name == 'mode'){
this.mode = (this.which.value == 'manual') ? false : true;
}
if(!this.mode){return}
this.changeindex();
},
'changeindex': function(){
for(var i = 0; i < this.dropdown.length; i++){
if(this.dropdown[i].name == 'mode'){
i++;
}
if(this.dropdown[i].name != this.which.name){
for(var j = 0; j < this.dropdown[i].options.length; j++){
if(this.dropdown[i].options[j].value == this.which.value){
this.dropdown[i].options[j].selected = true;
}
}
}
}
},
'reset': function(){
for(var i = 0; i < this.dropdown.length; i++){
this.dropdown[i].options[0].selected = true;
}
}
};
};

function validate_required(field,alerttxt)
{
with (field)
{
if (value==null||value=="")
{
alert(alerttxt);return false;
}
else
{
return true;
}
}
}

function validate_form(thisform)
{
with (thisform)
{
if (validate_required(products_price,"Price cannot be left blank!")==false)
{
products_price.focus();
return false;
} else return true;
}
}
</script>
</head>



The form:
echo tep_draw_form('new_pro', FILENAME_CATEGORIES, 'cPath=' . $cPath . (isset($HTTP_GET_VARS['pID']) ? '&pID=' . $HTTP_GET_VARS['pID'] : '') . '&action=new_pro_preview&editstatus=adminmode" onsubmit="return validate_form(this)"', 'post', 'enctype="multipart/form-data"');



The pull-downs:
echo str_replace('&quot;','"',tep_draw_pull_down_menu('supplier[' . $values['products_options_values_id'] . ']"'.'onchange="supplier.select.change(this);"', $manufacturers2_array, $attributes['supplier']));

subexpression

5:26 am on Jul 2, 2010 (gmt 0)

10+ Year Member



I reorganized your code, and added a critical code block, and removed a few unnecessary things:
<script type="text/javascript">
var supplier = new function(){
self = this;
self.select = {
'dropdown': [],
'which': '',
'mode': false,
'load': function(){
this.dropdown = document.getElementsByTagName('select');
this.reset();
},
'change': function(select){
this.which = select.options[select.selectedIndex];
if(select.name == 'mode'){
this.mode = (this.which.value == 'manual') ? false : true;
}
if(!this.mode){return}
this.changeindex();
},
'changeindex': function(){
for(var i = 0; i < this.dropdown.length; i++){
if(this.dropdown[i].name == 'mode'){
i++;
}
if(this.dropdown[i].name != this.which.name){
for(var j = 0; j < this.dropdown[i].options.length; j++){
if(this.dropdown[i].options[j].value == this.which.value){
this.dropdown[i].options[j].selected = true;
}
}
}
}
},
'reset': function(){
for(var i = 0; i < this.dropdown.length; i++){
this.dropdown[i].options[0].selected = true;
}
}
};
};

window.onload = function(){
supplier.select.load();
}

function validate_required(field,alerttxt){
with(field){
if(value == null || value == ''){
alert(alerttxt);return false;
}
else {
return true;
}
}
}

function validate_form(thisform){
with(thisform){
if(!validate_required(products_price, 'Price cannot be left blank!')){
products_price.focus();
return false;
}
return true;
}
}
</script>


Try pasting it in exactly as it is above and see if it works for you.

The form & pull-downs PHP code looks good.
I see you addded 'onchange="supplier.select.change(this);"'
That looks correct.

You'll have to be careful that your PHP code for the pull-downs is able to recreate something which can control the "mode"...manual or automatic:
<select name="mode" onchange="supplier.select.change(this);">
<option value="manual">Manual Mode</option>
<option value="automatic">Automatic Mode</option>
</select>

Notice how the value="" won't coincide with the rest of your dropdowns because of "manual" and "automatic" are used to toggle the functionality, whereas the others have a number (23, 24, etc.) for the value.

- s

chutes

5:34 am on Jul 2, 2010 (gmt 0)

10+ Year Member



Re-pasted everything with your code suggestions; nothing.

I think I may be placing:
<select name="mode" onchange="supplier.select.change(this);">
<option value="manual">Manual Mode</option>
<option value="automatic">Automatic Mode</option>
</select>

in the wrong spot. Can you tell me if this looks like the proper place?

<select name="mode" onchange="supplier.select.change(this);">
<option value="manual">Manual Mode</option>
<option value="automatic">Automatic Mode</option>
</select>
<?php
$rows = 0;
$options_query = tep_db_query("select products_options_id, products_options_name from " . TABLE_PRODUCTS_OPTIONS . " where language_id = '" . $languages_id . "' order by products_options_id");
while ($options = tep_db_fetch_array($options_query)) {
$values_query = tep_db_query("select pov.products_options_values_id, pov.products_options_values_name, pov.order_value from " . TABLE_PRODUCTS_OPTIONS_VALUES . " pov, " . TABLE_PRODUCTS_OPTIONS_VALUES_TO_PRODUCTS_OPTIONS . " p2p where pov.products_options_values_id = p2p.products_options_values_id and p2p.products_options_id = '" . $options['products_options_id'] . "' and pov.language_id = '" . $languages_id . "' order by pov.order_value");
$header = false;
while ($values = tep_db_fetch_array($values_query)) {
$rows ++;
if (!$header) {
$header = true;
?>

<td colspan="2"><font color="#898400"><i><b><?php echo $options['products_options_name']; ?></b></i></font></td>
<td><font color="#898400"><i><b>Qty</b></i></font></td>
<td><font color="#898400"><i><b>Location</b></i></font></td>
<td><font color="#898400"><i><b>SKU</b></i></font></td>
<td width="30"></td>
<td colspan="3"><font color="#898400"><i><b>Addl. Cost</b></i></font></td>
</tr>
<?php
}
$attributes = array();
if (sizeof($HTTP_POST_VARS) > 0) {
if ($HTTP_POST_VARS['option'][$rows]) {
$attributes = array('products_attributes_id' => $HTTP_POST_VARS['option'][$rows],
'options_values_price' => $HTTP_POST_VARS['price'][$rows],
'price_prefix' => $HTTP_POST_VARS['prefix'][$rows],
'attribute_sort' => $HTTP_POST_VARS['attribute_sort'][$rows],
'quantity' => $HTTP_POST_VARS['quantity'][$rows],
'supplier' => $HTTP_POST_VARS['supplier'][$rows],
'location' => $HTTP_POST_VARS['location'][$rows]);
}
} else {
$attributes_query = tep_db_query("select products_attributes_id, options_values_price, price_prefix, attribute_sort, quantity, supplier, location from " . TABLE_PRODUCTS_ATTRIBUTES . " where products_id = '" . $pInfo->products_id . "' and options_id = '" . $options['products_options_id'] . "' and options_values_id = '" . $values['products_options_values_id'] . "'");
if (tep_db_num_rows($attributes_query) > 0) {
$attributes = tep_db_fetch_array($attributes_query);
}
}
?>
<tr class="<?php echo (floor($rows/2) == ($rows/2) ? 'attributes-even' : 'attributes-odd'); ?>">
<td><?php echo tep_draw_checkbox_field('option[' . $values['products_options_values_id'] . ']', $attributes['products_attributes_id'], $attributes['products_attributes_id']) . '&nbsp;' . $values['products_options_values_name']; ?>&nbsp;</td>
<td><?php echo tep_draw_hidden_field('attribute_sort[' . $values['products_options_values_id'] . ']', $values['order_value'], 'size="1"'); ?></td>
<td><?php echo tep_draw_input_field('quantity[' . $values['products_options_values_id'] . ']', $attributes['quantity'], 'size="1"'); ?></td>
<td><?php echo str_replace('&quot;','"',tep_draw_pull_down_menu('supplier[' . $values['products_options_values_id'] . ']"'.'onchange="supplier.select.change(this);"', $manufacturers2_array, $attributes['supplier']));?></td>
<td><?php echo tep_draw_input_field('location[' . $values['products_options_values_id'] . ']', $attributes['location'], 'size="6"'); ?></td>
<td></td>
<!-- <td><?php echo tep_draw_input_field('prefix[' . $values['products_options_values_id'] . ']', $attributes['price_prefix'], 'size="2"'); ?></td>--!>
<td><?php //populate attributes + / -
$attribute_addon_selection = array(array('id' => '', 'text' => 'n/a'),
array('id' => '+', 'text' => '+'),
array('id' => '-', 'text' => '-'));
echo tep_draw_pull_down_menu('prefix[' . $values['products_options_values_id'] . ']', $attribute_addon_selection, $attributes['price_prefix']); ?></td>
<td><?php echo tep_draw_input_field('price[' . $values['products_options_values_id'] . ']', $attributes['options_values_price'], 'size="1"'); ?></td>
</tr>

subexpression

6:08 am on Jul 2, 2010 (gmt 0)

10+ Year Member



It can be anywhere in within <body></body>.
But, it looks like the table starts without a <table> tag, or even a table row <tr> tag.

The <select name="mode"></select> element doesn't even have to be inside of <form></form> tags.
The script I posted iterates through select elements and doesn't rely on document.forms[0] or document.new_pro to access the inner elements.

So, it's placement shouldn't affect the operation of the script.
If you check the outputted HTML in your browser (right-click, View Page Source), you should be able to determine if the other select elements are getting rendered with their values.

I noticed at the very end of your last post, after the </tr> tag, you're missing two braces:
    <?php
}
}
?>

Otherwise, the two while loops are incomplete.

Like I said before, check the outputted HTML, view the source and see if the values are getting rendered.

- s

chutes

6:37 am on Jul 2, 2010 (gmt 0)

10+ Year Member



Still getting:
Error: supplier is not defined
Line: 1


I'm wondering if this may have something to do with it?
<?
if ($_GET['read'] != "only") {
switch($_GET['action']){
case 'new_product_preview':
$onload = isset($_GET['pID']) ? 'document.update_product.submit();' : 'document.insert_product.submit();';
break;
case 'new_master_preview':
$onload = isset($_GET['pID']) ? 'document.update_master.submit();' : 'document.insert_master.submit();';
break;
default:
$onload = 'SetFocus();';
break;
}
} else {
$onload = 'SetFocus();';
}
?>
<body marginwidth="0" marginheight="0" topmargin="0" bottommargin="0" leftmargin="0" rightmargin="0" bgcolor="#FFFFFF" onload="<? echo $onload; ?>">


Those are the only instances of onload.

I've tried your earlier suggestions regarding onload but none of them worked; though I suspect I may have been placing them in the wrong spot. If you believe this is causing my issue, where do you suggest the best spot for the supplier onload function goes?

I also checked on that php bracket and it is indeed there, I just skipped pasting it in my sample. :)

subexpression

7:22 am on Jul 2, 2010 (gmt 0)

10+ Year Member



Well, you're right!
If the supplier object is "not defined", then it's because you already called onload="" event handler in the body tag.
All it takes is a single onload call before it's "used up", so to speak. It can only be called once, unless an additional onload method is created to append new functions and reinitialize everything.

Try this:
<script type="text/javascript">
var supplier = new function(){
self = this;
self.event = {
'addonload': function(func){
var oldonload = window.onload;
if(typeof window.onload != 'function'){
window.onload = func;
}
else {
window.onload = function(){
oldonload();
func();
}
}
}
};
self.select = {
'dropdown': [],
'which': '',
'mode': false,
'load': function(){
this.dropdown = document.getElementsByTagName('select');
this.reset();
},
'change': function(select){
this.which = select.options[select.selectedIndex];
if(select.name == 'mode'){
this.mode = (this.which.value == 'manual') ? false : true;
}
if(!this.mode){return}
this.changeindex();
},
'changeindex': function(){
for(var i = 0; i < this.dropdown.length; i++){
if(this.dropdown[i].name == 'mode'){
i++;
}
if(this.dropdown[i].name != this.which.name){
for(var j = 0; j < this.dropdown[i].options.length; j++){
if(this.dropdown[i].options[j].value == this.which.value){
this.dropdown[i].options[j].selected = true;
}
}
}
}
},
'reset': function(){
for(var i = 0; i < this.dropdown.length; i++){
this.dropdown[i].options[0].selected = true;
}
}
};
};

supplier.event.addonload(
function(){
supplier.select.load();
}
);

function validate_required(field,alerttxt){
with(field){
if(value == null || value == ''){
alert(alerttxt);return false;
}
else {
return true;
}
}
}

function validate_form(thisform){
with(thisform){
if(!validate_required(products_price, 'Price cannot be left blank!')){
products_price.focus();
return false;
}
return true;
}
}
</script>


Place this script between the <head></head> tags in your document.
I think we're getting close here.

- s

chutes

9:04 am on Jul 2, 2010 (gmt 0)

10+ Year Member



Completely stumped. Replaced old code with your updated version; no errors via the error console, but the pulldowns don't change.

I even tried to disable to current onload function, still no result.

Clearly there is a conflict of sorts, I just don't know what else to look for. Any ideas?



I tried in IE, and IE's error console reads the following:
Webpage error details
Message: Not implemented

Line: 26
Char: 5
Code: 0


Line 26:
 self = this;
which is right beneath: var supplier = new function(){


So, I tried adding:

function changeindex(thisselect){

right beneath the script initialization... IE prompted me to add another } just before </script>

IE now touts the following error:
Message: 'supplier' is undefined
Line: 697
Char: 1
Code: 0

line 697: <select name="mode" onchange="supplier.select.change(this);">


Does
<select name="mode" onchange="supplier.select.change(this);">
need an array info? Like:
<select name="mode" onchange="supplier[j].select.change(this);">


For some reason, no matter how many times I edit this post, the forum is adding a [ color ] thing to my post. I don't know where that's from, but it isn't in my code. :)