Update the partia view based on Main view custom filters

Viewed 188

Code searchView and PartialResultView

SearchView

  @model Shared.Model.Search.GLSearch
@{

    ViewData["Title"] = "Search GL";
}
<!-- start page title -->
<div class="row">
    <div class="col-12">
        <div class="page-title-box">
            <div class="page-title-right">
                <ol class="breadcrumb m-0">
                    <li class="breadcrumb-item"><a href="javascript: void(0);">UBold</a></li>
                    <li class="breadcrumb-item"><a href="javascript: void(0);">Forms</a></li>
                    <li class="breadcrumb-item active">Elements</li>
                </ol>
            </div>
            <h4 class="page-title">Search Customer</h4>

        </div>
    </div>
</div>
<!-- end page title -->



<form asp-action="" asp-controller="" method="post">

    <div class="row">
        <div class="col-lg-12">
            <div class="card-box">
                <div class="form-row">


                    <div class="form-group col-md-2">
                        <label asp-for="Name" class="col-form-label"></label>
                        <input asp-for="Name" type="text" class="form-control" />

                    </div>
                    <div class="form-group col-md-2">
                        <label asp-for="Code" class="col-form-label"></label>
                        <input asp-for="Code" type="text" class="form-control" />

                    </div>
                    <div class="form-group col-md-3">
                        <label asp-for="GLSectionId" class="col-form-label">Section </label>
                        <select asp-for="GLSectionId" asp-items="@(new SelectList(Model.glSections,"Id","Name"))" class="form-control">
                            <option value="">Choose</option>

                        </select>
                    </div>
                    <div class="form-group col-md-3">
                        <label asp-for="GLGroupId" class="col-form-label">Group</label>
                        <select asp-for="GLGroupId" asp-items="@(new SelectList(Model.glGroups,"Id","Name"))" class="form-control">
                            <option value="">Choose</option>

                        </select>
                    </div>

                    <button type="button" id="search" class="btn btn-primary waves-effect waves-light">Search</button>

                </div>



            </div> <!-- end card-box -->


        </div> <!-- end col -->

    </div> <!-- end row -->



</form>

<div id="view-all"></div>
    

Search_PartiaView

@model PagedResult<Shared.Model.Masters.GLMaster.GLViewModel>
@{

}


@if (Model == null || Model.RowCount == 0)
{
    <p>No results found</p>
}
else
{

    <div class="col-lg-12">
        <div class="card-box">
            <h4 class="header-title">Customers</h4>
            <p class="sub-header">

            </p>

            <div class="table-responsive">
                <table class="table table-hover mb-0">
                    <thead>
                        <tr>
                            <th data-priority="1">#</th>
                            <th data-priority="3">Name</th>
                            <th data-priority="6">Code</th>
                            <th data-priority="6">Section</th>
                            <th data-priority="6">Group</th>
                            <th data-priority="6">
                                <a onclick="showInPopup('@Url.Action("AddOrEditGL","GLMaster",new {area = "Masters"},Context.Request.Scheme)','New GL')" class="btn btn-success text-white"><i class="fas fa-random"></i> New GL</a>
                            </th>

                        </tr>
                    </thead>
                    <tbody>
                        @foreach (var item in Model.Results)
                        {
                        <tr>
                            <th scope="row">@item.Id</th>
                            <td>@item.Name</td>
                            <td>@item.Code</td>
                            <td>@item.GLSection</td>
                            <td>@item.GLGroup</td>
                            <td>
                                <div>
                                    <a onclick="showInPopup('@Url.Action("AddOrEditGL","GLMaster",new { area= "Masters",id = item.Id},Context.Request.Scheme)','Update GL')" class="btn btn-info text-white"><i class="fas fa-pencil-alt"></i> Edit</a>
                                    <form  asp-area="Masters"  asp-action="DeleteGL" asp-route-id="@item.Id" onsubmit="return jQueryAjaxDelete(this)" class="d-inline">
                                        <input type="submit" value="Delete" class="btn btn-danger" />
                                    </form>
                                </div>
                            </td>

                        </tr>

                        }

                    </tbody>
                </table>
            </div> <!-- end table-responsive-->

        </div> <!-- end card-box -->
    </div> <!-- end col -->
    <!-- Responsive Table js -->



}

