Zmiana koloru oraz aktywności checkboxa w zależności od kliknięć użytkownika i danych w bazie

0

Witam. To są moje pierwsze kroczki w Net Core WebApp.
Słowami wstępu tworzę stronę w której będzie można dokonać rezerwacji pomieszczenia.

Używając DropdownList wybieram interesującą mnie salę

Następnym krokiem jest 10 checkboxów, aby wybrać godziny rezerwacji. Muszę od razu po wybraniu pokoju odświeżyć listę dostępnych godzin. Czy kroki podejmowane przeze mnie tzn. wybór sali oraz wybór godziny muszą być oddzielnymi metodami POST i tam po prostu zmieniam interesujące mnie dane? W jaki sposób z poziomu Modelu zmieniać kolor kontrolki i jej aktywność?

Widok:

@page
@model App.Areas.Identity.Pages.Account.Manage.CreateRoomReservationModel
@{
    ViewData["Title"] = "Tworzenie rezerwacji";
    ViewData["ActivePage"] = ManageNavPages.CreateReservation;
}


<h4>@ViewData["Title"]</h4>
<partial name="_StatusMessage" model="Model.StatusMessage" />
<div class="row">
    <div class="col-md-6">
        <form method="post">
            <div class="form-group" style="background-color:antiquewhite; padding:10px; border-radius:5px; margin-bottom:10px; margin-top:10px">
                <label asp-for="Input.ApplicationUser"></label>
                <select name="UsersList" asp-for="Input.ApplicationUser" class="form-control">
                    @if (!(Model.Users is null))
                    {
                        @foreach (var item in Model.Users)
                        {
                            <option>
                                @Html.DisplayFor(modelItem => item.FirstName) @Html.DisplayFor(modelItem => item.LastName) (@Html.DisplayFor(modelItem => item.Email))
                            </option>
                        }
                    }
                </select>
                <span asp-validation-for="Input.ApplicationUser" class="text-danger"></span>
            </div>
            <div class="form-group" style="background-color:antiquewhite; padding:10px; border-radius:5px; margin-bottom:10px; margin-top:10px">
                <label asp-for="Input.Room"></label>
                <select name="RoomList" asp-for="Input.Room" class="form-control">
                    @if (!(Model.Rooms is null))
                    {
                        @foreach (var item in Model.Rooms)
                        {
                            <option class="form-control">
                                @Html.DisplayFor(modelItem => item.Name) - @Html.DisplayFor(modelItem => item.Price)zł/55min.
                            </option>
                        }
                    }
                </select>
                <span asp-validation-for="Input.Room" class="text-danger"></span>
            </div>
            <div class="form-group" style="background-color:antiquewhite; padding:10px; border-radius:5px; margin-bottom:10px; margin-top:10px">
                <label asp-for="Input.ReservationDate"></label>
                <input asp-for="Input.ReservationDate" class="form-control" />
                <span asp-validation-for="Input.ReservationDate" class="text-danger"></span>
            </div>
            <div class="form-group" style="background-color:antiquewhite; padding:10px; border-radius:5px; margin-bottom:10px; margin-top:10px">
                <div id="H10" class="form-control" style="background-color:white; border-color:black">
                    <input asp-for="Input.Hour10" class="text-danger" />
                    <label asp-for="Input.Hour10"></label>
                </div>
                <div id="H11" class="form-control" style="background-color:white; border-color:black">
                    <input asp-for="Input.Hour11" class="text-danger" />
                    <label asp-for="Input.Hour11"></label>
                </div>
                <div id="H12" class="form-control" style="background-color:white; border-color:black">
                    <input asp-for="Input.Hour12" class="text-danger" />
                    <label asp-for="Input.Hour12"></label>
                </div>
                <div id="H13" class="form-control" style="background-color:white; border-color:black">
                    <input asp-for="Input.Hour13" class="text-danger" />
                    <label asp-for="Input.Hour13"></label>
                </div>
                <div id="H14" class="form-control" style="background-color:white; border-color:black">
                    <input asp-for="Input.Hour14" class="text-danger" />
                    <label asp-for="Input.Hour14"></label>
                </div>
                <div id="H15" class="form-control" style="background-color:white; border-color:black">
                    <input asp-for="Input.Hour15" class="text-danger" />
                    <label asp-for="Input.Hour15"></label>
                </div>
                <div id="H16" class="form-control" style="background-color:white; border-color:black">
                    <input asp-for="Input.Hour16" class="text-danger" />
                    <label asp-for="Input.Hour16"></label>
                </div>
                <div id="H17" class="form-control" style="background-color:white; border-color:black">
                    <input asp-for="Input.Hour17" class="text-danger" />
                    <label asp-for="Input.Hour17"></label>
                </div>
                <div id="H18" class="form-control" style="background-color:white; border-color:black">
                    <input asp-for="Input.Hour18" class="text-danger" />
                    <label asp-for="Input.Hour18"></label>
                </div>
                <div id="H19" class="form-control" style="background-color:white; border-color:black">
                    <input asp-for="Input.Hour19" class="text-danger" />
                    <label asp-for="Input.Hour19"></label>
                </div>
                <div id="H20" class="form-control" style="background-color:white; border-color:black">
                    <input asp-for="Input.Hour20" class="text-danger" />
                    <label asp-for="Input.Hour20"></label>
                </div>
                <div id="H21" class="form-control" style="background-color:white; border-color:black">
                    <input asp-for="Input.Hour21" class="text-danger" />
                    <label asp-for="Input.Hour21"></label>
                </div>
            </div>
        </form>
    </div>
