Dynamic 3-tier vertical menu - how?

I want to create a 3-tier hierarchical menu that functions like the one here: http://css-tricks.com/snippets/

I want a fixed layout of 3 columns side-by-side. The first column contains letters A-Z.
Clicking a letter populates the second column - starting from the top, not from the position of the selected letter (so the ASP.Net Menu control is out). The selected item in column 2 then populates column 3, again from the top.

What are the options?
TimHudspithAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Scott Fell, EE MVEDeveloper & EE ModeratorCommented:
I don't understand the link you posted or at least it does not match up with what you are trying to achieve.

If you have 3 div's each one column.  You could use ajax to grab all choices starting with "a" and place in column 2 and so on.  Or with a page refresh, send to the url and grab the querystring.

<div id="col1">
    <ul>
         <li><a href="">a</a></li>
         <li><a href="">b</a></li>
         <li><a href="">c</a></li>
         <li><a href="">z</a></li>
    </ul>
</div>
<div id="col2">
    <ul>
         <li><a href="">Choices from Col1</a></li>
         <li><a href="">Choices from Col1</a></li>
         <li><a href="">Choices from Col1</a></li>
         <li><a href="">Choices from Col1</a></li>
    </ul>
</div>
<div id="col1">
    <ul>
         <li><a href="">Choices from Col2</a></li>
         <li><a href="">Choices from Col2</a></li>
         <li><a href="">Choices from Col2</a></li>
         <li><a href="">Choices from Col2</a></li>
    </ul>
</div>

Open in new window


If the total choices are not very many, I would just send all choices to the browser at once and use js/jquery to display. I have used chained many times http://www.appelsiini.net/projects/chained.  If you end up having to send 1000 choices to the browser at once, that may be slow.  But sending 50 or 100 options may be ok.  Then you could let people make multiple choices from col1,2 and 3 without hitting the db each time.  Or you could have it hardcoded.


From the sample code, you can see it is easy to set up.  They just use the class from the first column to populate the 2nd and so on.
<select id="mark" name="mark">
  <option value="">--</option>
  <option value="bmw">BMW</option>
  <option value="audi">Audi</option>
</select>
<select id="series" name="series">
  <option value="">--</option>
  <option value="series-3" class="bmw">3 series</option>
  <option value="series-5" class="bmw">5 series</option>
  <option value="series-6" class="bmw">6 series</option>
  <option value="a3" class="audi">A3</option>
  <option value="a4" class="audi">A4</option>
  <option value="a5" class="audi">A5</option>
</select>

Open in new window

0
TimHudspithAuthor Commented:
I have the 3-column <div> structure in place and all my A-Z items in a <ul> in the first <div>. Columns 2 and 3 will have to be populated dynamically from the database - there are approx 1000 entries at the moment but this will grow. I'm new to web dev so need some pretty detailed guidance on how to take this forward using AJAX to grab the data for the next column (coming from SQL Server).

I'm building this in ASP.Net by the way, if that changes things.
0
Scott Fell, EE MVEDeveloper & EE ModeratorCommented:
I think 1000 entries is too much to send to the browser.

What would happens is you would pick a letter in column one. That would send an ajax call to populate column 2 and so on.
0
Big Business Goals? Which KPIs Will Help You

The most successful MSPs rely on metrics – known as key performance indicators (KPIs) – for making informed decisions that help their businesses thrive, rather than just survive. This eBook provides an overview of the most important KPIs used by top MSPs.

TimHudspithAuthor Commented:
OK, but what I need to know is how AJAX calls and returns data from SQL Server, then iterates that to populate the second <ul>.
0
Scott Fell, EE MVEDeveloper & EE ModeratorCommented:
Here is a working sample of what I am talking about  http://jsbin.com/gusebitu/1/edit

This is using jquery ajax https://api.jquery.com/jQuery.ajax/

The first column you would populate on page load

The 2nd column would populate by clicking a letter.  In my sample, I am hitting the url     'http://jsbin.com/hutiyike/1.js.  This is static data and in your case could be php/asp.  Notice I am passing the variable id.  The get really looks like http://jsbin.com/hutiyike/1.js?id=a  or somepage.php?id=a.  Use your own logic to grab all the "a" words.

The 2nd pass does the same thing but a little different. I am passing an attribute data-item. This would be generated by your serverside code.  You can grab the data from that by using jquery attr("data-item").  The -item can be whatever you want to call it.  This would hit your 2nd url that will get us the next set of results for the last column.



<!DOCTYPE html>
<html>
<head>
<script src="http://code.jquery.com/jquery-1.10.2.min.js"></script>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>
<body>
  <div class="col">
    <ul class="first">
      <li><a href="#">A</a></li>
      <li><a href="#">B</a></li>
      <li><a href="#">C</a></li>
    </ul>
    </div>
  <div class="col two"></div>
  <div class="col three"></div>
  
</body>
</html>

Open in new window

// http://jsbin.com/hutiyike/1.html
// sample data
//<li><a href="#" data-item="1">Aardvark</a></li>
//<li><a href="#" data-item="2">Aardwolf</a></li>
//<li><a href="#" data-item="3">Aasvogel</a></li>

