3

In my view I have a table with a foreach loop that shows data in my model.

<table id="dt_table_tools" class="table table-striped table-condensed">
    <thead>
        <tr>
            <th>@Html.DisplayNameFor(model => model.ItemOptions.First().Active)</th>
            <th>@Html.DisplayNameFor(model => model.ItemOptions.First().ItemOptionCode)</th>
            <th>@Html.DisplayNameFor(model => model.ItemOptions.First().Name)</th>
            <th></th>
        </tr>
    </thead>
    <tbody>
        @foreach (ItemDetailItemOptionViewModel ItemOption in Model.ItemOptions)
        {

            <tr>
                <td>@Html.DisplayFor(model => ItemOption.Active)</td>
                <td>@Html.DisplayFor(model => ItemOption.ItemOptionCode)</td>
                <td>@Html.DisplayFor(model => ItemOption.Name)</td>

                <td>
                @Html.ActionLink("Edit", "Edit", new { id = ItemOption.ItemOptionId }) 
                </td>

            </tr>
        }
    </tbody>
</table>

I then have a modal form that allows me to add new data via an ajax call back to the server, and then it add's a row onto the end of the table to show the new data:

var handleSuccess = function (result) {
    if (result.success) {
        var $tr = $('<tr>').append(
            $('<td>').text(result.Active),
            $('<td>').text(result.ItemOptionCode),
            $('<td>').text(result.Name),
            $('<td>')
            ).appendTo('#dt_table_tools');
    } else {
        $('#itemOptionFormContainer').html(result);
    }
};

This all works ok with the exception that the new row added to the table does not appear in the same format. For example the 'Active' column shows 'true' instead of the tick box:

enter image description here

How can I get the jquery code to use @Html.DisplayFor(model => ItemOption.Active) so that the data is shown as expected?

4 Answers 4

3

You should be aware that DisplayFor function is called by the server and handleSuccess function will be called by the client.

What you are trying to do is, make the client call DisplayFor function. Client (browser) has no idea about DisplayFor, it is a .NET function in System.Web.Mvc.dll.

So what you should do is explained by "5te". The server should return a PartialViewResult to your AJAX call. For that to work, create a view and put the below inside it:

@model YourModelType
<tr>
            <td>@Html.DisplayFor(m => m.ItemOption.Active)</td>
            <td>@Html.DisplayFor(m => m.ItemOption.ItemOptionCode)</td>
            <td>@Html.DisplayFor(m => m.ItemOption.Name)</td>

            <td>
            @Html.ActionLink("Edit", "Edit", new { id = ItemOption.ItemOptionId }) 
            </td>

</tr>

In your Action that handled the AJAX call, do the following:

ActionResult YourAjaxHandlingAction(...args...)
{
    if(/*There is no error in your model*/)
    {
        YourModelType model = new YourModelType();


        // initialize an instance of YourModelType
        // using ...args...
        model.ItemOption.Active = ...;
        model.ItemOption.ItemOptionCode = ...;
        model.ItemOption.Name = ...;

        return PartialView("NewlyCreatedViewName", model);
    }
    else
    {
        // You can choose whatever http status code makes sense
        // e.g 301, 400 etc..
        return HttpStatusCodeResult(400, "An error occurred");
    }
}

Now in the Javascript, you should append the incoming HTML as you have done previously. Depending on how you make the ajax call, this part changes (AjaxHelper or jquery.ajax ?).


EDIT

I have edited the code above to include what you should do in case of an error. When you make the AJAX call, you can use a failure handler to display whatever you want on the screen.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for the clear explanation. I was originally doing it in a similar way to this however introduced the JSON to handle result.success and display back the model if the validation failed. If I always pass back a partial view, then how in the javscript can I work out if there was an error or not?
@Joseph I made an edit to the answer. You can use Response.StatusCode = 400 and return something more appropriate as the body of your response.
2

Try this

var $tr = $('<tr>').append(
            $('<td><input type="checkbox" checked="@result.active"/></td>'),
            $('<td>').text(result.ItemOptionCode),
            $('<td>').text(result.Name),
            $('<td>')
            ).appendTo('#dt_table_tools');

4 Comments

that would work in the example of the check box, but I want to user the HTML.DisplayFor helper for other types as well and not have to manually but the html in each part of the jquery.
i dont know if i am getting your requirement or not, but at the end HTML.DisplayFor is parsed to pure html only
Lets saying for example that my model property had [DisplayFormat(DataFormatString = "{0:N}", ApplyFormatInEditMode = true)]. Using the @HTML.DisplayFor would format this correctly.
dont know but .clone might be useful
2
+25

it is still tied to the model but if you are using it for check boxes this may still come in handy. you can include the html.display for in the javascript

$('<td>').text('@Html.DisplayFor(x => x.ItemOption.Active)'),

Comments

1

You could change your AJAX ASP.NET MVC action to return PartialViewResult instead of JSON. This partial view would then contain the Html required to display the table row using the typical Html.DisplayFor methods that you are looking to use (and you would get this for free by refactoring the view you are currently using to also use this). Your jquery would then append the returned Html to the table rather than attempting to construct a new row:

$(result).appendTo('#dt_table_tools');

However, if you prefer to not change the action from JSON then I think the best bet is to use clone as mentioned in another response.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.