Partial View (AddEditGL)

@model Shared.Model.Masters.GLMaster.GLModel
@{
    Layout = null;
    ViewData["Title"] = "Add Customer";
}

<div class="row">
    <div class="col-lg-12">
        <div class="card-box">
            <form asp-action="AddOrEditGL" asp-controller="GLMaster" asp-area="Masters" asp-route-id="@Model.Id" onsubmit="return jQueryAjaxPost(this);">
                <div asp-validation-summary="ModelOnly" class="text-danger"></div>
                <input type="hidden" asp-for="@Model.Id" />
              

                <div class="row">
                    <div class="col-md-4">
                        <div class="form-group">
                            <label asp-for="Name" class="control-label"></label>
                            <input asp-for="Name" type="text" class="form-control">
                            <span asp-validation-for="Name" class="text-danger"></span>
                        </div>
                    </div>

                    <div class="col-md-4">
                        <div class="form-group">
                            <label asp-for="NameLang" class="control-label"></label>
                            <input asp-for="NameLang" type="text" class="form-control">
                            <span asp-validation-for="NameLang" class="text-danger"></span>
                        </div>
                    </div>


                </div>

           

                <div class="form-group">
                    <div class="col-md-6 offset-md-3">
                        <input type="submit" value="Submit" class="btn btn-primary btn-block" />
                    </div>
                </div>


            </form>

        </div> <!-- end card-box -->


    </div> <!-- end col -->

</div> <!-- end row -->

I have View with Partial view (is for results in table) . When i click Edit button in Search_PartiaView i need to open popup (Partial View (AddEditGL)) and data should be loaded ajax and submit the button after update.. I need to use jquery unobtrusive validation in popup and also without refresh the page ..Please let me know hw to do..Thanks

EDIT

I Have implemented similar to this Ajax crud popup

I Have Main view and Partial view. Also AddOrEdit View for Add/edit Master.

My Current solution works.. But inmy main view i have filter based on 2 filds.

After add/edit grid load all the result but if filter applied i also need to filter the grid ..

My Javascript code Here:

jQueryAjaxPost = form => {
    try {
        $.ajax({
            type: 'POST',
            url: form.action,
            data: new FormData(form),
            contentType: false,
            processData: false,
            success: function (res) {
                if (res.isValid) {
                    $('#view-all').html(res.html)    --- here actually data coming all without filter                
                    $('#form-modal .modal-body.p-4').html('');
                    $('#form-modal .modal-title').html('');
                    $('#form-modal').modal('hide');
                    showAll(4, 1);   ---  it is the javascript fuction call  to call the
 api again
                }
                else
                    $('#form-modal .modal-body.p-4').html(res.html);
            },
            error: function (err) {
                console.log(err)
            }
        })
        //to prevent default form submit event
        return false;
    } catch (ex) {
        console.log(ex)
    }
}

