gameloverr2
gameloverr2

Reputation: 95

Razor Pages .NetCore OnPost Handler

I am working on a project in C# with .NetCore Razor Pages and I have this page where a user makes an appointment by completing some fields.

I have this field that is a calendar and the user can select a date from it. Based on that date I want to populate a drop down with a list of hours that are available for an appointment.

I tried to use Handlers like OnPost() but that requires a submit button, but I only have the calendar input.

This is the code I use in my Razor Page for the calendar


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

In my model page I should have something like

 public IActionResult OnPostStartDate()
 {
    \\code that brings from the database the available hours 
 }

Is there any other function that I can use so when the user chooses a date from the calendar the dropdown will be populated with the available hours?

EDIT In my Razor Page

@section Scripts {
    <script>
          $("#StartDate").on("change", function () {
              var time = $(this).val();
              $("#select").empty();
              $("#select").append("<option value=''>select </option>");
              $.getJSON(`?handler=Time&time=${time}`, (data) => {
                $.each(data, function (i, item) {
                $("#select").append("<option value='"  + "'>" + item.hour + "</option>");
                });
            });      
        });
    </script>
}





<form class="form-style" method="post" id="createBTForm">
    <div asp-validation-summary="ModelOnly" class="text-danger"></div>
        <div class="form-group">
            <label asp-for="StartDate" class="control-label"></label>
            <input asp-for="StartDate" class="form-control" />
            <span asp-validation-for="StartDate" class="text-danger"></span>
        </div>

   <select id="select" asp-for="Time" class="form-control"></select>

   <div class="form-group button-position col-md4">
          <input type="submit" id="placeRequest" name="placeRequest" value="Place Request" class="btn btn-primary" />
   </div>
</form>

In my model Page

[Required(ErrorMessage = "Field cannot be empty!")]
[BindProperty]
[DataType(DataType.Date)]
[Display(Name = "Start Date:")]
public DateTime StartDate { get; set; }

//this is null after selecting an option from the dropdown
[BindProperty]
public string Time { get;set; }

//this is the method that should work when I press the Place Request submit button
public async Task<IActionResult> OnPost()
{
    if (!ModelState.IsValid)
    {
        return Page();
    }

    //here I send the data to the database     
           
    return Redirect(Url.Page(indexPage));
}


//this is the method that puts the values on the dropdown (this works)
public async Task<IActionResult> OnGetTime(DateTime time)
{
    //Here I set my model based on database data
      var finalHours = leaveFromLocations.Where(f => !unavailable.Contains(f));

      foreach (var h in finalHours)
      {
             model.Add(new Hours
             {
                  Hour = h
              });
      }

      return new JsonResult(model);

}

The problem is that after I send the json model to the dropdown and the values appear in the dropdown I can't take the option that is selected (in debug after choosing an option the Time property appears null)

Upvotes: 0

Views: 3002

Answers (1)

Yinqiu
Yinqiu

Reputation: 7180

You can write an onchange function and then use ajax to send data to backend.Below is a simple demo.

 <form method="post">
        <div asp-validation-summary="ModelOnly" class="text-danger"></div>
        <div class="form-group">
            <label asp-for="Time.StartDate" class="control-label"></label>
            <input asp-for="Time.StartDate" class="form-control" />
            <span asp-validation-for="Time.StartDate" class="text-danger"></span>
        </div>
        <select id="select" asp-for="Time.Hour" class="form-control"></select>
        <div class="form-group">
            <input type="submit" value="Create" class="btn btn-primary" />
        </div>
</form>
@section Scripts {
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
<script>
    $("#Time_StartDate").on("change", function () {
        var time = $(this).val();
        $("#select").empty();
        $("#select").append("<option value=''>select </option>");
        $.getJSON(`?handler=Time&time=${time}`, (data) => {
            $.each(data, function (i, item) {
                //"id" and "hours" is in your JsonResult(model),and remember The first letter of the attribute must be lowercase
                $("#select").append("<option value='" + item.id + "'>" + item.hours + "</option>");
            });
        });
    });
</script>
}

Backend:

  public IActionResult OnGetTime(DateTime time)
    {
        //this is a fake data,you can query your data here.
        var model = new List<Hour>
        {
            new Hour
            {
                Id=1,
                Hours=1
            },
            new Hour
            {
                Id=2,
                Hours=2
            },
        };
        return new JsonResult(model);
    }

Test result: enter image description here

Upvotes: 1

Related Questions