Ergebnis 1 bis 6 von 6

Thema: Katalog Liste via Ajax nachladen

  1. #1
    Contao-Nutzer
    Registriert seit
    04.05.2011.
    Ort
    Österreich / Steiermark
    Beiträge
    74

    Standard Katalog Liste via Ajax nachladen

    Wie der Titel schon sagt, würde ich gerne eine Katalog Liste ausgeben und diese Liste dann per Ajax nachladen.

    D.h. ich habe zwei Buttons (next, prev) und beispielsweise 5 Elemente die angezeigt werden. Beim Klick auf "next" werden die nächsten 5 angezeigt, usw.

    Wie setzt man dies am besten um?

  2. #2
    Maintainer Avatar von xtra
    Registriert seit
    02.07.2009.
    Ort
    Tuebingen
    Beiträge
    2.007
    User beschenken
    Wunschliste

    Standard

    kleines Javascript

    Ich hab mir aus Spass mal einen "endless cataloglist scroller" gebaut.

    templates/theme/catalog_full_endless_page.tpl:
    PHP-Code:
    <?php if (count($this->entries)): ?>

    <div class="layout_full endlesspage" id="<?php echo $this->entries[0]['tablename']; ?>_endlessscroll">

    <?php $GLOBALS['TL_JAVASCRIPT'][] = 'tl_files/endlesscataloglist.js'?>
    <script type="text/javascript">
    <!--//--><![CDATA[//><!--
    // now start up our AjaxPage handler. Remember to do this only once!
    window.addEvent('domready', function(){new AjaxEndlessCatalogList({id: '<?php echo $this->entries[0]['tablename']; ?>_endlessscroll', scrollOffset: 400});});
    //--><!]]>
    </script>

    <?php foreach ($this->entries as $entry): ?>
    <div class="item<?php echo $entry['class'] ? ' '.$entry['class'] : ''?>">
    <?php if($entry['linkEdit']): ?><?php echo $entry['linkEdit']; ?><?php endif; ?>

    <?php foreach ($entry['data'] as $field=>$data): ?>
    <?php 
    if (strlen($data['raw']) && !in_array($field, array('catalog_name','parentJumpTo'))): ?>
    <div class="field <?php echo $field?>">
        <div class="label"><?php echo $data['label']; ?></div>
        <div class="value"><?php echo $data['value']; ?></div>
    </div>
    <?php endif; ?>
    <?php 
    endforeach; ?>
    </div>
    <?php endforeach; ?>
    </div>

    <?php else: ?>
    <p class="info">Invalid item reference for catalog.</p>
    <?php endif; ?>
    tl_files/endlesscataloglist.js
    PHP-Code:
    /**
     * Class AjaxEndlessCatalogList
     * 
     * And endless scrolling page script for catalog lists.
     * @copyright  CyberSpectrum 2011
     * @author     Christian Schiffler <http://www.cyberspectrum.de>
     */

    var AjaxEndlessCatalogList = new Class({
        Implements: [
    Options],
        
    options:{
            
    scrollOffset:200
        
    },
        
    urls:[],
        
    requestnull,
        
    dummyFormElement:new Element('div'),
        
    RequestClass: new Class({
            Extends: 
    Request,
            
    options: {
                
    evalScriptsfalse,
                
    evalResponsefalse
            
    },
            
    success: function(textxml)
            {
                var 
    js;
                
    text text.stripScripts(function(script){js script;});
                
    js js.replace(/<!--|\/\/-->|<!\[CDATA\[\/\/>|<!\]\]>/g'');
                
    this.onSuccess(textxmljs);
            }
        }),
        
    initialize:function(options)
        {
            
    this.setOptions(options);
            
    this.grabPagination();
            
    this.addListener();
            $(
    this.options.id).store('scroller'this);
        },
        
    grabPagination: function(container)
        {
            var 
    flag={beyondcurrent:false};
            var 
    cont=(!container)?$(this.options.id).getParent():container;
            
    // find pagination
            
    $$(cont.getElements('div.pagination li')).filter((function(eidxarr){
                var 
    e2;
                if((
    e2=e.getElement('span')) && e2.hasClass('current')){this.beyondcurrent=true;return false};
                
    e2=e.getElement('a');
                return 
    this.beyondcurrent && e2 && !(e2.hasClass('prev') || e2.hasClass('next') || e2.hasClass('first') || e2.hasClass('last'));
            }).
    bind(flag)).each((function(e)
            {
                var 
    url e.getElement('a').href;
                if(!
    this.urls.contains(url))
                    
    this.urls.push(url);
            }).
    bind(this));
            if(!
    container)
                
    cont.getElement('div.pagination').destroy();
        },
        
    getNextPage: function()
        {
            if(
    this.request)
            {
                return;
            }
            var 
    url this.urls.shift();
            if(!
    url)
                return;
            var 
    spinner = new Spinner(this.options.id, {
                
    img:{ 'style''background: url("plugins/mediabox/images/MinimalLoading.gif") no-repeat fixed center center transparent; width: 100px; height:100px;'},
                
    content: {'style':'background-color: #000;'}
            }).
    show();
            
    // now load via ajax.
            
    this.request = new this.RequestClass({
                
    'link''chain',
                
    'method''get',
                
    urlurl,
                
    onSuccess: (function(textxmljs){spinner.destroy();this.request=nullthis.pageLoaded(textxmljs);}).bind(this)
            }).
    send();
        },
        
    pageLoaded: function(textxmljs)
        {
            var 
    el=Elements.from(text);
            var 
    id=this.options.id;
            var 
    scanNode=function(e)
            {
                
    // skip text nodes
                
    if(!e)return null;
                if(
    e.id==id)return e;
                var 
    childNode= -1childNodes e.childNodes;
                while((
    childNodes.length>++i) && (childNode childNodes.item(i)))
                {
                    var 
    tmp2=scanNode(childNode);
                    if(
    tmp2)
                        return 
    tmp2;
                }
            }
            var 
    e=null;
            for(var 
    i=0;i<el.length;i++)
            {
                
    scanNode(el[i]);
                if(
    e)
                    break;
            }
            if(
    e)
            {
                $(
    this.options.id).adopt($(e).getChildren())
                
    this.grabPagination($(e).getParent());
            }
            
    // TODO: execute all javascript we got in this request. To handle MediaBox etc.
        
    },
        
    addListener: function()
        {
            
    window.addEvent('scroll', (function()
            {
                if($(
    document).getScroll().>= $(document).getScrollSize().y-window.getSize().y-this.options.scrollOffset)
                {
                    
    this.getNextPage();
                }
            }).
    bind(this));
        }
    }); 
    Das funktioniert aber nicht, wenn das Listenmodul per Inserttag eingebunden wird, da zu diesem Zeitpunkt die GLOBALS bereits ausgewertet sind und somit das JS nicht mehr eingebunden wird.
    Beachte weiterhin, in den nachgeladenen Objekten werden keine Javascriptaufrufe ausgewertet. d.h. Mediabox wird nicht funktionieren.

    Hinweis zur Funktionalitaet:
    Dieses Vorgehen ersetzt dynamisch die eingebundene pagination und bietet somit automatisch einen non JS fallback.

    Gruss
    Chris
    Bedenke stets: Wenn Du ungenaue oder unzureichende Angaben machst, so koennte dies die Bearbeitung deiner Frage endlos verzoegern (oder sogar dazu fyhren, dass ich zu viel nachdenken muss und die Antwort vergesse!). Kein Support per PN.

  3. #3
    Contao-Nutzer
    Registriert seit
    04.05.2011.
    Ort
    Österreich / Steiermark
    Beiträge
    74

    Standard

    Danke für deine schnelle Antwort, nur leider ist dies nicht ganz das was ich brauche, da bei dieser Lösung ja nur die Pagination ersetzt wird ...

  4. #4
    Maintainer Avatar von xtra
    Registriert seit
    02.07.2009.
    Ort
    Tuebingen
    Beiträge
    2.007
    User beschenken
    Wunschliste

    Standard

    ... und wenn du nach unten ans Ende der Seite scrollst, automatisch die jeweils naechste Seite nachgeladen wird und du weiter scrollen kannst und dann automatisch die jeweils naechste Seite... usw. usf.
    Bedenke stets: Wenn Du ungenaue oder unzureichende Angaben machst, so koennte dies die Bearbeitung deiner Frage endlos verzoegern (oder sogar dazu fyhren, dass ich zu viel nachdenken muss und die Antwort vergesse!). Kein Support per PN.

  5. #5
    Contao-Nutzer
    Registriert seit
    04.05.2011.
    Ort
    Österreich / Steiermark
    Beiträge
    74

    Standard

    hab nun deine .tpl bzw .js verwendet.

    läuft prima nur will ich das ganze mit buttons und nicht mit scrollen. also einen prev und next button. ich habe deine dateien mal ein bisschen abgeändert.

    der script teil in der .tpl datei sieht nun folgendermaßen aus:
    HTML-Code:
    <script type="text/javascript">
    window.addEvent('domready', function(){								 
    		$('next').addEvent('click', function(event){
    		new AjaxEndlessCatalogList({
    			id: "<?php echo $this->entries[0]['tablename']; ?>_endlessscroll"										  
    		});
    	});
    	$('previous').addEvent('click', function(event){
    											  
    	});
    });
    </script>
    
    ...
    
    <div class="buttons">
        <a id="next" href="javascript:void(0)">next</a>
        <a id="previous" href="javascript:void(0)">previous</a>
    </div>
    und bei der js datei habe ich folgende funktionen geändert:

    Code:
    addListener: function()
        {
            window.addEvent('click', (function()
            {
    			this.getNextPage();
    			
            }).bind(this));
        }
    leider bin ich im umgang mit js/ajax ein neuling.

    der next button funktioniert nun, jedoch wird beim zweiten bzw. dem mehrmaligen klick auf next ein fehler im firebug ausgegeben:
    Code:
    cont.getElement("div.pagination") is null
    [Bei diesem Fehler anhalten] cont.getElement('div.pagination').destroy();
    wie zuvor schon erklärt sollen z.b. 3 elemente in der listenansicht angezeigt werden und beim klick auf next die nächsten 3 (die zuvor angezeigten sollen entfernt werden -> dazu würe dich auch noch einen rat benötigen.. )
    Geändert von bluuba (04.07.2011 um 16:28 Uhr)

  6. #6
    Contao-Nutzer
    Registriert seit
    04.05.2011.
    Ort
    Österreich / Steiermark
    Beiträge
    74

    Standard

    Habe es nun selbst geschafft. Hier dir Code für Interessenten:

    .tpl Datei:

    Code:
    <?php if (count($this->entries)): ?>
    
    <div class="layout_full endlesspage" id="<?php echo $this->entries[0]['tablename']; ?>_endlessscroll">
    
    <?php $GLOBALS['TL_JAVASCRIPT'][] = 'tl_files/endlesscataloglist.js'; ?>
    <script type="text/javascript">
    window.addEvent('domready', function(){								 
    	new AjaxEndlessCatalogList({
    		id: "<?php echo $this->entries[0]['tablename']; ?>_endlessscroll"
    	});
    	$('next').addEvent('click', function(event){
    		new AjaxEndlessCatalogList({
    			id: "<?php echo $this->entries[0]['tablename']; ?>_endlessscroll"										  
    		});
    	});
    	$('previous').addEvent('click', function(event){
    		new AjaxEndlessCatalogList({
    			id: "<?php echo $this->entries[0]['tablename']; ?>_endlessscroll"										  
    		});
    	});
    });
    </script>
    <?php 
    $count = 1; ?>
    <?php foreach ($this->entries as $entry): ?>
    <?php 
    if($count == 4 )
    	$count = 1;
       ?>
        <div id="<?php echo $count;?>" class="item <?php echo $entry['class'] ? ' '.$entry['class'] : ''; ?>">
        <?php if($entry['linkEdit']): ?><?php echo $entry['linkEdit']; ?><?php endif; ?>
        
        <?php foreach ($entry['data'] as $field=>$data): ?>
            <?php if (strlen($data['raw']) && !in_array($field, array('catalog_name','parentJumpTo'))): ?>
                <div class="field <?php echo $field; ?>">
                    <div class="value"><?php echo $data['value']; ?></div>
                </div>
            <?php endif; ?>
        <?php endforeach; ?>
        
        </div>
        <?php $count++;?>
    <?php endforeach; ?>
    </div>
    <div class="buttons">
        <a id="next" href="javascript:void(0)">next</a>
        <a id="previous" href="javascript:void(0)">previous</a>
    </div>
    <?php else: ?>
    <p class="info">Invalid item reference for catalog.</p>
    <?php endif; ?>

    .js-Datei:

    Code:
    /**
     * Class AjaxEndlessCatalogList
     * 
     * And endless scrolling page script for catalog lists.
     * @copyright  CyberSpectrum 2011
     * @author     Christian Schiffler <http://www.cyberspectrum.de>
     */
    var AjaxEndlessCatalogList = new Class({
        Implements: [Options],
        options:{
            scrollOffset:200
        },
        urls:[],
    	bgurls:[],
    	lastAct: 1, 
    	request: null,
        dummyFormElement:new Element('div'),
        RequestClass: new Class({
            Extends: Request,
            options: {
                evalScripts: false,
                evalResponse: false
            },
            success: function(text, xml)
            {
                var js;
                text = text.stripScripts(function(script){js = script;});
                js = js.replace("/<!--|//-->|<![CDATA[//>|<!]]>/g", '');
                this.onSuccess(text, xml, js);
            }
        }),
        initialize:function(options)
        {
    		this.lastAct=1;
            this.setOptions(options);
            this.grabPagination();
            this.addListener();
            $(this.options.id).store('scroller', this);
        },
        grabPagination: function(container)
        {
            var flag={beyondcurrent:false};
            var cont=(!container)?$(this.options.id).getParent():container;
            // find pagination
            $$(cont.getElements('div.pagination li')).filter((function(e, idx, arr){
                var e2;
                if((e2=e.getElement('span')) && e2.hasClass('current')){this.beyondcurrent=true;return false};
                e2=e.getElement('a');
                return this.beyondcurrent && e2 && !(e2.hasClass('prev') || e2.hasClass('next') || e2.hasClass('first') || e2.hasClass('last'));
            }).bind(flag)).each((function(e)
            {
                var url = e.getElement('a').href;
                if(!this.urls.contains(url)) {
                    this.urls.push(url);
    				this.bgurls.push(url);
    			}
            }).bind(this));
            if(!container) {
    		   	if(cont.getElement('div.pagination')==null)
    		   	{
    			}
    			else
    			{
    				this.bgurls.unshift('http://'+location.host+location.pathname+'?page=1');
    				cont.getElement('div.pagination').destroy()	
    			}
    		}
        },
        getNextPage: function()
        {
            if(this.request)
            {
                return;
            }
    		if(this.lastAct==2)
    		{
    			var temp = this.urls.shift();
    		}
            var url = this.urls.shift();
            if(!url)
                return;
            var spinner = new Spinner(this.options.id, {
                img:{ 'style': 'background: url("tl_files/template/Loading.gif") no-repeat fixed center center transparent; width: 720px; height:215px; '},
                content: {'style':'background-color: #000; margin-top:-20px; margin-left:-20px;'}
            }).show();
            // now load via ajax.
    		this.lastAct=1;
            this.request = new this.RequestClass({
                'link': 'chain',
                'method': 'get',
                url: url,
                onSuccess: (function(text, xml, js){spinner.destroy();this.request=null; this.pageLoaded(text, xml, js);}).bind(this)
            }).send();
        },
    	getPrevPage: function()
        {
            if(this.request)
            {
                return;
            }
            if(this.urls.length>=this.bgurls.length)
    			return;
    		var tlang = this.bgurls.length;
    		var templang = this.urls.length;
    		var lang = tlang - templang;
    		lang--;
    		
    		if(this.lastAct==1)
    		{
    			this.urls.unshift(this.bgurls[lang]);
    			lang--;
    			this.urls.unshift(this.bgurls[lang]);
    		}
    		
    		else {
    			this.urls.unshift(this.bgurls[lang]);
    		}
    		
    		var url = this.bgurls[lang];
    		
            if(!url)
                return;
            var spinner = new Spinner(this.options.id, {
                img:{ 'style': 'background: url("tl_files/template/Loading.gif") no-repeat fixed center center transparent; width: 720px; height:215px; '},
                content: {'style':'background-color: #000; margin-top:-20px; margin-left:-20px;'}
            }).show();
            // now load via ajax.
    		this.lastAct=2;
            this.request = new this.RequestClass({
                'link': 'chain',
                'method': 'get',
                url: url,
                onSuccess: (function(text, xml, js){spinner.destroy();this.request=null; this.pageLoaded(text, xml, js);}).bind(this)
            }).send();
        },
        pageLoaded: function(text, xml, js)
        {
            var el=Elements.from(text);
            var id=this.options.id;
            var scanNode=function(e)
            {
                // skip text nodes
                if(!e)return null;
                if(e.id==id)return e;
                var childNode, i = -1, childNodes = e.childNodes;
                while((childNodes.length>++i) && (childNode = childNodes.item(i)))
                {
                    var tmp2=scanNode(childNode);
                    if(tmp2)
                        return tmp2;
                }
            }
            var e=null;
            for(var i=0;i<el.length;i++)
            {
                e = scanNode(el[i]);
                if(e)
                    break;
            }
            if(e)
            {
    			$('1').dispose();
    			$('2').dispose();
    			$('3').dispose();
    			
    			
                $(this.options.id).adopt($(e).getChildren());
            }
            // TODO: execute all javascript we got in this request. To handle MediaBox etc.
        },
        addListener: function()
        {
            $('next').addEvent('click', (function()
            {
    			this.getNextPage();
            }).bind(this));
    		
    		$('previous').addEvent('click', (function()
    		{
    			this.getPrevPage();
    
    		}).bind(this));
        }
    });



    Nun habe ich noch eine Frage:

    Beachte weiterhin, in den nachgeladenen Objekten werden keine Javascriptaufrufe ausgewertet. d.h. Mediabox wird nicht funktionieren.
    Aus was für einen Grund werden keine Javascriptaufrufe ausgewertet?

    mfg

Aktive Benutzer

Aktive Benutzer

Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)

Lesezeichen

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •