[JQuery] i [PHP] menu do PHP Fusion

0

Witam

Jest to Mój pierwszy temat na tym forum, więc proszę o zrozumienie.

Mam skrypt menu rozwijanego Accordion dokładnie w JQuery i PHP. Menu to jest dostosowane do PHP-Fusiona, i działa prawidłowo, ale jest jeden mały problem, w którym polski support niestety nie chce pomóc.

Przedstawię problem najprościej jak się tylko da.

Do menu mogę dodawać linki oraz kategorie, które się rozwijają i zawierają w sobie inne linki, Problem jest taki, że gdy pod normalnymi linkami dodam kategorie, to wszystkie nowo utworzone linki, wędrują to tejże kategorii. Mogę dodawać nowe kategorie i nowe linki do nich, ale nie mogę dodać żadnego bezpośredniego linku, poza kategorią, ponieważ jak już pisałem każdy nowy link, wędruje do ostatnio utworzonej kategorii.

Proszę was specjalistów o zobaczenie niżej podanych kodów i modyfikację, abym mógł dodawać nowe linki, na końcu menu poza kategorią.

Proszę się tez nie zniechęcać wielkością kodu. Proszę także o odpowiedzi tylko ludzi doświadczonych i znających Bardzo Dobrze te języki, nie potrzebuję przekierowań do kursów itd itp. Potrafię korzystać z google.

PHP:

<?php
/*-------------------------------------------------------+
| PHP-Fusion Content Management System
| Copyright (C) 2002 - 2008 Nick Jones
| http://www.php-fusion.co.uk/
+--------------------------------------------------------+
| Filename: accordion_navigation_panel.php
| Author: Robert Gaudyn (Wooya)
| Version: 1.0
+--------------------------------------------------------+
| This program is released as free software under the
| Affero GPL license. You can redistribute it and/or
| modify it under the terms of this license which you
| can read by viewing the included agpl.txt or online
| at www.gnu.org/licenses/agpl.html. Removal of this
| copyright header is strictly prohibited without
| written permission from the original author(s).
+--------------------------------------------------------*/
if (!defined("IN_FUSION")) { die("Access Denied"); }
	
