views:

58

answers:

2

I have this button, and when clicked, it sends an ajax call which changes the value of score_up.

I dont see what the problem is. I tried firbug, but apparently it's not even detecting the javscript? :)) Thanks.

jquery:

$('.stats').delegate('.support', 'click', function(e) {

      //stop event
      e.preventDefault();
      //get the id
       var the_id = $(this).closest('.score').attr('id').split('_').pop();
        //the main ajax request
       $.ajax({
           context:this,
           type: "POST",
           data: "action=support&id=" + the_id,
           url: "ajax/sa.php",
          success: function (msg) {

               $(this).siblings("h2.score_up").html(msg).fadeIn();
                //remove down button
                // and remove support button


           }
      });
   });

html:

 <ul class="stats">
        <li id="support_23"class="score">
            <h2 class="score_up">12</h2>
            <span style="text-align:center;">Supporters</span>
        </li>
        <li>
    <button type="submit" value="Actions" class="support" title="support">
        <i></i>
        <span>Support</span>
    </button>
</li>


//vote down button

 <li id="down_23"class="score">
            <h2 class="score_down">12</h2>
            <span style="text-align:center;">down</span>
        </li>
        <li>
    <button type="submit" value="Actions" class="down" title="down">
        <i></i>
        <span>down</span>
    </button>
</li>

    </ul>
+2  A: 

Your HTML is invalid, so I would do:

<form action="javascript:alert('form')";>
<ul class="stats">
    <li id="topic_23"class="score">
        <h2 class="score_up">12</h2>
        <span style="text-align:center;">Supporters</span>
    </li>
    <li>
      <button type="submit" value="Actions" class="support" title="support">
      <i></i><span>Support</span></button>
    </li>
</ul>
</form>

And then the jQuery (which in your original would not work, since you wanted .siblings() and not .closest() would now be:

var the_id = $(this).closest("li").siblings('.score').attr('id')
                    .split('_').pop();

and success:

$(this).closest("li").siblings("li.score").find("h2.score_up")
       .html(msg).fadeIn();

I think you also run into troubles with prevent default, since you want to prevent default on the form, and in that case you might run into problems with delegate.

Here is what I would do with .live():

// Prevent form from submitting
$("form").live("submit", function(e) {
    e.preventDefault(); });

// Run Ajax
$('button.support').live('click', function(e) {
      //get the id
       var $score = $(this).closest("li").siblings('.score'),
           the_id = $score.attr('id').split('_').pop();
        //the main ajax request
      $.ajax({
           context:this,
           type: "POST",
           data: "action=support&id=" + the_id,
           url: "ajax/sa.php",
           success: function (msg) {
               $score.find("h2.score_up").html(msg).fadeIn(); 
           }
      });
});

Try it out on this jsFiddle

Peter Ajtai
thanks @peter its not working still
getaway
@getaway, your success isn't quite right either. Was still in the process of editing. Ok, added in the corrected succes callback too.
Peter Ajtai
thank you very much, it solved the ajax bit, pheeeeeew, thanks again +uovote from me, but its not updating the score, i get the right reponse from firebug, but it deosnt not update the score on the webpage (H2.support bit) :))
getaway
@getaway - I think there's something odd going on with your `.preventDefault()`, since you want to prevent the default on `submit` not `click`. The way I know how to do that is with `live()`. I put together a working example on jsFiddle. You might be able to use delegate on the click sitll, but I was having problems with it.
Peter Ajtai
it works on js fiddle but not on my page, i tried your alternative but its still the same thing
getaway
@getaway - I also added a little cleanup to your HTML. Since you had invalid HTML that may have also been causing problems. Try it now. Also, if you can get it to work on jsFiddle but not your page, that means your page is somehow different.
Peter Ajtai
+2  A: 

It is not valid HTML for a <button> to be a direct child of a <ul>.

Children of <ul> should be <li>. I wouldn't expect things to work properly with invalid HTML.

HTML with <button> inside a <li>:

<ul class="stats">
    <li id="topic_23" class="score">
        <h2 class="score_up">12</h2>
        <span style="text-align:center;">Supporters</span>
    </li>
    <li>
        <button type="submit" value="Actions" class="support" title="support">
            <i></i>
            <span>Support</span>
        </button>
    </li>
</ul>

jQuery, fixing some of the traversal methods:

