TLBB TLBB - 2 months ago 10
Ajax Question

Ajax: Send model ID to controller from list itterated by foreach loop

I need to be able to click a button that is generated by a foreach (or for-loop if that is needed).

When the button is generated, it should have the models ID so that when the Ajax is called, it will send the id to the controller call.

I'm running into an issue, when the Ajax is called, it will simply have the value of the last model in the list, so some type of overwriting is happening.

Controller Ajax [This is not finished, I plan on doing a return call, but for now I'm simply trying to get the post to the method working]

public void AjaxTest(TestStepDisplayModel testStepDisplayModel)
{

}


Partial View

@model AsyncDemo.Models.TestStepDisplayModels


<h3>Main Test Steps</h3>
<table class="table">
<tr>
<th width="20" class="gray">
Step #
</th>
<th width="180" class="gray">
Test Step
</th>
<th width="50" class="gray">
Timeout
</th>
<th width="50" class="gray">
Actions
</th>
</tr>

@foreach (var testStep in Model.TestStepDisplayModelContainer)
{
@Html.EditorFor(m => testStep)
}
</table>


EditorTemplate

@model AsyncDemo.Models.TestStepDisplayModel


<tr>
<td>
<b>@Model.StepSequenceNumber</b>
</td>
<td>
<b>@Model.TestStepName</b>
</td>
<td>
<b>@Model.TimeOut</b>
</td>
<td>
<div align="left">
<button class="EditSuiteName" id="ajaxGet">Edit Test Suite Name</button>
</div>
</td>
</tr>

<script type="text/javascript">
$(function () {
$(document).off('click', '#ajaxGet').on('click', '#ajaxGet', function () {
event.stopImmediatePropagation();

var model = {
TestStepId: '@Model.TestStepId'
}

$.ajax({
type: 'POST',
url: '/Home/AjaxTest',
data: JSON.stringify(model),
contentType: 'application/json; charset=utf-8',
dataType: "json"
});
});
});

</script>


TestStepDisplayModel

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace AsyncDemo.Models
{
public class TestStepDisplayModel
{
public int TestStepId { get; set; }
public string TestStepName { get; set; }
public int StepSequenceNumber { get; set; }
public TimeSpan? TimeOut { get; set; }

}
}


TestStepDisplayModels (Simply a model that holds a list of models)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace AsyncDemo.Models
{
public class TestStepDisplayModels
{

public List<TestStepDisplayModel> TestStepDisplayModelContainer { get; set; }
}
}


What I want to do is make it so the Ajax can simply retrieve data that could be stored inside the button during it's created (As in, the button is created and the model id that is being displayed in the loop is stored in the button) so that when clicked the Ajax can retrieve the id for the controller.

I also feel like the actual script is not in the correct part of the code, I feel like putting it inside the EditorTemplate is simply wrong, but I'm new to Ajax so I'm not so sure.

Answer

First of all, you should not keep the hardcoded static Id value inside a loop. Id's of elements should be unique.

Instead of Id,Use the css class for your jQuery selection when wiring up the click event. Also you can keep the item Id in html 5 data attrbute

 <button class="EditSuiteName ajaxLink" data-id="@Model.Id" >Edit Test Suite</button>

Now you do not need to put your jQuery code for button click event handling inside the editor template. Since you are putting it inside the editor template, that code will be executed many times (As many times as your items in the collection. That is the reason you had to call the off method! Also your code is getting the last item's Id !

Put this code in your main view. So the the events will be wired up only once!

$(function () {
    $(document).('click', '.ajaxLink', function (e) {
        e.preventDefault();
        var model = {
            TestStepId: $(this).data("id");
        }

        $.ajax({
            type: 'POST',
            url: '/Home/AjaxTest',
            data: JSON.stringify(model),
            contentType: 'application/json; charset=utf-8',
            dataType: "json"
        }).done(function(result){
           alert("ajax code success");
           // do something with result  
        }).fail(function() {
               alert( "error" );
        });
    });
});
Comments