Home > Mobile >  Date and Integer Inputs get reset when Post-back occurs
Date and Integer Inputs get reset when Post-back occurs

Time:06-07

I have a form that a user needs to fill out. If they enter the correct values for all required fields including the "Date of Birth" and "Total number of persons to occupy apartment" the values they entered are removed during a Page Postback.

This occurs if the user fails to click on the checkbox to accept the terms and conditions. All other values including DropDownList values retain their selected values on Post-back except for the "Date of Birth" and "Total number of persons to occupy apartment".

How can I figure this out?

Application Model

public class Application
{
    public int ApplicationId { get; set; }
    public string AppFirstName { get; set; }
    public string AppLastName { get; set; }
    public DateTime AppDateOfBirth { get; set; }
    public int AppTotalPersonsOccupy { get; set; }
    public bool AppAgreeToTerms { get; set; }

    public int StateId { get; set; }
    public State State { get; set; }
}

ApplicationFormViewModel

public class ApplicationFormViewModel
{
    [Required(ErrorMessage = "First Name is required")]
    [Display(Name = "First Name")]
    [StringLength(25)]
    [MaxLength(25)]
    public string AppFirstName { get; set; }

    [Required(ErrorMessage = "Last Name is required")]
    [Display(Name = "Last Name")]
    [StringLength(25)]
    [MaxLength(25)]
    public string AppLastName { get; set; }

    [Required(ErrorMessage = "Please make a selection")]
    [Display(Name = "State")]
    public int StateId { get; set; }
    public IEnumerable<SelectListItem> States { get; set; }

    [Required(ErrorMessage = "Date of Birth is required")]
    [Display(Name = "Date of Birth")]
    [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:MM/dd/yyyy}")]
    [DataType(DataType.Date)]
    public DateTime AppDateOfBirth { get; set; }

    [Required(ErrorMessage = "Total number of persons to occupy apartment is required")]
    [Display(Name = "Total number of persons to occupy apartment")]
    [Range(1, 10, ErrorMessage = "Must be between 1 to 10")]
    public int AppTotalPersonsOccupy { get; set; }

    //[Required(ErrorMessage = "You must exept terms to continue")]
    [Display(Name = "I agree to the pre rental application terms & conditions")]
    //[Range(typeof(bool), "false", "false", ErrorMessage = "You must accept the Terms")]
    [Controllers.ApplicationController.CheckBoxRequired(ErrorMessage = "You must agree to the terms and condtions!")]
    public bool AppAgreeToTerms { get; set; }
}

ApplicationController

public class ApplicationController : Controller
{
    private readonly ApplicationDbContext _db;

    public ApplicationController(ApplicationDbContext db)
    {
        _db = db;
    }


    // GET: /<controller>/
    public IActionResult Index()
    {
        return View();
    }


    public class CheckBoxRequired : ValidationAttribute
    {
        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            //get the entered value
            var application = (ApplicationFormViewModel)validationContext.ObjectInstance;
            //Check whether the IsAccepted is selected or not.
            if (application.AppAgreeToTerms == false)
            {
                //if not checked the checkbox, return the error message.
                return new ValidationResult(ErrorMessage == null ? "You must agree to the terms and condtions!" : ErrorMessage);
            }
            return ValidationResult.Success;
        }
    }


    // GET: /Create
    public IActionResult Create()
    {
        ApplicationFormViewModel renterdropdownvm = new ApplicationFormViewModel()
        {
            States = _db.States.Select(i => new SelectListItem
            {
                Text = i.StateInt,
                Value = i.StateId.ToString()
            }),
        };
        return View(renterdropdownvm);
    }


    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Create(ApplicationFormViewModel applicationVM)
    {
        if (ModelState.IsValid)
        {
            var applicationObj = new Application();
            {
                applicationObj.AppFirstName = applicationVM.AppFirstName;
                applicationObj.AppLastName = applicationVM.AppLastName;
                applicationObj.StateId = applicationVM.StateId;
                applicationObj.AppDateOfBirth = applicationVM.AppDateOfBirth;
                applicationObj.AppTotalPersonsOccupy = applicationVM.AppTotalPersonsOccupy;
                applicationObj.AppAgreeToTerms = applicationVM.AppAgreeToTerms;
            }

            _db.Applications.Add(applicationObj);
            await _db.SaveChangesAsync();

            var newlyCreatedId = applicationObj.ApplicationId;
            return RedirectToAction(nameof(Confirmation), new { id = newlyCreatedId });
        }

        // re-populate the dropdown field here before returning the view
        ApplicationFormViewModel applicationvmrepopulate = new ApplicationFormViewModel()
        {
            States = _db.States.Select(i => new SelectListItem
            {
                Text = i.StateInt,
                Value = i.StateId.ToString()
            }),
        };

        return View(applicationvmrepopulate);
    }


    // GET: Application/Confirmation/id
    public async Task<IActionResult> Confirmation(int? id)
    {
        if (id == null)
        {
            return NotFound();
        }

        var appconfirm = await _db.Applications.SingleOrDefaultAsync(m => m.ApplicationId == id);

        if (appconfirm == null)
        {
            return NotFound();
        }

        return View(appconfirm);
    }

}

