Wrote a nested accordion

I’m new to dhtmlx. It’s wonderful.

I have many modules in my project and plan to implement by dhtmlx accordion. But its multiMode is not so good cause it ocuupies too many screens. And singleMode still has same problems when there is many accordion items. So I rewrote the file dhtmlxaccordion.js to touch my needs.

My thinking is, at first all items should be closed. illustration:


When I click someone, it should open and all other items should be closed. illustration:


Cause I have many modules, so my accordion item has its subaccordion as shown. Click sub accordion to open illustrate as below, the items in subaccordion implementss using dataviews:


And all items will close when I click the opened item.illustration:

These modification is added in dhtmlxaccordion.js:

  1. Function enableSingleModeClose() is added to enable such mechanism.
  2. Function getItemNums() is used to get whether an accordion item has nested accordions.
  3. (OnActive, false) event will be triggered when an opend item is clicked

Client side code is:

function loadAccordion (obj,id) { var accord = obj.attachAccordion (); // accordion level 1 accord.setSkin (wup.skin); accord.enableSingleModeClose (true); // its an added function accord.loadXML ('./Common/mainAccord.php?type=accord&id='+id,function(){ if (accord.getItemNums() == 0) { // has no accordion,its an added function attachDataView (obj); // show dataview } else { accord.forEachItem (function(item){ // item of accordion level 1 loadAccordion (item,item.getId()); // level 2 }); } }); }

Server code is:

[code] echo “”;

	$sql = "SELECT * FROM Accordion WHERE idParent = ?";
	$stmt = $res->prepare ($sql);
	$result = $stmt->execute (array($id));
	
	$rows = $stmt->fetchAll ();
	$first = true;
	foreach ($rows AS $row) {
		$sql = "SELECT * FROM Accordion WHERE idParent = ?";
		$stmt = $res->prepare ($sql);
		$result = $stmt->execute (array($row['idAccordion']));
		$sonNums = $stmt->rowCount ();

		if ($sonNums == 0) {
			$sql = "SELECT * FROM Accordion_has_DataView ";
			$sql.= "WHERE Accordion_has_DataView.idAccordion =? ";
			$stmt = $res->prepare ($sql);
			$stmt->execute (array($row['idAccordion']));
			$dataviewNums = $stmt->rowCount ();
		}

		if (!empty($dataviewNums))
			echo "<cell id='".$row['idAccordion']."' open='".$first."' icon='".$row['CellIcon']."' idParent='".$row['idParent']."'>".$row['CellName']."</cell>";
		$first = false;
	}
	echo "</accordion>";

[/code]

Cause I am also a newer to js. I don’t know how to solve a problem in my solution. That is at first dhtmlxaccordion always opens one item but my wish is all items should be closed.

dhtmlxaccordion.js
dhtmlxaccordion.rar (7.79 KB)

Hi

this.addItem = function(itemId, itemText) {

this.openItem(itemId); <-- this will open item right after adding
return item;
}

for xml loading, after all items will rendered also call accord.setSizes()
which will fix borders if all items will closed on init

Hi Andrei.

I have noticed them in “this.addItem = function(itemId, itemText)”, but only deleted " this.openItem(itemId);" a few days ago. The result is all items is closed after load, but then can’t closed if it opened. The right way is to delete all these three lines. So all items will closed after load and click to open and click to close.
Thanks!

[code] this.openItem(itemId);

	this._enableOpenEffect = e;
	//
	if (!this.multiMode) this._defineLastItem(); else this.setSizes();
	//
	
	return item;

[/code]