2

I've seen quite a few posts on this, but I wanted to try to get a best practice down before going down the route I think I will likely need to go. I'm attempting to update my view after I've inserted a new record into the database:

Pretty basic set-up:

<table id="grid-basic" class="table table-condensed table-hover table-striped">
    <thead>
        <tr>
            <th data-column-id="role_id">ID</th>
            <th data-column-id="description">Description</th>
            <th data-column-id="commands" data-formatter="commands" data-sortable="false">Commands</th>
        </tr>
    </thead>
    <tbody>
        @foreach (var item in Model)
        {
            <tr>
                <td>@item.Id</td>
                <td>@item.Name</td>
            </tr>
        }
    </tbody>
    <tfoot>
        <tr>
            <td></td>
            <td style="padding-right: 20px;">
                <div id="add-role-text-group" class="form-group">
                    <input id="add-role-text" type="text" class="form-control input-md" placeholder="Add Role" data-container="body" title="A role description must be entered."/>
                    <span class="glyphicon glyphicon-remove form-control-feedback" aria-hidden="true"></span>
                </div>
            </td>
            <td style="vertical-align: middle;"><button type="button" class="btn btn-xs btn-default command-add"><span class="fa fa-plus"></span></button></td>
        </tr>
    </tfoot>
</table>

My C# code

// GET: Application Role Management
        [Route("role")]
        public ActionResult Role()
        {
            return View(RoleManager.Roles.ToList<IdentityRole>());
        }

        [HttpPost]
        [Route("addrole")]
        public async Task<ActionResult> AddRole(string description)
        {
            IdentityRole role = new IdentityRole();
            role.Name = description;

            var result = await RoleManager.CreateAsync(role);
            if (result.Succeeded)
            {
                return RedirectToAction("role");
            } else {
                return RedirectToAction("Error");
            }
        }

AJAX POST

$.ajax({
     type: "POST",
     url: "@Url.Action("AddRole")", // the method we are calling
     contentType: "application/json; charset=utf-8",
     data: JSON.stringify({ description: $element.val() }),
     dataType: "json"
});

I load the View, grab all the roles in the system and display into a grid. I have an inline row for insertion of a new role. I type in the new role, click a plus button. It POSTs to the AddRole route. How can I now update the model and update the grid?

From what I've seen, I need to run the insert, grab all the roles again, and update the grid in the "success" event. Is this true? Or is there a more conventional, MVC means to doing this via ASP.net? Obviously, I could go down the path of using Knockout or something to that extent, but I'm wondering if there is a means to updating the view this way.

jlrolin
  • 1,604
  • 9
  • 38
  • 67
  • Are you using a jquery plugin for your table? –  Aug 28 '15 at 03:24
  • Using bootgrid - https://github.com/rstaib/jquery-bootgrid – jlrolin Aug 28 '15 at 03:26
  • Not familiar with bootgrid, but the [documentation](http://www.jquery-bootgrid.com/Documentation#methods) appears to have an `append` method which I assume is for adding new rows –  Aug 28 '15 at 03:38
  • I'm asking if there is a means to updating the model from the server side. I'm redirecting to load the view again and nothing happens. I assume that's because I've done that in a POST and that can't happen. But I'm not entirely sure. – jlrolin Aug 28 '15 at 03:42
  • 1
    Your edit shows your using ajax to post so `return RedirectToAction()` in your POST method is pointless (ajax calls do not redirect) and in any case you have specified `dataType: "json"`. Change your method to `return Json(...);` (you probably want to return the ID of the role you just created?). You already know the `description` so you should be able to use the bootgrid `append()` method to add a new row based on the returned ID and the value of the textbox. –  Aug 28 '15 at 03:47
  • I was aware this was likely the case, so I thank you for confirming. – jlrolin Aug 28 '15 at 21:38

3 Answers3

0

If you want to reload the current page after adding the role you can do one thing,

add success function in ajax call and put like below

success:function(){
     window.location.href ="your current page url"
}
Ravi
  • 475
  • 4
  • 12
0

Your POST method is attempting to redirect to another action method, but ajax calls do not redirect. Change you method to return the new roles Id value and return it to the view as json

[HttpPost]
[Route("addrole")]
public async Task<ActionResult> AddRole(string description)
{
  IdentityRole role = new IdentityRole();
  role.Name = description;
  var result = await RoleManager.CreateAsync(role);
  if (result.Succeeded)
  {
    return Json(role.Id);
  } else {
    return Json(null);
  }
}

Then modify your ajax to add the new role in the success callback based on the value of the textbox and the returned Id value

var description = $('#add-role-text').val();
var url = '@Url.Action("AddRole")';
var table = $('#grid-basic');
$.post(url, { description: description }, function(id) {
  if (!id) { 
    // oops 
    return;
  }
  var newRow = [{ role_id: id, description: description }];
  table.bootgrid("append", newRow);
}).fail(function() {
  // oops - display error message?
});
0

All you need to do is use

return Json(role.Id,JsonRequestBehavior.AllowGet);

and then in your ajax call say...

success:function(data){
 if(data.Id>0){
  $("#grid-basic").append('<tr><td>data.Id</td><td>//description comes here</td></tr>');
 }
 else{
  alert("error");
 }
}

If it is about updating the table then you can either append a row to the table
the above way or you can reload page or else you can return a partial view and then append it to the div. It is preferred to return a Json and then append the above way.

Zaker
  • 537
  • 16
  • 30
  • Because OP is using Bootgrid. This just adds the html for a new row and does not ad all the other necessary data used by Bootgrid (for searching, sorting etc) Bootgrid has a specific `append()` method for adding new rows (see my answer). And you have not indicated how to add the description. –  Aug 30 '15 at 03:26