//http://jsbin.com/yupiwolu/1.html
//sample data
//<li><a data-item="1">col 3 A</a></li>
//<li><a data-item="2">col 3 B</a></li>
//<li><a data-item="3">col 3 C</a></li>
$(function () {
    // first column select
    $('.first li a').click(function (e) {
        e.preventDefault();
        var firstLetter = $(this).text();


        $.ajax({
            type: 'get',
            url: 'http://jsbin.com/hutiyike/1.js',
            dataType: "html",
            data: {
                id: firstLetter
            }
        }).done(function (msg) {
            $('div.two').html('<ul>' + msg + '</ul>');

            $('.two ul li a').click(function () {
                theData = $(this).attr('data-item');
                $.ajax({
                    type: 'get',
                    url: 'http://jsbin.com/yupiwolu/1',
                    dataType: "html",
                    data: {
                        id: theData
                    }
                }).done(function (msg) {
                    $('div.three').html('<ul>' + msg + '</ul>');

                });
            });


        }); // ajax




    }); //click



});

Open in new window

.col{width:100px;float:left;margin-right:10px;border-left-style:solid;min-height:100px;

Open in new window

0
TimHudspithAuthor Commented:
Dealing with the AJAX call first - I'm getting an undefined error.

I've created a function in the code-behind file (HomePage.aspx.vb) to run a parameterised query on the database using the letter clicked in the list as the parameter. It returns the data (a list of categories beginning with the letter clicked) as xml.

<WebMethod()>
    Public Shared Function GetCategory(letter As String) As String
        Using dtb As New DataTable
            Using myConn As New dbConn
                Using conn As SqlConnection = myConn.cnn
                    Dim strCmd As String = "SELECT Category FROM T_Categories WHERE Letter = '" + letter + "'"
                    Using dap As New SqlDataAdapter(strCmd, conn)
                        dap.Fill(dtb)
                        Using sw As StringWriter = New StringWriter()
                            dtb.TableName = letter & "_Categories" 'or next line fails
                            dtb.WriteXml(sw, XmlWriteMode.IgnoreSchema)
                            Return sw.ToString
                        End Using
                    End Using
                End Using
            End Using
        End Using
    End Function

Open in new window


This works in VB but I run into problems when I call this with AJAX. You can see below that I've set it up to give me basic feedback so I know if I'm on the right track, but it just gives me 'error'.

<script type="text/javascript">
        $(document).ready(function () {

            $("#A2Z li").click(function (e) {
                e.preventDefault();
                var Letter = $(this).text();

                $.ajax({
                    type: "GET",
                    url: "HomePage.aspx.vb/GetCategory",
                    data: Letter,
                    contentType: "application/json; charset=utf-8",
                    dataType: "json",
                    success: function (response) {
                        alert("success");
                    },
                    failure: function (response) {
                        alert("failure");
                    },
                    error: function (response) {
                        alert("error");
                    }
                });
            });
        });
</script>

Open in new window

0
Scott Fell, EE MVEDeveloper & EE ModeratorCommented:
Can you please post a link to your working sample?

I am not a .net developer, I am sorry if this is a dumb question, but you have the url going to a .vb, is that correct?

url: "HomePage.aspx.vb/GetCategory",

Open in new window


The url should be something you can surf to.  My guess is you need to use the .aspx page.
0
TimHudspithAuthor Commented:
I'm inching forward with this. My AJAX call is now successfully returning data from my VB function. I had to change the format of the AJAX data parameter to '{letter: "' + Letter + '" }', and point to the correct file - as you said. So the first section of my JQuery looks like this:

$(function () {

            $("#A2Z li").click(function (e) {
                e.preventDefault();
                var Letter = $(this).text();
               
                $.ajax({
                    type: "POST",
                    url: "HomePage.aspx/GetCategory",
                    contentType: "application/json; charset=utf-8",
                    data : '{letter: "' + Letter + '" }',
                    dataType: "json",
                    success: OnSuccess,
                    error: function (xhr, ajaxOptions, thrownError) {
                        alert("Error" + xhr.status);
                    },
                    failure: function (response) {
                        alert(response.d);
                    }
                }); //ajax
            });

Open in new window


The data returned (string data type) looks like this:

<Document Element>
    <Categories>
          <Category>Item A<Category>
    <Categories>
    <Categories>
          <Category>Item B<Category>
    <Categories>
<Document Element>
         
Not very elegant but it's coming through at least. I want to iterate the <Category> nodes and add them as <li> elements to a <ul> I have in my second <div>. The code I have is below but it doesn't work:

function OnSuccess(response) {
                $xml = $($.parseXML(response));
                $xml.find("<Category>").each(function(node){
                    var text = $(node).text();
                    var myli = $('<li>' + text + '</li>');
                    $('#Categories').append(myli);
                })
})

Open in new window

0
Scott Fell, EE MVEDeveloper & EE ModeratorCommented:
Work on your xml, it does not appear to be valid.  Everything should be closed in the same order it was opened.
0
Scott Fell, EE MVEDeveloper & EE ModeratorCommented:
Using the jquery docs as an example and after fixing up your xml output, you can try the code below.  Then replace for your response.

var xml = "<DocumentElement><Categories><Category>Item A</Category></Categories><Categories><Category>Item B</Category></Categories></DocumentElement>",
  xmlDoc = $.parseXML( xml ),
  $xml = $( xmlDoc ),
  $Categories = $xml.find( "Categories" );

$Categories.each(function(){
  console.log($(this).text());
});
 

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
TimHudspithAuthor Commented:
Thanks for all that.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
HTML

From novice to tech pro — start learning today.