Controller:

 [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> AddOrEditGL(int id,GLModel glModel)
        {
            if (ModelState.IsValid)
            {

                var mappedGL = _mapper.Map<GLDTO>(glModel);
                //Insert
                if (id == 0)
                {                 
                    await _glService.CreateGL(mappedGL);                  
                }
                //Update
                else
                {
                    await _glService.UpdateGL(mappedGL);
                    //Call Update
                }

               // How do i filter  the based on Main view  form controls
                  
                return Json(new { isValid = true, html = Helper.RenderRazorViewToString(this, "_GLViewAll", null) });
            }
            return Json(new { isValid = false, html = Helper.RenderRazorViewToString(this, "AddOrEditGL", glModel) });
        }

my Current solution call the api again ( 2 server calls) one for update and another for call update table .. i need to do the same in single call ..Please help to do?

Note: I dont need complete solution , I only need to how to get the AddOrEditGL Controller post method Main view form control text fieds text to filter in DB

2 Answers

I recommend using the jQuery Unobtrusive AJAX library. Its very easy to use:

It can fetch partial views and place them in a container of your choice using the data-ajax-update="#panel"

<a href="" data-ajax="true" data-ajax-url="/GetEditModal" data-ajax-update="#panel" data-ajax-success="SuccessCallback">Click here</a>

<div id="panel"></div>

This is an example of a controller action that would return the modal:

public IActionResult GetEditModal() => Partial("ViewName");

Then when the modal is placed in your container, using the data-ajax-success attribute a callback method is called, parse the form using the jQuery Unobtrusive Validation like this:

function SuccessCallback() {
   //You can also use the keyword "this" instead of getting the form with jquery
   $.validator.unobtrusive.parse($(this));
   //or
   $.validator.unobtrusive.parse($form);
}

Very useful resources : Link - jQuery Unobtrusive AJAX - GitHub

Update

What i did in previous projects is to include an empty edit modal (a modal with an empty body) then using the library and the data-ajax-update i would replace the body of that modal every time the user pressed the edit button on a table item like this:

<div class="modal fade" id="eModal" data-keyboard="false" data-backdrop="static">
    <div class="modal-dialog modal-lg">
        <div class="modal-content id="modalContentE">
            <div class="modal-header">
                <h4 class="modal-title"><i class="nav-icon fas fa-edit"></i> Edit Data</h4>
                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                    <span aria-hidden="true"><i class="fas fa-times-circle text-white"></i></span>
                </button>
            </div>  
            //New data goes here   
        </div>
    </div>
</div>

And your add Modal would be a regular full modal and each time the user use it to submit data, clear the form.

If you want to update/add and show the searched data in one request,The quick way is to copy the SearchGLPartial code to the AddOrEditGL function and pass the pageSize,pageIndex,name,code,GLSectionId and GlGroupId by ajax:

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> AddOrEditGL(int id,GLModel glModel,string name,string code,string GLSectionId,string GlGroupId...)
{
    if (ModelState.IsValid)
    {
        var mappedGL = _mapper.Map<GLDTO>(glModel);
        //Insert or
        //Update
        //copy the SearchGLPartial code here and return view with data
    }
    return Json(new { isValid = false, html = Helper.RenderRazorViewToString(this, "AddOrEditGL", glModel) });
}

If you just do not want to remove showViewAll() jquery,I think you could set session for the filter condition when you first search the data in SearchGLPartial action.Then in your AddOrEdit action,get the session and set the correct url.Finally,you could get the url in ajax success response:

 public IActionResult SearchGLPartial(string name,string code,string GLSectionId,string GLGroupId)
{
    HttpContext.Session.SetString("name", name);
    HttpContext.Session.SetString("code", code);
    HttpContext.Session.SetString("GLSectionId", GLSectionId);
    HttpContext.Session.SetString("GLGroupId", GLGroupId);
    var data = Gllist.Where(a => a.Name.Contains(name) & a.Code.Contains(code)).FirstOrDefault();//filter by yourself
    return PartialView("_Search", data);
}

AddOrEdit:

 [HttpPost]
 [ValidateAntiForgeryToken]
 public async Task<IActionResult> AddOrEditGL(int id,GLModel glModel)
 {
        if (ModelState.IsValid)
        {
            //Insert
            //Update
            var name = HttpContext.Session.GetString("name");
            //other session data...
            return Json(new { isValid = true, url="Home/Index?name="+name+"&code="+xxx+"&...."});
        }
        return Json(new { isValid = false, html = Helper.RenderRazorViewToString(this, "AddOrEditGL", glModel) });
 }

Then your ajax:

success: function (res) {
         if (res.isValid) {
               window.location.href = response.url;  
}
         else
              $('#form-modal .modal-body.p-4').html(res.html);
},
Related