C# asp.net mvc Set CheckBoxFor checked-property with Model-Value - javascript

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 =)

Related

Ignore Model validation in HTML form

Here's my setup
HTML
#using (Html.BeginForm("Action", "Controller", FormMethod.Post, new { #class = "form-horizontal", role = "form", enctype = "multipart/form-data", id = "mainForm" }))
{
<div class="form-group">
#Html.LabelForRequired(m => m.Prop1)
#Html.DropDownListFor(m => m.Prop1, (SelectList)ViewBag.SelectList, "Select Role...", new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.Prop1, null, new { #class = "help-block" })
</div>
<div class="row">
<div class="col-sm-2 pull-right">
<button type="submit" class="btn btn-default" id="previous">#Html.T("Back")</button>
<button type="submit" class="btn btn-primary">#Html.T(Model.ButtonText)</button>
</div>
</div>
}
View Model Setup
public class ViewModel{
[Required]
public string Prop1 { get; set;}
}
What I am trying to achieve is that when I hit the back button, I want to ignore any form validation and just redirect the user to my post back action in the controller.
Here's what my JavaScript looks like
$("#previous").off('click').on('click', (evt) => {
var form = $("#mainForm");
if (form.length != 0) {
this.resetFormValidation(form);
}
var actionUrl = $('#mainForm').attr('action');
var indexOfBackslash = actionUrl.lastIndexOf('/');
var newActionUrl = actionUrl.slice(0, indexOfBackslash + 1);
var newActionUrl = newActionUrl + 'BackSubmit';
$('#mainForm').attr('action', newActionUrl);
(<any>$('#mainForm').validate()).cancelSubmit = true;
if (form.length != 0) {
this.resetFormValidation(form);
}
});
}
resetFormValidation(form: any) {
$("#mainForm").find('[data-valmsg-replace]')
.removeClass('field-validation-error')
.addClass('field-validation-valid')
.empty();
$("#mainForm").find('div.has-error').removeClass('has-error');
}
This still shows the field validation and does not go through with the post-back. What am I missing?

how to add default option value from dropdown using mvc?

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);
}

Change EditorFor in time of change input

I want to change Editorfor that display already data from database when i change input
i will take output of input and split it and put result in 2 EditorFor
<input type="text" value="Set Date" id="reservationtim onchange=myFunction()>
#Html.EditorFor(model => model.StartDate, new { htmlAttributes = new { #class = "form-control" }, id = "startDate" })
#Html.EditorFor(model => model.EndDate, new { htmlAttributes = new { #class = "form-control" } , id = "endDate" })
and the function :
<script>
function myFunction() {
var date = document.getElementById("reservationtime").value;
var res = date.split("-");
model => model.StartDate = res[0];
document.getElementById("startDate") = res[0];
document.getElementById("endDate") = res[1];
}
</script>
You're trying to set the element reference itself to the value you want. Rather you need to set the value attribute of the element reference:
document.getElementById("startDate").value = res[0];
Also, it looks like you're trying to mix server-side and client-side code here. Remember that JavaScript is not processed until the document has already been processed by the server and returned to the client. Once you're client-side, all that exists is just the DOM, which is created by the browser based on the HTML document the server sent down. In other words, the fact that you used EditorFor or whatever is completely lost. All you have is the result (i.e. HTML) of that call to EditorFor.
You should first correct your HTML, as some attributes are not specified correctly.
<input type="text" value="Set Date" id="reservationtime" onchange="myFunction()">
#Html.EditorFor(model => model.StartDate, new { #class = "form-control" } )
#Html.EditorFor(model => model.EndDate, new { #class = "form-control" } )
I don't know why you are explicitly setting id for above two editors. they by default take property name as ID. so I would suggest following script for it.
<script>
function myFunction() {
var date = document.getElementById("reservationtime").value;
var res = date.split("-");
model => model.StartDate = res[0];
if(res.length>1) {
document.getElementById("StartDate").value = res[0];
document.getElementById("EndDate").value = res[1];
// if you still want to set ID properties instead of using default use following
// document.getElementById("StartDate").value = res[0];
// document.getElementById("EndDate").value = res[1];
}
}
</script>

Selecting dropdown value shows a Textbox, but doesn't stores a value passed in it

