How to reconcile index in HTML and Javascript

I am using an according script that requires two elements to share the same index number, for example: runAccordion2 and Accordion2Content, which both need to share the “2.”

I am dynamically populating each of those elements from a database, and using item[‘id’] to fill in the index number of each element so they are paired correctly, with each pair sharing the database index number. Unfortunately, the JS doesn’t seem to recognize the index numbering this way.

Here is the code that grabs the data from the database and shows it:

function showRecords() {
        results.innerHTML = ''; // clear the results div
        db.transaction(function(tx) {
          tx.executeSql(selectAllStatement, [], function(tx, result) {
dataset = result.rows;
            for (var i = 0, item = null; i < dataset.length; i++) {
              item = dataset.item(i);
             results.innerHTML = '<div id="AccordionContainer" class="AccordionContainer">';
              results.innerHTML +=
                  '<div onclick="runAccordion(' + item['id'] + ');"><input class="AccordionTitle" type="button" value="' + item['term'] + '"></div><div id="Accordion' + item['id'] + 'Content" class="AccordionContent"><div class="glossaryContent"><button class="glossaryEditButton" style="float:left;" onClick="loadRecord(' + item['id'] + ')">Edit</button>  ' +  '<button class="glossaryDelButton" style="float:right;" onClick="deleteRecord(' + item['id'] + ')">Delete</button>' + item['definition'] + '</div></div>';
}
          });
        }); results.innerHTML += '</div>';  exportRecords(); /* populates the hidden span with non-HTML version of code so it's ready to export. */
      }

Here’s the code that references the index number in the JS:

function runAccordion(index)
{
  var nID = "Accordion" + index + "Content";
  if(openAccordion == nID)
    nID = '';

  setTimeout("animate(" + new Date().getTime() + "," + TimeToSlide + ",'"
      + openAccordion + "','" + nID + "')", 33);

  openAccordion = nID;
}

As a result, when I click on the Delete or Edit buttons, they don’t active, with Google Tools stating that the index is out of bounds. Google Tools shows all the data correctly entered into the database, so the database entry part is working fine. Also, only the first record is showing; subsequent records don’t get listed.

The accordion idea is an addition to the code, which worked perfectly before adding the accordion. I am using this accordion script: http://tech.pro/tutorial/697/javascript-and-css-tutorial-accordion-menus

Thanks!

If you could give us access to a test page, this should be relatively trivial to resolve.

Hi StevenHu,

Kindly got through below suggestions, they might help you.

  1. Through firefox - firebug addon please check if the dynamic content is coming properly along with the value.
  2. Instead of just using ‘click’ event, try to use ‘live’ + ‘click’ for dynamic values
  3. Try to compare the actual index instead of making it a string.

Just to elaborate on this, the .live() method was deprecated in jQuery 1.9
If you are using this version, you will have to use .on() instead.

Hi Pullo,

Thanks for your input :slight_smile:

I put all the code into one HTML page, attached. Unfortunately, now it is giving another error,

could not prepare statement (1 near “-”: syntax error)

I looks like the page did not like the use of a dash in my database name. I took care of that and now the accordion works - almost! The accordion is now populated by the database, but when clicking on the title, the accordion opens and shuts quickly. I don’t see how it stays open. Revised page is attached.

first simplify the html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
    "http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>
  <title></title>
<style type="text/css">
<!--
.AccordionTitle, .AccordionContent, .AccordionContainer
{
  position:relative;
  width:200px;
}

.AccordionTitle
{
  height:20px;
  overflow:hidden;
  cursor:pointer;
  font-family:Arial;
  font-size:8pt;
  font-weight:bold;
  vertical-align:middle;
  text-align:center;
  background-repeat:repeat-x;
  display:table-cell;
  background-image:url('title_repeater.jpg');
  -moz-user-select:none;
}

.AccordionContent {
  background-Color:#FFFFCC;
  overflow:hidden;
  display:none;
}

.AccordionContainer
{
  border-top: solid 1px #C1C1C1;
  border-bottom: solid 1px #C1C1C1;
  border-left: solid 2px #C1C1C1;
  border-right: solid 2px #C1C1C1;
}
-->
</style>

<script type="text/javascript">

