0

EDIT - I am putting in more info to help get the answer. What I am doing is using autocomplete to add items to a list;

   <section id="rightSide" class="shrinkwrap" style="float: right;margin-top:10px;width:500px;">
        <fieldset>
            <legend>Select Other Materials</legend>
            <form method="get" action="@Url.Action("CreateOtherMaterials", "DataService")"
                  data-scd-ajax="true" data-scd-target="#otherMaterialList">
                <p>Select a Material: <input type="search" name="searchOtherMaterial" id="searchOtherMaterial" data-scd-autocomplete="@Url.Action("AutocompleteOtherMaterial", "DataService")" style = "width: 300px;" class="submitOtherMaterialSelectionNew" data-scd-add-other-material="@Url.Action("AddOtherMaterialNew", "DataService")"/>
                    @Html.DialogFormButton("Add New Material", Url.Action("AddMaterial", "Popup"), "Add New Material", null, Url.Action("Create"))
                </p>
            </form>  

            @Html.Partial("_OtherMaterials", Model.SupplierMaterialList.Where(x => x.PrimaryMaterialFlag == false).ToList())

        </fieldset>
    </section>

So everytime an item is entered, the list grows. I am wondering if the problem is that the script does not pick up the latest updates to the page? The partial view _OtherMaterials looks like

@model IList<SupplierMaterial>

<div id="otherMaterialList" >
    <p>These materials have now been added for this supplier</p>
    <table>
        @Html.DisplayForModel()
    </table>
</div>

This is a grid that uses the DisplayTemplate below to display rows of data;

@model SupplierMaterial
<tr>
    <td>@Model.Material.MaterialName </td>
    <td>
        <form class="shrinkwrap" method="get" action="@Url.Action("RemoveOtherMaterial", "DataService")">
            <input type="button" value="Remove" class="removeItem"/>
            @Html.HiddenFor(model => model.MaterialId)
        </form>
    </td>
</tr>

The form does not overlap with any other. When the user clicks on the button this code is meant to run;

$('.removeItem').click(function () {
    alert("test");
    var $form = $(this).closest("form");
    var options = {
        url: $form.attr("action"),
        type: $form.attr("method"),
        data: $form.serialize()
    };

    $.ajax(options).done(function (data) {
        var $tr = $(this).closest("tr");
        $tr.remove();
    });

    return false;
});

However the click event is not captured by this code, and I can't work out why

arame3333
  • 9,887
  • 26
  • 122
  • 205

2 Answers2

1

when you are working with dynamic content that has been added to the page on the fly, event handlers like click() will not get bound to dynamically added selectors by itself.

you should put your code in delegate() or on() indside document load that can handle future contents.

$('body').delegate('.removeItem', 'click', function(){
var $form = $(".shrinkwrap");
var options = {
    url: $form.attr("action"),
    type: $form.attr("method"),
    data: $form.serialize()
};

$.ajax(options).done(function (data) {
    var $tr = $(this).parent("tr");
    $tr.remove();
 });
});

you can use much more closer selector than body to make the response more faster. you could also use live('selector', function(){}); but it has been deprecated as of jQuery v1.9. Hope this helps.

Rohit416
  • 3,416
  • 3
  • 24
  • 41
  • I think live has been replace with on? – arame3333 May 21 '13 at 13:59
  • The delegate does the job. Now I know when to use it. – arame3333 May 21 '13 at 14:03
  • glad that worked for you, `on()` was not replaced with `live()` it was added in when `live()` and `delegate()` was in existance as an alternative but much expressive. but `live()` was dropped from set of jQuery API from `jQuery v1.9`. however it will work till `v1.8.3` – Rohit416 May 22 '13 at 04:53
0

Try to replace

alert(test);

with

alert('test');

I think here you have stuck up and try like this

$('.removeItem').click(function () {
    var $form = $(".shrinkwrap");
    var options = {
        url: $form.attr("action"),
        type: $form.attr("method"),
        data: $form.serialize()
    };

    $.ajax(options).done(function (data) {
        var $tr = $(this).parent("tr");
        $tr.remove();
    });
});
GautamD31
  • 28,552
  • 10
  • 64
  • 85
  • Good point, although I put that there when it was not working – arame3333 May 21 '13 at 13:00
  • Because it is a display template and repeated many times, the var $form will be a collection of forms which is not what I want. I appreciate advice on how I can improve the code. The main issue is that the event is not firing and the alert is not running – arame3333 May 21 '13 at 13:06