• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 489
  • Last Modified:

Create menu and submenu from external .js file

Hello again all

Very recently dakyd answered my question and the answer is below. However, I now need a modification to the script and although I can see where, I can't figure out the how.

The script takes data from an external .js file and creates a table. It also creates a alphabetical menu.

What I now need is alphabetical submenus as well.

As you will see from the script, the menu is created from the field data[#][2]. What I want, is to create the top menu from data[#][3] and a submenu from data[#][2]. ie: data[#][3] are English counties and data[#][2] are English towns. So what I want is a top menu of English counties and when a link is clicked, a submenu appears showing the towns relevant to that county. I hope that makes sense.

I also want to have a mouseover on the links that say something like 'View the properties in... ' and it shows the data from the relevant field. For example, if the county is Surrey, the mouseover says 'View the properties in Surrey'. If the town is Reading, the mouseover will say 'View the properties in Reading'. I know it should go in the createOptions() function as myAnchor.mouseover = ... , and I can get it to say 'View the properties in... ', but that's as far as I get.

Anyway, here's the my .js file and dakyd's code:

The external properties.js file:
var data = new Array();

data[0] = "Chester Square | Belgravia | London | £3,450,000 | An opportunity to acquire this magnificent and superbly refurbished family house built circa 1840 and situated at the eastern end of this prestigious Belgravia garden square, set in one of London's premier locations. The accommodation comprises entrance hall, dining room, reception room, kitchen/breakfast room, six bedrooms, family room, study/library, study, utility room, en-suite shower room, two en suite bath/shower rooms, bathroom, cloakroom, conservatory, roof terrace and balcony. ";
 
data[1] = "Audley Square | Mayfair | London | £5,750,000 | An impressive ambassadorial Grade II listed 18th century freehold residence with private garden and garaging located in the heart of Mayfair with views over Tilney Street towards Hyde Park. The property is conveniently located close to the comprehensive shopping and transport facilities that Mayfair has to offer. ";
 
data[2] = "Hereford House, North Road | Mayfair | London | £2,150,000 | A recently refurbished fourth floor (with lift) of a portered building off Park Lane, this impressive three bedroom apartment offers vast living space. The property comprises a 24ft reception room with natural stone fireplace, spacious dining room, stylish kitchen, sumptuous master suite and two further bedrooms both with en suite bathrooms. ";

data[3] = "Eaton Place | Belgravia | London | £1,985,000 | An elegant and immaculate three bedroom maisonette set on the third and fourth floors of this imposing period building. The property has recently been refurbished to a very high standard and comprises entrance hall, L-shaped drawing/dining room, kitchen, master bedroom, dressing room, two further bedrooms, cloakroom, two en-suite bathrooms, shower room and direct lift access. Ideally situated in this prestigious Belgravia address, the property is within easy access of a wide array of shopping, transport and entertainment facilities. ";

data[4] = "Yeomans Row | Knightsbridge | London | £1,750,000 | A rare opportunity to acquire a four bedroom freehold terraced house situated in this quiet cul-de-sac off the Brompton Road in the heart of Knightsbridge. The property comprises entrance hall, dining room, eat-in-kitchen, L-shaped drawing room, four bedrooms, bathroom, cloakroom, patio garden, utility and storage in basement. ";
 
data[5] = "Warriner Gardens | Battersea | London | £265,000 | A charming one bedroom garden flat in this fantastic location just moments from Battersea Park. The well appointed accommodation comprises reception room with bay window and stripped wood floors, double bedroom with fitted cupboards, large kitchen / diner with bay window to side, bathroom and lovely private paved garden to the rear. Warriner Gardens runs along side Prince Of Wales Drive and is within walking distance to both Battersea Park and Queenstown Road train stations and all the local amenities on Battersea Park Road. No onward chain. ";
 
data[6] = "Brompton Road | Knightsbridge | London | £875,000 | A bright and spacious apartment set on the fifth floor of this popular portered block. The property has been recently decorated and comprises entrance hall, reception room, dining hall, four bedrooms, en-suite bathroom, en-suite shower room, cloakroom, kitchen, lift and porter. Ideally situated in this prestigious address it is within easy access to the wide range of amenities of Knightsbridge. ";
 
data[7] = "Thurloe Place | Knightsbridge | London | £735,000 | A wonderfully bright and spacious second floor flat situated in this mansion block. The flat benefits from porterage and access (by separate negotiation) to the roof terrace and Thurloe Gardens. The flat comprises of two bedrooms and a study, en-suite shower room, bathroom, eat-in kitchen, utility room and large reception room. ";

data[8] = "Cale Street | Chelsea | London | £2,000,000 | A rare opportunity to acquire a magnificent five bedroom period house located in this popular Chelsea Green Village, benefiting from a garden and swimming pool. The property is in good condition and comprises reception room, dining room, kitchen, five bedrooms, three en suite shower rooms, two en suite bathrooms, garden, terrace, heated swimming pool and spa. Ideally situated in this prestigious address, it is within easy access to the wide range of amenities available in Chelsea. ";
 
data[9] = "North Audley Street | Mayfair | London | £2,200,000 | A grand second floor family apartment with high ceilings and views towards Grosvenor Square. The apartment has been modernised over recent years and is beautifully presented. ";
 
data[10] = "Cheyne Walk | Chelsea | London | £999,000 | A bright and spacious fourth floor three bedroom apartment set in this prestigious portered block. The property is offered in good condition throughout and comprises entrance hall, reception room, dining area, open plan kitchen, master bedroom with en-suite bathroom, two further bedrooms and a shower room. Further benefits include lift, 24 hour porterage, underground parking space and access to communal gardens. Ideally situated within easy access to the wide range of amenities available in Chelsea with the added bonus of amazing river views. ";
 
data[11] = "Warriner Gardens | Battersea | London | £275,000 | A bright well presented top floor two bedroom flat in this popular road running parallel behind Battersea Park. This split level property comprises reception room with bay window, kitchen / breakfast room, master bedroom with fitted cupboards, bedroom, bathroom and access to large loft space. Warriner Gardens runs parallel to Prince Of Wales Drive and is conveniently located for access to the open spaces of Battersea Park. Transport is provided by way of Battersea Park station and Queenstown Road. ";

data[12] = "Stroude Road | Virginia Water | Surrey | £999,000 | A former lodge house to Luddington House, the property has undergone extensive refurbishment. Barn like living room with open timbered roofing, travertine marble flooring with underfloor heating throughout kitchen, lounge and hallways. Privately gated with electronic gating; the property sits in an acre of land in one of the most desirable areas for residential property in the UK. Large deck flanked on 2 sides by the house with solid oak double glazed patio doors folding to open the house completely onto gardens. Property is surrounded by a 2ft thick 10 ft high listed Victorian Wall forming a completely private sanctuary. The walls are lit at night as are the 3 gardens. ";

data[13] = "Hillcrest Gardens | Esher | Surrey | £679,500 | Bluebells, birds and badgers – plus brilliant London commuting - are a bonus with this exceptional double-fronted, detached, period five bedroom home on the slopes of Telegraph Hill. Favourably and peacefully situated backing on to woodlands in one of the area’s most sought-after roads, this substantial 1930s property offers an ideal location for London commuters and their families – lovely walks and fresh air on the doorstep but conveniently within a few minutes’ stroll of all amenities. The secure garden is ideal for children and pets and boasts its own locked private gate into the bluebell woods and hence on to Telegraph Hill - requiring the grand sum of £1 a year to be paid for the privilege to the local authority! The badgers? Regular nightly visitors who come to the back gate for their supper of peanuts and a handful of dog food. ";

data[14] = "Wadbrook Street  | Kingston Upon Thames | Surrey | £359,950 | Top (fifth) floor flat in luxury development with direct views on to the Thames. Two bed, 2 bath apartment with GCH, doube glazing and balcony. Apartment complex includes concierge service, underground parking and gymnasium. ";

data[15] = "West End Lane | Stoke Poges | Buckinghamshire | £1,300,000 | An outstanding home that abounds with character and charm, boasting many individual features. West End Lane is arguably the finest road in Stoke Poges, within walking distance of the world famous Stoke Park Golf & Country club, a small picturesque pocket with some of South Bucks aesthetically appealing countryside. ";

data[16] = "Church Street | Bloxham | Oxfordshire | £420,000 | A well appointed Grade 2 listed period House with large gardens in one of North Oxfordshire's most highly regarded villages, this property was originally part of a larger house & dates back to the 17th Centuary. It was renevated & split into 2 in 1999 & has the feel of an old property, with the reassurance of new fixtures & fittings in a lot of areas. We have been very happy in the house & extended the property further in 2001 rather than move as we wanted to stay where we were, but a growing family means we now need to move to a bigger property. Bloxham is a beautiful village with a thriving community, a number of shops, 4 Pubs & a large church. There is a park with childrens play area a few hundred yards from the the house. Bloxham is just 3 miles from Banbury which has all the amenities you would expect of a large town. ";

data[17] = "Maidensgrove | Henley On Thames | Oxfordshire | £820,000 | The house is split level and L shaped with versatile accommodation. The whole of the ground floor has under floor electric heating controlled by individual thermostats, and hardwood parquet flooring most of which is covered by cream wool fitted carpets. The windows and patio doors are double-glazed. The House has a Tyrolean finish that is painted magnolia. A mature hedge borders the front edge of the property. There is a detached double garage 5.56m x 5.17m with two up and over doors, security lights cover the shingle covered parking area for several cars. To the right/front of the house, there are mature fur trees behind which is a useful utility area. To the left/front are a lawn with miniature magnolia tree and an apple tree. The secluded sides and back of the house are mainly lawn with daffodils, herbaceous beds, mature trees, shrubs and clumps of rhododendrons. The patio runs the length of the house and is covered at the kitchen end as mentioned. Through the wrought iron gate between the house and the garage, there is a small kitchen garden planted with herbs. ";

data[18] = "Cozens Lane | Kingham | Oxfordshire | £435,000 | Revelling in an enviable private position within the picturesque sought after village of Kingham, this detached Cotswold residence has been superbly maintained & refurbished by the present owners, & must be inspected to be fully appreciated. The village further enhances the property with its many amenities & facilities which include well-regarded schools, post office, public house, restaurant & hotel. Situated just outside the village, a Hereford to London Paddington mainline railway station is to be found. The accommodation briefly comprises; entrance porch, entrance hall, sitting room, dining room, kitchen, utility room, 3/4 bedrooms, one en-suite shower room & 2 bathrooms. The property benefits from oil fired central heating, large gravelled driveway, double glazing & mature landscaped gardens. ";

data[19] = "Sharnden Manor | Mayfield | East Sussex | £895,000 | Substantial country house, wonderfully situated in an elevated position Approached via shared private drive. Private parking. 2 garages, Middle House retains many of the principal rooms. Nearby, Sharnden Lodge, Coach House, and Lower Sharnden, whilst not at all obtrusive, provide a comfortable feeling of security. Sharnden would admirably suit a growing family, weekend commuters, or as a pied à terre from which to travel abroad. ";

data[20] = "Dunsden Green | Reading | Oxfordshire | £1,375,000 | Peacefully located in a rural but not isolated setting along a no-through lane in the unspoilt hamlet of Dunsden Green in Oxfordshire. Constructed of local brick under a clay tiled roof with leaded light windows, is believed to have been built in 1635 as an ale house. It has been extensively renovated and extended by the present owners and now offers an ideal family home and for those with equestrian interests. The property benefits from a good range of outbuildings including garaging for four cars and a stable yard. There is ample space for the addition of a summer house, swimming pool and tennis court, subject to planning consent. ";

data[21] = "Lincoln Road | Gerrards Cross | Buckinghamshire | £995,000 | Beautiful Family Home, Situated On A Private Estate, Close To Gerrards Cross Golf Club. Our Home Has Been Lovingly Restored And Refurbished To A High Standard, 4 Bedrooms, Master With Ensuite Bathroom And Dressing Room, 2Nd With Ensuite Shower Room. Entrance Porch, Entrance Hall, Cloakroom, Kitchen, Breakfast Room, Family Room, Sitting Room, Dining Room, Conservatory, Garage And Indoor Pool Complex With Changing Rooms, Shower/Steam Room Etc. Gas Fired Central Heating, Large Private Gardens To The Rear Of The Property With A Terraced Area Of Block Paviour Leading Up To A Level Lawn Area With Flower Beds And Shrub Borders, With A Pond And Waterfall. Outside Lighting And Tap And Electricity To Front And Rear. ";

data[22] = "Hall Piece | Clifton Reynes | Buckinghamshire | £795,000 | A splendid period barn conversion, enjoying an idyllic location in a sought sfter hamlet. This impressive property has many outstanding features, most notably an aga kitchen and an inglenook fireplace. In addition to the substancial property there is a self contained annexe.The property commands open views to both front and rear elevations and benefits from oil fired radiator central heating, double glazing, an alarm system and a double width garage. ";

data[23] = "Montpelier Terrace | Brighton | East Sussex | £1,150,000 | Exceptional Italianate period villa Grade 2 listed c1840 in sunny, happy, cosmopolitan free-thinking Brighton and Hove, East Sussex, having arguably the most equable climate in Great Britain, a place where more and more notable personalities are choosing to live. Located in central Brighton it is situated in what is arguable the most prime location for a residence in the city. The first of any of these lovely villas to be built in the road, both of Heatherset's entrances front onto the elegant tree-lined Montpelier Villas one of the most prestigious residential areas in Brighton and Hove. It offers an easily kept, managable sized periphery garden with Italian style planted pots, tubs and urns on a York stone courtyard with herbacious borders, lilac and other shrubs -all within an immaculately kept 2 metre high clipped hedge. This grand and historic town house being so positioned to form as it were the gateway to the prestigious Clifton Hill Conservation Area of which it is an important part - potentially a designer's dream home. ";

-------
Here's the properties.htm file:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>

<title>Properties For Sale</title>
<style type="text/css">
// #myOpts {float:left; width:150px;}
// #firstSortLink {float:left;}
// #secondSortLink {float:right;}

.standard {font-family:Geneva, Arial, Helvetica, sans-serif; font-size:70%; color:rgb(134,146,165); font-weight:bold; letter-spacing:1.2px;}

.headline {font-family:Geneva, Arial, Helvetica, sans-serif; font-size:70%; color:#008080; font-weight:bold; letter-spacing:1.2px;}

a {font-family:Geneva, Arial, Helvetica, sans-serif; font-size:75%; color:#008080; font-weight:bold; letter-spacing:1.2px; text-decoration:none;}

a:hover {font-family:Geneva, Arial, Helvetica, sans-serif; font-size:75%; color:rgb(134,146,165); font-weight:bold; letter-spacing:1.2px;text-decoration:none;}

img {border:0;}
</style>

<script type="text/javascript" src="properties.js"></script>
<script type="text/javascript">
defaultStatus = " "

var opts = new Array();
var sortType = "ascending"; // CHANGE THIS IF WANT DIFFERENT SORT - ascending or descending //

for(i=0, n=data.length; i < n; i++)
{
  // first get parts of array
  var parts = data[i].split(" | ");

  // create new entry for data[i]
  var temp = new Array();

  temp[0] = "<p class='headline' style='font-size:100%;margin-bottom:5px'>" + parts[0] + ", " + parts[1] + ", " + parts[2] +"</p>";
  temp[1] = parts[3];
  temp[2] = "<p style='margin-top:5px;margin-bottom:10px'>" + parts[4] +"</p>";
  temp[3] = "<hr>";

  // store temp back into data
  data[i] = temp;

  // store unique options for drop down
  opts[parts[1]] = 1;
}

function createTable(arr) {
  var numcols=1;
  var numrows=arr[0].length, trow, tcell;
  tbl=document.getElementById("container").firstChild;

  // sort array by price
  if (sortType == "ascending")
    arr.sort(mySort);
  else if (sortType == "descending")
    arr.sort(myReverseSort);

  // first clear all rows except sorter row
  for (var i = 0, n = tbl.rows.length; i < n; i ++)
    tbl.removeChild(tbl.rows[0]);

  // now re-build table
  for(var n=0;n<arr.length;n+=numcols){
    for(var i=0;i<numrows;i++){
      trow=document.createElement("tr");
      for(var j=0;j<numcols;j++){
        tcell=document.createElement("td");
        if(!arr[n+j]){tcell.innerHTML="";}
        else{tcell.innerHTML=arr[n+j][i];}
        trow.appendChild(tcell);
      }
      tbl.appendChild(trow);
    }
  }

  // hide the welcome message
  document.getElementById("welcome").style.display = "none";
}

function createOptions()
{
  var obj = document.getElementById("myOpts").getElementsByTagName("tbody")[0];

  var temp = new Array();
  for (var i in opts)
    temp[temp.length] = i;
  temp.sort();

  for (var i = 0, n = temp.length; i < n; i++)
  {
    var myRow = document.createElement("tr");
    var myCell = document.createElement("td");
    var myAnchor = document.createElement("a");
    myAnchor.href = "#";
    myAnchor.className = "theClassName";
    myAnchor.innerHTML = temp[i];
    myAnchor.onclick = filter;
    myAnchor.onfocus = function() {if(this.blur)this.blur();};
    myCell.appendChild(myAnchor);
    myRow.appendChild(myCell);
    obj.appendChild(myRow);
  }

  // add in last link for "ALL"
  var myRow = document.createElement("tr");
  var myCell = document.createElement("td");
  var myAnchor = document.createElement("a");
  myAnchor.href = "#";
  myAnchor.className = "theClassName";
  myAnchor.innerHTML = "List all properties";
  myAnchor.onclick = function() {includeArr = data; createTable(data);};
  myAnchor.onfocus = function() {if(this.blur)this.blur();};
  myAnchor.onmouseover = function() {window.status='View entire property list'; return true};
  myAnchor.title = "This will load the entire property list.\nAs this is quite large, it may take some\ntime to download, so please be patient";
  myCell.appendChild(myAnchor);
  myRow.appendChild(myCell);
  obj.appendChild(myRow);
}

function filter()
{
  var key = this.innerHTML;
  includeArr = new Array();
  for (var i = 0, n = data.length; i < n; i ++)
  {
    var location = data[i][0];
    if (location.indexOf(key) > -1)
      includeArr[includeArr.length] = data[i];
  }
  createTable(includeArr);
}

function mySort(a, b)
{
  var priceStrA = a[1].split("-")[0].substr(1);
  priceStrA = priceStrA.split(",").join("");
  var priceA = parseInt(priceStrA);

  var priceStrB = b[1].split("-")[0].substr(1);
  priceStrB = priceStrB.split(",").join("");
  var priceB = parseInt(priceStrB);

  if (priceA > priceB)
    return 1;
  else if (priceA == priceB)
    return 0;
  else
    return -1;
}

function myReverseSort(a, b)
{
  return (-1 * mySort(a, b));
}

</script>

</head>

<body onload="includeArr = data; createOptions();">

<table align="center" border="0">

      <td width="130" align="left" valign="top">
            <table id="myOpts" border='0'><tbody></tbody></table>
      <td>

      <td width="410" align="left" valign="top">
            <table id="container" align="center" cellspacing="0" cellpadding="0" border="0" width="400" class='standard'><tbody></tbody><p></table>

            <div id="welcome" class="standard">Hello, this is a quick welcome message.  It's mission, which it has chosen to accept, is to to illustrate the behavior of this page.  It is not much to look at it, as it is trying to keep a low profile.  This message will self-destruct (disappear) when you click on one of the links on the left.  G'luck.</div>
      </td>

<table>

</body>
</html>

--------

I don't want radical changes (if possible) just enhancements please.

Many thanks in advance.

Regards

Pantyboy
0
Martin Cotterill
Asked:
Martin Cotterill
  • 3
  • 2
1 Solution
 
dakydCommented:
Give this a shot - I had to change the menu system from tables to a list-based/CSS approach, because using tables makes things overly complicated and doesn't provide you nearly as much flexibility.  I also sorted the sub-menus alphabetically, though that doesn't necessarily match the order in which the properties appear (properties are sorted by price).  Anyhow, hope that helps.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>

<title>Properties For Sale</title>
<style type="text/css">
.standard {font-family:Geneva, Arial, Helvetica, sans-serif; font-size:70%; color:rgb(134,146,165); font-weight:bold; letter-spacing:1.2px;}

.headline {font-family:Geneva, Arial, Helvetica, sans-serif; font-size:70%; color:#008080; font-weight:bold; letter-spacing:1.2px;}

a {font-family:Geneva, Arial, Helvetica, sans-serif; font-size:75%; color:#008080; font-weight:bold; letter-spacing:1.2px; text-decoration:none;}

a:hover {font-family:Geneva, Arial, Helvetica, sans-serif; font-size:75%; color:rgb(134,146,165); font-weight:bold; letter-spacing:1.2px;text-decoration:none;}

#nav, #nav ul {
  margin: 0;
  padding: 0;
  list-style: none;
}

#nav li ul {
  display: none;
}

#nav li ul a {
  margin-left: 20px;
}
img {border:0;}
</style>

<script type="text/javascript" src="properties.js"></script>
<script type="text/javascript">
defaultStatus = " ";

var opts = new Array();
var sortType = "ascending"; // CHANGE THIS IF WANT DIFFERENT SORT - ascending or descending //
var lastSub = null;

for(i=0, n=data.length; i < n; i++)
{
  // first get parts of array
  var parts = data[i].split(" | ");

  // create new entry for data[i]
  var temp = new Array();

  temp[0] = "<p class='headline' style='font-size:100%;margin-bottom:5px'>" + parts[0] + ", " + parts[1] + ", " + parts[2] +"</p>";
  temp[1] = parts[3];
  temp[2] = "<p style='margin-top:5px;margin-bottom:10px'>" + parts[4] +"</p>";
  temp[3] = "<hr>";

  // store temp back into data
  data[i] = temp;

  // store unique options for drop down
  if (!opts[parts[2]])
    opts[parts[2]] = new Array();
  opts[parts[2]][parts[1]] = 1;
}

function createTable(arr) {
  var numcols=1;
  var numrows=arr[0].length, trow, tcell;
  tbl=document.getElementById("container").firstChild;

  // sort array by price
  if (sortType == "ascending")
    arr.sort(mySort);
  else if (sortType == "descending")
    arr.sort(myReverseSort);

  // first clear all rows except sorter row
  for (var i = 0, n = tbl.rows.length; i < n; i ++)
    tbl.removeChild(tbl.rows[0]);

  // now re-build table
  for(var n=0;n<arr.length;n+=numcols){
    for(var i=0;i<numrows;i++){
      trow=document.createElement("tr");
      for(var j=0;j<numcols;j++){
        tcell=document.createElement("td");
        if(!arr[n+j]){tcell.innerHTML="";}
        else{tcell.innerHTML=arr[n+j][i];}
        trow.appendChild(tcell);
      }
      tbl.appendChild(trow);
    }
  }

  // hide the welcome message
  document.getElementById("welcome").style.display = "none";
}

function createOptions()
{
  var obj = document.getElementById("nav");

  var temp = new Array();
  for (var i in opts)
    temp[temp.length] = i;
  temp.sort();
  var innerTemp = new Array();

  for (var i = 0, n = temp.length; i < n; i++)
  {
    var listItem = document.createElement("li");
    var myAnchor = document.createElement("a");
    myAnchor.href = "#";
    myAnchor.className = "theClassName";
    myAnchor.innerHTML = temp[i];
    myAnchor.onclick = filter;
    myAnchor.onfocus = function() {if(this.blur)this.blur();};
    myAnchor.title = "Show all properties for " + temp[i];
    listItem.appendChild(myAnchor);

    var sub = document.createElement("ul");

    var innerTemp = new Array();
    for (var j in opts[temp[i]])
      innerTemp[innerTemp.length] = j;
    innerTemp.sort();

    for (var j = 0, k = innerTemp.length; j < k; j ++)
    {
      var subLi = document.createElement("li");
      var tempAnchor = document.createElement("a");
      tempAnchor.href = "#";
      tempAnchor.className = "subMenu";
      tempAnchor.innerHTML = innerTemp[j];
      tempAnchor.onclick = filter;
      subLi.appendChild(tempAnchor);
      sub.appendChild(subLi);
    }
    listItem.appendChild(sub);
    obj.appendChild(listItem);
  }

  // add in last link for "ALL"
  var listItem = document.createElement("li");
  var myAnchor = document.createElement("a");
  myAnchor.href = "#";
  myAnchor.className = "lastOne";
  myAnchor.innerHTML = "List all properties";
  myAnchor.onclick = function() {if (lastSub != null) lastSub.style.display = "none"; lastSub = null; includeArr = data; createTable(data);};
  myAnchor.onfocus = function() {if(this.blur)this.blur();};
  myAnchor.onmouseover = function() {window.status='View entire property list'; return true};
  myAnchor.title = "This will load the entire property list.\nAs this is quite large, it may take some\ntime to download, so please be patient";
  listItem.appendChild(myAnchor);
  obj.appendChild(listItem);
}

function filter()
{
  if (this.parentNode.getElementsByTagName("ul").length > 0)
  {
    if (lastSub != null)
      lastSub.style.display = "none";
    lastSub = this.parentNode.getElementsByTagName("ul")[0];
    lastSub.style.display = "block";  
  }

  var key = this.innerHTML;
  includeArr = new Array();
  for (var i = 0, n = data.length; i < n; i ++)
  {
    var location = data[i][0];
    if (location.indexOf(key) > -1)
      includeArr[includeArr.length] = data[i];
  }
  createTable(includeArr);
}

function mySort(a, b)
{
  var priceStrA = a[1].split("-")[0].substr(1);
  priceStrA = priceStrA.split(",").join("");
  var priceA = parseInt(priceStrA);

  var priceStrB = b[1].split("-")[0].substr(1);
  priceStrB = priceStrB.split(",").join("");
  var priceB = parseInt(priceStrB);

  if (priceA > priceB)
    return 1;
  else if (priceA == priceB)
    return 0;
  else
    return -1;
}

function myReverseSort(a, b)
{
  return (-1 * mySort(a, b));
}

</script>

</head>

<body onload="includeArr = data; createOptions();">

<table align="center" border="0">

     <td width="175" align="left" valign="top">
          <ul id="nav"></ul>
     <td>

     <td width="410" align="left" valign="top">
          <table id="container" align="center" cellspacing="0" cellpadding="0" border="0" width="400" class='standard'><tbody></tbody><p></table>

          <div id="welcome" class="standard">Hello, this is a quick welcome message.  It's mission, which it has chosen to accept, is to to illustrate the behavior of this page.  It is not much to look at it, as it is trying to keep a low profile.  This message will self-destruct (disappear) when you click on one of the links on the left.  G'luck.</div>
     </td>

<table>

</body>
</html>
0
 
Martin CotterillDabblerAuthor Commented:
Hi dakyd

What can I say? You've come up trumps once again. It works like a dream.

Something came to mind as I was using the script ("Oh no, here we go again!" I hear you cry). If I wanted to create some blurb about the counties that shows each time you click a top level menu item instead of a full list as it is now, would that be easy to do.

What I'm thinking is that, say you clicked the menu item 'Surrey', instead of getting the full list of properties in Surrey, you got some blurb about Surrey; if you clicked London, some blurb about London would show, etc. Would this easy to do and how would it be done? Also, how would you then create a 'list all properties' link in each submenu to show all the properties of that county?

If you don't wish to answer these supplemental questions, please say so, I won't be offended in any way as I don't want to overstep the mark. If you think that they should be posted as a seperate question, please say and I will do so, they are just something that came to mind as I was looking at the results of the script.

Regards

Pantyboy
0
 
dakydCommented:
I had to change a few things around, but the end result is that you'll get a blurb for each county that will disappear once a city is chosen.  The blurbs themselves are stored in an array called "blurbs", much the same way that the properties were stored in an array.  This one isn't external, though you could easily move it to an external js file.  Hope that helps.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>

<title>Properties For Sale</title>
<style type="text/css">
.standard {font-family:Geneva, Arial, Helvetica, sans-serif; font-size:70%; color:rgb(134,146,165); font-weight:bold; letter-spacing:1.2px;}

.headline {font-family:Geneva, Arial, Helvetica, sans-serif; font-size:70%; color:#008080; font-weight:bold; letter-spacing:1.2px;}

a {font-family:Geneva, Arial, Helvetica, sans-serif; font-size:75%; color:#008080; font-weight:bold; letter-spacing:1.2px; text-decoration:none;}

a:hover {font-family:Geneva, Arial, Helvetica, sans-serif; font-size:75%; color:rgb(134,146,165); font-weight:bold; letter-spacing:1.2px;text-decoration:none;}

#nav, #nav ul {
  margin: 0;
  padding: 0;
  list-style: none;
}

#nav li ul {
  display: none;
  margin-left: 10px;
  cursor: pointer;
}

img {border:0;}
</style>

<script type="text/javascript" src="properties.js"></script>
<script type="text/javascript">
defaultStatus = " ";

var blurbs = new Array();
blurbs["Buckinghamshire"] = "Buckinghamshire blurb goes here."
blurbs["East Sussex"] = "The blurb about East Sussex will take the place of this message."
blurbs["London"] = "Would you like some info about London?  This is where it will be.";
blurbs["Oxfordshire"] = "Info!  Info!  I've got info about Oxfordshire!";
blurbs["Surrey"] = "Psst ... yeah, hey you .... you interested in information on Surrey?";


var opts = new Array();
var sortType = "ascending"; // CHANGE THIS IF WANT DIFFERENT SORT - ascending or descending //
var lastSub = null;

for(i=0, n=data.length; i < n; i++)
{
  // first get parts of array
  var parts = data[i].split(" | ");

  // create new entry for data[i]
  var temp = new Array();

  temp[0] = "<p class='headline' style='font-size:100%;margin-bottom:5px'>" + parts[0] + ", " + parts[1] + ", " + parts[2] +"</p>";
  temp[1] = parts[3];
  temp[2] = "<p style='margin-top:5px; padding-bottom:10px; border-bottom: 1px solid black'>" + parts[4] +"</p>";

  // store temp back into data
  data[i] = temp;

  // store unique options for drop down
  if (!opts[parts[2]])
    opts[parts[2]] = new Array();
  opts[parts[2]][parts[1]] = 1;
}

function createTable(arr) {
  var numcols=1;
  var numrows=arr[0].length, trow, tcell;
  tbl=document.getElementById("container").firstChild;

  // sort array by price
  if (sortType == "ascending")
    arr.sort(mySort);
  else if (sortType == "descending")
    arr.sort(myReverseSort);

  // first clear all rows
  for (var i = 0, n = tbl.rows.length; i < n; i ++)
    tbl.removeChild(tbl.rows[0]);

  // now re-build table
  for(var n=0;n<arr.length;n+=numcols){
    for(var i=0;i<numrows;i++){
      trow=document.createElement("tr");
      for(var j=0;j<numcols;j++){
        tcell=document.createElement("td");
        if(!arr[n+j]){tcell.innerHTML="";}
        else{tcell.innerHTML=arr[n+j][i];}
        trow.appendChild(tcell);
      }
      tbl.appendChild(trow);
    }
  }

  // show table && hide the blurb/welcome message
  tbl.parentNode.style.display = "block";
  document.getElementById("content").style.display = "none";
}

function createOptions()
{
  var obj = document.getElementById("nav");

  var temp = new Array();
  for (var i in opts)
    temp[temp.length] = i;
  temp.sort();
  var innerTemp = new Array();

  for (var i = 0, n = temp.length; i < n; i++)
  {
    var listItem = document.createElement("li");
    var myAnchor = document.createElement("a");
    myAnchor.href = "#";
    myAnchor.className = "theClassName" + i;
    myAnchor.innerHTML = temp[i];
    myAnchor.onclick = showSub;
    myAnchor.onfocus = function() {if(this.blur)this.blur();};
    myAnchor.title = "Show all properties for " + temp[i];
    listItem.appendChild(myAnchor);

    var sub = document.createElement("ul");

    var innerTemp = new Array();
    for (var j in opts[temp[i]])
      innerTemp[innerTemp.length] = j;
    innerTemp.sort();

    for (var j = 0, k = innerTemp.length; j < k; j ++)
    {
      var subLi = document.createElement("li");
      var tempAnchor = document.createElement("a");
      tempAnchor.href = "#";
      tempAnchor.className = "subMenu";
      tempAnchor.innerHTML = innerTemp[j];
      tempAnchor.onclick = function() {filter(this.innerHTML);};
      subLi.appendChild(tempAnchor);
      sub.appendChild(subLi);
    }
    var subLi = document.createElement("li");
    var tempAnchor = document.createElement("a");
    tempAnchor.className = "subMenu";
    tempAnchor.innerHTML = "All Properties in " + temp[i];
    tempAnchor.onclick = function() {filter(this.parentNode.parentNode.parentNode.firstChild.innerHTML);};
    subLi.appendChild(tempAnchor);
    sub.appendChild(subLi);
    listItem.appendChild(sub);
    obj.appendChild(listItem);
  }

  // add in last link for "ALL"
  var listItem = document.createElement("li");
  var myAnchor = document.createElement("a");
  myAnchor.href = "#";
  myAnchor.className = "lastOne";
  myAnchor.innerHTML = "List all properties";
  myAnchor.onclick = function() {if (lastSub != null) lastSub.style.display = "none"; lastSub = null; includeArr = data; createTable(data);};
  myAnchor.onfocus = function() {if(this.blur)this.blur();};
  myAnchor.onmouseover = function() {window.status='View entire property list'; return true};
  myAnchor.title = "This will load the entire property list.\nAs this is quite large, it may take some\ntime to download, so please be patient";
  listItem.appendChild(myAnchor);
  obj.appendChild(listItem);
}

function filter(key)
{
  includeArr = new Array();
  for (var i = 0, n = data.length; i < n; i ++)
  {
    var location = data[i][0];
    if (location.indexOf(key) > -1)
      includeArr[includeArr.length] = data[i];
  }
  createTable(includeArr);
}

function showSub()
{
  // show correct sub-menu
  if (lastSub != null)
    lastSub.style.display = "none";
  lastSub = this.parentNode.getElementsByTagName("ul")[0];
  lastSub.style.display = "block";

  // show blurb && hide table
  var key = this.innerHTML.replace(/^(\s+)|(\s+)$/g, "");
  var blurbObj = document.getElementById("content");
  blurbObj.innerHTML = blurbs[key];
  blurbObj.style.display = "block";
  document.getElementById("container").style.display = "none";
}

function mySort(a, b)
{
  var priceStrA = a[1].split("-")[0].substr(1);
  priceStrA = priceStrA.split(",").join("");
  var priceA = parseInt(priceStrA);

  var priceStrB = b[1].split("-")[0].substr(1);
  priceStrB = priceStrB.split(",").join("");
  var priceB = parseInt(priceStrB);

  if (priceA > priceB)
    return 1;
  else if (priceA == priceB)
    return 0;
  else
    return -1;
}

function myReverseSort(a, b)
{
  return (-1 * mySort(a, b));
}

</script>

</head>

<body onload="includeArr = data; createOptions();">

<table align="center" border="0">

     <td width="175" align="left" valign="top">
          <ul id="nav"></ul>
     <td>

     <td width="410" align="left" valign="top">
          <table id="container" align="center" cellspacing="0" cellpadding="0" border="0" width="400" class='standard'><tbody></tbody><p></table>

          <div id="content" class="standard">Hello, this is a quick welcome message.  It's mission, which it has chosen to accept, is to to illustrate the behavior of this page.  It is not much to look at it, as it is trying to keep a low profile.  This message will self-destruct (disappear) when you click on one of the links on the left.  G'luck.</div>
     </td>

</table>

</body>
</html>
0
 
Martin CotterillDabblerAuthor Commented:
Hi dakyd

Bang on. Absolutely bang on.

I won't pretend to understand what any of this code means as I've been trying from the very first, but this is fantastic.

Thanks very, very much.

Regards

Pantyboy
0
 
dakydCommented:
No sweat, glad to hear you got what you wanted.  I can explain the code if that'll help, but if you're not worried about it so long as it works, then that works for me, too.  =p  Thanks for the points.
0

Featured Post

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

  • 3
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now