0

I really dislike page loads, I think they detract from the user experience, so I'm trying to make my web application heavily AJAX-ified.

When the user clicks on "Add new", Javascript generates a form based on a model using Razor, with the following code:

<script type="text/javascript">

    var strNewCategoryForm = '<div><i class="glyphicon glyphicon-folder-open rightfolderpadding"></i>@using (Html.BeginForm("AddCategory", "Password", FormMethod.Post, new { @class="newcategoryform", role = "form", id="[1]" })) { @Html.AntiForgeryToken() @Html.PasswordFor(m => m.Category_ParentID, new { type = "hidden", value = "0" }) @Html.PasswordFor(m => m.CategoryName, new { type = "text" })  <span class="btn-group groupalign"><a href="#" onclick="saveNewCategory(\'#[2]\');return false;" class="btn btn-xs btn-primary"><i class="glyphicon glyphicon-save"></i>Save</a></span> }</div>';

</script>

The code works great, Razor is able to generate the form within the string, so I dont have any issues with making this work. However, for code readability and ease of development, it's not that great.

I'm still quite new to MVC and razor, so I'm just wondering, is there a better or "MVC/Razor standard" way of doing this, that I don't know about?

Edit: In case anyone is interested, I've used both bits of Exception's answers:

In the partial view:

@model Secure_Password_Repository.Models.Category

<div><i class="glyphicon glyphicon-folder-open rightfolderpadding"></i> \
    @using (Ajax.BeginForm("AddCategory", "Password", new AjaxOptions { HttpMethod="post", OnFailure="" }, new { @class="newcategoryform", role = "form", id="[1]" })) 
    { 
    @: \
    @Html.AntiForgeryToken() @: \
    @Html.HiddenFor(m => m.Category_ParentID, new { value = "0" }) @: \
    @Html.TextBoxFor(m => m.CategoryName) @: \
    @: <span class="btn-group groupalign"><a href="#" onclick="saveNewCategory(\'#[2]\');return false;" class="btn btn-xs btn-primary"><i class="glyphicon glyphicon-save"></i>Save</a></span>  \
    }</div>

In the main view:

<script type="text/javascript">

    var strNewCategoryForm = '@Html.Partial("_NewCategoryForm")';

</script>

The "\" at the end of each line in the partial view tell JavaScript that each line is continuation of a string value.

binks
  • 1,001
  • 2
  • 10
  • 26
  • "I really dislike page loads" This seems very general. What did you mean by this exactly? Are you encountering a web page that takes many seconds to load initially? – Jason Evans Aug 22 '14 at 11:59
  • Consider using jQuery to return partial views. As for using `@Ajax` methods have a look at SO questions and answers [here](http://stackoverflow.com/questions/498680/pros-and-cons-of-ms-ajax-vs-jquery-in-an-asp-net-mvc-app) and [here](http://stackoverflow.com/questions/3840967/how-to-update-a-div-with-ajax-beginform-and-execute-a-javascript-function) and [here](http://stackoverflow.com/questions/777523/asp-net-ajax-vs-jquery-in-asp-net-mvc) –  Aug 22 '14 at 12:23

2 Answers2

2

Answer 1 :-

If You are so keen to AJAX-ify your web app then better way is to use Ajax helper in Asp.MVC such as

@Ajax.BeginForm() or @Ajax.ActionLink() and Helpers like @Html.Partial() ,

@Html.RenderPartial() etc. are also handy for asynchronously loading data.

Their Basic Usage(I m taking hypothetical example here) :-

@Ajax.ActionLink("Show", 
                 "Show", 
                  null, 
                  new AjaxOptions { HttpMethod = "GET", 
                  InsertionMode = InsertionMode.Replace, 
                  UpdateTargetId = "dialog_window_id", 
                  OnComplete = "your_js_function();" })

@using (Ajax.BeginForm("Edit", "Cars", new AjaxOptions
{
    InsertionMode = InsertionMode.Replace, 
    HttpMethod = "POST",
    OnSuccess = "updateSuccess"
}, new { @id = "updateCarForm" })) { ..... } 

Follow this link :- http://www.codeguru.com/csharp/.net/working-with-ajax-helper-in-asp.net-mvc.htm

Above link will be helpful for you to understand building Forms with Ajax Helpers.

and one thing more the way you are building forms with razor syntax in javascript is not at all a good option 'in my opinion'.


Answer 2 :-

A small demo how to build a completely ajax-ified form which donot require any page reload:

 @using (Ajax.BeginForm("Index", "Home", null, new AjaxOptions { HttpMethod = "POST", InsertionMode = InsertionMode.Replace, UpdateTargetId = "Mydiv" }, new { @id = "frm" , @style ="width:700px" }))
 { 
  //Your HTML here
 }

Make above View a Partial View say 'Index.cshtml' and then return it this way through Controller as :

Public ActionResult Index()
{
  return PartialView("Index");
}

Making Partial Views and loading Partial views through Jquery is handy to make unobtrusive forms.

Kartikeya Khosla
  • 18,743
  • 8
  • 43
  • 69
  • Nice, this is exactly the sort of thing I was talking about. I'll give this is a shot and it works, I'll make this as the correct answer. – binks Aug 22 '14 at 11:15
  • Unfortunantly this doesn't actually help. I suppose it's like manuFS says, its more of a HTML thing... Although this is great, and I will use this - the thing I'm trying to do is make a form appear when a button is clicked as opposed to making the form Ajax-ified (which has already been done). – binks Aug 22 '14 at 11:35
  • @binks...plz see updated answer..and moreover below code will create problem with dynamic data.. – Kartikeya Khosla Aug 22 '14 at 11:43
  • Thanks, this all helped greatly. Also adding "\" at the end of each line means I can make the razor code look nice (on multiple lines) and still store it in a JS variable. – binks Aug 23 '14 at 12:01
1

This is more of an HTML-thing than MVC/Razor, as you are essentially asking on how to embed templates into your website. AFAIK html doesn't Support templating out of the box just yet, so you'd Need some JavaScript for that (in your case right now, you're probably using jquery)

Most template engines like knockoutjs, handlebars, etc. (maybe even jquery) support embedding templates similar to this:

<script type="text/html" id="my_template">
    <div>
        <p>
            My template
        </p>
    </div>
</script>

The browser would not render that html, but a JavaScript library would use it (optionally doing some runtime data-binding) and display it.

Note: you can obviously put the html from that template into a partial view:

_MyTemplate.cshtml:

    <div>
        <p>
            My template
        </p>
    </div>

View:

<script type="text/html" id="my_template">
    @Html.Partial("MyTemplate")
</script>

Most template engines also support loading templates asynchronously, in which case you just render them the partial view alone.

Hope this helps a little.

Manuel Schweigert
  • 4,884
  • 4
  • 20
  • 32
  • Hmm... interesting, I hadn't through about using a partial view, I'll give that a shot. – binks Aug 22 '14 at 11:36
  • Thanks, this answer was correct, but since Exception also wrote about this and the Ajax.Beginform(), of which both have helped me, I've marked his answer as the correct one. – binks Aug 23 '14 at 12:00