add_to_head("<style type='text/css'>
		/* A few IE bug fixes */
		* html ul ul li a { height: 100%; }
		* html ul li a { height: 100%; }
		* html ul ul li { margin-bottom: -1px; }
	</style>");
add_to_head("<script type='text/javascript' src='".INFUSIONS."accordion_navigation_panel/accordion.js'></script>");
add_to_head("<script type='text/javascript'>
jQuery().ready(function(){	
	// applying the settings
	jQuery('#navigation').Accordion({
		active: 'h2.selected',
		header: 'h2.head',
		alwaysOpen: false,
		animated: true,
		showSpeed: 400,
		hideSpeed: 800
	});
});	
</script>");

$list_open = false;
$i = 0;

openside($locale['global_001']);
$result = dbquery(
	"SELECT tl.link_name, tl.link_url, tl.link_window, tl.link_order FROM ".DB_SITE_LINKS." tl
	WHERE ".groupaccess('tl.link_visibility')." AND link_position<='2'
	ORDER BY link_order"
);
if (dbrows($result)) {
	
	echo "<div id='navigation'>\n";
	echo "<div id='nav_bok'></div>";
	while($data = dbarray($result)) {
			if ($data['link_name'] != "---" && $data['link_url'] == "---") {
				if ($list_open) { echo "</ul>\n"; $list_open = false; }
				//echo "<h2 class='".(!$i ? "selected" : "head")."'>".$data['link_name']."</h2>\n";
				
				echo "<h2 class='".(!$i ? "head" : "head")."' style='cursor:pointer'>".$data['link_name']."</h2>\n";
				
			} else if ($data['link_name'] == "---" && $data['link_url'] == "---") {
				if ($list_open) { echo "</ul>\n"; $list_open = false; }
				echo "<hr class='side-hr' />\n";
			} else {
				if (!$list_open) { echo "<ul>\n"; $list_open = true; }
				$link_target = ($data['link_window'] == "1" ? " target='_blank'" : "");
				if (strstr($data['link_url'], "http://") || strstr($data['link_url'], "https://")) {
					echo "<li><a href='".$data['link_url']."'".$link_target." class='side'>".THEME_BULLET." <span>".$data['link_name']."</span></a></li>\n";
				} else {
					echo "<li><a href='".BASEDIR.$data['link_url']."'".$link_target." class='side'>".THEME_BULLET." <span>".$data['link_name']."</span></a></li>\n";
				}
			}
			$i++;
	}
	if ($list_open) { echo "</ul>\n"; }
	echo "</div>\n";
} else {
	echo $locale['global_002'];
}
closeside();
?>

JQuery:

/*
 * Accordion 1.3 - jQuery menu widget
 *
 * Copyright (c) 2006 Jörn Zaefferer, Frank Marcia
 *
 * Dual licensed under the MIT and GPL licenses:
 *   http://www.opensource.org/licenses/mit-license.php
 *   http://www.gnu.org/licenses/gpl.html
 *
 * Revision: $Id: jquery.accordion.js 1524 2007-03-13 20:09:19Z joern $
 *
 */

/**
 * Make the selected elements Accordion widgets.
 *
 * Semantic requirements:
 *
 * If the structure of your container is flat with unique
 * tags for header and content elements, eg. a definition list
 * (dl > dt + dd), you don't have to specify any options at
 * all.
 *
 * If your structure uses the same elements for header and
 * content or uses some kind of nested structure, you have to
 * specify the header elements, eg. via class, see the second example.
 *
 * Use activate(Number) to change the active content programmatically.
 *
 * A change event is triggered everytime the accordion changes. Apart from
 * the event object, all arguments are jQuery objects.
 * Arguments: event, newHeader, oldHeader, newContent, oldContent
 *
 * @example jQuery('#nav').Accordion();
 * @before <dl id="nav">
 *   <dt>Header 1</dt>
 *   <dd>Content 1</dd>
 *   <dt>Header 2</dt>
 *   <dd>Content 2</dd>
 * </dl>
 * @desc Creates an Accordion from the given definition list
 *
 * @example jQuery('#nav').Accordion({
 *   header: 'div.title'
 * });
 * @before <div id="nav">
 *  <div>
 *    <div class="title">Header 1</div>
 *    <div>Content 1</div>
 *  </div>
 *  <div>
 *    <div class="title">Header 2</div>
 *    <div>Content 2</div>
 *  </div>
 * </div>
 * @desc Creates an Accordion from the given div structure
 *
 * @example jQuery('#nav').Accordion({
 *   header: 'a.head'
 * });
 * @before <ul id="nav">
 *   <li>
 *     <a class="head">Header 1</a>
 *     <ul>
 *       <li><a href="#">Link 1</a></li>
 *       <li><a href="#">Link 2></a></li>
 *     </ul>
 *   </li>
 *   <li>
 *     <a class="head">Header 2</a>
 *     <ul>
 *       <li><a href="#">Link 3</a></li>
 *       <li><a href="#">Link 4></a></li>
 *     </ul>
 *   </li>
 * </ul>
 * @desc Creates an Accordion from the given navigation list
 *
 * @example jQuery('#accordion').Accordion().change(function(event, newHeader, oldHeader, newContent, oldContent) {
 *   jQuery('#status').html(newHeader.text());
 * });
 * @desc Updates the element with id status with the text of the selected header every time the accordion changes
 *
 * @param Map options key/value pairs of optional settings.
 * @option String|Element|jQuery|Boolean active Selector for the active element, default is the first child, set to false to display none at start
 * @option String|Element|jQuery header Selector for the header element, eg. div.title, a.head, default is the first child's tagname
 * @option String|Number showSpeed Speed for the slideIn, default is 'slow' (for numbers: smaller = faster)
 * @option String|Number hideSpeed Speed for the slideOut, default is 'fast' (for numbers: smaller = faster)
 * @option String selectedClass Class for active header elements, default is 'selected'
 * @option Boolean alwaysOpen Whether there must be one content element open, default is true.
 * @option Boolean animated Set to false to disable animations. Default: true
 * @option String event The event on which to trigger the accordion, eg. "mouseover". Default: "click"
 *
 * @type jQuery
 * @see activate(Number)
 * @name Accordion
 * @cat Plugins/Accordion
 */

/**
 * Activate a content part of the Accordion programmatically at the given zero-based index.
 *
 * If the index is not specified, it defaults to zero, if it is an invalid index, eg. a string,
 * nothing happens.
 *
 * @example jQuery('#accordion').activate(1);
 * @desc Activate the second content of the Accordion contained in <div id="accordion">.
 *
 * @example jQuery('#nav').activate();
 * @desc Activate the first content of the Accordion contained in <ul id="nav">.
 *
 * @param Number index (optional) An Integer specifying the zero-based index of the content to be
 *				 activated. Default: 0
 *
 * @type jQuery
 * @name activate
 * @cat Plugins/Accordion
 */
 
/**
 * Override the default settings of the Accordion. Affects only following plugin calls.
 *
 * @example jQuery.Accordion.setDefaults({
 * 	showSpeed: 1000,
 * 	hideSpeed: 150
 * });
 *
 * @param Map options key/value pairs of optional settings, see Accordion() for details
 *
 * @type jQuery
 * @name setDefaults
 * @cat Plugins/Accordion
 */

jQuery.fn.extend({
	// nextUntil is necessary, would be nice to have this in jQuery core
	nextUntil: function(expr) {
	    var match = [];
	
	    // We need to figure out which elements to push onto the array
	    this.each(function(){
	        // Traverse through the sibling nodes
	        for( var i = this.nextSibling; i; i = i.nextSibling ) {
	            // Make sure that we're only dealing with elements
	            if ( i.nodeType != 1 ) continue;
	
	            // If we find a match then we need to stop
	            if ( jQuery.filter( expr, [i] ).r.length ) break;
	
	            // Otherwise, add it on to the stack
	            match.push( i );
	        }
	    });
	
	    return this.pushStack( match );
	},
	// the plugin method itself
	Accordion: function(settings) {
		// setup configuration
		settings = jQuery.extend({}, jQuery.Accordion.defaults, {
			// define context defaults
			header: jQuery(':first-child', this)[0].tagName // take first childs tagName as header
		}, settings);

		// calculate active if not specified, using the first header
		var container = this,
			active = settings.active
				? jQuery(settings.active, this)
				: settings.active === false
					? jQuery("<div>")
					: jQuery(settings.header, this).eq(0),
			running = 0;

		container.find(settings.header)
			.not(active || "")
			.nextUntil(settings.header)
			.hide();
		active.addClass(settings.selectedClass);

		function clickHandler(event) {
			// get the click target
			var clicked = jQuery(event.target);
			
			// due to the event delegation model, we have to check if one
			// of the parent elements is our actual header, and find that
			if ( clicked.parents(settings.header).length ) {
				while ( !clicked.is(settings.header) ) {
					clicked = clicked.parent();
				}
			}
			
			var clickedActive = clicked[0] == active[0];
			
			// if animations are still active, or the active header is the target, ignore click
			if(running || (settings.alwaysOpen && clickedActive) || !clicked.is(settings.header))
				return;

			// switch classes
			active.toggleClass(settings.selectedClass);
			if ( !clickedActive ) {
				clicked.addClass(settings.selectedClass);
			}

			// find elements to show and hide
			var toShow = clicked.nextUntil(settings.header),
				toHide = active.nextUntil(settings.header),
				data = [clicked, active, toShow, toHide];
			active = clickedActive ? jQuery([]) : clicked;
			// count elements to animate
			running = toHide.size() + toShow.size();
			var finished = function(cancel) {
				running = cancel ? 0 : --running;
				if ( running )
					return;

				// trigger custom change event
				container.trigger("change", data);
			};
			// TODO if hideSpeed is set to zero, animations are crappy
			// workaround: use hide instead
			// solution: animate should check for speed of 0 and do something about it
			if ( settings.animated ) {
				if ( !settings.alwaysOpen && clickedActive ) {
					toShow.slideToggle(settings.showSpeed);
					finished(true);
				} else {
					toHide.filter(":hidden").each(finished).end().filter(":visible").slideUp(settings.hideSpeed, finished);
					toShow.slideDown(settings.showSpeed, finished);
				}
			} else {
				if ( !settings.alwaysOpen && clickedActive ) {
					toShow.toggle();
				} else {
					toHide.hide();
					toShow.show();
				}
				finished(true);
			}

			return false;
		};
		function activateHandlder(event, index) {
			// call clickHandler with custom event
			clickHandler({
				target: jQuery(settings.header, this)[index]
			});
		};

		return container
			.bind(settings.event, clickHandler)
			.bind("activate", activateHandlder);
	},
	// programmatic triggering
	activate: function(index) {
		return this.trigger('activate', [index || 0]);
	}
});

jQuery.Accordion = {};
jQuery.extend(jQuery.Accordion, {
	defaults: {
		selectedClass: "selected",
		showSpeed: 'slow',
		hideSpeed: 'fast',
		alwaysOpen: true,
		animated: true,
		event: "click"
	},
	setDefaults: function(settings) {
		jQuery.extend(jQuery.Accordion.defaults, settings);
	}
});
0

BTW, używaj proszę kolorowania składni. To w sumie nie Twoja wina, bo słabo jest to na tym forum zaprojektowane (tj. nie jest wyjaśnione), ale można robić coś takiego < code =JEZYK_PROGRAMOWANIA>< / code > (oczywiście bez tych dodatkowych spacji, które musiałem wstawić, by nie zamieniło tych tagów). Np. < code = php >, albo < code = javascript >. Nie wiem jak inni, ale ja mam trudności z ogarnięciem kodu bez kolorowania. I może jakiś link do strony tego całego dodatku...? Myślę, że odpowiedzi należy szukać w tamtejszej dokumentacji i przykładach.

0

Zgodnie z zaleceniem, składnia pokolorowana.

Z linkiem do tego Menu będzie bardzo ciężko, ponieważ skrypt został pobrany przeze mnie z forum supportu PHP-Fusiona, ale myślę że to jest cały kod jaki powinien być przedstawiony (po dodaniu tego kodu, oraz biblioteki JQuery, działa prawidłowo).

Jeśli ktoś potrafi mi pomóc to bardzo proszę, o tą pomoc.

0

Ale żadnego INSERT, ani UPDATE tu nie widzę...
Sam skrypt wyświetlania linków.

0

Niestety nie wiem co mógł bym tutaj jeszcze podać, co by mogło ułatwić rozwiązanie tego problemu. Na polskim supporcie były tylko te dwa pliki, których źródło podałem wyżej, i nic więcej. Po skopiowaniu ich do katalogu "infusions" w PHP-Fusion, tylko się podmienia, starą nawigację, na właśnie tą Accordion w Panelu Administracyjnym, poprzez wybranie z listy.

Jeśli wiecie co mogę tutaj jeszcze podać z PHP-Fusiona, to proszę napiszcie.

0

@stingtanner:
Dzięki za kolory.

Naszym problemem może być niedostateczna wiedza o PHP Fusion i o tym dodatku. Ja np. znam się dobrze na samym języku PHP, doskonale na języku JavaScript i nieźle na bibliotece jQuery. O PHP Fusion wiem tyle co nic -- nie używam tego.

Dziwi mnie brak dokumentacji do tego dodatku. Ta dokumentacja, którą masz w komentarzu w kodzie JavaScript, należy do Accordion -- wtyczki do biblioteki jQuery. Dokumentacja dostępna jest również na stronie http://docs.jquery.com/UI/Accordionquery.com/UI/Accordion">http://docs.jquery.com/UI/Accordion</a>

To nie jest więc problem. Po prostu nie wiadomo, co dokładnie robi Fusion razem z tym dodatkiem menu. Najwyraźniej po prostu zmienia widok menu, czyli wygenerowany kod HTML tego menu. I dodaje wtyczkę jQuery/Accordion od strony skryptów. Nie znając Fusion (chyba że Demonical Monk zna -- ja nie) nie wiemy, jak zarządza linkami. Jaka jest struktura bazy. W jaki sposób przechowywane są tam kategorie, w jaki linki. W jaki sposób dodawane są i przechowywane (ogólnie: zarządzane przez Fusion) "normalne linki", a w jaki "kategorie"? Cóż, nie mam zielonego pojęcia! Czy Fusion w ogóle umożliwia wrzucenie linków "luzem" -- tak, by nie należały do żadnej kategorii? Możesz normalnie (bez tej wtyczki) dodać zwykły, normalny link najwyższego poziomu, nie zamknięty w żadnej kategorii?

Jeśli tak, to w miarę proste rozwiązanie Twoich problemów może być możliwe. Wygląda na to, że wtyczka Accordion niepotrzebnie zżera Ci te wrzucone luzem linki. Jeśli jednak są one jakoś wyróżnione przez Fusion (pewnie są, pytanie tylko jak), to da się zmienić widok (kod HTML) tak, by Accordion zostawił je w spokoju.

Powiedz jeszcze, czy dobrze rozumiem, o co Ci chodzi. Czy chcesz mieć taką strukturę?

--- początek menu ---
--- początek działania wtyczki accordion ---
KATEGORIA PIERWSZA
link pierwszy kategorii pierwszej
link drugi kategorii pierwszej
link trzeci kategorii pierwszej
KATEGORIA DRUGA
link pierwszy kategorii drugiej
link drugi kategorii drugiej
KATEGORIA TRZECIA
link pierwszy kategorii trzeciej
link drugi kategorii trzeciej
link trzeci kategorii trzeciej
--- koniec działania wtyczki Accordion ---
bezpośredni link pierwszy (nie związany z żadną kategorią)
bezpośredni link drugi (nie związany z żadną kategorią)
bezpośredni link trzeci (nie związany z żadną kategorią)
--- koniec menu ---

Coś takiego? Czy może chcesz, by bezpośrednie linki były nie tylko na końcu, ale również pomiędzy kategoriami?

0

uwaga na przyszłość - wątki z nic niemówiącym tematem jak ten "Bardzo proszę o pomoc" będą lądowały w koszu - tym razem poprawiłem z racji świeżości na forum :)

0

@Marooned:
Dzięki za wyrozumiałość

Postaram się odpowiedzieć na nie które pytania, jak tylko potrafię.

Wtyczka Accordion nie kończy się tam gdzie podałeś, ona jest całym menu. Linki dodane przed jakąkolwiek kategorią, w kategorii, i ewentualnie poza nimi jako ostatnie, są tym jednym menu accordion.

Czy Fusion w ogóle umożliwia wrzucenie linków "luzem" -- tak, by nie należały do żadnej kategorii? Możesz normalnie (bez tej wtyczki) dodać zwykły, normalny link najwyższego poziomu, nie zamknięty w żadnej kategorii?

Mogę ale będą już należeć do menu Accordion, z tym że przed jakąkolwiek kategorią może być link bezpośredni, a po utworzeniu kategorii, każdy kolejny link jest już zabierany przez ostatnio utworzoną kategorię.

Struktura tak jak podałeś, z tym że przed pierwszą kategorią też możliwość bezpośrednich linków.
Już nawet nie chcę żadnej mieszaniny link, kategoria, link bezpośredni, kategoria, tylko żeby przed kategoriami, i po kategoriach można było dodawać bezpośrednie linki.

Aby pokazać jak teraz działa to menu, zamieściłem PHP-Fusiona na serwerze http://d-s-t.prv.pl/news.php, działa tak jak tam widać.

Jeśli chodzi natomiast o strukturę bazy danych i jak Fusion to dodaje, to przyznam się szczerze, nie znam się na tym, ale jeśli to nie problem, to mógł bym podesłać dane do FTP, Panelu Administracyjnego oraz bazy danych strony, którą podałem wyżej.

Wiem że to jest szukanie, kogoś kto wyręczył by mnie w tym, ale po prostu skończyły mi się wszystkie wyjścia, z jakich mogłem skorzystać i jedyne jakie mi pozostało to prosić o pomoc.

0

omfg, jakim cudem ci to w ogóle działa?! Każdy anchor w górnym menu ma identyczne ID... (ID=rollover)

0

W takiej postaci pobrałem to menu z forum polskiego supportu PHP-Fusiona

Jeśli to pomoże to podaje linka do tematu, z forum supportu, z którego to poprałem to menu:
http://www.php-fusion.pl/forum/viewthread.php?thread_id=21018&rowstart=0

0

Dzięki za umieszczenie tego na serwerze, bardzo się przyda.

Jeśli chodzi o tę strukturę, to chciałem wiedzieć, czy chcesz, by tak to działało. Nie czy tak to w tym momencie działa. Wiem, że Accordion obejmuje całość. Ale rozumiem, że chcesz, by tak NIE było: żeby za Accordionem (czyli za rozwijalnymi kategoriami) dało się wrzucić zwykłe linki, nie działające jak Accordion (a dlatego nie działające, znajdujące się poza nim!). Teraz jeszcze dopisałeś, że chciałbyś, by takie linki były również nad Accordionem.

Btw. z tego co widzę po demie, to już tak działa: linki Strona główna i Galeria zdjęć nie należą do Accordionu. Chcesz teraz osiągnąć podobny efekt z linkami umieszczonymi na końcu menu, tak? Dodaj plz jakiś link w ten sposób, w jaki byś chciał dodawać takie zewnętrzne linki (położone na końcu i nie należące do żadnej kategorii). Czy takim linkiem jest "strona id 1"?

0

Taki efekt właśnie chciałbym osiągnąć.

Dodałem do tego Menu nowy link, znajduje się on w w ostatniej kategorii, i ten link chciałbym aby był, poza tą ostatnią kategorią.

0

I co da się to menu uratować, czy jednak można skazać je na straty?

1 użytkowników online, w tym zalogowanych: 0, gości: 1