Weird Javascript Bug (jQuery) in a simple test page

I am writing a Mediawiki extension. I am actually at a very early stage;). Here you can find the code (well, I can send only one link, so submit a github url) / eugenkiss / discussion-extension

I have a strange jQuery problem that I just can't solve, even using firebug and trying to debug my code. I downloaded the current code and example here: http://jsfiddle.net/NMpU5/

Try opening a discussion and clicking on at least two “reply” links. Then click the cancel button of the first form that appeared. I don’t know why, but when you click the cancel button, another form closes instead of the desired one.

You can also change this. For example, open two forms and close the last open. It works first. But when you try to close another form (by clicking on cancel), it will not disappear. However, the event is fired as shown by firebug. Sometimes, when I click on another answer anchor, after that, as many forms open as I clicked on the button, which, it would seem, does not work to cancel another form.

Well, for my desired extension, I could, of course, limit the existence of open forms to one — why else do you need two or more open forms? But I just want to find a damn mistake, since I already spent a lot of time looking for it! You know, this is a precious mistake for me;)

By the way, I'm using jQuery 1.4.2

Javascript


$(document).ready(function() {
    // Hide the discussion bodys per default
    $(".discussion").addClass("closed")
        .children(".discussion-body").hide();

    // Register two custom events for the individual discussion divs      
    // "open" & "close" in order to make the discussion bodys
    // collapsable and be able to toggle the events by clicking
    // the "discussion-header-button" anchor
    $(".discussion")
    .bind("open", function(e) {
       if(!$(this).hasClass("opened")) {
           $(this).children(".discussion-body").slideDown();
           $(this).find(".discussion-header-button").html("[-]");
           $(this).addClass("opened");
           $(this).removeClass("closed");
       }
    })
    .bind("close", function(e) {
       if(!$(this).hasClass("closed")) {
           $(this).children(".discussion-body").slideUp();
           $(this).find(".discussion-header-button").html("[+]");
           $(this).addClass("closed");
           $(this).removeClass("opened");
       }
    })
    .find(".discussion-header-button").click(function(){
        relatedDiscussion = $(this).parents(".discussion");
        if(relatedDiscussion.hasClass("closed")) {
            relatedDiscussion.trigger("open");
        }
        else if(relatedDiscussion.hasClass("opened")) {
            relatedDiscussion.trigger("close");
        }
    });

    // Register custom "showForm" & "destroyForm" events on posts       
    // in order to make the "Reply" button work
    // TODO: Maybe add "preview" & "submit"
    $(".discussion-body .post")
    .bind({
        showForm: function(){
            post = $(this);
            postBody = post.find(".post-body").first();
            postHeader = post.find(".post-header").first();

            postBody.append(postCommentFormHtml);
            replyLink = postHeader.find(".reply");
            replyLink.unbind();

            form = postBody.find(".post-comment-form");
            form.slideDown();

            // create actions for the form buttons
            form.find(".cancel").click(function(){
                post.triggerHandler("destroyForm");
            });
            form.find(".preview").click(function(){
                // Hier muss mit Ajax und der Datenbank gespielt
                // werden um ein preview erstellen zu können
            });
            form.find(".submit").click(function(){
                // Hier muss mit Ajax und der Datenbank gespielt
                // werden um den Post abschicken zu können
            });
        },
        destroyForm: function(){
            post = $(this);
            postBody = post.find(".post-body").first();
            postHeader = post.find(".post-header").first();

            replyLink = postHeader.find(".reply");
            replyLink.click(replyAction);

            form = postBody.find(".post-comment-form");
            form.slideUp(function(){
                    $(this).remove();
            });
        }
    });
    //$(".discussion-post-comment").click(createPostCommentForm);
    $(".discussion .reply").click(replyAction);

    function replyAction(event){
        // Note: It is important to use triggerHandler instead of trigger
        // otherwise the "showForm" event of all parents is triggered
        // recursively (bubbling) and this is not desired
        event.preventDefault();
        relatedPost = $(this).parents(".post").first();
        relatedPost.triggerHandler("showForm");
    }
});
postCommentFormHtml = "\
    <div class='post-comment-form' style='display:none;'><br>\
    <form action='textarea.htm'>\
        <textarea name='post' cols='50' rows='8'></textarea>\
        <br>\
        <input class='submit' type='submit' value=' Post '>\
        <input class='preview' type='submit' value=' Preview '>\
        <input class='cancel'type='reset' value=' Cancel '>\
    </form>\
    </div>";​

HTML


<div class="discussion">
<div class="discussion-header">
    <a class="discussion-header-button">[+]</a>
    Diskussion: 3 Kommentar(e)
    <a class="discussion-post-comment">Post Comment</a>
</div>
<div class="discussion-body">
<div class="post">
    <div class="post-header">
        <span class="post-header-name">Eugen</span>
        <span class="post-header-date">2010-02-25 12:32:30</span>
        <a class="reply" href="#">Reply</a>
        <a class="edit" href="#">Edit</a>
        <a class="delete" href="#">Delete</a>
    </div>
    <div class="post-body">
        Ich denke das sollte anders sein!
    </div>
    <div class="post">
        <div class="post-header">
            <span class="post-header-name">Markus</span>
            <span class="post-header-date">2010-02-25 12:32:31</span>
            <a class="reply" href="#">Reply</a>
         <a class="edit" href="#">Edit</a>
         <a class="delete" href="#">Delete</a>
        </div>
        <div class="post-body">
            Ich denke nicht
        </div>
    </div>
</div>
<div class="post"> 
    <div class="post-header">
        <span class="post-header-name">Jan</span> 
        <span class="post-header-date">2010-03-25 12:32:30</span>
        <a class="reply" href="#">Reply</a>
        <a class="edit" href="#">Edit</a>
        <a class="delete" href="#">Delete</a>
    </div>
    <div class="post-body">
        Mal was ganz anderes: Denkt ihr das selbe was ich denke?
    </div>
</div>
</div>
</div>

: , . , : ( Firebug), "post" (, , "postbody" ) ( "destroyForm" ) , . , post

Edit2: alls id http://jsfiddle.net/NMpU5/1/

+3
5

, ( , "post" "relatedDiscussion" ) "var" . , , . , , . , , "", , , "post" , .

 var post = $(this);

.

+3

, : . A , .

+3

jQuery live .

script

$(".cancel").live("click", function(){
    $(this).closest(".post-comment-form").slideUp('',function(){ $(this).remove(); });
});
$(".preview").live("click", function(){
    // Hier muss mit Ajax und der Datenbank gespielt
    // werden um ein preview erstellen zu können
});
$(".submit").live("click", function(){
    // Hier muss mit Ajax und der Datenbank gespielt
    // werden um den Post abschicken zu können
});

post.triggerHandler("destroyForm");, , , , LOL.

+1

jQuery "#something", "document.getElementById()" . , , "id" ; , . , "find()" "id", .

In this case, you need to use the "name" attributes for the form input fields.

0
source

you do not need to change identifiers to classes. you just need unique identifiers for each item, so you can get the correct one.

-1
source

Source: https://habr.com/ru/post/1734880/


All Articles