I'm pretty new to ASP.NET MVC, and I'm trying to figure out if I am able to bind data to my model property from within a loop.
Can I bind it maybe in the onClick
event?
At the moment chosenTime
is 1/01/0001 12:00:00 AM.
My code for the view is as follows:
@model ResSProject.Models.Sittings.SittingTimesVM
<div class="d-flex justify-content-center">
<div>@Model.RestaurantName</div>
<div class="px-5">@Model.Date.ToString("dd-MMMM-yyyy")</div>
<div>@Model.NumberOfGuests</div>
</div>
<form method="post" asp-action="Reservation">
@{TimeSpan T1 = new TimeSpan(0, 15, 0);
for (var increase = Model.SittingsStart.Subtract(T1); increase < Model.SittingsEnd;)
{
increase = increase.AddMinutes(15);
<input class="btn btn-primary w-50 mx-auto mt-3 " type="button" asp-for="ChosenTime" value="@increase.ToString("HH:mm tt")" />
}
}
<input type="submit" value="Submit" />
<input type="hidden" asp-for=NumberOfGuests />
<input type="hidden" asp-for=Date />
<input type="hidden" asp-for=RestaurantName />
<input type="hidden" asp-for=RestaurantId />
<input type="hidden" asp-for=SittingsStart />
<input type="hidden" asp-for=SittingsEnd />
</form>
My view model class is:
using ResSProject.Data;
using System.ComponentModel.DataAnnotations;
namespace ResSProject.Models.Sittings
{
public class SittingTimesVM
{
public DateTime Date { get; set; }
public int RestaurantId { get; set; }
public string RestaurantName { get; set; }
public int NumberOfGuests { get; set; }
public DateTime ChosenTime { get; set; }
public DateTime SittingsStart { get; set; }
public DateTime SittingsEnd { get; set; }
}
}
Button type element cannot be passed to backend. I think you need set a hidden input and use js to set the chosen time.
Besides, the value of the inputs are just time without date(value="@increase.ToString("HH:mm tt")"
). When you post the value, it will bind time with current date to the property ChosenTime
. If the SittingsStart
and SittingsEnd
are not the same date with current now, the chosen time will be not correct.
Whole working demo:
@model SittingTimesVM
<div class="d-flex justify-content-center">
<div>@Model.RestaurantName</div>
<div class="px-5">@Model.Date.ToString("dd-MMMM-yyyy")</div>
<div>@Model.NumberOfGuests</div>
</div>
<form method="post" asp-action="Reservation">
@{TimeSpan T1 = new TimeSpan(0, 15, 0);
for (var increase = Model.SittingsStart.Subtract(T1); increase < Model.SittingsEnd;)
{
increase = increase.AddMinutes(15);
<input class="btn btn-primary w-50 mx-auto mt-3 " type="button" asp-for="ChosenTime"
onclick="GetValue(this)" value="@increase.ToString("dd-MMMM-yyy HH:mm tt")" />
}
}
<input asp-for="ChosenTime" type="hidden"/>
<input type="submit" value="Submit" />
<input type="hidden" asp-for=NumberOfGuests />
<input type="hidden" asp-for=Date />
<input type="hidden" asp-for=RestaurantName />
<input type="hidden" asp-for=RestaurantId />
<input type="hidden" asp-for=SittingsStart />
<input type="hidden" asp-for=SittingsEnd />
</form>
@section Scripts
{
<script>
function GetValue(e)
{
$('input:hidden[name=ChosenTime]').val($(e).val())
}
</script>
}
Backend:
[HttpPost]
public void Reservation(SittingTimesVM model)
{
//do your stuff...
}
Another way I better suggest is to combine <input>
elements to one <select>
element, and it is no need add any onclick event to set value. It can bind to model property successfully upon you set asp-for="ChosenTime"
for the <select>
element.
@{
TimeSpan T1 = new TimeSpan(0, 15, 0);
<select type="button" asp-for="ChosenTime">
@for (var increase = Model.SittingsStart.Subtract(T1); increase < Model.SittingsEnd;)
{
increase = increase.AddMinutes(15);
<option value="@increase.ToString("dd-MMMM-yyy HH:mm tt")">@increase.ToString("HH:mm tt")</option>
}
</select>
}