Just nu i M3-nätverket
Gå till innehåll

Trädmeny


Dahlgren

Rekommendera Poster

Hejsan.

 

Hur gör jag lättast en meny i träd-stil som den Clas Ohlson har på sin sida: http://www.clasohlson.se/

 

Det jag tänkte på var hur man ska lösa det hela i databasen. Ska det tillverkas en ny tabell för varje nivå eller?

 

Någon som kan hjälpa mig med det här?

 

Mvh

[inlägget ändrat 2003-07-28 19:47:07 av Gren]

Länk till kommentar
Dela på andra webbplatser

Ska det tillverkas en ny tabell för varje nivå eller?

 

Tycker jag inte. Det räcker med att skapa kolumner som visar vilken nivå den hör till respektive ID:t på rubriken i den föregående kategorin. (så att man vet vad som ska öppnas när man klickar på länken)

 

Länk till kommentar
Dela på andra webbplatser

Men då måste jag ju ändå ha en tabell för varje nivå för att kunna hänvisa till ett speciellt nivå-id.

 

Länk till kommentar
Dela på andra webbplatser

ID (Auto_increment) | level | name | previous |

1 1 Om sidan 0

2 2 Copyright 1

3 1 Nyheter 0

4 2 Arkiv 3

5 3 År-01 4

 

likannde detta använder jag på mitt förum som jag håller på omed och det fungerar bra

 

[EDIT] Previous är alltså det unika ID:t på posten i föregående hierarki

[inlägget ändrat 2003-07-28 21:31:18 av lillen_009]

Länk till kommentar
Dela på andra webbplatser

Hur ska du annars veta vilka poster som ska öppnas? Du har ju olika kategorier som visas från start (de poster som visas är de som har level=0

 

 

För nivå 1 bllir det:

 

"SELECT * FROM menu WHERE level=1 AND previous=" & request.querystring("previous") & " ORDER BY name DESC"

 

 

Det finns ju olika poster och alla underkategorier ska inte öppnas samtidigt. level säger inget om vilken tidigare rubrik den hör till

 

 

 

Länk till kommentar
Dela på andra webbplatser

Okej, jag ska testa att göra som du beskriver. Lite svårt att spekulera i hur det blir när man inte håller på att programmera med det just för tillfället.

 

Länk till kommentar
Dela på andra webbplatser

Det går säker bra. Bestäm dig bara för i tid och du ska skicka värden i querystrin eller genom <input type="hidden">

 

Återkom om du har problem

 

Länk till kommentar
Dela på andra webbplatser

Level är onödig. Previous=0 kan användas för poster överst i trädet. Jag föredrar dock att kalla det för Parent=Förälder.

 

 

Länk till kommentar
Dela på andra webbplatser

Magnus Gladh

Nu när du fått tag i din databasstruktur. Så kommer du garanterat stötta på problemt att när vet jag hur många underposter en post har.

 

Det vanliga är att man försöker loppa sig igenom på någon vänster och man kommer fram till att det inte går eftersom du inte vet hur många underpost en post har, och att de är olika på varje post :)

 

Det är här som rekursivitet kommer in i bilden. Det är helt enkelt en funktion som kallar på sig själv till ett givet vilkor. I detta fallet när det inte finns fler poster.

 

När det inträffar så börjar den rekursiva funktionen rulla upp sig och kan då kalla på andra under poster för en högre post. Säg att din databas ser ut så här.

 

ID|Parent|Name

==============

_1|_____0|MC

_2|_____6|SAAB

_3|_____2|9-3

_4|_____1|Honda

_5|____4|VFR750

_6|_____0|Bilar

_7|_____6|Volvo

_8|_____7|Combi

_9|_____7|Cab

10|_____8|V70

11|_____9|S60

 

 

Om du skriver ut denna som en meny så blir det så här

-------------------

 

MC

_Honda

__VFR750

Bilar

_Volvo

__Combi

___V70

__Cab

___S60

_SAAB

__9-3

 

 

Här kan du alltså inte gör någon sorts loop eftersom de olika posterna har olika många underposter.

 

Däremot vår rekursiva funktion klara det här jätte bra. Så här fungerar den:

 

1. Skapa en funktion som hämtar alla poster som har PARENT = ????

2. Skriv ut posten och kalla sedan på funktinen med den nya postens PARENT ID.

 

Enkelt va?

 

Så här skulle den kunna se ut:

 

function getPost(iParent)
'-- open connection to databas
....

'-- build SQL statment
sSQL = "SELECT * FROM [posts] WHERE [Parent] = " & iparent

'-- get all posts
oRs = .......

'-- loop throu record set
do until oRs.eof
_response.write oRs.fields("Name").value
_'-- get all subpost for this post
_getPost(oRs.fields("ID").value)
_oRs.movenext
loop

'-- clean up databasconnection after us.
.....
end function

 

Så svårare än så är det inte. Vad som händer är att första gången som man kallar på funktionen så skickar man in 0, alltså:

