Adding a New Row In The Razor WebGrid

The Razor WebGrid isn't just used for displaying data. I have already looked at how to edit data inline within the WebGrid, so this article looks at how to add new rows of data. within a rendered grid.

This article kind of follows on from the Inline Editing with the WebGrid post I published previously in that it offers a way for the user to add new records without leaving the confines of the WebGrid. The solution shares other similarities in that it relies on jQuery. Here's the WebGrid . It obtains data from a database of books and displays that without paging or sorting enabled:

@{
   var db = Database.Open("Books");
   var commandText = string.Empty;
   if(IsPost){
       commandText = @"INSERT INTO Books (Title, ISBN, AuthorId, CategoryId, Price) VALUES (@0, @1, @2, @3, @4)";
       var title = Request["title"];
       var isbn = Request["isbn"];
       var authorId = Request["authorId"];
       var categoryId = Request["categoryId"];
       var price = Request["price"];
       db.Execute(commandText, title, isbn, authorId, categoryId, price);
   }
   commandText = @"SELECT Title, ISBN, FirstName + ' ' + LastName As Author, Category, Price 
                 FROM Books
                 INNER JOIN Authors ON Books.AuthorId = Authors.AuthorId
                 INNER JOIN Categories ON Books.CategoryId = Categories.CategoryId";
   var books = db.Query(commandText);
   var grid = new WebGrid(books, canPage: false, canSort:false);
}
<form method="post">
    @grid.GetHtml(columns: grid.Columns(grid.Column("Title", style: "title"),
                                        grid.Column("ISBN", style: "isbn"),
                                        grid.Column("Author", style: "author"),
                                        grid.Column("Category", style: "category"),
                                        grid.Column("Price", style: "price", format: @<text>@item.Price.ToString("c")</text>)))
</form>
<button id="add">Add</button>

There are two things to comment on. First, the grid is wrapped in a form. Second, there is a block of code that executes if the form is posted. It inserts a new record into the database. However, there are no form fields at the moment. These are added by some jQuery code when the Add button is clicked:

@section script{
<script type="text/javascript">
    $(function () {
        $('#add').on('click', function () {
            $('table').append('<tr>' +
                    '<td><input name=\'title\' id=\'title\' /></td>' +
                    '<td><input name=\'isbn\' id=\'isbn\' /></td>' +
                    '<td><select name=\'authorId\' id=\'authorId\'></select></td>' +
                    '<td><select name=\'categoryId\' id=\'categoryId\'></select></td>' +
                    '<td><input name=\'price\' id=\'price\' /></td>' +
                    '</tr><tr><td colspan=\'5\'><button>Save</button></td>');
             $.getJSON('/GetData/Authors', function (authors) {
                $('#authorId').append(
                        $('<option/>')
                            .attr('value', '')
                            .text('-- Select Author --'));
                $.each(authors, function (index, author) {
                    $('#authorId').append(
                        $('<option/>')
                            .attr('value', author.AuthorId)
                            .text(author.Author)
                    );
                });
            });
             $.getJSON('/GetData/Categories', function (categories) {
                $('#categoryId').append(
                        $('<option/>')
                            .attr('value', '')
                            .text('-- Select Category --'));
                $.each(categories, function (index, category) {
                    $('#categoryId').append(
                        $('<option/>')
                            .attr('value', category.CategoryId)
                            .text(category.Category)
                    );
                });
            });
            $('#add').hide();
        });
    });
</script>
}

When the Add button is clicked, an extra row is added to the table that the WebGrid generates. It consists of a collection of inputs and dropdowns. Since this is added to the table, it becomes part of the form. A Save buttion is also provided and the Add button is hidden so that users can't create multiple rows.

webgrid row

The dropdown lists are populated by AJAX requests that obtain JSON from a file designed specifically for that purpose:

@{
    Layout = null;
    Response.ContentType = "application/json";
    var db = Database.Open("Books");
    var commandText = "";
    switch (UrlData[0]){
        case "Authors":
            commandText = @"SELECT AuthorId, FirstName + ' ' + LastName As Author FROM Authors";
            break;
        case "Categories":
            commandText = @"SELECT CategoryId, Category FROM Categories";
            break;
    }
     var data = db.Query(commandText);
    Json.Write(data, Response.Output); 
}

The Layout is set to null to prevent any additional HTML from interfering with the response and the content type of the response is set to application/json. Depending on the value passed in to UIrlData[0] (the last segment of the AJAX request url), the SQL is set to retrieve either authors or categories. The resulting data is then converted to JSON using the JSON helper and sent to the browser.

Now all the user has to do is to fill in some data in the form and click the Save button. The current code lacks any kind of input validation but that isn't the focus of this article. If you want to learn more about how to validate form fields, you can refer to Validation In Razor Web Pages 2. Otherwise this article has shown a simple way to extend the Razor WebGrid to include the ability to add new data through it.