I am working on a form in which i have to validate my user inputs (i.e, textbox and dropdownlist). in this i have used both MVC architecture as well as entity framework.
In this form i have to make a validation that the input in textboxt should not be blank and the dropdownlist should also contain a valid option
the form is generated using razor html syntax
VIEW
<form method="post">
<table>
<tr>
<td>
#Html.Label(" Cartidge Number ") <span style="color:red">*</span>
</td>
<td>
#Html.TextBoxFor(model => model.CartridgeNumber, "", new { #id = "txtNumber"})
#Html.ValidationMessageFor(model => model.Brand)
</td>
</tr>
<tr>
<td>
#Html.Label(" Brand ") <span style="color:red">*</span>
</td>
<td>
#Html.DropDownListFor(model => model.Brand, ViewBag.BrandId as SelectList,"Please Select", new { #id = "ddlBrands" })
#Html.ValidationMessageFor(model => model.Brand)
</td>
</tr>
<tr>
Model
Modelname is CartridgeModel which is generated using entity framework's database first approach
namespace MultiInfoMediaCloudSolution.Models
{
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
public partial class CartridgeModel
{
[Display(Name = "Cartridge Number: ")]
[Required(ErrorMessage = " Please Enter Cartridge Number ")]
public string CartridgeNumber { get; set; }
[Display(Name = "Brand: ")]
[Required(ErrorMessage = " Please Select Brand ")]
public string Brand { get; set; }
public string CartridgeKeywords { get; set; }
public Nullable<bool> IsActive { get; set; }
public Nullable<short> CreatedBy { get; set; }
public Nullable<System.DateTime> CreatedDate { get; set; }
public Nullable<short> ModifiedBy { get; set; }
public Nullable<System.DateTime> ModifiedDate { get; set; }
public virtual Brand BrandName { get; set; }
}
}
Controller
{
// check if the user has selected to edit the item or not.
if (userAction == "Edit")
{
var _Printer = (from c in _multiInfoMediaEntities.PrinterModels
where c.PrinterModelNo.Equals(PrinterModelNo)
select c).First();
//to store PrinterModelNo
string printerNumberTemp = _Printer.PrinterModelNo;
TempData["PrinterModelNo"] = printerNumberTemp;
TempData["IsActive"] = _Printer.IsActive;
TempData["userAction"] = "Edit";
return View(_Printer);
}
else
{
return View();
}
}
catch (Exception ex)
{
throw new Exception(ex.Message.ToString());
}
I am using a javaScript to validate my form which is unusually not giving me any result as per my expections,
the javascript is as follow
JavaScript
//................................Go Function is user for the Validation in all the List........................
function GO() {
var ddl = document.getElementById("dllFilter");
var brands = document.getElementById("ddlBrands");
if (ddl.options[ddl.selectedIndex].text == "Please Select") {
alert("Please select search field");
}
if(brands.innerText == "Please Select")
{
alert("Please select brand")
}
}
//................................
//.......................Clear function is Used for Clearing the textbox Value from all the List........................
function Clear() {
document.getElementById('txtSearch').value = 'Enter Value';
//ViewData["Selected"] = "Please Select";
}
//......................................................................................................
So, can anyone help me or guide me in solving this problem. ?
If you require simple client side validation, you can use the "required" attribute
<input type="text" required /> or in your case #Html.TextBoxFor(model => model.CartridgeNumber, "", new { #id = "txtNumber", required = "required"})
As for the dropdown you can use the same required attribute but for it to work the first 'option' child element must have a blank string for value <option value="">Please select an option</option>
Related
I'm working on an asp.net core mvc website for a homework. The app is using identity server for login. I'm trying to show a pop-up alert after an user enters the correct credentials and presses the Login button(something like javascript alert). I've created a boolean property inside the .cs file which becomes true when an user succesfully logs in. In the .cshtml file I've added a script block which contains a function that shows an alert when the boolean property is true. The issue is that the function is executed when the page is created(at that moment the property is false) even though I'm calling the function on button click.
Any suggestions which might be the issue?
Login.cshtml
#page
#model LoginModel
#{
ViewData["Title"] = "Log in";
}
<div class="container w-50 text-center">
<h1 class="display-4" style="margin-bottom: 80px;">#ViewData["Title"]</h1>
<section>
<form id="account" method="post">
<h4>Use a local account to log in.</h4>
<hr />
<div asp-validation-summary="All" class="text-danger"></div>
<div class="form-group">
<label asp-for="Input.Email"></label>
<input asp-for="Input.Email" class="form-control" />
<span asp-validation-for="Input.Email" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Input.Password"></label>
<input asp-for="Input.Password" class="form-control" />
<span asp-validation-for="Input.Password" class="text-danger"></span>
</div>
<div class="form-group">
<div class="checkbox">
<label asp-for="Input.RememberMe">
<input asp-for="Input.RememberMe" />
#Html.DisplayNameFor(m => m.Input.RememberMe)
</label>
</div>
</div>
<div class="form-group">
<button onclick="showAlert()" type="submit" class="btn btn-primary">Log in</button>
</div>
<div class="form-group">
<p>
<a asp-page="./Register" asp-route-returnUrl="#Model.ReturnUrl">Register as a new user</a>
</p>
</div>
</form>
</section>
</div>
<script type="text/javascript">
showAlert = function () {
if (#LoginModel.alert) {
alert("Logged in succesfully");
#LoginModel.alert = false;
}
}
</script>
#section Scripts {
<partial name="_ValidationScriptsPartial" />
}
Login.cshtml.cs
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text.Encodings.Web;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using BookingApp.ApplicationLogic.DataModel;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.UI.Services;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Logging;
namespace BookingApp.Areas.Identity.Pages.Account
{
[AllowAnonymous]
public class LoginModel : PageModel
{
private readonly UserManager<User> _userManager;
private readonly SignInManager<User> _signInManager;
private readonly ILogger<LoginModel> _logger;
[BindProperty] static public bool alert { get; set; } = false;
public LoginModel(SignInManager<User> signInManager,
ILogger<LoginModel> logger,
UserManager<User> userManager)
{
_userManager = userManager;
_signInManager = signInManager;
_logger = logger;
}
[BindProperty]
public InputModel Input { get; set; }
public IList<AuthenticationScheme> ExternalLogins { get; set; }
public string ReturnUrl { get; set; }
[TempData]
public string ErrorMessage { get; set; }
public class InputModel
{
[Required]
[EmailAddress]
public string Email { get; set; }
[Required]
[DataType(DataType.Password)]
public string Password { get; set; }
[Display(Name = "Remember me?")]
public bool RememberMe { get; set; }
}
public async Task OnGetAsync(string returnUrl = null)
{
if (!string.IsNullOrEmpty(ErrorMessage))
{
ModelState.AddModelError(string.Empty, ErrorMessage);
}
returnUrl = returnUrl ?? Url.Content("~/");
// Clear the existing external cookie to ensure a clean login process
await HttpContext.SignOutAsync(IdentityConstants.ExternalScheme);
ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList();
ReturnUrl = returnUrl;
}
public async Task<IActionResult> OnPostAsync(string returnUrl = null)
{
returnUrl = returnUrl ?? Url.Content("~/");
if (ModelState.IsValid)
{
// This doesn't count login failures towards account lockout
// To enable password failures to trigger account lockout, set lockoutOnFailure: true
var result = await _signInManager.PasswordSignInAsync(Input.Email, Input.Password, Input.RememberMe, lockoutOnFailure: false);
if (result.Succeeded)
{
alert = true;
_logger.LogInformation("User logged in.");
return LocalRedirect(returnUrl);
}
if (result.RequiresTwoFactor)
{
return RedirectToPage("./LoginWith2fa", new { ReturnUrl = returnUrl, RememberMe = Input.RememberMe });
}
if (result.IsLockedOut)
{
_logger.LogWarning("User account locked out.");
return RedirectToPage("./Lockout");
}
else
{
ModelState.AddModelError(string.Empty, "Invalid login attempt.");
return Page();
}
}
// If we got this far, something failed, redisplay form
return Page();
}
}
}
Are you sure #LoginModel.alert gives out a JS-boolean? Because it usually doesn't when writing JS with razor.
If the output is not exactly understood as boolean by Javascript at this point, it is "truthy". E.g. if it is parsed as a string, the condition is "true" for JS.
In JS I would always suggest checking values with ===, just to be on the type-safe side. For example:
if (#Json.Encode(LoginModel.alert) === true) {
// ...
}
I have page, where i add one or many products (this part is working) and its adding products including (Product Name, Serial number, Qty) to database. As also you see in screenshots i have single input field Customer Name which i want get value of Customer Name input feild and sending with each products to database.
Example when data inserted into database:
Customer Name | Product Name | Serial number | Qty
Stackoverflow A 1234 1
Stackoverflow B 4567 2
But, right now look like this in my database when its inserting data :
Customer Name | Product Name | Serial number | Qty
null A 1234 1
null B 4567 2
To be honest i dont know how can i sending value of Customer Name input field with each products when its trying insert data into database. Can anyone please help me or point me into the right direction! Thanks in advance :)
Controller:
[HttpPost]
public JsonResult ProcessCreateRMA(CreateRMAVM vm)
{
using (var namespace = new namespace())
{
if (vm.vares == null)
{
vm.vares = new List<CreateRMAVM.vare>();
}
foreach (var item in vm.vares)
{
var rmainsert = new RMA_History
{
//CustomerName = item.CustomerName,
ProductName = item.ProductName,
Serialnumber = item.Serialnumber,
Qty = item.Qty,
};
db.RMA_History.Add(rmainsert);
}
db.SaveChanges();
}
return Json(vm, JsonRequestBehavior.AllowGet);
}
JavaScript:
<script>
$(document).ready(function () {
//Add input field
var i = 0;
$("#add").click(function (e) {
i++;
e.preventDefault();
$("#tbhold").append('<tr id="row' + i + '"><td><div><input type="text" name="vares[' + i + '].ProductName" id=' + i + ' /></div></td><td><div><input type="text" name="vares[' + i + '].SerialNumber" id=' + i + '/></div></td><td><div style="padding:0" class="col-md-12"><input id="Qty" name="vares[' + i + '].Qty"/></div></td><td><button type="button" class="btn btn-danger btn_remove" id="' + i + '" name="remove"><i class="fa fa-minus-circle" aria-hidden="true"></i>Remove</button></td></tr>');
});
//Remove input field
$(document).on('click', '.btn_remove', function () {
var button_id = $(this).attr("id");
$("#row" + button_id + '').remove();
});
//Save to db by click
$("#submit").click(function (e) {
e.preventDefault();
$.ajax({
type: 'POST',
url: '#Url.Action("ProcessCreateRMA", "User")',
dataType: 'json',
data: ($('#add_rma').serialize()),
success: function (result) {
console.log(result);
},
error: function () {
console.log('something went wrong - debug it!');
}
});
});
});
</script>
View:
<label>Customer Name</label>
<input type="text" name="CustomerName" id="CustomerName">
<form name="add_rma" id="add_rma">
<table id='tbhold' class="table">
<thead>
<tr>
<th>Product Name </th>
<th>Serial number</th>
<th>Qty</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<div>
<input type="text" name="vares[0].ProductName" id="ProductName" />
</div>
</td>
<td>
<div>
<input type="text" name="vares[0].Serialnumber" id="Serialnumber" />
</div>
</td>
<td>
<div>
<input name="vares[0].Qty" id="Qty"/>
</div>
</td>
<td>
<button type="button" name="add" id="add">Add more</button>
</td>
</tr>
</tbody>
</table>
<input type="submit" name="submit" id="submit" value="Submit" />
</form>
ViewModel:
public class CreateRMAVM
{
public List<vare> vares { get; set; }
public class vare
{
public vare()
{
}
public vare(/*string CustomerName*/ string ProductName, string SerialNumber, string Qty)
{
}
//public string CustomerName { get; set; }
public string ProductName { get; set; }
public string SerialNumber { get; set; }
public string Qty { get; set; }
}
}
I have updated your code to work. If you are using a datagrid, I might recommend you use one of the numerous ones out there and not try to rebuild it yourself. jqGrid (http://www.trirand.com/blog/) is one that's popular
Leave the CompanyName inside your form
Update your model as such. I've include the Customer in CreateRMAVM and in vare
public class CreateRMAVM
{
public List<vare> vares { get; set; }
public string CustomerName { get; set; }
public class vare
{
public vare()
{
}
public vare(/*string CustomerName*/ string ProductName, string SerialNumber, string Qty)
{
}
public string CustomerName { get; set; }
public string ProductName { get; set; }
public string SerialNumber { get; set; }
public string Qty { get; set; }
}
}
Update your controller as such. CustomerName will come populated in CreateRMAVM, and then there's a line of code to copy into the vare lists
[HttpPost]
public JsonResult Create(CreateRMAVM vm)
{
try
{
if (vm.CustomerName != null && vm.vares != null)
{
vm.vares.Select(c => { c.CustomerName = vm.CustomerName; return c;
}).ToList();
}
<input type="text" name="CustomerName" id="CustomerName">
is not within your form definition. Move this into the form
this is my item
public class RequestViewModel
{
public long FeederId { set; get; }
public int A { set; get; }
public int B { set; get; }
public int C { set; get; }
public int Remain { set; get; }
}
and this is my Add model that i want to send from my form to my Controller
public class RequestAddListViewModel
{
public List<SuppliantRequestFeederAddViewModel> SuppliantRequestFeederAddViewModels { set; get; }
public List<SelectListItem> FeederSelectListItems { set; get; }
public long NodeId { set; get; }
}
first time my form load i have One item i have a button when i click on it my first row clone and append to my form for example now i have 8 item on my form, i can delete each item on client side. if i didn't delete any item and submit form there no problem.
My problem is when delete one of item for example second one when deleted and then submit my form there is no item on my controller. nothing send to Controller.
View
#for (int index = 0; index < Model.RequestAddListViewModel.Count; index++)
{
var req = Model.RequestAddListViewModel[index];
<tr class="requestrow">
<td>
#Html.DropDownListFor(p => p.req[index].FeederId, Model.FeederSelectListItems, new { #class = "form-control" })
</td>
<td>
#Html.TextBoxFor(p => p.req[index].A, new { #class = "form-control" })
</td>
<td>
#Html.TextBoxFor(p => p.req[index].B, new { #class = "form-control" })
</td>
<td>
#Html.TextBoxFor(p => p.req[index].C, new { #class = "form-control" })
</td>
<td>
<button type="button" class="btn btn-primary btn-icon btn-rounded newfeeder"><i class="icon-plus2"></i></button>
</td>
</tr>
}
and my jQuery script (Edited):
var inputCount=0;
$(document).on('click', '.newfeeder', function () {
inputCount++;
var tr = $(this).closest("tr").clone();
tr.find("input").val(0);
tr.find("button").removeClass("btn-primary").addClass("btn-danger").removeClass("newfeeder").addClass("deleterow");
tr.find("button i").removeClass("icon-plus2").addClass("icon-trash");
tr.find("input,select").each(function () {
$(this).attr({
'name': function (_, name) { return name.toString().replace('0', inputCount) },
'id': function (_, id) { return id.toString().replace('0', inputCount) }
});
});
$(this).closest("tr").after(tr);
});
$(document).on('click', '.deleterow', function() {
$(this).closest("tr").remove();
});
finally i found my solution after add or delete new item to my form
i call this function ReCreateIndex()
function ReCreateIndex(container) {
$(container).each(function (index, obj) {
$("input,select", $(this)).each(function () {
if ($(this).attr("name")) {
var name = $(this).attr("name").replace($(this).attr("name").replace(/[^0-9]/gi, ''), index);
$(this).attr("name", name);
}
if ($(this).attr("id")) {
var id = $(this).attr("id").replace($(this).attr("id").replace(/[^0-9]/gi, ''), index);
$(this).attr("id", id);
}
});
});
}
it means that after any change on items,index of items recreated.
I have an amount field in a view that is required if a checkbox is checked.
Once Razor renders the View with Model data, and a user checks a checkbox without a corresponding amount entered. The Validation message appears. If I de-select that checkbox, the validation message does not disappear.
I've tried to use jquery to remove all the rules generated, but if the user were to checkbox again, prior to post back, those validation rules would have been removed (unless I store them... which is getting really ugly.)
Is there an acceptable way to re-validate client-side with the same requirements in the MVC Model?
Model:
[Display(Name = "Include Amount")]
public bool IncludeAmount { get; set; }
[Display(Name = "Amount")]
[RequiredIf("IncludeAmount", TargetValue = true, ErrorMessage = "Amount is required.")]
[MaxDigits(10, 2)]
[RegularExpression(RegularExpressions.Money, ErrorMessage = ErrorMessages.NumericValueInvalidFormat)]
[GreaterThanZero]
public Nullable<decimal> Amount { get; set; }
View:
<td class="dataEntryLabel" colspan="2">
#Html.LabelFor(model => model.IncludeAmount)
</td>
<td class="dataEntryField" colspan="2">
#Html.CheckBoxFor(model => model.IncludeAmount, new { id = "IncludeAmount" })
<span class="dollar-sign">#Html.TextBoxFor(model => model.Amount, "{0:F}", new { id = "Amount", disabled = "disabled" })</span>
#Html.ValidationMessageFor(model => model.Amount)
</td>
JavaScript (Client-side):
function fixUnobtrusiveValidations() {
var form = getForm();
(<any>$).validator.unobtrusive.parse(form);
}
function onClickCheckBoxIncludeAmount(){
fixUnobtrusiveValidations();
}
$('IncludeAmount').click(onClickCheckBoxIncludeAmount);
Try this to disable the client side validation on onclick events
Refer: https://jqueryvalidation.org/validate/#onclick
$("#myform").validate({
onclick: false,
});
OR
$("#yourChkboxID").validate({
onclick: false,
});
This worked:
if (!($('#IncludeAmount').checked)){
toggleValidatorVisibility($('#Amount'), false);
}
function toggleValidatorVisibility(element: any, value) {
var td: any = element.closest('td');
if (value) {
td.find('span.field-validation-error').show();
} else {
td.find('span.field-validation-error').empty();
}
}
I can't get the following jQuery code to work (it doesn't transfer selected items between listboxes) in an MVC 5 app:
<script>
$(function () {
$("add").click(function () {
$("#listBoxAvail > option:selected").each(function () {
$(this).remove().appendTo("#listBoxSel");
});
});
$("remove").click(function () {
$("#listBoxSel > option:selected").each(function () {
$(this).remove().appendTo("#listBoxAvail");
});
});
});
</script>
The rest of the markup with the listboxes is:
#using (Html.BeginForm())
{
#Html.ListBoxFor(m => m.SelectedAttributes, Model.Attributes, new {id="listBoxAvail", SIZE = 5} )
<input type="submit" name="add"
id="add" value="MoveRight" />
<input type="submit" name="remove"
id="remove" value="MoveLeft" />
<input type="submit" name="remove-all" id="remove-all" value="RemAll" />
<input type="submit" name="select-all" id="select-all" value="SelAll" />
#Html.ListBoxFor(m => m.SelectedAttributes2, Model.SelectedItems, new { id = "listBoxSel", SIZE = 5})
}
</div>
The ViewModel is:
public class OptInViewModel
{
public IEnumerable<string> SelectedAttributes { get; set; }
public IEnumerable<string> SelectedAttributes2 { get; set; }
public IEnumerable<SelectListItem> Attributes { get; set; }
public IEnumerable<SelectListItem> SelectedItems { get; set; }
}
And the controller is:
public ActionResult Index()
{
AttributeEntities db = new AttributeEntities();
List<SelectListItem> listSelectListItems = new List<SelectListItem>();
List<SelectListItem> listSelItems = new List<SelectListItem>();
foreach (var attributes in db.HarmonyAttributes)
{
SelectListItem selectList = new SelectListItem
{
Text = attributes.AttributeName,
Value = attributes.AtrributeLabel,
Selected = false
};
listSelectListItems.Add(selectList);
}
foreach (var sel in db.SelectedHarmonyAttributes)
{
SelectListItem selList = new SelectListItem
{
Text = sel.CustomLabel,
Value = sel.HarmonyAttribute_ID.ToString(),
Selected = false
};
listSelectListItems.Add(selList);
}
OptInViewModel viewModel = new OptInViewModel
{
Attributes = listSelectListItems,
SelectedItems = listSelItems
};
return View(viewModel);
}
}
I can't figure out why the JQuery script won't work. What am I doing wrong?
Looks like selector is wrong, you are trying to assign handler to element "add":
$("add")
instead of element with id "add"
$("#add")
Same for "remove" element.
I know I am years late, but it might help somebody else.
It's refreshing because you buttons are o type submit.
Change this :
<input type="submit" name="remove"
id="remove" value="MoveLeft" />
To this :
<input type="button" name="remove"
id="remove" value="MoveLeft" />