getPost(0)

 

Då kommer man få ett recordset som innehåller Bilar och MC. Man kommer först Skriva ut MC på skärmen och sedan kommer man kalla på functionen med MC's ID nummer och funktionen kommer att hämta ut alla poster som har MC som Parent, i detta fallet är det HONDA. Honda kommer att skrivas ut på skärmen på man kommer nu hämta all poster som har HONDA som Parent och det är posterna VFR750. VFR750 kommer skrivas ut på skärmen och man kommer återigen kalla på funktinen nu med VFR750's ID nummer.

 

om vi nu skulle titta i minnet så skulle vi ha 3 stycken recordset öppna. (

Ett som innehåller.

-----------------------

MC <- HÄR STÅR VI I DETTA RS

Bilar

 

Ett som innehåller

----------------

Honda <- HÄR STÅR VI I DETTA RS

 

Ett som innehåller

---------------

VFR750 <- HÄR STÅR VI I DETTA RS

 

När vi sedan har skrivit ut VFR750 på skärmen så kommer vi att kalla på funktionen med VFR750's ID nummer. Vilket gör att vi skall ta ut alla poster som har VFR750 som parent. Det finns inga poster och denna funktion kommer avslutas. (Vi har nu nått botten på vår rekursiva funktion, för denna gren iallafall)

 

Vi kommer då "hoppa" tillbaka till den funktion som skrev ut VFR750 på skärmen och forsätta vår kod precis efter vårt anrop till funktionen getPost(). Vad vi gör då är att vi hämtar nästa post i recordsetet, och eftersom det inte finns fler så avslutats denna funktion med. Och vi hoppar tillbaka funktionen som skrev ut Honda och ser om det finns fler poster i detta recordset. Det finns det inte och vi avslutar även denna funktion.

 

Vi har nu endast ett recordset i minnet.

-------------------------

MC <- HÄR STÅR VI JUST NU

Bilar

 

Vi kommer alltså tillbaka till funktionen, som skriver ut alla som har PARENT = 0 på skärmen, vi går till nästa post i listan och ser att det är BILAR.

Bilar kommer att skrivas ut på skärmen och vi kommer att hämta alla poster som har BILAR som Parent. Och vi får ett nytt recordset som innehåller.

----------------

Volvo

Saab

 

och sedan går vi igenom detta recordset och kollar om någon av dessa poster har underposter och om dessa underposter har underposter osv osv..

 

Du har nu byggt en rekursiv funktione som kan hämta en trädstruktur oberoende av hur den ser ut så länge dinna översta poster har Parent = 0 och varje annan post är kopplad till en ParentPost.

 

Om du har en riktigt stor trädstruktur kommer detta att ta en liten stund att gå igenom och du får en del databasanrop.

 

Så om du har SQL Server så kan du göra en SP som gör en temporär tabell till dig som strukturerar upp din trädstruktur så som den skall vara och sedan kan du loopa igenom 1 recordset med 1 databsanrop istället.

 

Kollar på http://www.gladh.nu/asphelp för hur en sådan SP kan se (tagit från Books Online)

 

- Magnus

-----------------------------------------------------

Ropen skalla, BBB (eller BOSTREAM) åt alla!!!

 

[inlägget ändrat 2003-07-29 09:11:35 av Magnus Gladh]

Länk till kommentar
Dela på andra webbplatser

Bra svar Magnus Gladh!!!

 

Det vanliga är att man försöker loppa sig igenom på någon vänster och man kommer fram till att det inte går eftersom du inte vet hur många underpost en post har, och att de är olika på varje post :)

 

Är du säker. Jag har fått det att fungera iallfall... Kanske inte optimalt, men det fungerar iallfall. (Inte att loppa utan att loopa :] )

 

 

Länk till kommentar
Dela på andra webbplatser

Magnus Gladh

ja för loppa går inte, loopa går säkert men det måste bli bra mycket mer kod som måste skrivas. Du skulle inte kunna visa koden så kan vi se om det håller hela vägen.

 

- Magnus

-----------------------------------------------------

Ropen skalla, BBB (eller BOSTREAM) åt alla!!!

 

Länk till kommentar
Dela på andra webbplatser

Du skulle inte kunna visa koden så kan vi se om det håller hela vägen.

 