$('.stats').delegate('.support', 'click', function(e) {
      //stop event
      e.preventDefault();
        // cache a reference to the previous <li> element
        //   since it is used more than once
       var $prevLi = $(this).closest('li').prev('li');
      //get the id
       var the_id = $prevLi.attr('id').split('_').pop();
        //the main ajax request
       $.ajax({
           context:this,
           type: "POST",
           data: "action=support&id=" + the_id,
           url: "ajax/sa.php",
          success: function (msg) {
               $prevLi.find("h2.score_up").html(msg).fadeIn();
           }
      });
 });
patrick dw
hey patrick, what do you think i should do then, this is a bit different from the other one we did? when we were working with links, im trying to do this with buttons for my blog!!!
getaway
@getaway - Did this code work? I placed the `<button>` in its own `<li>`. Not sure if that's how you want it. We could place it in the first `<li>`, but will need to change a little then.
patrick dw
parick it works fine , but instead of chnaging the score up, it removes it
getaway
sorry it deos work, thank you very much :))
getaway
patrick can i ask, how deos once remove the button after the click if the score is gone throw!!!
getaway
@getaway - Are you saying you want to remove the `<button>` after the AJAX response has been received?
patrick dw
@Patrick, does `e.preventDefault()` on the `click` of the submit button work to stop submittal? I somehow can't get it to do that ==> http://jsfiddle.net/dbBHQ/ ---------------- I thought you had to use preventDefault with the `submit` action of the `form` itself.
Peter Ajtai
@patrick i dnt think i need it e.prevent default, yeh i want to remove 2 button on the succes function? i have updated the code on the question
getaway
@Peter - Your code wasn't running onDomReady. You need to choose that from the menu on the left or wrap your code with `.ready()`. http://jsfiddle.net/dbBHQ/1/ :o)
patrick dw
updated code @patrick :)) , i just wanted both buttons, so basically the vote cast, so the user is not allowed to vote anymore, just once, if you get what i mean
getaway
You're right. Strange, I thought `.delegate()` was like `.live()`, in that one of its advantage is that it can be used for all now and future elements and so may be run before DOM ready? ----------- I guess `.stats` must be part of the DOM when delegate is run, but `.support` can be added later....
Peter Ajtai
@getaway - First, please pay attention to this. The placement of your buttons *is invalid*. They should *not* be a direct child of `<ul>`. They need to be inside a `<li>`. In your code update, they are not. I can't give meaningful advice on invalid HTML because I don't know what sort of corrections the browser will make.
patrick dw
@patrick, sorry, sorry i chnaged the code, i totally forgot!!
getaway
@Peter - They are almost exactly the same, but with one important difference. The `.live()` method places the handler on the `document` object which is available immediately. But `.delegate()` is placed on descendant elements of the `<body>`. As such, you can't assign handlers to them until they're available (just like any other element).
patrick dw
Thanks Patrick. I haven't used `delegate` much only `live`.
Peter Ajtai
@getaway - Now you have 2 elements with the same ID of `topic_23`. This is invalid. I have a feeling that you want all the elements to be under a single `<li id="topic_23">`. That would seem to make sense if you have several `id="topic_xx"` elements.
patrick dw
@Peter - You're welcome. I personally think `live()` is overused/over-recommended. Typically dynamic events are added to some specific container that can have a delegate. I personally wouldn't use `.live()` unless there's some sort of element that could be placed at any location on the page. I don't think that happens too often.
patrick dw
@patrick i have chnaged the id, this the only element on the page that needs updating, so yeh i have changed them to thier id names, sorry again, someone neeeds to slap me :))
getaway
@getaway - So you want to remove *both* buttons? And if so, will the 2 `<li>` elements be right next to each other, or are they separated by other elements?
patrick dw
they are next to each other? yeh i want to remove two buttons on success please :))
getaway
@getaway - From the button, traverse up to its `<li>` then over to the proper `<li>` that has the other button, then `.find()` the button. Then remove the original button. Something like this: `$(this).closest('li').next().next().find('button').remove(); $(this).remove();`
patrick dw
thanks @patrick :)) it removes the support button, but not the down button :))
getaway
@getaway - did your HTML change from the question? `$(this).closest('li')` gives you the `<li>` element. Then according to your question, the `<li>` that contains the down button is not the next `<li>` but the one after it. So we do `.next().next()`. Then the `<button>` is a child of that, so we do `.find('button')`. Any change to the HTML structure may break it.
patrick dw
@patrick thank you its works, thank you very much, your a star yet again!! :))
getaway