I have a view page to show a multi select check box. Here is the code to show that.
#{
foreach (SelectListItem item in Model.VendorCategoryList)
{
string name = item.Text;
bool chkResult = item.Selected;//Model.VendorCategoryList;
<tr class="VendorCategoryClassSave">
<td style="width: 4%;text-align:right;padding-right:15px;">
<label>
#Html.CheckBox("chkVendorCategoryDetailId_" + item.Value, chkResult, new { #class = "chkVendorCategoryDetailClass" })
</label>
</td>
<td style="width: 10%;">
<label>#Html.Label(name)</label>
</td>
</tr>
}
}
Controller
public ActionResult NewVendor(int custid = 0)
{
List<SelectListItem> VendorCategory = _commonRepository.VendorCategory
.AsEnumerable().Where(x => x.status == 1).Select(x => new SelectListItem
{
Text = x.catename,
Value = x.cateid.ToString(),
Selected=false
}).ToList();
foreach(SelectListItem item in VendorCategory)
{
item.Selected = setSelectedcategory(Convert.ToInt32(item.Value), custid);
}
var model = new HomeViewModel
{
VendorCategoryList = new SelectList(VendorCategory, "Value", "Text", "Selected")
};
return View("../Masters/View_Vendor", model);
}
Model
public HomeViewModel
{
public SelectList VendorCategoryList { get; set; }
}
What happens is that even though I set "true" for the Selected attribute in the selectlistitem it always shows as false. See the images below pic1. In the pic1 it says clearly that the selected property is "true". But when I select each item from the model in foreach loop, it says that the selected property is "false". See pic2. Pic2. Can you please help me what I am doing wrong.
This is only happening in the foreach loop. Out side of loop it shows the correct value(true). Thanks in advance.
Related
In dropdown am fetching the value from the database i't is working fine ..i need to add <option value='-1'>Root</option> by manually which is not present in the database.
<div class="col-lg-4">
<fieldset class="form-group">
<label class="form-label" for="exampleInput">Domain Name</label>
#Html.DropDownList("DomainID", null, "--- Select Domain Name ---", new { #class = "select2-arrow" })
#Html.ValidationMessageFor(model => Model.DomainID, null, new { #style = "color: red" })
</fieldset>
</div>
<div class="col-lg-4">
<fieldset class="form-group">
<label class="form-label" for="exampleInput">Parent Module</label>
<select id="ParentModuleID" class="select2-arrow" name="ParentModuleID"></select>
#Html.ValidationMessageFor(model => Model.ParentModuleID, null, new { #style = "color: red" })
</fieldset>
</div>
Jquery:
$("#DomainID").change(function () {
var id = $(this).val();
$("#ParentModuleID").empty();
$.get("ParentModule_Bind", { DomainID: id }, function (data) {
var v = "<option>--- Select Domain Name ---</option>";
$.each(data, function (i, v1) {
v += "<option value=" + v1.Value + ">" + v1.Text + "</option>";
});
$("#ParentModuleID").html(v);
});
});
in above jquery <option>--- Select Domain Name ---</option> i need to add root with value of -1
public JsonResult ParentModule_Bind(string DomainID)
{
userType type = new userType();
DataSet ds = type.ParentModule_Bind(DomainID);
List<SelectListItem> statelist = new List<SelectListItem>();
foreach (DataRow dr in ds.Tables[0].Rows)
{
statelist.Add(new SelectListItem { Text = dr["ModuleName"].ToString(), Value = dr["ModuleID"].ToString() });
}
return Json(statelist, JsonRequestBehavior.AllowGet);
}
You can either add a line in jQuesry like this
v += "<option value='-1'>root</option>";
or add a line in controller above foreach like this
statelist.Add(new SelectListItem { Text = "root", Value = "-1" });
to achieve the result.
Why do any of this in the UI with jQuery?
One big problem I see is that your are mixing business logic of your list data with UI manipulation.
If this value is always needed for the ParentModel list regardless of DomainID, then I'd modify you method that returns you the list
public JsonResult ParentModule_Bind(string DomainID)
{
userType type = new userType();
DataSet ds = type.ParentModule_Bind(DomainID);
//change the following line
var statelist = new List<SelectListItem> { new SelectListItem { Text = "Root", Value = "-1" };
foreach (DataRow dr in ds.Tables[0].Rows)
{
statelist.Add(new SelectListItem { Text = dr["ModuleName"].ToString(), Value = dr["ModuleID"].ToString() });
}
return Json(statelist, JsonRequestBehavior.AllowGet);
}
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();
}
}
In my form i have a chekbox and when i click the checkbox a textbox is enabled.
When i submit the form i got both values(checkbox and textbox)and the site refresh,after the refresh the checkbox is checked but the textbox is disabled but has the last insert value.
If i submit again without making something the textbox returns null and not the last insert value.
I want that the checkbox got the value from my model and change the behavior of the textbox disabled-property und if no new value will be insert,it should return the last insert value.
When i set the model property of false the checkbox is also checked.
Has anyone a idea what i can do ?
View:
#Html.TextBoxFor(m => m.FilterModel.FilterOrgNameValue, new { #class = "form-control", #id = "OrganisatioName", #disabled = "disabled" })
#Html.CheckBoxFor(m => m.FilterModel.FilterOrgNameIsCheckedValue, new { #class = "form-control", #id = "OrgNameChecked", #checked = (Model.FilterModel.FilterOrgNameIsCheckedValue ? "checked" : "unchecked")})
JavaScript:
$("#OrgNameChecked").click(function () {
$('#OrganisatioName').attr("disabled", $(this).is(':unchecked'));
});
Model:
public bool FilterOrgNameIsCheckedValue { get; set; }
Controller (Function which got called by submit):
public ActionResult Index(AdminOrganizationModel m)
{
AdminOrganizationModel model = new AdminOrganizationModel();
if(TempData["model"] != null)
{
m = (AdminOrganizationModel)TempData["model"];
}
if(m.FilterModel == null)
{
m.FilterModel = new AdminOrganizationFilterModel();
}
model = m;
OrganizationBusinessObject organizationBusinessObject = new OrganizationBusinessObject(DbContext);
var organizations = DbContext.GetAllEntitiesQueryable<Organization>();
organizations = FilterOrganizations(organizations, model);
InitializeLicenseList(1);
AdminOrganizationModelBuilder modelBuilder = new AdminOrganizationModelBuilder();
IList<AdminOrganizationModel> organizationsModels = modelBuilder.GetModelCollection(organizations);
model.Organizations = new AjaxGridFactory().CreateAjaxGrid(organizationsModels.AsQueryable(), 1, false, 10) as AjaxGrid<AdminOrganizationModel>;
return View(model);
}
Fields after submit
Simple Solution ;)
I added a simple if statement in the View:
<div class="col-sm-2">
#if (Model.FilterModel.FilterOrgNameIsCheckedValue)
{
#Html.TextBoxFor(m => m.FilterModel.FilterOrgNameValue, new { #class = "form-control", #id = "OrganisatioName"})
}
else
{
#Html.TextBoxFor(m => m.FilterModel.FilterOrgNameValue, new { #class = "form-control", #id = "OrganisatioName", #disabled = "disabled" })
}
</div>
I guess its not the best way but it works =)
I need to make my own validate function, and i found this: http://www.tugberkugurlu.com/archive/asp-net-mvc-remote-validation-for-multiple-fields-with-additionalfields-property
I was trying to use Remote Attribute, however chrome doesn't send any information to my JsonResult Method and i don't know why.
Console is empty when i switching between fields:
I found a similar problem
Remote Validation for LIST of MODELs
But still it doesn't work.
Scripts are in BundleConfig, i see them in the source page.
jquery.validate.js:
remote: function( value, element, param ) {
//...
//data[element.name] = value;
data[element.name.substr(element.name.lastIndexOf(".") + 1)] = value;
//...
});
jquery.validate.unobtrusive:
adapters.add("remote", ["url", "type", "additionalfields"], function (options) {
var value = {
url: options.params.url,
type: options.params.type || "GET",
data: {}
},
prefix = getModelPrefix(options.element.name);
$.each(splitAndTrim(options.params.additionalfields || options.element.name), function (i, fieldName) {
var paramName = fieldName.substr(fieldName.lastIndexOf(".") + 1);
var actualFieldName = appendModelPrefix(fieldName, prefix)
value.data[paramName] = function () {
return $(options.form).find(":input").filter("[name='" + escapeAttributeValue(actualFieldName) + "']").val();
};
});
setValidationValues(options, "remote", value);
});
My ViewModel:
[Remote("Divisibility", "Account", ErrorMessage = "Value is incorrect. (REMOTE)")]
public int Amount { get; set; }
My View:
#model PROJECT.WebUI.ViewModels.DataItemVm
//... the rest of table
#using (Html.BeginForm())
{
#Html.ValidationSummary("", new { #class = "text-danger" })
for (var i = 0; i < Model.FirstSetList.Count; i++)
{
<tr>
<td>
#Html.DisplayFor(model => model.FirstSetList[i].Name)
#Html.HiddenFor(model => model.FirstSetList[i].Name)
</td>
<td>
#Html.DisplayFor(model => model.FirstSetList[i].Pack)
#Html.HiddenFor(model => model.FirstSetList[i].Pack)
</td>
<td>
#Html.TextBoxFor(model => model.FirstSetList[i].Amount)
#Html.HiddenFor(model => model.FirstSetList[i].Amount)
</td>
</tr>
}
<input type="submit" value="Confirm" class="btn btn-success" />
}
My Controller:
public JsonResult Divisibility(int Amount)
{
var value = User.Identity.GetUserId().Where(x => x.Equals("qqqqq"));
//I know that this condition does not make sense, but this was only for test.
//Anyway like i said, chrome doesn't send anything to this method.
return Json(value == null, JsonRequestBehavior.AllowGet);
}
Actual html generated for one input for an Amount property
<td>
<input data-val="true" data-val-number="The field Amount must be a number." data-val-remote="Value is incorrect (REMOTE)." data-val-remote-additionalfields="*.Amount" data-val-remote-url="/Account/Divisibility" data-val-required="The Amount field is required." id="FirstSetList_0__Amount" name="FirstSetList[0].Amount" type="text" value="0">
<input id="FirstSetList_0__Amount" name="FirstSetList[0].Amount" type="hidden" value="0">
</td>
I need to be able to require certain fields if someone selects a value of "Yes" from a dropdown. I've used the following code but it doesn't seem to work.
$(function () {
$('#anyAdditionalInc').keyup(function () {
if ($(this).val() == "No") {
$('#additionalIncomeSource').removeAttr('required');
$('#additionalIncomeAmt').removeAttr('required');
} else {
$('#additionalIncomeSource').attr('required', 'required');
$('#additionalIncomeAmt').attr('required', 'required');
}
});
});
My dropdown looks like this
<div class="form-group">#Html.LabelFor(m => m.anyAdditionalInc, new { #class = "col-sm-2 control-label" })
<div class="col-sm-10">
<div class="col-sm-4">#Html.DropDownListFor(m => m.anyAdditionalInc, new SelectList(new List
<Object>{ new { value = "", text = "----"}, new { value = "Yes", text = "Yes"}, new { value = "No", text = "No"}, }, "value", "text"), new { #class = "form-control", id = "anyAdditionalInc" }) #Html.ValidationMessageFor(m => m.anyAdditionalInc)</div>
</div>
</div>
Any help is appreciated. It doesnt seem to want to require the validation on the source and amt fields when selecting yes.
A dropdown (I guess you mean a <select> element by that) doesn't have much keyup events. Try change instead:
$(function () {
$('#anyAdditionalInc').change(function () {
var active = $(this).val() != "No"),
fields = $('#additionalIncomeSource, #additionalIncomeAmt');
fields.prop('required', active);
if (!active) fields.val("");
});
});
Even though #Bergi answered the question from a client-side perspective, since you tagged the question asp.net-mvc-4 I presume you may wish to know how it's done on the server side (where it really matters!):
You can simply check it in your controller:
public ActionResult Foo(SomeModel someModel) {
if (someModel.anyAdditionalInc != "Yes") {
ModelState.AddModelError("", "You must select yes");
}
}
Or if you want to push the logic into your model itself:
public class SomeModel: IValidatableObject {
public string anyAdditionalInc {get; set;}
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) {
if (this.anyAdditionalInc != "Yes") {
yield return new ValidationResult("You must select yes");
}
}
}
Notice how the model:
Implements IValidateableObject
Has a method named Validate which returns the type IEnumerable<ValidationResult>
During the model binding process this method will automatically be called and if a validation result is returned your ModelState will no longer be valid. So using this familiar code in your controller will make sure you don't take any action unless your custom conditions check out:
public class SomeController {
public ActionResult SomeAction() {
if (ModelState.IsValid) {
//Do your stuff!
}
}
}