</div>

@section Scripts {
    <partial name="_ValidationScriptsPartial" />
}

Model:

public class CreateRoomReservationModel : PageModel
    {
        private readonly ApplicationDbContext _dbContext;
        private readonly UserManager<ApplicationUser> _userManager;
        private readonly SignInManager<ApplicationUser> _signInManager;
        private readonly ILogger<RegisterModel> _logger;

        public CreateRoomReservationModel(
            UserManager<ApplicationUser> userManager,
            SignInManager<ApplicationUser> signInManager,
            ILogger<RegisterModel> logger,
            ApplicationDbContext dbContext)
        {
            _userManager = userManager;
            _signInManager = signInManager;
            _logger = logger;
            _dbContext = dbContext;
        }

        [TempData]
        public string StatusMessage { get; set; }

        public class InputModel
        {
            [Required(ErrorMessage ="Wymagane - Właściciel rezerwacji")]
            [Display(Name ="Właściciel rezerwacji")]
            public ApplicationUser ApplicationUser { get; set; }

            [Required(ErrorMessage ="Wymagane - Sala")]
            [Display(Name ="Wybierz salę")]
            public Room Room { get; set; }

            [Required(ErrorMessage ="Wymagane - Data rezerwacji")]
            [Display(Name ="Data rezerwacji")]
            [DataType(DataType.Date, ErrorMessage ="Data jest nieprawidłowa")]
            public DateTime ReservationDate { get; set; }

            [Display(Name ="10:00-10:55")]
            public bool Hour10 { get; set; }
            [Display(Name = "11:00-11:55")]
            public bool Hour11 { get; set; }
            [Display(Name = "12:00-12:55")]
            public bool Hour12 { get; set; }
            [Display(Name = "13:00-13:55")]
            public bool Hour13 { get; set; }
            [Display(Name = "14:00-14:55")]
            public bool Hour14 { get; set; }
            [Display(Name = "15:00-15:55")]
            public bool Hour15 { get; set; }
            [Display(Name = "16:00-16:55")]
            public bool Hour16 { get; set; }
            [Display(Name = "17:00-17:55")]
            public bool Hour17 { get; set; }
            [Display(Name = "18:00-18:55")]
            public bool Hour18 { get; set; }
            [Display(Name = "19:00-19:55")]
            public bool Hour19 { get; set; }
            [Display(Name = "20:00-20:55")]
            public bool Hour20 { get; set; }
            [Display(Name = "21:00-21:55")]
            public bool Hour21 { get; set; }
        }
        [BindProperty]
        public InputModel Input { get; set; }

        public bool AdminOptionEnabled { get; set; }
        public List<Room> Rooms { get; set; }
        public List<ApplicationUser> Users { get; set; }
        
        private async Task LoadAsync(ApplicationUser user)
        {
            Rooms = await _dbContext.Rooms.ToListAsync();
            AdminOptionEnabled = await _userManager.IsInRoleAsync(user, "Admin");
            if (AdminOptionEnabled)
                Users = await _dbContext.Users.ToListAsync();
            else
            {
                Users = new List<ApplicationUser>();
                Users.Add(user);
            }
            //Input.ApplicationUser = user;

        }
        public async Task<IActionResult> OnGetAsync()
        {
            var user = await _userManager.GetUserAsync(User);
            if (user == null)
            {
                return NotFound($"Nie znaleziono użytkownika ID '{_userManager.GetUserId(User)}'.");
            }
            
            await LoadAsync(user);
            return Page();
        }
    }
0

Wykombinowałem coś takiego:
Dobre podejście? W jaki sposób można zrobić coś w stylu custom control żeby nie wklejać tego samego kodu 10 razy?

