Tyler Johnson
Tyler Johnson

Reputation: 111

ASP.Net core - on form submit, refresh just a div and not the whole page

There are a lot of suggestions out there for this. But every answer I've seen hasn't really applied to .Net Core. I've been stuck for days so I'm hoping for help.

I have a very simple form - just two fields. When I submit, the controller returns to reload the page - return RedirectToAction(nameof(Index));.

I need it to just reload a div and not the whole Index page. I already have ajax in place to refresh the div on intervals. So, I need to figure out how to either return to just a div refresh and not a return RedirectToAction(nameof(Index)); - which I don't think is possible - or make it fire off that Ajax section on submit. I'm assuming Ajax the best option but I'm stumped.

Form:

<form asp-controller="Home" asp-action="CreateBreak" class="DthdropdownGroup ml-3">
<div class="btn-group" style="margin-left:-1rem">
    <select class="form-group dropdownStyling btn-sm dropdown-toggle d-inline-block btn-outline-light" style="width: 7.4em;" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" id="EmployeeId" asp-for="EmployeeId">
        <option>Dispatcher</option>
        @foreach (var item in Model.Employees)
        {
            <option class="dropdown-item pr-1 form-control" value="@item.Id">@item.DisplayName</option>
        }
    </select>
</div>

<div class="btn-group">
    <select class="form-group dropdownStyling btn-sm dropdown-toggle d-inline-block btn-outline-light" style="width: 7.3em" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" id="EmpPosition" asp-for="EmpPosition">
        <option>Position</option>
        @foreach (var item in Model.Positions)
        {
            <option class="dropdown-item pr-1" value="@item.Id">@item.PositionName</option>
        }
    </select>
</div>
<button type="submit" class="btn btn-sm btn-block dropdownStyling" id="break-submit" style="margin-left: -1rem; width:15rem;">Submit</button>

Controller:

        [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> CreateBreak([Bind("Id,TimeEntered,TimeCleared,EmpSent,EmployeeId,EmpPosition,RlfPosition")] Break @break)
    {
        if (ModelState.IsValid)
        {
            @break.TimeEntered = DateTime.Now;
            _context.Add(@break);
            await _context.SaveChangesAsync();
            return RedirectToAction(nameof(Index));
        }
        return View(@break);
    }

Ajax set up that already works to refresh just the sections I need refreshed:

function RefreshDropDownsPartial() {
$.ajax({
    success: function () {
        $(" #DropDownsPartialDiv ").load(window.location.href + " #DropDownsPartialDiv ");
        $(" .audioAlert ").load(window.location.href + " .audioAlert ");
    },
    error: function () {

    }
});

Part of the index page that establishes the div I need reset on form submit:

<div class="listContent d-inline-block" id="DropDownsPartialDiv">
    @await Html.PartialAsync("../Shared/_Lists")
</div>

Break Model:

    namespace Seating.Models
{
    public partial class Break
    {
        public int Id { get; set; }
        public DateTime TimeEntered { get; set; }
        public DateTime? TimeCleared { get; set; }
        public bool? EmpSent { get; set; }
        public int EmployeeId { get; set; }
        public int EmpPosition { get; set; }
        public int? RlfPosition { get; set; }

        public virtual Position EmpPositionNavigation { get; set; }
        public virtual Employee Employee { get; set; }
        public virtual Position RlfPositionNavigation { get; set; }
    }
}

ViewModel that fills the dropdowns:

        public class ListsVM
    {
        public ListsVM()
        {
            Employees = new List<Employee>();
            Positions = new List<Position>();
        }
        public IEnumerable<Dth> Dths { get; set; }
        public IEnumerable<Break> Breaks { get; set; }
        public IEnumerable<Lunch> Lunches { get; set; }
        public IEnumerable<Employee> Employees { get; set; }
        public IEnumerable<Position> Positions { get; set; }

        public int EmployeeId { get; set; }
        public int EmpPosition { get; set; }
        public bool EmpSent { get; set; }
        public bool LunchTime { get; set; }
        public bool LongerLunch { get; set; }
        public bool DblLunch { get; set; }
    }

The /Shared/_Lists just returns tables that go above the form. I can post that code but it's working well. I just need to refresh those tables on submit. Thank you all for your time.

Upvotes: 2

Views: 2476

Answers (1)

Jerdine Sabio
Jerdine Sabio

Reputation: 6140

You're on the right path with using ajax, follow steps below;

  1. Use controller action below; we're now returning json, and binding only 2 parameters.
[HttpPost]
public async Task<JsonResult> CreateBreak(int EmployeeId, int EmpPosition)
{
   Break newBreak = new Break();

   newBreak.EmployeeId = EmployeeId;
   newBreak.EmpPosition = EmpPosition;
   newBreak.TimeEntered = DateTime.Now;
      
   _context.Add(newBreak);
   await _context.SaveChangesAsync();

   return Json(newBreak);
}
  1. Add an id to your form, I used ajax_submit.
<form id="ajax_submit" asp-controller="Home" asp-action="CreateBreak" class="DthdropdownGroup ml-3">
...
</form>
  1. Add this new script, this will send the values to the controller action above. Once successful, it will refresh that part of the div.
@section scripts {
   <script>
      $(document).ready(function(){

         // bind event to your form
         $("#ajax_submit").submit(function(e){

            // prevent regular form submit
            e.preventDefault();
  
            var data = {
               'EmployeeId' : $("#EmployeeId").val(),
               'EmpPosition' : $("#EmpPosition").val()
            }       
  
            $.ajax({
               url: '@Url.Action("CreateBreak","Home")',
               type: 'POST',
               data: data,
               success: function(result){
                  console.log(result);
                   
                  // refresh
                  $(" #DropDownsPartialDiv ").load(window.location.href + " #DropDownsPartialDiv ");
                  $(" .audioAlert ").load(window.location.href + " .audioAlert ");
               },
               error: function (err){
                  console.log(err);
               }
            });
         })
      });
   </script>
}

3A. Check your layout; Jquery should be before the RenderSection scripts

<script src="~/lib/jquery/dist/jquery.min.js"></script>
@RenderSection("Scripts", required: false)

You could also try $(document).on("submit","#ajax_submit", function(e)

@section scripts {
   <script>
      $(document).ready(function(){

         // bind event to your form
         $(document).on("submit","#ajax_submit", function(e){
         // prevent regular form submit
            e.preventDefault();
  
            var data = {
               'EmployeeId' : $("#EmployeeId").val(),
               'EmpPosition' : $("#EmpPosition").val()
            };      
  
            $.ajax({
               url: '@Url.Action("CreateBreak","Home")',
               type: 'POST',
               data: data,
               success: function(result){
                  console.log(result);
                   
                  // refresh
                  $(" #DropDownsPartialDiv ").load(window.location.href + " #DropDownsPartialDiv ");
                  $(" .audioAlert ").load(window.location.href + " .audioAlert ");
               },
               error: function (err){
                  console.log(err);
               }
            });
         });
      });
   </script>
}

Upvotes: 3

Related Questions