views:

313

answers:

3

I am reading Beginning CakePHP, and to make it so that you can vote on comments, it tells you to create a couple of AJAX links:

<?=$ajax->link('<li>up</li>',
                      '/comments/vote/up/'.$comment['Comment']['id'],
                      array('update' => 'vote_'.$comment['Comment']['id']),
                      null, false);?>
<?=$ajax->link('<li>down</li>',
                      '/comments/vote/down/'.$comment['Comment']['id'],
                      array('update' => 'vote_'.$comment['Comment']['id']),
                      null, false);?>

This works fine in IE, but in FF it doesn't do anything at all. It doesn't even reach the controller or model, because the links it generates don't do anything.

The HTML it generates looks like this:

<a id="link2128392960" onclick=" event.returnValue = false; return false;" href="/blog/comments/vote/up/1"/>
<li>
  <a id="link2128392960" onclick=" event.returnValue = false; return false;" href="/blog/comments/vote/up/1">up</a>
</li>
<script type="text/javascript">
  //<![CDATA[
  Event.observe('link2128392960', 'click', function(event) { new Ajax.Updater('vote-1','/blog/comments/vote/up/1', {asynchronous:true, evalScripts:true, requestHeaders:['X-Update', 'vote-1']}) }, false);
  //]]>
</script>
A: 

Using php short tags ("<? ") can be considered a bad practice, plus they are being removed in php 6.

code_burgar
What's wrong with that? http://javascript.about.com/library/blxhtml.htm
Kai
My bad, fixed. CDATA tags are ok inside <script> tags
code_burgar
Yeah the book uses short tags in the sample code, and they're enabled on my server so I just copied it. I guess in future I could avoid it.
Rob
+1  A: 

I don't think it's valid HTML to have an anchor tag without an ending anchor tag, like in your first link:

<a id="link2128392960" onclick=" event.returnValue = false; return false;" href="/blog/comments/vote/up/1"/>

Maybe Firefox is mad at you for that.

You also have two tags with the same id, which is also invalid HTML, but might also mean that your Javascript is searching for clicks on the second link but that link is being "eaten" by the first link because you never ended it.

Just throwing out ideas ;p

Kai
I can't change this. I am just using CakePHP framework which generates that. It should work with Firefox since it is pretty major and used on many websites. Either I have done something wrong in the PHP or CakePHP is bugged.
Rob
Well after the code is generated, PHP's job is done. The symptoms you're describing are in the client after the HTML is already generated, so the first step is to figure out what's wrong in the HTML and the next is to fix that in PHP.
Kai
+4  A: 

Firstly, the HTML output you pasted isn't accurate. It looks like you copied this from Firebug or something instead of your browsers actual 'View Source' page. CakePHP doesn't actually generate self-closing anchor tags in this scenario (<a /> as opposed to <a></a>) like your example shows.

I believe this points out your problem though. The fact that your browser's HTML parser (or Firebug's) tried to correct the code at runtime points to your HTML being malformed. Specifically, you cannot put a block-level element (<li>) inside an inline element (<a>).

<div class="actions">
    <ul>
        <li>
            <?php echo $ajax->link('up', array(
                'controller' => 'comments',
                'action' => 'vote',
                'up',
                $comment['Comment']['id']
            ), array(
                'update' => 'vote_' . $comment['Comment']['id']
            ), null, false); ?>
        </li>
        <li>
            <?php echo $ajax->link('down', array(
                'controller' => 'comments',
                'action' => 'vote',
                'down',
                $comment['Comment']['id']
            ), array(
                'update' => 'vote_' . $comment['Comment']['id']
            ), null, false); ?>
        </li>
    </ul>
</div>

The above example will produce valid HTML as the inline <a> elements will then be wholly nested within block-level <li> elements. This should hopefully fix the functionality of your page in standards-compliant browsers.

deizel
Well explained! I hadn't seen the inline vs. block element consideration.
Kai
You were exactly right, thank you.
Rob