Stuart
Stuart

Reputation: 4258

MVC PartialViews and JQuery, JS being applied to all PartialViews

I have my main page which contains a number of PartialViews

Here is my Index.cshtml

<div class="container">
    @{
        foreach (var summary in Model.Summaries)
        {
            <div class="partialViewWrapper">
                @Html.Partial("_Summary", summary)               
            </div>
        }
    }
</div>

Here is my Javascript:

$(document).ready(function() {
    $(".toggle").on("click",
        function() {
            var btn = $(this);
            var state = btn.html();
            if (state === 'Show Down Times') {
                btn.html('Hide Down Times');
                $('.foo').show();
            } else {
                btn.html('Show Down Times');
                $('.foo').hide();
            }

My partial View (relevant bits):

<div class="row">
        <div class="col-md-12">
            <button class="toggle btn btn-default" >Show Down Times</button>
        </div>
        <div class="foo col-md-12" style="display: none">
            <table class="table table-striped table-bordered table-responsive">
            ...
            </table>
         </div>
</div>

My issue is, when I click the button on the first partial view, it changes its text to Hide from Show, but both Partial Views show their respective table.

So, the JS to change the button text is being applied to the correct partial view buttons but the showing / hiding the table is being applied to all partial views.

I think I need to do something with $(this) rather than just referencing it by class but I have no idea how to achieve this with JQuery.

Thanks,

Upvotes: 0

Views: 42

Answers (2)

Tariq B.
Tariq B.

Reputation: 573

The reason is $('.foo'). Since you are not pointing out the table in a specific partial. The selector selects all classes with the class foo.

The solution to this problem is to

Either

Select the sibling of the parent using the parent and next functions with btn and then use hide or show.

Or

Add an additional attribute to the button say data-target and add the name of the class or id. Access it using btn.data('target') and then use hide or show.

Upvotes: 0

user3559349
user3559349

Reputation:

Use relative selectors to get the .closest() ancestor containing both elements and then .find() the other element inside that ancestor.

var btn = $(this);
var foo = btn.closest('.row').find('.foo');
if (state === 'Show Down Times') {
    btn.html('Hide Down Times');
    foo.show();
} else {
    btn.html('Show Down Times');
    foo.hide();
}  

Upvotes: 2

Related Questions