• This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn more.

e.preventDefault() only working for first post

AndyB

Well-known member
#1
Hello,

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

pic001.jpg

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.
 

Daniel Hood

Well-known member
#2
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() { });
)
 

AndyB

Well-known member
#3
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.