PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Thursday, September 8, 2022

[FIXED] How do I serialise item in Model for a jQuery Ajax POST using ActionLink

 September 08, 2022     ajax, asp.net-mvc, c#, jquery, post     No comments   

Issue

I am using the following example model:

public class MyModel
{
    public int Id { get; set; }

    public string Text { get; set; }
    public string Description { get; set; }

    public bool? Accepted { get; set; }
}

Using this to show buttons if value for Accepted is null, otherwise show their choice:

@foreach (var item in Model) {
<tr>
    <td>
        @Html.DisplayFor(modelItem => item.Text)
    </td>
    <td>
        @Html.DisplayFor(modelItem => item.Description)
    </td>
    <td class="accepted">
     @{
         if (item.Accepted == null)
         {
             @Html.ActionLink("Accept", "Edit", "MyModels", new { id = item.Id, Accepted = true, Text = item.Text, Description = item.Description },
             new { @class = "btn btn-success btn-xs" })
             @Html.ActionLink("Decline", "Edit", "MyModels", new { id = item.Id, Accepted = false, Text = item.Text, Description = item.Description },
             new { @class = "btn btn-danger btn-xs" })
         }
         else if (item.Accepted == true)
         {
             <span>Accepted</span>
         }
         else if (item.Accepted == false)
         {
             <span>Declined</span>
         }
     }
    </td>

Its working - But how could I handle this if there were 50 or 100 properties - I couldn't put them on the Actionlink?

My model in view is IEnumerable<MyModel> and I need to access the releveant item.Id in the foreach loop and serialise but I am not sure how? for example as below but model is a json Array of all Objects, cannot access item.id out of scope (in the <script> tag at botton of View), how do i just get the single item:

$('#MyTable td.accepted a').click(function() {
    var model = @Html.Raw(Json.Encode(Model));   // this is an array of Objects (Model is IEnumerable<MyModel>)
    $.ajax({
        url: this.href,
        type: 'POST',
        contentType: 'json',
        data: model[item.id], //here I just want to get 1 object
        success: function(result) {
            window.location.reload(true);
        }
    });
    return false;
});

So I am sure there is a better way to accomplish this, e.g. sent the single item in the Model as one in the POST - I searched but could find no relevant question - please enlighten me.

P.S. sorry for my English, hope you can follow.

Edit: MVC Controller POST action:

[HttpPost]
    public ActionResult Edit([Bind(Include = "Id,Text,Accepted,Description")] MyModel myModel)
    {
        if (ModelState.IsValid)
        {
            _db.Entry(myModel).State = EntityState.Modified;
            _db.SaveChanges();
            return RedirectToAction("Index");
        }
        return View(myModel);
    }

enter image description here


Solution

Simple - use some forms and hidden inputs:

<td class="accepted">
    @{
        if (item.Accepted == null)
        {
            <form action="@Url.Action("Edit", "MyModels")" method="post" class="action-form">
                <input type="hidden" name="Id" value="@item.Id" />
                <input type="hidden" name="Accepted" value="true" />
                <button type="submit" class = "btn btn-success btn-xs">Edit</button>
            </form>

            <form action="@Url.Action("Edit", "MyModels")" method="post" class="action-form">
                <input type="hidden" name="Id" value="@item.Id" />
                <input type="hidden" name="Accepted" value="false" />
                <button type="submit" class = "btn btn-danger btn-xs">Decline</button>
            </form>
        }
        else if (item.Accepted == true)
        {
            <span>Accepted</span>
        }
        else if (item.Accepted == false)
        {
            <span>Declined</span>
        }
    }
</td>

Adjust your jQuery code a bit:

$('#MyTable form.action-form').on('submit', function(e) {

    e.preventDefault();

    var model = $(this).serialize();
    var url = $(this).attr('action');

    $.post(url, model)
        .done(function(result, status, jqxhr){
            window.location.reload(true);
        });
});

It looks as though you're using your data models as view models. I wouldn't recommend that, but you can make it work as-is by doing this:

[HttpPost]
public ActionResult Edit(MyModel model)
{
    if (ModelState.IsValid)
    {
        var entry = _db.MyModels.SingleOrDefault(m => m.ID == model.ID);
        if(entry != null)
        {
            entry.Accepted = model.Accepted;
            _db.SaveChanges();

            return RedirectToAction("Index");
        }
    }

    return View(myModel);
}

This way, you're only updating the properties that actually need to be changed.



Answered By - Tieson T.
Answer Checked By - David Goodson (PHPFixing Volunteer)
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © PHPFixing