Dodałem model

public class CheckBoxModel
        {
            public bool Selectable { get; set; } = false;
            public bool Checked { get; set; } = false;
        }
        public class InputModel
        {
            [Required(ErrorMessage ="Wymagane - Właściciel rezerwacji")]
            [Display(Name ="Właściciel rezerwacji")]
            public ApplicationUser ApplicationUser { get; set; }

            [Required(ErrorMessage ="Wymagane - Sala")]
            [Display(Name ="Wybierz salę")]
            public Room Room { get; set; }

            [Required(ErrorMessage ="Wymagane - Data rezerwacji")]
            [Display(Name ="Data rezerwacji")]
            [DataType(DataType.Date, ErrorMessage ="Data jest nieprawidłowa")]
            public DateTime ReservationDate { get; set; }

            [Display(Name ="10:00-10:55")]
            public CheckBoxModel Hour10 { get; set; }
            [Display(Name = "11:00-11:55")]
            public CheckBoxModel Hour11 { get; set; }
            [Display(Name = "12:00-12:55")]
            public CheckBoxModel Hour12 { get; set; }
            [Display(Name = "13:00-13:55")]
            public CheckBoxModel Hour13 { get; set; }
            [Display(Name = "14:00-14:55")]
            public CheckBoxModel Hour14 { get; set; }
            [Display(Name = "15:00-15:55")]
            public CheckBoxModel Hour15 { get; set; }
            [Display(Name = "16:00-16:55")]
            public CheckBoxModel Hour16 { get; set; }
            [Display(Name = "17:00-17:55")]
            public CheckBoxModel Hour17 { get; set; }
            [Display(Name = "18:00-18:55")]
            public CheckBoxModel Hour18 { get; set; }
            [Display(Name = "19:00-19:55")]
            public CheckBoxModel Hour19 { get; set; }
            [Display(Name = "20:00-20:55")]
            public CheckBoxModel Hour20 { get; set; }
            [Display(Name = "21:00-21:55")]
            public CheckBoxModel Hour21 { get; set; }
        }
        [BindProperty]
        public InputModel Input { get; set; }

Aktualny widok checkboxa

@if (Model.Input.Hour11.Selectable)
                {
                    <div id="H11" class="form-control" style="background-color:lightgrey; border-color:black">
                        <input asp-for="Input.Hour11.Checked" class="text-danger" disabled="disabled" />
                        <label asp-for="Input.Hour11.Checked"></label>
                    </div>
                }
                else
                {
                   @if (Model.Input.Hour11.Checked)
                    {
                        <div id="H11" class="form-control" style="background-color:darkseagreen; border-color:black">
                            <input asp-for="Input.Hour11.Checked" class="text-danger" />
                            <label asp-for="Input.Hour11.Checked"></label>
                        </div>
                    }
                    else
                    {
                        <div id="H11" class="form-control" style="background-color:white; border-color:black">
                            <input asp-for="Input.Hour11.Checked" class="text-danger" />
                            <label asp-for="Input.Hour11.Checked"></label>
                        </div>
                    }

                }

Występuje wyjątek przy próbie utworzenia instancji obiektu:
Wychodzi na to, że "Input" == null

public async Task<IActionResult> OnGetAsync()
        {
            var user = await _userManager.GetUserAsync(User);
            if (user == null)
            {
                return NotFound($"Nie znaleziono użytkownika ID '{_userManager.GetUserId(User)}'.");
            }

            Input.Hour10 = new CheckBoxModel();
            Input.Hour11 = new CheckBoxModel();

            await LoadAsync(user);
            return Page();
        }
1

Jak to jest nowy projekt to zobacz Blazor technologię. Odpowiedź M$ na UI Frameworki (angular, react itp.). Bawię się ostatnio w tym i moim zdaniem ma mega potencjał.

Do Twojego projektu też się nada bardzo dobrze. Dynamiczne odświeżanie itp. i wszystko możesz pisać w C#

0

Razor, Blazor, nie nadążam xD Zacząłem się uczyć tego i chcę to ogarnąć koniec kropka :D

Szukam rozwiązania już tylko jednego problemu bo z resztą dałem radę:
Mam model:

public class CheckBoxModel
        {
            [BindProperty]
            public bool Selectable { get; set; } = false;
            [BindProperty]
            public bool Checked { get; set; } = false;
        }
[BindProperty]
public CheckBoxModel Hour10 { get; set; } = new CheckBoxModel();
[BindProperty]
public CheckBoxModel Hour11 { get; set; } = new CheckBoxModel();