my view contains
<div class="col-md-3 ">
#{
List<SelectListItem> deformitylevel = new List<SelectListItem>();
deformitylevel.Add(new SelectListItem { Value = "hip", Text = "Hip" });
deformitylevel.Add(new SelectListItem { Value = "knee", Text = "Knee" });
deformitylevel.Add(new SelectListItem { Value = "ankle", Text = "Ankle" });
deformitylevel.Add(new SelectListItem { Value = "other", Text = "Other" });
}
#Html.DropDownListFor(model => model.DeformityLevel, deformitylevel, "--Select Level -", new { #class = "form-control", #onchange = "showdeformitytextbox()", id = "deformitydropdown" })
#Html.ValidationMessageFor(model => model.DeformityLevel, "", new { #class = "text-danger" })
</div>
<div class="col-md-3">
#Html.EditorFor(model => model.DeformityLevel, new { htmlattributes = new { #class = "form-control", id = "deformitytextbox" ,style= "display:none"} })
</div>
My function is
function showdeformitytextbox() {
if ($("#deformitydropdown option:selected").text() == 'Other') {
$("#deformitytextbox").show();
}
else {
$("#deformitytextbox").hide();
}
}
When I select "Other" in dropdownlist it stores 'other' in the database instead of storing a value which is entered in #Html.EditorFor.
What I'm forgetting Help!!
As mentioned by others, to make this cleaner, it would be best if you separated the model fields for the drop down and the textbox. Even if you get it to work using the below code, it will lead to more work if you have to return to the page with the other value selected. That said, the following does properly submit the expected value in the textbox. The key concept is to set the dropdown to disabled as you submit.
Assuming your form has an id of submitForm specified as follows:
#using (Html.BeginForm("someActionName", "someControllerName", FormMethod.Post, new { #id="submitForm"}))
Then the following code will ensure that the drop down doesn't submit its value by intercepting the form submission:
$("#submitForm").submit(function () {
if ($("#deformitydropdown option:selected").text() === "Other") {
$("#deformitydropdown").attr("disabled", true);
} else {
$("#deformitydropdown").removeAttr("disabled");
}
});
I would change the names of your current controls and make a hidden form element for DeformityLevel. Then set its value in javascript based on DropdownList and textbox change events.
***Something like this (jq not verified, just for illustration)
<select id="DeformityLevel_DDL">
<option></option>
<option></option>
<option></option>
</select>
<input type="text" id="DeformityLevel_TB" />
<input type="hidden" id="DeformityLevel" name="DeformityLevel" />
<script>
$(document).ready(function () {
$('#DeformityLevel_DDL').change(function () {
if ($(this).val() != 'other') {
$('#DeformityLevel').val(this.val());
}
});
$('#DeformityLevel_TB').on('change', function () {
$('#DeformityLevel').val($(this).val());
});
});
</script>
Well, your function only display the #deformitytextbox input, when the value entered there changes you should also update the model property.
If the form submits automatically on select change you should use preventDefault.
Try now with TextBox, your parameter for htmlAttributes is incorrect. Try:
<div class="col-md-3 ">
#Html.DropDownList("DeformityLevel", deformitylevel, "--Select Level -", new { #class = "form-control", #onchange = "showdeformitytextbox()", id = "deformitydropdown" })
#Html.ValidationMessage("DeformityLevel", "", new { #class = "text-danger" })
</div>
<div class="col-md-3">
#Html.TextBox("DeformityLevel", null, new { #class = "form-control", id = "deformitytextbox", style = "display:none;" })
</div>
<script>
function showdeformitytextbox() {
if ($("#deformitydropdown option:selected").text() == 'Other') {
$("#deformitytextbox").show();
}
else {
$("#deformitytextbox").hide();
}
}
</script>

Dropdownlist onchanged - Trouble persisting ViewModel

