用webgrid内联编辑

与Web Forms GridView控件不同,Web页面WebGrid不会通过内联编辑功能提供任何内容。本文通过增加jQuery来看待一种解决这一要求的一种方法。

我已经看了 使用WebGrid编辑的一种方法涉及调用包含一种表单的jQuery对话框。本文中涵盖的方法与每行数据一起呈现为只读,但转换为WebGrid中的可编辑格式,以便用户不必离开WebGrid以使其更改:

用webgrid内联编辑

此方法的关键是用readonly和可编辑版本的数据填充网格,然后使用jQuery 拨动 命令以按线的方式交换两个演示文稿。因此,当页面首先加载时,我需要为下拉列表编写的数据以及以只读模式显示的数据:

@{
    var db = Database.Open("Books"); 
    
    var books = db.Query(@"SELECT b.BookId, b.Title, b.ISBN, b.AuthorId, b.CategoryId, 
                            a.FirstName + ' ' + a.LastName AS AuthorName, c.Category  
                            FROM Books b INNER JOIN Authors a 
                            ON b.AuthorId = a.AuthorId  
                            INNER JOIN Categories c 
                            ON b.CategoryId = c.CategoryId 
                            ORDER BY b.BookId DESC");
                                                   
    var categories = db.Query("SELECT CategoryId, Category FROM Categories")
                        .Select(category => new SelectListItem {
                            Value = category.CategoryId.ToString(), 
                            Text = category.Category
                         }); 
                         
    var authors = db.Query("SELECT AuthorId, FirstName + ' ' + LastName AS AuthorName FROM Authors")
                        .Select(author => new SelectListItem {
                            Value = author.AuthorId.ToString(), 
                            Text = author.AuthorName
                         });   
                         
    var grid = new WebGrid.(books);                                                         
}

代码获得了三组数据 - 我要显示的书籍详细信息,书籍可以属于的类别以及书籍所写的作者。最后两组数据被转换为枚举<SlectListItem>。这是它们可以直接插入HTML.DropdownList助手。最后,将书籍数据传递给WebGrid。这是网格的代码:

@grid.GetHtml(
    tableStyle : "table",
    alternatingRowStyle : "alternate",
    selectedRowStyle: "selected",
    headerStyle : "header", 
    columns : grid.Columns(
        grid.Column("", 
                    style: "col1", 
                    format: @<text>
                                <button class="edit-book display-mode" id="@item.BookId">Edit</button>
                                <button class="save-book edit-mode" id="@item.BookId">Save</button>
                            </text>),
        grid.Column("Title",
                    style: "col2",
                    format: @<text>
                                <span id="title" class="display-mode">@item.Title</span>
                                @Html.TextBox("Title", item.Title, new {@class="edit-mode", size = 45})
                            </text>),
        grid.Column("AuthorName",
                    header : "Author",
                    style: "col3",
                    format: @<text>
                                <span id="authorname" class="display-mode">@item.AuthorName</span>
                                @Html.DropDownList("AuthorId", null, authors, item.AuthorId, new {@class="edit-mode"})
                            </text>),
        grid.Column("Category",
                    style: "col4",
                    format: @<text>
                                <span id="category" class="display-mode">@item.Category</span>
                                @Html.DropDownList("CategoryId", null, categories, item.CategoryId, new {@class="edit-mode"})
                            </text>),
        grid.Column("ISBN",
                    style: "col5",
                    format: @<text>
                                <span id="isbn" class="display-mode">@item.ISBN</span>
                                @Html.TextBox("ISBN", item.ISBN, new {@class="edit-mode", size = 20})
                            </text>)
     )    
)

注意的主要是在每个细胞中有两个项目。在大多数情况下,存在包含用于显示的项目的跨度,以及用于编辑项目的表单元素。正如我之前提到的那样,我正在使用HTML表单助手,主要是因为它们需要比HTML本身更少的代码。设计用于显示器的所有项目都是CSS类"display-mode"。表单字段具有CSS类"edit-mode"适用于他们。第一列中的两个按钮都给出了两个CSS类。

jigsaw的下一部分是管理两种模式之间切换的jQuery代码:

<script>
    $(function () {
        $('.edit-mode').hide();
        $('.edit-book').on('click', function () {
            var tr = $(this).parents('tr:first');
            tr.find('.edit-mode, .display-mode').toggle();
        });
        $('.save-book').on('click', function () {
            var tr = $(this).parents('tr:first');
            var bookId = $(this).prop('id');
            var title= tr.find('#Title').val();
            var authorId = tr.find('#AuthorId').val();
            var categoryId = tr.find('#CategoryId').val();
            var isbn = tr.find('#ISBN').val();
            $.post(
                '/EditBook',
                { BookId: bookId, Title: title, AuthorId: authorId, CategoryId: categoryId, ISBN: isbn },
                function (book) {
                    tr.find('#title').text(book.Title);
                    tr.find('#authorname').text(book.AuthorName);
                    tr.find('#category').text(book.Category);
                    tr.find('#isbn').text(book.ISBN);
                }, "json");
            tr.find('.edit-mode, .display-mode').toggle();
        });
    })
</script>

此脚本所做的第一件事是将所有项目隐藏使用CSS类 编辑模式 导致所有表单字段和保存按钮被隐藏。将事件处理程序连接到“编辑”按钮的单击“事件”。这会引用按钮所处的表行,然后切换具有CSS类的所有项目的可见性 编辑模式显示模式。既然 编辑模式 物品在一开始时隐藏,他们现在变得可见,并且隐藏所有显示项目。

jquery.代码的下一部分将事件处理程序应用于“保存”按钮的单击事件。与上一个事件处理程序一样,它获得引用当前行,然后从表单字段和下拉列表中获取值以及从保存按钮本身(已应用于其ID属性的当前项的ID)。然后,它打包这些值并将它们张贴到名为EditBook.cshtml的页面。注意缺席 <form> 代码中的标签; jQuery负责构建帖子请求。然后它需要编辑簿页面返回和使用它来更新包含所显示数据的跨度的数据。最后, 编辑模式显示模式 当前行中的项目再次将其可见性切换。

以下是编辑簿.chtml文件的代码:

@{
    var bookId = Request["BookId"];
    var title= Request["Title"]; 
    var authorId = Request["AuthorId"];
    var categoryId = Request["CategoryId"];
    var isbn = Request["ISBN"];
    var db = Database.Open("Books");
    var sql = "UPDATE Books SET Title = @0, AuthorId = @1, CategoryId = @2, ISBN = @3 WHERE BookId = @4";
    db.Execute(sql, title, authorId, categoryId, isbn, bookId);
    sql = @"SELECT b.Title, b.ISBN,  a.FirstName + ' ' + a.LastName AS AuthorName, c.Category  
            FROM Books b INNER JOIN Authors a ON b.AuthorId = a.AuthorId  
            INNER JOIN Categories c ON b.CategoryId = c.CategoryId 
            WHERE BookId = @0";
    var result = db.QuerySingle(sql, bookId);
    Json.Write(result, Response.Output);
}

它从请求集合中获取值,并使用它们更新数据库表。然后它从适当形状的数据库中检索回的数据。最后,JSON帮助程序用于将该数据发送回呼叫代码以进行消耗。

本文的代码可用 GitHub..