function Accordion(o){
 var obj=document.getElementById(o.ID);
 if (obj){
  var ms=o.Speed,m=this.bycls('Accordion',obj),s=this.bycls('AccordionContent',obj),a=[],z0=0;
  for (;z0<m.length;z0++){
   if (s[z0]){
    s[z0].style.display='block';
    a[z0]=[s[z0],s[z0].offsetHeight,true,0];
    s[z0].style.display='none';
    this.addevt(m[z0],'mouseup','toggle',z0);
   }
  }
  this.a=a;
  this.lst=a[0];
  this.ms=typeof(ms)=='number'?ms:1000;
 }
}

Accordion.prototype={

 toggle:function(nu){
  var o=this,a=this.a[nu];
  o.lst!=a&&!o.lst[2]?o.animate(o.lst,o.lst[3],0,new Date(),o.ms):null;
  a[0].style.display='block';
  o.animate(a,a[3],a[2]?a[1]:0,new Date(),this.ms);
  a[2]=!a[2];
  o.lst=a
 },

 animate:function(a,f,t,srt,mS){
  clearTimeout(a[4]);
  var o=this,ms=new Date().getTime()-srt,n=(t-f)/mS*ms+f;
  if (isFinite(n)){
   a[3]=Math.max(n,0);
   a[0].style.height=a[3]+'px';
  }
  if (ms<mS){
   a[4]=setTimeout(function(){ o.animate(a,f,t,srt,mS); },10);
  }
  else {
   a[3]=t;
   a[0].style.height=t+'px';
   t==0?a[0].style.display='none':null;
  }
 },


 addevt:function(o,t,f,p){
  var oop=this;
  if (o.addEventListener){
   o.addEventListener(t,function(e){ return oop[f](p);}, false);
  }
  else if (o.attachEvent){
   o.attachEvent('on'+t,function(e){ return oop[f](p); });
  }
 },

 bycls:function (nme,el){
  for (var reg=new RegExp(' '+nme+' '),els=el.getElementsByTagName('*'),ary=[],z0=0; z0<els.length;z0++){
   if(reg.test(' '+els[z0].className+' ')){
    ary.push(els[z0]);
   }
  }
  return ary;
 }

}

</script>

<script type="text/javascript">

function Init(){

new Accordion({
 ID:'AccordionContainer', // the unique ID name of the accordian parent DIV.    (string)
 Speed:1000               //(optional) the animation duration in milli seconds. (number, default = 1000)
});

}

if (window.addEventListener){
 window.addEventListener('load',Init, false);
}
else if (window.attachEvent){
 window.attachEvent('onload',Init);
}

</script>

</head>

<body>
<div id="AccordionContainer" class="AccordionContainer">

    <div class="AccordionTitle">
      <input name="" value="Accordion 1"  class="Accordion" >
    </div>
    <div class="AccordionContent">
      I Am Accordion 1.<br>
      I Am Accordion 1.<br>
      I Am Accordion 1.<br>
      I Am Accordion 1.<br>
    </div>

    <div class="AccordionTitle">
      <span class="Accordion" >Accordion 2</span>
    </div>
    <div class="AccordionContent" >
     I Am Accordion 2.<br>
     I Am Accordion 2.<br>
     I Am Accordion 2.<br>
     I Am Accordion 2.<br>
     I Am Accordion 2.<br>
     I Am Accordion 2.<br>
     I Am Accordion 2.<br>
    </div>

    <div class="AccordionTitle">
      <span class="Accordion" >Accordion 3</span>
    </div>
    <div class="AccordionContent">
    I Am Accordion 3.<br>
    I Am Accordion 3.<br>
    I Am Accordion 3.<br>
    I Am Accordion 3.<br>
    I Am Accordion 3.<br>
    </div>

    <div class="AccordionTitle">
      <span class="Accordion" >Accordion 4</span>
    </div>
    <div id="Accordion4Content" class="AccordionContent">
     I Am Accordion 4.<br>
     I Am Accordion 4.<br>
    </div>

    <div class="AccordionTitle">
      <span class="Accordion" >Accordion 5</span>
    </div>
    <div id="Accordion5Content" class="AccordionContent">
     I Am Accordion 5.<br>
     I Am Accordion 5.
    </div>

</div>

</body>

</html>

This is an entirely different accordion. I notice that sometimes when clicking a second or third accordion title, it merely closes an open one without opening the title clicked on.