e.preventDefault() only working for first post


Well-known member

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


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:
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:
<xen:require css="andy_audiolist.css" />

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

<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>



var audio;
var playlist;


function init()
    audio = $('#audio');
    playlist = $('#playlist');
        sourceUrl = $(this);
        run(sourceUrl, audio[0]);

function run(sourceUrl, player)
        player.src = sourceUrl.attr('href');
        par = sourceUrl.parent();

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.

Daniel Hood

Well-known member
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:
playlist.on('click', 'a', function() { });


Well-known member
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:

	playlist.on('click', 'a', function(e)
		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.