Create View

<form method="post" asp-action="Create">
    <div >
        <label asp-for="AppFirstName" ></label>
        <input asp-for="AppFirstName"  />
        <span asp-validation-for="AppFirstName" ></span>
    </div>

    <div >
        <label asp-for="AppLastName" ></label>
        <input asp-for="AppLastName"  />
        <span asp-validation-for="AppLastName" ></span>
    </div>

    <div >
        <label asp-for="StateId" ></label>
        <select asp-for="StateId" asp-items="@Model.States" >
            <option></option>
        </select>
        <span asp-validation-for="StateId" ></span>
    </div>

    <div >
        <label asp-for="AppDateOfBirth" ></label>
        <input asp-for="AppDateOfBirth" type="date" value=""  />
        <span asp-validation-for="AppDateOfBirth" ></span>
    </div>

    <div >
        <label asp-for="AppTotalPersonsOccupy" ></label>
        <input asp-for="AppTotalPersonsOccupy" type="number" value=""  />
        <span asp-validation-for="AppTotalPersonsOccupy" ></span>
    </div>

    <p >“I AGREE TO THE TERMS AND CONDITIONS”</p>
    <div >
        <input asp-for="AppAgreeToTerms" >
        <label asp-for="AppAgreeToTerms" ></label>
        <span asp-validation-for="AppAgreeToTerms" ></span>
    </div>

<div >
    <input type="submit" value="Submit Rental Application"  />
</div>

CodePudding user response:

This occurs if the user fails to click on the checkbox to accept the terms and conditions. All other values including DropDownList values retain their selected values on Post-back except for the "Date of Birth" and "Total number of persons to occupy apartment.

After a lot of investigation and research, I am able to find the issue in your code. You have set the value empty as value="" while the page has been reloaded which is not correct.

Solution:

You should modify a few of the properties within your existing code at "Create View" as below:

Instead Of

 <div >
        <label asp-for="AppDateOfBirth" ></label>
        <input asp-for="AppDateOfBirth" type="date" value=""  />
        <span asp-validation-for="AppDateOfBirth" ></span>
    </div>

    <div >
        <label asp-for="AppTotalPersonsOccupy" ></label>
        <input asp-for="AppTotalPersonsOccupy" type="number" value=""  />
        <span asp-validation-for="AppTotalPersonsOccupy" ></span>
    </div>

Note: Setting value="" as empty for your two-property AppDateOfBirth and AppTotalPersonsOccupy causing the removal of this two input fields during post-back action.

Replace With

<div >
        <label asp-for="AppDateOfBirth" ></label>
        <input asp-for="AppDateOfBirth" type="date"  />
        <span asp-validation-for="AppDateOfBirth" ></span>
    </div>

    <div >
        <label asp-for="AppTotalPersonsOccupy" ></label>
        <input asp-for="AppTotalPersonsOccupy" type="number"   />
        <span asp-validation-for="AppTotalPersonsOccupy" ></span>
    </div>

Output

enter image description here

I have tested that in my environment and it's working as expected.

  • Related