e.preventDefault() only working for first post

AndyB

Well-known member
Hello,

I'm creating an Audio List add-on. Here's an example of two posts each with an Audio List player.

pic001.webp

In the first post the player works perfectly, I can click any of the songs and the player plays. In the second post when I click a song it open a new window instead of playing in the audio player as it should.

I'm using the a Custom BB Code with a PHP callback.

PHP code:
PHP:
<?php
class Andy_AudioList_Index
{
    public static function render(array $tag, array $rendererStates, XenForo_BbCode_Formatter_Base $formatter)
    {
        // continue only if a view response
        $view = $formatter->getView();
        if ($view)
        {
            // get url
            $url = $tag['option'];
                       
            // get database
            $db = XenForo_Application::get('db');
           
            // run query           
            $audiolist = $db->fetchAll("
                SELECT folder_url, filename, title           
                FROM xf_audiolist
                WHERE folder_url = ?
                ORDER BY title ASC       
            ", $url);
           
            // get audiolistDefault
            foreach ($audiolist as $list)
            {
                if ($audiolistDefault == '')
                {
                    $audiolistDefault = $list['folder_url'] . $list['filename'];
                }
            }           

            // send to template   
            $template = $view->createTemplateObject('andy_audiolist_render', array(
                'audiolistDefault' => $audiolistDefault,
                'audiolist' => $audiolist
            ));
            return $template;
        }
    }
}

Template code:
Code:
<xen:require css="andy_audiolist.css" />

<audio id="audio" preload="auto" controls>
<source src="{$audiolistDefault}" type="audio/mp3" >
</audio>

<ul id="playlist" class="audiolist">

<xen:foreach loop="$audiolist" value="$list" i="$i">
<xen:if is="{$i} == 1">
<li class="active"><a href="{$list.folder_url}{$list.filename}">{$list.title}</a></li>
<xen:else />
<li class="audiolist"><a href="{$list.folder_url}{$list.filename}">{$list.title}</a></li>
</xen:if>
</xen:foreach>

</ul>

<script>

var audio;
var playlist;

init();

function init()
{
    audio = $('#audio');
    playlist = $('#playlist');
   
    playlist.find('a').click(function(e)
    {
        e.preventDefault();
        sourceUrl = $(this);
        run(sourceUrl, audio[0]);
    });
}

function run(sourceUrl, player)
{
        player.src = sourceUrl.attr('href');
        par = sourceUrl.parent();
        par.addClass('active').siblings().removeClass('active');
        audio[0].load();
        audio[0].play();
}

</script>

The problem I think has something to do with the e.preventDefault() function. It only works for the first post and not the second post.

Thank you for your help.
 
That's because you're not looping through the results of .find() so it's only using the first one. Look at the .on() function instead (something like:
Code:
playlist.on('click', 'a', function() { });
)
 
Hi Daniel,

I really appreciate you taking the time to help me with this.

So I substituted the line of code per your example and the results are identical. I also added a console.log code to help me see what is going on:

PHP:
	playlist.on('click', 'a', function(e)
	{
		e.preventDefault();
		console.log( $( this ).attr( 'href' ) );
		sourceUrl = $(this);
		run(sourceUrl, audio[0]);
	});

I can now see that when I click on one of the songs in post #1 the web console shows it being clicked twice, even though I only clicked it once. So you're right the JavaScript code is grabbing the same five links twice.
 
Top Bottom