HendPro12
HendPro12

Reputation: 1104

C# MVC4 Jquery Ajax Post Partial View Update

I have the following partial view.

@using System.Data;
@using System.Dynamic;
@using System.Collections.Generic;
@using System.Linq;
@model TheMProject.Models.MyViewModel  

 <div id="Item_Buttons">
      <h2 class="alignleft">Table 1</h2>
      <p class="alignright">Item Name<input type="text" name="item_name" value="@Html.ValueFor(x => x.itemname)" class="search-query" placeholder="Search" style ="width:100px"/>
            <button class="btn btn-success" id="Change_Item_Name" value="Change_Item_Name" name="action:Change_Item_Name" type="button"> Change Item Name</button>
                            Grade<input type="text" name="item_grade" value="@Html.ValueFor(x => x.grade)" class="search-query" placeholder="Search" style="width:100px"/>
            <button class="btn btn-success" id="ChangeItemGrade" value="ChangeItemGrade" name="action:Change_Grade" type="button">Change Grade</button>
                            Delete Record<input type="text" name="delete_item" value="@Html.ValueFor(x => x.itemname)" class="search-query" placeholder="Search" style ="width:100px"/>
            <button class="btn btn-success" id="DeleteItem" value="DeleteItem" name="action:Delete_Item" type="button">Delete Record</button>
  </p>
    <div style="clear: both;"></div>
    </div>
<section>
    <div id ="firstgrid">
        <table id="TTable" class="gridTable">
            <thead class="gridHead">
                <tr>
                    @Html.DisplayFor(x => x.TColumns)
                </tr>
            </thead>
            <tbody>
                @Html.DisplayFor(x => x.TRows)
            </tbody>
        </table>
        </div>
</section>
    <section>
            <form id="form1">
        <div id="grid">
            <table id="CTable" class="gridTable">
                <thead class="gridHead">
                    <tr>
                        @Html.DisplayFor(x => x.Columns)
                    </tr>
                </thead>
                <tbody>
                    @Html.DisplayFor(x => x.Rows)
                </tbody>
            </table>
                </div>
            </form>
        </section>
<section>
    <div id ="Display_Average">
        <table id="AvgDisplayTable" class="gridTable">
            <thead class="gridHead">
                <tr>
                    @Html.DisplayFor(x => x.AvgColumns)
                </tr>
            </thead>
            <tbody>
                @Html.DisplayFor(x => x.AvgRows)
            </tbody>
        </table>
        </div>
</section>
<button class="btn" id="SubmitAverage" value ="SubmitAverage" name="action:SubmitAverage" type="button">Submit Averages</button>

<div id="ItemNameDiv" title="Change Item Name">
    @using (Html.BeginForm("ChangeItemName", "Home", "POST"))
    {
        <section>
            Heat Name:<input type="text" name="itemName" value="@Html.ValueFor(x => x.heatname)" style ="width:100px"/>
            Change to:<input type="text" name="updatedName" value="" style="width: 100px" />
            <input type="button" id="ChangeItemName" name="ChangeItemName" value="Change" />
        </section>
    }
</div>

<div id="ItemGradeDiv" title="Change Item Grade">
    @using (Html.BeginForm("ChangeGrade", "Home", "POST"))
    {
        <section>
            Item Grade:<input type="text" name="grade" value="@Html.ValueFor(x => x.grade)" style ="width:100px"/>
            Change to:<input type="text" name="updatedName" value="" style="width: 100px" />
            <input type ="hidden" name="hiddenItem" value ="@Html.ValueFor(x => x.itemname)" />
            <input type="submit" name="ChangeGrade" value="Change" />
        </section>
    }
</div>

<div id="DeleteItemDiv" title="Delete Item">
@using (Html.BeginForm("DeleteItem", "Home", "POST"))
{
    <section>
        Heat Name:<input type="text" name="itemName" value="@Html.ValueFor(x => x.itemname)" style ="width:100px"/>
        <input type="submit" name="DeleteItem" value="Delete" />
    </section>
}
    </div>

When the Change Item Name button is clicked, an ajax post is called with jquery as seen here:

   $(document).ready(function () {
        $('#ChangeItemName').click(function (e) {
            var tdata = $('#form1').serialize();
            var origname = $('#ItemNameDiv').find('input[name="itemName"]').first().val();
            var newname = $('#ItemNameDiv').find('input[name="updatedName"]').first().val();
            $.ajax({
                type: "POST",
                data: {
                    mCollection: tdata,
                    itemName: origname,
                    updatedName: newname
                },

                url: "Home/ChangeItemName",
                success: function (result) { success(result); }
            });
        });


        function success(result) {

            $('#ItemNameDiv').dialog('close');
            $("#My_Partial_V").html(result);
        }
    });

. Upon completion, the partial view is refreshed with the updated data from the post. Including the jquery required for this post, there are other scripts required to perform other actions in the view such as hiding the divs shown below the submit average button until other buttons are clicked. After the first time the previously mentioned ajax post is performed, if the same button is clicked the post is called twice instead of once, the third time its clicked it runs 4 times, etc.

Ive tried moving the script reference

<script src="@Url.Content("~/Scripts/partialitemscripts.js")" 
type="text/javascript"></script>

outside of the partial view and into the view which contains the partial as well as into the layout file. When I try these two methods everything loads correctly until the partial view is refreshed at which time all the scripts fail to be called/referenced.

Upvotes: 1

Views: 6114

Answers (2)

Bart Beyers
Bart Beyers

Reputation: 3384

You could try to move the script outside of the Partialview and into the mainview (like you said), but change it a little: instead of triggering the function when the document is loaded, put it all in a function:

function ajaxCallback(result){
    $('#ChangeItemName').click(function (e) {
        var tdata = $('#form1').serialize();
        var origname = $('#ItemNameDiv').find('input[name="itemName"]').first().val();
        var newname = $('#ItemNameDiv').find('input[name="updatedName"]').first().val();
        $.ajax({
            type: "POST",
            data: {
                mCollection: tdata,
                itemName: origname,
                updatedName: newname
            },

            url: "Home/ChangeItemName",
            success: function (result) { success(result); }
        });
    });
}    

Then you call this function from the ready event of your main view (the one that contains the partial).

To fix your button not working anymore when you've done an ajax request you've got to update your success-function to call the ajaxCallback (this would be in the partialitemscripts.js together with the ajaxCallback function):

function success(result) {
        $('#ItemNameDiv').dialog('close');
        $("#My_Partial_V").html(result);
        ajaxCallback();
    }

I'm not sure it this is the ideal solution, but I managed to get something similar working this way.

Upvotes: 5

idipous
idipous

Reputation: 2910

Although it is hard from the code posted to make sure. It seems that the reason the scripts fail after the first time is because you use the .html() which adds elements to the DOM and the click() event has not been binded to those new elements.

In this case you should use on() or delegate(). See the jquery documentation for how to use those. It is simple.

Upvotes: 0

Related Questions