Skulle gärna vilja det, men den ligger på datorn i Växjö :(

Befinner mig i Bolänge nu...

 

Länk till kommentar
Dela på andra webbplatser

Jag trixade lite med din kod så det blev såhär:

 

<!-- #include file=adovbs.inc -->
<%
Function getPost(intParent)
	'-- open connection to databas
	Set objConn = Server.Createobject("ADODB.Connection") 
	Set objRS = Server.CreateObject("ADODB.Recordset")
	objConn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & Server.MapPath("menu.mdb") 

	'-- build SQL statment
	strSQL = "SELECT * FROM tblMenu WHERE [PARENT] = " & intParent
	objRS.Open strSQL, objConn, adOpenStatic, adLockOptimistic

	'-- get all posts
	'objRs = .......

	'-- loop throu record set
	While Not objRs.EOF = True

		Response.Write(objRs("NAMN") & "<br>")

		'-- get all subpost for this post
		getPost(objRs("ID"))
		objRs.MoveNext

	Wend

	'-- clean up databasconnection after us.
	objRS.Close
	Set objRS = nothing
	objConn.Close
	Set objConn = nothing
End Function

getPost(0)
%>

 

Det fungerar bra, men hur ska jag göra för att få den här menyn expanderbar, så att man kan klicka på ett + framför varje kategori som har underkategorier?

 

Satt och försökte fixa detta själv men det var knivigare än jag trodde. Förslag?

 

Mvh

 

Länk till kommentar
Dela på andra webbplatser

Magnus Gladh

Japp det är klurigare. Du kan inte göra det i ASP utan måste ta hjälp av JavaScript.

 

Jag satt också och fibblade med det ett tag, försökte med en massa DIV tagar och sånt. Det slutade med att jag gjorde om det så att varje post blev ett objekt i JavaScript.

 

Det fungerar bra. Men ger den nackdelen att du inte kan se i HTML-koden hur din meny ser ut, eftersom den koden genereras från JavaScriptet, och de olika objekten genereras från ASP. Litte kluddigt att förklara men fungerar bra.

 

Tips är att kolla på någon dynamisk meny från http://www.dhtmlcentral.com och sedan bygga om det så man hämtar datan från databasen med ASP istället för att hårdkoda in det i JavaScript koden.

 

- Magnus

-----------------------------------------------------

Ropen skalla, BBB (eller BOSTREAM) åt alla!!!

 

Länk till kommentar
Dela på andra webbplatser

Hade du fått det att fungera sa du? Skulle du kunna visa koden så jag kan se hur du har gjort för jag kan inte javascript.

 

mvh

 

Länk till kommentar
Dela på andra webbplatser

Magnus Gladh

Se om jag hittar det när jag kommer hem.

 

- Magnus

-----------------------------------------------------

Ropen skalla, BBB (eller BOSTREAM) åt alla!!!

 

Länk till kommentar
Dela på andra webbplatser

Magnus Gladh

oopss!! Helt glömt bort det.. :(

 

Snor min Javascript kod från en site på nätet, du får dock själv pussla ihop din ASP kod.

 

<script language='javascript1.2'>
mainLevel = createLevel("main");
oLevel_1 = addLevel(mainLevel, createLevel('EN_HUVUDRUBRIK',''));	
oLevel_2 = addLevel(oLevel_1, createLevel('EN_UNDER_RUBRIK',''));	
oLevel_3 = addLevel(oLevel_2, createLevel('EN_LÄNK_I_EN_RUBRIK','/blablabla.ASP'));	
document.write(drawMenu(mainLevel));
</script>

Javascript koden kan du ladda ner härifrån:

http://shop.cgi.se/deladrycker/include/tassadarMenu.js

 

Det du får göra i din ASPkod är alltså att skapa texten:

oLevel_3 = addLevel(oLevel_2, createLevel('EN_LÄNK_I_EN_RUBRIK','/blablabla.ASP'));

 

oLevel_3 = Namnet på det object som man skapar och som man sedan kan referera till.

addLevel() = säger att jag vill lägga till en ny rubrik/länk till just denna rubrik/underrubrik.

oLevel_2 = är den rubrik/underrubrik som är Parent till min nya skapade rubrik.

CreateLevel() = skapar en ny rubrik/underrunbrik. Du har 2 inparameter. Den första är namnet på rubriken/underrubriken/länken. och den andra är själva länken, om du inte skickar med en länk blir det en rubrik, annars en länk.

 

Sedan i din HTML kod skriver du så här.

<script language='javascript1.2'>
mainLevel = createLevel("main");
<% CreateMainLevel() %>
document.write(drawMenu(mainLevel));
</script>

 

Och CreateMainLevel() skriver alltså ut de olika AddLevel() methoderna så dessa kan anropas från JavaScriptet.

 

- Magnus

-----------------------------------------------------

Ropen skalla, BBB (eller BOSTREAM) åt alla!!!

 

[inlägget ändrat 2003-08-04 09:36:16 av Magnus Gladh]

Länk till kommentar
Dela på andra webbplatser

  • 1 year later...

Jag har själv jobbat med ett träd och detta var ju en guldgruva. Har dock kört fast på att få indragen på plats. Är det någon som har ett förslag på lösening? SÅ att man utan javascript och så ändå kan se strukturen liksom. för som det är nu landar ju allt på varann.

 

 

Länk till kommentar
Dela på andra webbplatser

Arkiverat

Det här ämnet är nu arkiverat och är stängt för ytterligare svar.

×
×
  • Skapa nytt...