Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Show new values, based on first category selection 1

Status
Not open for further replies.

youradds

Programmer
Jun 27, 2001
817
GB
Hi,

I'm trying to find a bit of code that will do the following:

1) You have a SELECT field called "catidselect", which has a list of a load of categories (with values held as "ID" numbers)
2) Someone selects one of the categories, and then a new SELECT field (called "catid") is updated with a list of categories that exist in and array (?) , ready for people to just select that.

I'm 100% sure this is possible, but can't find any code samples anywhere :/

Any ideas?

TIA

Andy
 
heheh fraid not, sorry ;)

Ended up using this one:


Now just to get past this bloomin SuEXEC crap that keeps going on with this server I'm working on - driving me mad! (perl scripts fine in SSH, but as soon as in a browser is gives an SuEXEC error - yukky!)

Cheers

Andy
 
Man, this is still driving me bonkers :(


No JS errors, and the script that I've written to replace the .php script he provided, works:


Code below:

Code:
#!/usr/bin/perl
# ==================================================================


    use strict;
    use lib '/home/user/public_html/cgi-bin/admin';
    use GT::Base;
    use GT::Plugins qw/STOP CONTINUE/;
    use Links qw/$CFG $IN $DB/;
    use CGI::Carp qw(fatalsToBrowser);
 
    local $SIG{__DIE__}  = \&Links::fatal;
    
    Links::init('/home/user/public_html/cgi-bin/admin');
   
    print $IN->header( 'text/javascript' );


    my $cat_id = $IN->param('ID');
    my $tbl = $DB->table('Category');
       $tbl->select_options('ORDER BY Full_Name DESC');
    my $sth = $tbl->select( { FatherID => $cat_id } );

	  while (my $hit = $sth->fetchrow_hashref) {
	    print qq|  obj.options[obj.options.length] = new Option('$hit->{Full_Name}','$hit->{ID}');\n|;
	  }

..yet it refuses to populate the field - EUGH!!!!

Any ideas?

TIA

Andy
 
Hi,

Ok, coming back to this now. Basically, I need something like here (appologies for the name, I'm not that way enclined - but its the best example my friend could find me of what he wanted =))


If you look at the "Quick Search", you will see that when you select a country, it then loads the States (or for some countries, the state). Then, you select a state - and it lists the states.

Now, I'm quite competent with coding a Perl application that can be used with this, but AJAX is still a bit of a mystery to me :(

What I have in terms of a data structure is:

Continent/Countries/States/Cities/
..and:
Continent/Countries/Islands/Cities/

So, what I'm aiming to do - is have 1 "select" box, which then loads another one - with all the countries, then when they select that - it will load either the states/islands for that country, and again - another one will load after that, with a list of the cities.

I'm sure this will be a piece of cake for quite a few people.

All I'm thinking of, is when the SELECT box value is grabbed, it passes something like:

getcats.cgi?ID=1234 (where 1234 is the category ID).

TIA for any advice.

Andy
 
Hi

My first reaction was "that is easy, let us help him".

My second reaction was "with what more ?".

You received a couple of good links that should be enough to move your development forward. Another set of example is completely pointless. Probably you should understand some basics first.

So better explain what you (mis)understood from those examples, how you tried to implement them and where you failed.

Feherke.
 
Hi,

I've taken a look at the examples again - but they don't seem to do what I need. For example, - this looked perfect, until I realised we can't have ALL the data in one place, as its over 500,000 categories (as we list pretty much everywhere in the world, including cities) - so we need to have it pass to a .cgi script, and then grab the appropriate data from that (and return it back to the form)

As I said - I'm still new to all this AJAX stuff (even Javascript I'm still playing around with, and although I have an understanding of how to write simple functions - I'm a far cry from "great" at it =)

Cheers

Andy
 
Hi

Evidently the ajaxray example is useless. Especially in your case.

The gobarfly example you mentioned seems to be Ok, but without seeing the client-side code too, I have no idea what is wrong there.

Anyway, this is a working example, doing exactly what you want. ( Or at least, exactly what I understood. )
HTML:
<form action="">

Continent : <select id="continent" onchange="load('country',this)">
<option value="0">-- select one --</option>
<option value="1">Africa</option>
<option value="2">Asia</option>
<option value="3">Australia</option>
<option value="4">Europe</option>
<option value="5">North America</option>
<option value="6">South America</option>
</select><br>

Country : <select id="country" onchange="load('state',this)">
<option value="0">-- select one --</option>
</select><br>

State : <select id="state" onchange="load('city',this)">
<option value="0">-- select one --</option>
</select><br>

City : <select id="city">
<option value="0">-- select one --</option>
</select><br>

</form>
JavaScript:
var continent,country,state,city

function load(next,what)
{
  if (!continent) {
    continent=document.getElementById('continent')
    country=document.getElementById('country')
    state=document.getElementById('state')
    city=document.getElementById('city')
  }
  if (!continent) return

  var nextelem=document.getElementById(next)

  var url='givemedata.php?next='+next+'&continent='+escape(continent.options[continent.options.selectedIndex].value)
  if (what.id=='country' || what.id=='state') {
    url+='&country='+escape(country.options[country.options.selectedIndex].value)
    if (what.id=='state') url+='&state='+escape(state.options[state.options.selectedIndex].value)
  }

  var data=ajaj(url)

  if (next=='country' || next=='state' || next=='city') {
    for (var i=city.options.length-1;i>0;i--) city.options[i]=null
    if (next=='country' || next=='state') {
      for (var i=state.options.length-1;i>0;i--) state.options[i]=null
      if (next=='country') for (var i=country.options.length-1;i>0;i--) country.options[i]=null
    }
  }

  for (var one in data) nextelem.options[nextelem.options.length]=new Option(data[one],one)
}
Code:
<?php

$continent=mysql_real_escape_string($_GET[continent]);
$country=mysql_real_escape_string($_GET[country]);
$state=mysql_real_escape_string($_GET[state]);

switch ($_GET[next]) {
  case 'country': $sql="select id,name from country where continent='$continent' order by name"; break;
  case 'state': $sql="select id,name from state where continent='$continent]' and country='$country' order by name"; break;
  case 'city': $sql="select id,name from city where continent='$_GET[continent]' and country='$country' and state='$state' order by name"; break;
}

$data=array();

$con=mysql_connect('hostname','username','password');
mysql_select_db('database');
$res=mysql_query($sql);
while ($row=mysql_fetch_assoc($res)) $data[$row[id]]=$row[name];

header('Content-type: text/javascript');

echo json_encode($data);

?>
As I do not like to use huge JavaScript libraries, I put together my own function. My code uses the below, I you not like it, you will have to change only the ajaj() call.
Code:
// ajaj   version 1.0   november 2008   written by Feherke
// AJAJ - Asynchroneous Javascript And JSON

if (typeof XMLHttpRequest=='undefined') {
  XMLHttpRequest=function() {
    try { return new ActiveXObject('Msxml2.XMLHTTP.6.0') } catch (e) { }
    try { return new ActiveXObject('Msxml2.XMLHTTP.3.0') } catch (e) { }
    try { return new ActiveXObject('Msxml2.XMLHTTP') } catch (e) { }
    try { return new ActiveXObject('Microsoft.XMLHTTP') } catch (e) { }
  }
}

function ajaj(url,call)
{
  var http=new XMLHttpRequest()
  var async=typeof call=='function'
  var result=undefined

  if (!http) return

  try { http.open('GET',url,async) } catch (e) { return undefined }

  if (async) {
    http.onreadystatechange=function() {
      var result=undefined

      if (http.readyState==4 && http.status==200) {
        try { eval('result='+http.responseText) } catch (e) { }
        call(result)
      }
    }
  }

  try { http.send(null) } catch (e) { return undefined }

  if (async) return undefined

  if (http.readyState!=4 || http.status!=200) return undefined

  try { eval('result='+http.responseText) } catch (e) { return undefined }

  return result
}

Feherke.
 
H8i,

Thanks - its late here now, but I'll test this tomorrow - and will no doubt post.

Thanks for taking the time to reply :)

Cheers

Andy
 
Hi,

Ok, trying to use this example:


However, it doesn't work :/


I've checked the error logs, and nothing is coming up - so I'm at a loss as to whats wrong :/

I've checked to make sure all the JS files are being loaded ok, and they are (Web Developer add-on, for FF)

Anyone got any ideas?

TIA

Andy
 
Hi

The gayguide example works. When selecting from the first [tt]select[/tt], the new values are requested, received and loaded into the second [tt]select[/tt].

If by doesn't work you mean you see nothing happening, then check why and returns empty array.

Feherke.
 
You star - got it working !!!! :)

