Dropdownlist onchanged - Trouble persisting ViewModel - javascript

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>

Related

unable to hide/show div tag using jquery

I am trying to hide or show my div tag based on the selection of a value from my dropdown. There are 2 values in the dropdown, select the value 1 will hide the div, selecting the other will show the div. But it is not working, my div tag is always invisible. Please help me, thanks in advance.
Please see the sample code:
#if (Model.Selectedtype == 3)
{
<div id="testDiv" class="form-group col-md-3">
#Html.LabelFor(model => model.testvalue, new { #class = "col-form-label col-form-label-sm text-primary" })
#Html.EditorFor(model => model.testvalue, null, new { htmlAttributes = new { #class = "form-control form-control-sm selectpicker show-tick", data_live_search = true, title = "Select an option", data_icon_base = "fa", data_tick_icon = "fa-check" } })
</div>
}
function incidentChangeHandler(e) {
var selectedText = $(this).find("option:selected").text().toLowerCase();
var elem = $(this).parent();
var selectedValue = e.target.value;
if (selectedValue === '3') {
alert("entered");
$('#testDiv').addClass('d - none');
} else {
alert("else");
$('#testDiv').removeClass('d-none');
}
}

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

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

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

2nd dropdown not displaying after selecting the value from 2nd dropdown in asp.net mvc

I am using cascading dropdownlist in asp.net mvc.
When a value is selected from the first dropdown, the list is shown in 2nd dropdown. When I select the value from the 2nd dropdown it shows in the dropdown, but after clicking the submit button it disappears showing "Select from List". Why?
View:
<div class="row form-group">
<div class="col-md-6">
#Html.LabelFor(model => model.Religion_Id, new { #class = "control-label" })
<div class="input-group">
<span class="input-group-addon" style="background:white">
<i class="fa fa-cloud" style="color:#179CDC;"></i>
</span>
#Html.DropDownListFor(model => model.Religion_Id, Model.Religion, "Select From List", new { #class = "form-control select2me", #id = "ddlReligion" })
</div>
#Html.ValidationMessageFor(model => model.Religion_Id, string.Empty, new { #class = "small text-danger text-uppercase" })
</div>
<div class="col-md-6">
#Html.LabelFor(model => model.Sect_Id, new { #class = "control-label" })
<div class="input-group">
<span class="input-group-addon" style="background:white">
<i class="fa fa-cloud" style="color:#179CDC;"></i>
</span>
<div id="Sects">
#Html.DropDownListFor(model => model.Sect_Id, new List<SelectListItem>(), "Select Form List", new { #class = "form-control select2me", #id = "ddlSect" })
</div>
</div>
#Html.ValidationMessageFor(model => model.Sect_Id, string.Empty, new { #class = "small text-danger text-uppercase" })
</div>
</div>
<script>
$(document).ready(function () {
loadSect();
});
var loadSect = function (flag) {
if ("undefined" == typeof (flag)) {
flag = true;
}
$.ajax({
type: "post",
url: '#Url.Action("GetSects", "MyProfile", new { area = "Candidate" })',
data: { religionId: $('#ddlReligion').val() },
datatype: "json",
traditional: true,
success: function (data) {
var district = "<select id='ddlSect' class='form-control text-uppercase select2me' name='Sect_Id'>";
district = district + '<option value="">Select From List</option>';
for (var i = 0; i < data.length; i++) {
district = district + '<option value=' + data[i].Value + '>' + data[i].Text + '</option>';
}
district = district + '</select>';
$('#Sects').html(district);
if (flag) {
setOption($('#Sects select')[0], $('#HSPEC_ID').val())
}
if (jQuery().select2) {
$('#Sects .select2me').select2({
placeholder: "Select an option",
allowClear: true
});
}
}
});
};
$('#ddlReligion').change(function () {
loadSect(false);
});
function setOption(selectElement, value) {
var options = selectElement.options;
for (var i = 0, optionsLength = options.length; i < optionsLength; i++) {
if (options[i].value == value) {
selectElement.selectedIndex = i;
return true;
}
}
return false;
}
You are not doing a ajax submit. OR Your are not setting the value of second drop down back after post
In your code, I don't see any ajax submit after you choose the second drop dwn and hit submit. So the problem is you are posting this form to controller and then the controller is returning the view back with the same posted data. Now in the Razor syntax for the second drop down you are using
#Html.DropDownListFor(model => model.Sect_Id, new List<SelectListItem>(), "Select Form List", new { #class = "form-control select2me", #id = "ddlSect" })
Here you can see you are setting the value of second drop down by empty list new List<SelectListItem>() and that is why the second drop down is empty.
Solution
Either use AJAX submit for your form. So that your UI remains unchanged.
Change your Razor syntax to this
#Html.DropDownListFor(model => model.Sect_Id, Model.District, "Select Form List", new { #class = "form-control select2me", #id = "ddlSect" })
So add a additional property called Districts and initially set this Model.District to be new List<SelectListItem>() and then in your form post method you just pass back the data as received and it will be rendered properly after submit.

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>

Categories