why ajax.beginform not working and page is refreshed

569 Views Asked by At

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>
2

There are 2 best solutions below

1
On BEST ANSWER

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
0
On

Thanks a lot . This problem has been fixed. When I search for something, AJAX works correctly. For example, when I click on the header to sort, the grid is refereed, and it's OK.But when the page is loaded for the first time and I do not search for anything, if I click on the title of the grid columns or paging numbers , then the entire page refreshed. Please see the contents of the controller after your proposed changes:

  Function Index() As ActionResult
            Return View(db.Brands.ToList())
End Function

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

The first Function Index() As ActionResult that runs for the first time is likely to cause this problem, What is the offer and the solution? Thank's