i Widok:

<div class="form-group" style="background-color:antiquewhite; padding:10px; border-radius:5px; margin-bottom:10px; margin-top:10px">
                @if (!Model.Hour10.Selectable)
                {
                    <div id="Hour10" class="form-control" style="background-color:lightgrey; border-color:black">
                        <input asp-for="Hour10.Checked" class="text-danger" disabled="disabled" hidden="hidden" value="@Model.Hour10.Checked" checked="@Model.Hour10.Checked" />
                        <label asp-for="Hour10.Checked">10:00 - 10:55</label>
                    </div>
                }
                else
                {
                    @if (Model.Hour10.Checked)
                    {
                        <div id="Hour10" class="form-control" style="background-color:darkseagreen; border-color:black">
                            <input asp-for="Hour10.Checked" class="text-danger" value="@Model.Hour10.Checked" checked="@Model.Hour10.Checked"/>
                            <label asp-for="Hour10.Checked">10:00 - 10:55</label>
                        </div>
                    }
                    else
                    {
                        <div id="Hour10" class="form-control" style="background-color:white; border-color:black">
                            <input asp-for="Hour10.Checked" class="text-danger" value="@Model.Hour10.Checked" checked="@Model.Hour10.Checked"/>
                            <label asp-for="Hour10.Checked">10:00 - 10:55</label>
                        </div>
                    }

                }
                
            </div>

Gdy kliknę w CheckBox powinna zmienić się właściwość Hour10.Checked i jednocześnie zmienić się tło. jednak tak się nie dzieje. Co robię źle?

2

JavaScript aby zmieniać dynamicznie widok bez przeładowania modelu itp.

Np.

https://stackoverflow.com/questions/37189257/how-to-set-selected-item-background-color-in-select-element

1

Ahh to ja w ogóle nie w tym kierunku poszedłem w szukaniu w google. Zaraz spojrzę i dam znać czy mi się udało. Dziękuję Ci !

2

Panowie, działa <3

<div class="form-group" style="background-color:antiquewhite; padding:10px; border-radius:5px; margin-bottom:10px; margin-top:10px">
                <div id="H10_DIV" class="form-control" border-color:black">
                    <input id="H10_CB" asp-for="Hour10.Checked" class="text-danger" onchange="colorizeMe()" value="@Model.Hour10.Checked"/>
                    <label asp-for="Hour10.Checked">10:00 - 10:55</label>
                </div>
            </div>
function colorizeMe() {
            var cbChecked = document.getElementById("H10_CB").checked;
            document.getElementById("H10_DIV").style.backgroundColor = cbChecked ? "palegreen" : "white";
        }
0

Przepraszam Was za spam, jeszcze jedno pytanie w temacie:
W modelu CheckBoxModel

public class CheckBoxModel
        {
            [BindProperty]
            public bool Selectable { get; set; } = false;
            [BindProperty]
            public bool Checked { get; set; } = false;
        }

mam właściwość Selectable. Gdy jest ona ustawiona na false wtedy checkbox powinien być nieaktywny. osiągnąłem to w ten sposób:

disabled="@(!Model.Hour10.Selectable)"

Myślę teraz nad skryptem który pozwoli mi ustawić kolory tła nieaktywnych CheckBoxów. Czyli w skrócie jak wywołać skrypt od razu po wczytaniu się strony?
Próbowałem wywołać poprzedni skrypt w zdarzeniu onload jednak nie działa. Spróbowałem również w ten sposób:

@section Scripts {
    <partial name="_ValidationScriptsPartial" />
    document.addEventListener('loaded', dLoad());

    <script>
        function dLoad() {
            getElementById('H10_DIV').style.backgroundColor = "lightgray";
        }
        function ColorizeDIVByHour(element, elementDIV) {
            var cbChecked = element.checked;
            elementDIV.style.backgroundColor = (cbChecked ? "palegreen" : "white");
        }

    </script>
}

również bez powodzenia, mógłbym jeszcze raz prosić o pomoc?

EDIT:
Robiłem mortalkombat na klawiaturze i udało się bez skryptu :)

<div id="H10_DIV" class="form-control" style="border-color:black; background-color:@(Model.Hour10.Selectable ? "white" : "lightgray")">
                    <input asp-for="Hour10.Checked" class="text-danger" onchange="ColorizeDIVByHour(this, getElementById('H10_DIV'))" disabled="@(!Model.Hour10.Selectable)" />
                    <label asp-for="Hour10.Checked">10:00 - 10:55</label>
                </div>

screenshot-20200620151802.png

1 użytkowników online, w tym zalogowanych: 0, gości: 1