hsim
hsim

Reputation: 2080

Dynamically delete a row in view: only the first row is affected

I am trying to build a dynamic view where a user may add and delete row at will.

Up to now I've been successful with adding a new row, but deleting a row only remove the first line and now the new ones added.

Here's how the main view is rendered:

@using MyApp.Models
@using MyApp.Utilities
@model PackUtility

@{
    ViewBag.Title = "Item to Sell:" + Model.mTitle;
}

<script language="javascript">
    $(document).ready(function () {
        $('#addItemUtilityZone').click(function () {
            $.ajax({
                url: '@Url.Action("AddItemUtilityRow")',
                cache: false,
                success: function (html) {
                    $('#addItemUtilityZone').append(html);
                }
            });
        });
        $('a.deleteRow').click(function () {
            alert("clicked");
            $(this).parents("div.editorRow:first").remove();
            return false;
        });
    });
</script>

@using (Html.BeginForm("SelectItemToSell", "Item", FormMethod.Post, new { onsubmit = "ShowProgress()"}))
{
    @Html.ValidationSummary(true)

    <div class="formStyle baseFontSize">
        (...)
        <div>
                <div>
                    >> Possible Quantity: @Html.DisplayFor(_item => _item.mPossibleQuantity) <<
                </div>
                <div class="formStyle" id="addItemUtilityZone">
                    <label class="center bold bigFontSize">Options</label>
                    @foreach (ItemListingUtility utilityRow in Model.ListItemUtility)
                    {
                        Html.RenderPartial("ItemUtilityRow", utilityRow);
                    }

                </div>
                <div>
                    <a href="javascript:void(0);" id="addPackAuctionUtility">Add row</a>
                </div>
        </div>
    </div>
}

So there's this partial view that gets rendered in a foreach, and which is called by the ajax method in jquery:

@using HtmlHelpers.BeginCollectionItem
@model MyApp.Utilities.ItemListingUtility

@using (Html.BeginCollectionItem("_listItems"))
{
    <div class="editorRow defaultBaseStyle blueBorder">
        <div class="float-left defaultBaseStyle">
            <div class="float-left">Quantity:</div>
            <div class="float-right">@Html.DisplayFor(_item => _item.Quantity)
                @Html.HiddenFor(_item => _item.Quantity)
            </div>
        </div>
        <div class="float-left defaultBaseStyle">
            <div class="float-left">Price:</div>
            <div class="float-right">@Html.TextBoxFor(_item => _item.StartPrice, new { @class = "positive moneyValue"}) $</div>
        </div>
        <div class="clear"></div>
        <a href="javascript:void(0);" class="deleteRow">Delete</a>
    </div>
}

So as I mentioned, when a user clicks a "delete" link, only the original first section is affected, the rest never calls the jquery method, and I don't understand why or how to correct this.

Upvotes: 0

Views: 612

Answers (2)

Dhaval Marthak
Dhaval Marthak

Reputation: 17366

Try like this, You need event delegation here!

$('#addItemUtilityZone').on('click','a.deleteRow',function () {
   alert("clicked");
   //$(this).parents("div.editorRow").remove(); // remove parents
   //$(this).parents("div.editorRow:first").remove(); // To remove first always
    $(this).closest("div.editorRow").remove(); // Use closest()
   return false;
});

To remove the rows it would be better to use closest() rather than parents().

Event delegation allows us to attach a single event listener, to a parent element, that will fire for all children matching a selector, whether those children exist now or are added in the future.

$(document.body).on('click','a.deleteRow',function () {

});

You can have the closest parent element as a selector in case of an elements that are generated dynamically, I have got #addItemUtilityZone as new elements/rows are appended to this div you can also try document.body

Upvotes: 2

Bellash
Bellash

Reputation: 8184

With

        $(this).parents("div.editorRow").remove();

It should work. But if you want to filter, use

        $(this).parents("div.editorRow:first-child").remove();

Upvotes: 0

Related Questions