ajaxasp.net-mvcvb.netajax.beginform

why ajax.beginform not working and page is refreshed


I have a view that contains a WebGrid. There is also a section for WebGrid search and filtering that includes a text box and a submit button type.

By calling the index ActionResult, all records are loaded correctly in the grid, and when I enter a text in the text box and click the button, the information is received and filtered properly from the controller and it is loaded in the grid.

But by pushing the search button, all the objects on the page are refreshed, while only the grid should be updated, and the other objects on the page should not be refreshed.

(For example، After pressing the search button, the contents of the textbox (<input type="text" />) are empty and buttons blink.)

For this operation, I used Partial View and Ajax.Beginform in index view. Which part of the code is missing? Why are all the controls on the page updated?

This is my Controler:

Function Index(strName As String) As ActionResult
    If strName = Nothing Then
        Return View(db.Brands.ToList())
    Else
        Return View(db.Brands.Where(Function(x) x.BrandName.Contains(strName)).ToList())
    End If
End Function

PartialView:

@ModelType IEnumerable(Of Machinary.Brand)
@Code
    Dim wg As New WebGrid(Model, rowsPerPage:=10, canPage:=True, canSort:=True, ajaxUpdateContainerId:="wg1")
    Dim rowIndex = ((wg.PageIndex + 1) * wg.RowsPerPage) - (wg.RowsPerPage - 1)
End Code

@wg.GetHtml(tableStyle:="table table-bordered table-hovor", mode:=WebGridPagerModes.All,
                htmlAttributes:=New With {.id = "wg1", .class = "Grid"},
                firstText:="<<",
                lastText:=">>",
                footerStyle:="table-pager",
                columns:=wg.Columns(
                wg.Column("BrandName", Sorter("BrandName", "عنوان", wg)),
                wg.Column(header:="عملیات", format:=Function(item) New HtmlString(
                Html.ActionLink(" ", "BrandEdit", New With {.id = item.id}, htmlAttributes:=New With {.class = "glyphicon glyphicon-edit btn btn-info btn-sm", .data_toggle = "tooltip", .data_placement = "top", .title = "ویرایش"}).ToString() + " " +
                Html.ActionLink(" ", "BrandDelete", New With {.id = item.id}, htmlAttributes:=New With {.class = "glyphicon glyphicon-trash btn btn-danger btn-sm", .data_toggle = "tooltip", .data_placement = "top", .title = "حذف"}).ToString()))))


@functions
    Public Shared Function Sorter(columnName As String, columnHeader As String, grid As WebGrid) As String
        Return String.Format("{0} {1}", columnHeader, If(grid.SortColumn = columnName, If(grid.SortDirection = SortDirection.Ascending, "▲", "▼"), String.Empty))
    End Function
End Functions

Index.Vbhtml (Main View):

@Using (Ajax.BeginForm("Index", "Brand", FormMethod.Post, New AjaxOptions With {
                                            .InsertionMode = InsertionMode.Replace,
                                            .UpdateTargetId = "GridList"}))
End Using

<section Class="panel">
    <header Class="panel-heading tab-bg-dark-navy-blue">
        <label class="bg-transparent wht-color">برندها</label>
    </header>

    <div Class="panel-body pull-left">
        @Using (Html.BeginForm("Index", "Brand", FormMethod.Post))
            @Html.TextBox("strName", Nothing, New With {.class = "form-control", .PlaceHolder = "جستجو"})
            @<Button type="submit" value="" style="display: none"></Button>
        End Using

    </div>
    <div id="GridList">
        @Html.Partial("PVBrandList")
    </div>

</section>

<div Class="pull-left btn-toolbar">
    <div Class="btn btn-default">
        @Html.ActionLink(" ", "BrandAdd", Nothing, htmlAttributes:=New With {.class = "glyphicon glyphicon-plus btn btn-small", .data_toggle = "tooltip", .data_placement = "top", .title = "اضافه کردن سطر جدید"})
    </div>
    <div Class="btn btn-default">
        @Html.ActionLink(" ", "Index", Nothing, htmlAttributes:=New With {.class = "glyphicon glyphicon-tasks btn btn-small", .data_toggle = "tooltip", .data_placement = "top", .title = "لیست برندها"})
    </div>
</div>
<input type="text" />
<script type="text/javascript">
    $(function () {
        $('[data-toggle="tooltip"]').tooltip()
    })
</script>

Solution

  • The most obvious problem in your view is the submit button exists inside the form which uses Html.BeginForm() helper:

    @Using (Html.BeginForm("Index", "Brand", FormMethod.Post))
        @Html.TextBox("strName", Nothing, New With {.class = "form-control", .PlaceHolder = "XXXXX"})
        @<Button type="submit" value="" style="display: none"></Button>
    End Using
    

    which other form using Ajax.BeginForm() helper still empty:

    @Using (Ajax.BeginForm("Index", "Brand", FormMethod.Post, New AjaxOptions With {
                                                .InsertionMode = InsertionMode.Replace,
                                                .UpdateTargetId = "GridList"}))
    End Using
    

    This setup causing full postback when submit button click event triggered, and subsequently refresh the whole view instead of table grid (with textbox value cleared).

    If you want to use AJAX, make sure that you're using Ajax.BeginForm helper with submit button inside that form:

    @Using (Ajax.BeginForm("Index", "Brand", FormMethod.Post, New AjaxOptions With {
                                                .InsertionMode = InsertionMode.Replace,
                                                .UpdateTargetId = "GridList"}))
        @Html.TextBox("strName", Nothing, New With {.class = "form-control", .PlaceHolder = "XXXXX"})
        <button type="submit" style="display: none">Search</button>
    End Using
    

    And put <HttpPost> attribute on the target action which returns PartialView:

    <HttpPost()>
    Public Function Index(strName As String) As ActionResult
        If strName = Nothing Then
            Return PartialView(db.Brands.ToList())
        Else
            Return PartialView(db.Brands.Where(Function(x) x.BrandName.Contains(strName)).ToList())
        End If
    End Function