Afzaal Ahmad Zeeshan
Afzaal Ahmad Zeeshan

Reputation: 15860

How to use jQuery to show a form for a specific div

I am using jQuery to show and hide the edit options for each post. Here is the jQuery that I am using:

$(document).ready(function () {
    $(".post-menu").click(function () {
        $(".menu-options ul").toggle();
    });
    $(".edit-option").click(function () {
        $("#edit-post").show();
        $(".menu-options ul").toggle();
    });
    $("#never-mind").click(function () {
        $("#edit-post").hide();
    });
})

Slight introduction about code: the post-menu is the div which handles the show hide events, edit-options is the <ul> that has to popup containing edit and delete as <li> in it, the #edit-post is the div for a textarea, submit button (which uses ajax jquery; no need to have a form), and #never-mind is a button to close it.

The div code is:

<div class="post-menu">
    <div style="width: 20px; height: 8px;" >Options</div>
    <div class="menu-options">
        <ul>
            <li class="edit-option">Edit</li>
            <li class="delete-option">Delete</li>
        </ul>
    </div>
</div> // I missed this while writing the question, sorry for that!
    <div style="display: none;" id="edit-post">
        <textarea id="new-post-message">@row.Message</textarea>
        <br>
        <button onclick="updatepost(@row.PostId)">Save</button>
        <button id="never-mind">Never mind</button>
        <div class="error-post"></div>
    </div>

Desired Behavior: Show the options panel only for the selected post.

Current Behavior: The problem is that it unhides the option panel for every post when I just want to show the options panel the selected post.

What am I doing wrong?

Upvotes: 1

Views: 435

Answers (4)

cssyphus
cssyphus

Reputation: 40038

I'm a bit late to the party, but here's my response.

jsFiddle here

You have a few issues here (which is why it took a while to post this).

  1. If you are using a loop to output user posts, then the IDs will be duplicated. That is a no-no. Please use classes, or add a unique identifier to each ID. See the ID added to each post-menu div.
  2. Your jQuery says to toggle the UL element when the user clicks on the 'post-menu' div, but to also toggle the same element if they click on the 'edit' item, which is inside the 'post-menu' div. In other words, both events will fire when user clicks the EDIT button, and the UL will toggle twice. Use e.stopPropagation() to avoid that.
  3. Since you do not reliably know the unique ID of elements near the clicked item, you should use jQuery DOM traversal selectors, like next() or parent(). See my example.
  4. You can see how I alerted the found element ID as I worked to locate the correct element. I left in those tests just to show you how to do that.

REVISED HTML:

<div class="post-menu" id="PostMenu1">
    <div style="width: 20px; height: 8px;" id="OptionsDiv">Options</div>
    <div class="menu-options">
        <ul id="myUL" class="myUL">
            <li class="edit-option">Edit</li>
            <li class="delete-option">Delete</li>
        </ul>
    </div>
</div>
<div style="display: none;" class="edit-post">
    <textarea id="new-post-message">@row.Message1</textarea>
    <br>
    <button class="savebutt" onclick="updatepost(@row.PostId)">Save</button>
    <button class="never-mind">Never mind</button>
    <div class="error-post"></div>
</div>
<!-- ---------------------------------------------------------- -->
<div class="post-menu" id="PostMenu2">
    <div style="width: 20px; height: 8px;">Options</div>
    <div class="menu-options">
        <ul>
            <li class="edit-option">Edit</li>
            <li class="delete-option">Delete</li>
        </ul>
    </div>
</div>
<div style="display: none;" class="edit-post">
    <textarea id="new-post-message">@row.Message2</textarea>
    <br>
    <button onclick="updatepost(@row.PostId)">Save</button>
    <button class="never-mind">Never mind</button>
    <div class="error-post"></div>
</div>

REVISED JQUERY:

$(".post-menu").click(function () {
    $(this).find(".menu-options ul").toggle();
});
$(".edit-option").click(function (e) {
    $(this).find(".edit-post").show();
    //var x = $(this).closest('div').parent().next().attr('class');
    //alert(x);

    //$(this).parent().parent().find('ul').toggle();
    $(this).closest('div').parent().next().toggle();
    e.stopPropagation();
    //var x = $(this).parent().parent().find('ul').attr('class');
    //alert(x);
});
$(".never-mind").click(function () {
    //var x = $(this).closest('div').attr('class');
    //alert(x);
    $(this).closest('div').hide();
});
$('.delete-option').click(function(e) {
    var x = $(this).closest('div').parent().attr('id');
    alert('Deleting DIV with ID: ' + x);
    e.stopPropagation();

});

Upvotes: 1

Venkata Krishna
Venkata Krishna

Reputation: 15112

Assuming you have multiple divs with the class post-menu & you need its corresponding menu options to toggle based on the context. This is what you need.

$(".post-menu").click(function (e) {
    $(this).find(".menu-options ul").toggle();
});

EDIT: as @Roko mentioned.. if you don't want to bubble the event propagation..

use e.stopPropagation()

Upvotes: 2

Roko C. Buljan
Roko C. Buljan

Reputation: 206078

<div style="width: 20px; height: 8px;" />Options</div> is not the way we should close DIV elements (note the />)

Avoid the use of ID if you want to handle multiple elements use the right selectors for the job like $(this).next() etc... and you're done.

Upvotes: 2

Dani
Dani

Reputation: 1250

Would be useful for a jfiddle with multiple entries, but I think you just need to add $(this)

Also you might need to turn your menu options into a ID rather than a class

$(document).ready(function () {
 $(".post-menu").click(function () {
    $(this).(".menu-options ul").toggle();
});
$(".edit-option").click(function () {
    $(this).("#edit-post").show();
    $(this).(".menu-options ul").toggle();
});
$("#never-mind").click(function () {
    $(this).("#edit-post").hide();
});
})

Upvotes: 1

Related Questions