I am a ASP.NET developer that is trying to get to grips with MVC.
I'm creating a register page and I have 3 dropdowns.
Now the first dropdown must load first go to load the countries. Based on that I load the provinces and then based on that I load the cities in that province.
The trouble I'm having is that on the first change it keeps my selected value but on the second onchange it seems as everything is lost.
I load the reigster view by just loading countries so long. then the javascript posts it to an action.
cshtml
<label class="col-md-3 col-xs-5 control-label">Country:</label>
<div class="col-md-9 col-xs-7">
#Html.DropDownListFor(x => x.CountryId, (IEnumerable<SelectListItem>)ViewBag.CountryItems, "Please Select", new { #class = "form-control select", #onchange = "CallChangefunc(this.value, null)" })
</div>
</div>
<div class="form-group">
<label class="col-md-3 col-xs-5 control-label">Province:</label>
<div class="col-md-9 col-xs-7">
#Html.DropDownListFor(x => x.ProvinceId, (IEnumerable<SelectListItem>)ViewBag.ProvinceItems, "Please Select", new { #class = "form-control select", #onchange = "CallChangefunc(null, this.value)" })
</div>
</div>
<div class="form-group">
<label class="col-md-3 col-xs-5 control-label">City:</label>
<div class="col-md-9 col-xs-7">
#Html.DropDownListFor(x => x.CityId, (IEnumerable<SelectListItem>)ViewBag.CityItems, "Please Select", new { #class = "form-control select" })
</div>
</div>
The javascript
function CallChangefunc(countryId, provinceId) {
window.location.href = "/Master/SetDropDowns?provinceId=" + provinceId + "&countryId=" + countryId ;
}
First one "Register" loads 1'st then SetDropDowns gets called onchanged.
I load the viewbags(SelectedItemLists) otherwise I get errors on refresh. is there a better way to code the viewbags to not have in two places?
[HttpGet]
public ActionResult Register()
{
IEnumerable<SelectListItem> CountryItems = BusinessAPI.CountryManager.GetAllCountries().Select(ci => new SelectListItem
{
Value = ci.Id.ToString(),
Text = ci.Name
});
ViewBag.CountryItems = CountryItems;
IEnumerable<SelectListItem> ProvinceItems = BusinessAPI.ProvinceManager.GetAllProvincesByCountryId(0).Select(ci => new SelectListItem
{
Value = ci.Id.ToString(),
Text = ci.Name
});
ViewBag.ProvinceItems = ProvinceItems;
IEnumerable<SelectListItem> CityItems = BusinessAPI.CityManager.GetAllCitiesByProvinceId(0).Select(ci => new SelectListItem
{
Value = ci.Id.ToString(),
Text = ci.Name
});
ViewBag.CityItems = CityItems;
return View();
}
public ActionResult SetDropDowns(string provinceId, string countryId)
{
IEnumerable<SelectListItem> CountryItems = BusinessAPI.CountryManager.GetAllCountries().Select(ci => new SelectListItem
{
Value = ci.Id.ToString(),
Text = ci.Name
});
ViewBag.CountryItems = CountryItems;
int countId = 0;
if (countryId == "null")
countryId = string.Empty;
if (TempData["CountryId"] == null)
{
if (!string.IsNullOrEmpty(countryId))
{
countId = Convert.ToInt32(countryId);
TempData["CountryId"] = countId;
}
}
else
countId = Convert.ToInt32(TempData["ProvinceId"]);
IEnumerable<SelectListItem> ProvinceItems = BusinessAPI.ProvinceManager.GetAllProvincesByCountryId(Convert.ToInt32(countId)).Select(ci => new SelectListItem
{
Value = ci.Id.ToString(),
Text = ci.Name
});
ViewBag.ProvinceItems = ProvinceItems;
int provId = 0;
if (provinceId == "null")
provinceId = string.Empty;
if (TempData["ProvinceId"] == null)
{
if (!string.IsNullOrEmpty(provinceId))
{
provId = Convert.ToInt32(provinceId);
TempData["ProvinceId"] = provId;
}
}
else
provId = Convert.ToInt32(TempData["ProvinceId"]);
IEnumerable<SelectListItem> CityItems = BusinessAPI.CityManager.GetAllCitiesByProvinceId(provId).Select(ci => new SelectListItem
{
Value = ci.Id.ToString(),
Text = ci.Name
});
ViewBag.CityItems = CityItems;
return View("Register");
}
The problem is that you don't tell them to be selected, modify your lists that have SelectListItem like the example below, to tell what item from list is Selected.
IEnumerable<SelectListItem> CountryItems = BusinessAPI.CountryManager.GetAllCountries().Select(ci => new SelectListItem
{
Value = ci.Id.ToString(),
Text = ci.Name,
Selected = ci.id.ToString() == countryId // if match the condition is selected
});
Also, to keep both listed selected you can modify your View.
Modify the javascript function to send always the countryId. Doing this the current country will be always selected, even when you change province.
function CallChangefunc(provinceId) {
var countries = document.getElementById("CountryId");
var countryId = countries.options[countries.selectedIndex].value;
window.location.href = "/Master/SetDropDowns?provinceId=" + provinceId + "&countryId=" + countryId ;
}
Notice that on first dropdown CallChangefunc(null), with this we tell that we don't have a province selected, which is true.
<div class="col-md-9 col-xs-7">
#Html.DropDownListFor(x => x.CountryId, (IEnumerable<SelectListItem>)ViewBag.CountryItems, "Please Select", new { #class = "form-control select", #onchange = "CallChangefunc(null)" })
</div>
On second dropdown we send CallChangefunc(this.value), with this we tell what province was selected to take cities and to keep the current value selected after postback. And because the countryId is always send it will remain unchanged.
<div class="col-md-9 col-xs-7">
#Html.DropDownListFor(x => x.ProvinceId, (IEnumerable<SelectListItem>)ViewBag.ProvinceItems, "Please Select", new { #class = "form-control select", #onchange = "CallChangefunc(this.value)" })
</div>

Categories