It was due to the query -

$results = mysql_query('select * from test.select_chain where category="' . strtolower(mysql_real_escape_string(strip_tags($_REQUEST['category']))) . '"');

..but we are not using the table "test", but rather another one. Changing to this, and it works fine now:

$results = mysql_query('select * from select_chain where category="' . strtolower(mysql_real_escape_string(strip_tags($_REQUEST['category']))) . '"');

Thanks for your time :)

Andy
 
Mmm, can't get it to work with how I want :(

My SQL structure, is:

ID,Name,Full_Name,CatDepth

The 1st box, needs to have CatDepth = 0
The 2nd box, needs to have CatDepth = 1
The 3rd box, needs to have CatDepth = 2
The 3rd box, needs to have CatDepth = 3

Then, it would populate the different SELECT boxes.

The PHP code is:

Code:
<?php
if (@$_REQUEST['ajax']) {
    // connect to local database 'test' on localhost
    $link = mysql_connect('db162.domain.de', 'dbo271138635', 'password');
    if ($link == false)
    	trigger_error('Connect failed - ' . mysql_error(), E_USER_ERROR);

    $connected = mysql_select_db('db271138635', $link);
    
    if ($connected) {
/*        $results = mysql_query('select * from select_chain where category="' . strtolower(mysql_real_escape_string(strip_tags($_REQUEST['category']))) . '"');
*/
      
        $results = mysql_query('select * from glinks_Category where Full_Name LIKE "' . $_REQUEST['category'] . '/%"');

		echo 'select * from glinks_Category where Full_Name = "' . $_REQUEST['category'] . '"';;

        $json = array();
        
        while (is_resource($results) && $row = mysql_fetch_object($results)) {
            $json[] = '"' . $row->Full_Name . '"';
        }
        
        echo '[' . implode(',', $json) . ']';
        die(); // filthy exit, but does fine for our example.
    } else {
        user_error("Failed to select the database");
    }
}
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  "[URL unfurl="true"]http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">[/URL]
<html lang="en">
  <head>
    <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
    <title>Select Chain</title>
    <style type="text/css" media="screen">
    <!--
      BODY { margin: 10px; padding: 0; font: 1em "Trebuchet MS", verdana, arial, sans-serif; }
      BODY { font-size: 100%; }
      H1 { margin-bottom: 2px; font-family: Garamond, "Times New Roman", Times, Serif;}
      DIV.selHolder { float: left; border: 3px solid #ccc; margin: 10px; padding: 5px;}
      TEXTAREA { width: 80%;}
      FIELDSET { border: 1px solid #ccc; padding: 1em; margin: 0; }
      LEGEND { color: #ccc; font-size: 120%; }
      INPUT, TEXTAREA { font-family: Arial, verdana; font-size: 125%; padding: 7px; border: 1px solid #999; }
      LABEL { display: block; margin-top: 10px; } 
      IMG { margin: 5px; }
      SELECT { margin: 10px; width: 200px; }
    -->
    </style>

    <script src="jquery.js" type="text/javascript"></script>
    <script src="select-chain.js" type="text/javascript" charset="utf-8"></script>
    <script type="text/javascript">
    <!--
    $(function () {
        var cat = $('#categorySelect');
        var el = $('#elementSelect');
        var attr = $('#attributeSelect');
        var catselect = $('#catSelect');
        
        el.selectChain({
            target: attr,
            url: 'select-chain-test.php',
            data: { ajax: true, anotherval: "anotherAction" }            
        });        

        // note that we're assigning in reverse order
        // to allow the chaining change trigger to work
        cat.selectChain({
            target: el,
            url: 'select-chain-test.php',
            data: { ajax: true }
        }).trigger('change');

    });
    //-->
    </script>
  </head>
  <body id="page">
    <div id="doc">
        <h1>Select Chain</h1>
        <div class="selHolder">
            <h2>Continent</h2>
            <select id="categorySelect" name="category" size="5">
                <option>Gay Africa</option>
                <option>Gay Asia</option>

            </select>
        </div>
        <div class="selHolder">
            <h2>Country</h2>
            <select id="elementSelect" name="category" size="5">
                <option>[none selected]</option>
            </select>
        </div>
        <div class="selHolder">
            <h2>State/Province</h2>
            <select id="attributeSelect" name="category" size="5">
                <option>[none selected]</option>
            </select>
        </div>

        <div class="selHolder">
            <h2>City</h2>
            <select id="catSelect" name="catid" size="5">
                <option>[none selected]</option>
            </select>
        </div>



    </div>
  </body>
</html>

The code from select-chain.js is:

Code:
(function ($) {
    $.fn.selectChain = function (options) {
        var defaults = {
            key: "id",
            value: "label"
        };
        
        var settings = $.extend({}, defaults, options);
        
        if (!(settings.target instanceof $)) settings.target = $(settings.target);
        
        return this.each(function () {
            var $$ = $(this);
            
            $$.change(function () {
                var data = null;
                if (typeof settings.data == 'string') {
                    data = settings.data + '&' + this.name + '=' + $$.val();
                } else if (typeof settings.data == 'object') {
                    data = settings.data;
                    data[this.name] = $$.val();
                }
                
                settings.target.empty();
                
                $.ajax({
                    url: settings.url,
                    data: data,
                    type: (settings.type || 'get'),
                    dataType: 'json',
                    success: function (j) {
                        var options = [], i = 0, o = null;
                        
                        for (i = 0; i < j.length; i++) {
                            // required to get around IE bug ([URL unfurl="true"]http://support.microsoft.com/?scid=kb%3Ben-us%3B276228)[/URL]
                            o = document.createElement("OPTION");
                            o.value = typeof j[i] == 'object' ? j[i][settings.key] : j[i];
                            o.text = typeof j[i] == 'object' ? j[i][settings.value] : j[i];
                            settings.target.get(0).options[i] = o;
                        }

			// hand control back to browser for a moment
			setTimeout(function () {
			    settings.target
                                .find('option:first')
                                .attr('selected', 'selected')
                                .parent('select')
                                .trigger('change');
			}, 0);
                    },
                    error: function (xhr, desc, er) {
                        // add whatever debug you want here.
			alert("an error occurred");
                    }
                });
            });
        });
    };
})(jQuery);

I'm noy that great with AJAX/JS, so even after trying to debug, it doesn't seem to wanna play ball :(

TIA for any ideas.

Andy
 
Hi

I think this is what you want :
Code:
$results = mysql_query('select * from glinks_Category where Full_Name LIKE "' . $_REQUEST['category'] . '/%" [red]and CatDepth=[/red]' [red]. $_REQUEST['CatDepth'][/red]);

[gray]// ...[/gray]

el.selectChain({
    target: attr,
    url: 'select-chain-test.php',
    data: { ajax: true, anotherval: "anotherAction"[red], 'CatDepth': 1[/red] }
});        

cat.selectChain({
    target: el,
    url: 'select-chain-test.php',
    data: { ajax: true[red], 'CatDepth': 0[/red] }
}).trigger('change');
But I understand less and less from all this.

Feherke.
 
Thanks for the reply - I think thats along the right kinda trails.

Is there any way to add some debugging (popup alerts or whatever), so I can see what URL's are being called?

TIA for any suggestions :)

Cheers

Andy
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top