I am working on MVC application. I have a problem with a form in Create View (create.cshtml). The Form has a three select elements (dropdown list). The first one is filled by ViewBag.RodzajePojazdow which is loaded in 'Create' method in Controller.
public IActionResult Create()
{
ViewBag.RodzajePojazdow =
(
from rodzaj in _context.RodzajPojazdu
orderby rodzaj.IdRodzaju
select rodzaj
).ToList();
ViewBag.MarkiSamochodow =
(
from markaSam in _context.MarkaSamochodu
orderby markaSam.IdMarki
select markaSam
).ToList();
ViewBag.MarkiMotocykli =
(
from markaMot in _context.MarkaMotocykla
orderby markaMot.IdMarki
select markaMot
).ToList();
The options in the second select element (second dropdown) should be loaded in dependency of what option was choosen in the first dropdown list.
The content of the 'ViewBag.MarkiSamochodow' should be loaded in the second select element (second dropdown) only if in the first select element (e.g) A option was choosen. If in the first select element B option was choosen, the second select element (second dropdown) should be filled by the content of the 'ViewBag.MarkiMotocykli'.
I used Json in CreateMethod to serialize my ViewBags
string jsonMot = JsonConvert.SerializeObject(ViewBag.MarkiMotocykli);
string jsonSam = JsonConvert.SerializeObject(ViewBag.MarkiSamochodow);
ViewBag.jsonMarkiMotocykli = jsonMot;
ViewBag.jsonMarkiSamochodow = jsonSam;
Here is a piece of my HTML form:
<div class="form-group">
<label asp-for="IdRodzaju" class="control-label" for="wybierzRodzaj">Wybierz rodzaj pojazdu</label>
<select asp-for="IdRodzaju" class="form-control" id="wybierzRodzaj" onchange="uzupelnijMarki()">
#{
foreach (var item in ViewBag.RodzajePojazdow)
{
<option value="#item.IdRodzaju">#item.NazwaRodzaju</option>
}
}
</select>
#*<input asp-for="IdRodzaju" class="form-control" />*#
<span asp-validation-for="IdRodzaju" class="text-danger"></span>
</div>
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="MarkaPojazdu" class="control-label" for="wybierzMarke">Wybierz markę</label>
<select asp-for="MarkaPojazdu" class="form-control" id="wybierzMarke">
#*#{
--- If A option was choosen in previous select element do this:
foreach (var item in ViewBag.MarkiSamochodow)
{
<option value="#item.IdMarki">#item.NazwaMarki</option>
}
--- If B option was choosen in previous select element do this:
foreach (var item in ViewBag.MarkiMotocykli)
{
<option value="#item.IdMarki">#item.NazwaMarki</option>
}
}*#
</select>
And then in JS I've tried to load the ViewBag content to the second dropdown list, but the JSON.parse() method doesn't work correctly here
<script>
function uzupelnijMarki() {
var markiSamochodow = [];
var markiMotocykli = [];
var jsonMotocykle = '#ViewBag.jsonMarkiMotocykli';
var jsonSamochody = '#ViewBag.jsonMarkiSamochodow';
var markiSamochodow = JSON.parse(jsonSamochody);
var markiMotocykli = JSON.parse(jsonMotocykle);
var rodzaj = document.getElementById("wybierzRodzaj");
//var markisel = document.getElementById("wybierzMarke");
var seltype = rodzaj.options[rodzaj.selectedIndex].value;
alert(' napis');
if (seltype == 1) {
$("#wybierzMarke").empty();
markiSamochodow.forEach(function (obj) {
$('#wybierzMarke').append($('<option></option>').val(obj.NazwaMarki).html(obj.IdMarki))
});
}
if (seltype == 2) {
$("#wybierzMarke").empty();
markiMotocykli.forEach(function (obj) {
$('#wybierzMarke').append($('<option></option>').val(obj.NazwaMarki).html(obj.IdMarki))
});
}
}
</script>
Is there any easier way to fill the second dropdown in dependency of previous choosen option ?
Thank you,
Follow below steps:
First dropdown is populated by ViewBag.RodzajePojazdow which you are doing good.
Now, Intercept change event of First dropwdown via jquery/javascript and make a ajax call to call controller method and pass First dropdown selected value to contoller method method like as below:
Calling javacript function on change event of first dropdown
onChange="PopulateSecondDropdown(this.options[this.selectedIndex].value);"
Javascript function to make ajax call to Controller/PopulateSecondDropdown action:
function PopulateSecondDropdown(firstdropdwonvalue) {
$.ajax({
type: 'get',
dataType: 'json',
cache: false,
url: '/Controller/PopulateSecondDropdown',
data: { 'firstdropdwonvalue': firstdropdwonvalue },
success: function (response) {
if (response.length == 0) {
alert("no data found.");
}
else {
$.each(response, function (index, value) {
// bind second dropdwon with result here
});
}
},
error: function (error) {
console.log(error);
}
});
};
Controller method should be look like this. I am not sure about how linq work so , please validate once linq query:
[HttpGet]
public JsonResult PopulateSecondDropdown (string firstdropdwonvalue)
{
// Use firstdropdwonvalue value to select list for second dropdown
return Json((
from markaSam in _context.MarkaSamochodu
orderby markaSam.IdMarki
select markaSam
).ToList(), JsonRequestBehavior.AllowGet);
}
Related
Hello every one i have the following question ,i have a select tag that i want to populate with a list objects Here some code to explain:
#RequestMapping(value="/getAllIndustries")
#ResponseBody
public List<IndustryModel>getAllIndustries()
{
return generalSettingMerchantLookUpService.getBusinessNature(Constant.MERCHANT);
}
This return a list of industries models ,the following is the java script that i am using
function industryAjax()
{
alert("i am here")
var businessNatureId= $("#industrySelect option:selected").val();
$.ajax({
url : getContextPath() + "/getAllIndustries",
type : "get",
success : function(response) {
$('#industrySelect').empty();
$('#industrySelect').append($('<option>', {
value: 0,
text: 'Select'
}));
for (item in response) {
$('#industrySelect').append($('<option>', {
value: response[item].industryId,
text: response[item].industryInEnglish
}));
}
},
error : function(e) {
// alert("Submit failed" + JSON.stringify(e));
}
});
}
And here i my html
<div class="col-xs-12 col-sm-6 col-md-4 col-lg-4">
<label>Industry</label> <select class="form-control m-b"
id="industrySelect" name="industryId" onchange="industryChange();">
<option value="0">Choose Industry</option></select>
<p id="chooseIndustry" style="color: red;">please choose a valid industry</p>
</div>
So how can i display the list of industries that i get from controller in the html ,Best Regards
It might be the case that this method is not getting invoked because initially your dropdown does not contain any element. So there will not be any onchange event fired.
Try using below implementation:
$(document).on('click', "#industrySelect", function(event) {
industryAjax();
});
I've some problem with Select2, basically i need to fill some other form fields with data retrieved from Select2 Ajax search.
even following example found here:
Select2 4.0 - Push new entry after creation
I'm not able to fill some field programmatically with results founds from Select2
Just as example, consider that I've Three fields, i can use two of these fields to search data and i want that other remaining fields will be filled automatically after choosing one of ajax call returned values.
so, as example:
Test field 01 (Select2 field)
Test field 02 (Select2 field)
Test field 03 (standard input field)
If i search something on "Test field 01" i want that 02 and 03 will be filled automatically.
I've implemented one solution that you can find below but doesn't work with the Select2 fields, only with the input one.
If i use the code inspector i see that the new option inside the "select" element are correctly created and tagged as "selected" but seem that the "select2-selection__rendered" span element is not correctly update after triggering the "change" event
During my tests, I also notice that the the function "updateselect2" that i use to update the data is called four times each time i select one value from results and consequentially i found 4 time the same value in the destination select box.
take a look at animated gif below to see the complete behavior
There is something that i did wrong?
My setup is:
jquery-3.1.0
Select2 4.0.3
Below you can find a complete example of my current work:
HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"/>
<meta http-equiv="x-ua-compatible" content="ie=edge"/>
<title>Test</title>
<script src="jquery-3.1.0.min.js"></script>
<link rel="stylesheet" href="select2.min.css"/>
<script src="select2.full.js"></script>
</head>
<body>
<div class="section ">
<div class="container ">
<div class="row">
<div class="col-md-2">
<div class="form-group">
<label for="testField01" class="control-label">Test field 01</label>
<select id="testField01" class="form-control" name="testField01" style="width:150px;">
<option value=""></option>
</select>
</div>
</div>
<div class="col-md-2">
<div class="form-group">
<label for="testField02" class="control-label" >Test field 02</label>
<select id="testField02" class="form-control" name="testField02" style="width:150px;">
<option value=""></option>
</select>
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<label for="testField03" class="control-label" style="width:150px;">Test field 03</label>
<input id="testField03" class="form-control" value="" readonly="readonly" />
</div>
</div>
</div>
</div>
</div>
</body>
</html>
JAVASCRIPT:
var select2_query = {};
function markMatch(text, term) {
// Find where the match is
var match = text.toUpperCase().indexOf(term.toUpperCase());
var $result = $('<span></span>');
// If there is no match, move on
if (match < 0) {
return $result.text(text);
}
// Put in whatever text is before the match
$result.text(text.substring(0, match));
// Mark the match
var $match = $('<span style="color:red"></span>');
$match.text(text.substring(match, match + term.length));
// Append the matching text
$result.append($match);
// Put in whatever is after the match
$result.append(text.substring(match + term.length));
return $result;
}
function updateselect2(elId, values) {
var $element = $('#' + elId); // the element that Select2 is initialized on
if ($element.attr('id') == undefined) {
return false;
}
$element.empty();
var $option = $("<option selected></option>"); // the new base option
$option.val(values[elId]); // set the id
$option.text(values[elId]); // set the text
$element.append($option); // add it to the list of selections
$element.trigger("change"); // tell Select2 to update
}
function formatResult(result) {
if (result.loading) {
return result.text;
}
var term = select2_query.term || '';
var $formattedResult = markMatch(result.testField01 + ' - ' + result.testField03, term);
return $formattedResult;
}
function formatSelection(selection) {
if (!selection.selected) {
updateselect2('testField02', selection);
$('#testField03').val(selection.testField03);
}
return selection.testField01;
}
function initSearch(fieldId, searchType) {
$("#" + fieldId).select2({
ajax: {
url: "/search/data",
dataType: 'json',
delay: 250,
data: function (params) {
return {
id: params.term, // search term
by: searchType,
page: params.page
};
},
processResults: function (data, params) {
params.page = params.page || 1;
return {
results: data.items,
pagination: {
more: (params.page * 30) < data.total_count
}
};
},
cache: true
},
escapeMarkup: function (markup) {
return markup;
},
minimumInputLength: 4,
templateResult: formatResult,
templateSelection: formatSelection,
language: {
searching: function (params) {
select2_query = params;
return 'Searching…';
}
}
});
}
$(document).ready(function() {
$('testField01').select2();
$('testField02').select2();
initSearch('testField01', 'testField01');
initSearch('testField02', 'testField02');
});
JSON DATA SAMPLE:
{"total_count":1,"incomplete_results":false,"items":[{"id":1,"testField01":"123456789","testField01":"987654321", "testField03":"ABCDEFGHIJK"}]}
Well, when you append options to an select field, you need to reinitialize the select2 element like:
$element.select2("destroy");
instead of $element.trigger("change"); in the updateselect2() function.
Also, the correct way to change the value in select2 is not by triggering the change listener, but by invoking .select2('val', thevalue) which in your case would not work because of the new options, but keep that in mind.
Another note: No need to initialize the select2 in the document.ready, as initSearch will do it for you.
Last note: your sample json is wrong, you're passing testField01 twice
Edit for clarity: When an item in the dropdownlist is selected, call a method in my controller which will return a partialview and update a div on my page.
I have a ActionLink PartialView which I want to be called every time I select a new item in the dropdown list to update a table I have on my webpage - how do I make this happen without needing to press a button?
#Html.DropDownListFor(m => m.SelectedCustomerId, Model.CustomerIDItem)
I can do a Request["selectedCustomerId"] to retrieve the value from it without any problems but my question really is about the dynamic part. The first idea was to connect AJAX to the dropdownlist or using JQuery but I have no idea how to actually make this work.
Thanks in advance.
Edit 4:
Adding all of my code:
_DefaultValuesView.cshtml:
#Html.DropDownListFor(m => m.SelectedCustomerId, Model.CustomerIDItem)
<div id="divValues">
#{ Html.RenderPartial("_DefaultValuesPartialView");}
</div>
DefaultValuesController.cs
[HttpPost]
public PartialViewResult DefaultValuesPartialView(string SelectedCustomerId)
{
Session["theCustomerId"] = Request["selectedCustomerId"];
var model = new DefaultValuesModel
{
CustomerIDItem = GetCustomerIds(),
FieldIDItem = GetValues(),
CurrentValuesItem = GetCurrentValues()
};
model.TriggerOnLoad = true;
this.customerId = Convert.ToInt32(Request["selectedCustomerId"]);
errorMessage = "PartialView is loaded!";
model.TriggerOnLoadMessage = errorMessage;
return PartialView("_DefaultValuesPartialView", model);
}
I would do it like this:
#Html.DropDownListFor(m => m.SelectedCustomerId, Model.CustomerIDItem, new { #id = "customId" })
<div id="divValues">
</div>
$(function() {
$("#customId").change(function() {
var id = $(this).val();
$('#divValues').load('#Url.Action("DefaultValuesPartialView", "DefaultValues")?selectedCustomerId=' + id, function (response, status, xhr) {
$("#divValues").html(response);
});
});
});
Your controller Action then looks like this:
public PartialViewResult DefaultValuesPartialView(int? selectedCustomerId)
{
Session["theCustomerId"] = selectedCustomerId.Value;
var model = new DefaultValuesModel
{
CustomerIDItem = GetCustomerIds(),
FieldIDItem = GetValues(),
CurrentValuesItem = GetCurrentValues()
};
model.TriggerOnLoad = true;
this.customerId = selectedCustomerId.Value;
errorMessage = "PartialView is loaded!";
model.TriggerOnLoadMessage = errorMessage;
return PartialView("_DefaultValuesPartialView", model);
}
Please consider that your Partial views name needs to bee the same as your controller action name.
You load your data with the jQuery function .load this is a common way and I use everytime if I need to do something like you want to do
If I understood you correctly this should do it (it uses JQuery)... JSFiddle here
<select id="myDdl">
<option value="AM">AM</option>
<option value="PM">PM</option>
</select>
<div id="babylonAndTing">
A up lad.
</div>
$(function() {
$("#myDdl").change(function() {
$("#babylonAndTing").text( $('option:selected', this).text() );
});
});
P.S. Hmm on second thoughts, I answered your question title 'How do I dynamically update a div instantly when an item in a dropdownlist is selected?', but your question text is asking something different?!?!? Ah well I'll leave this answer for the people who read your title and come here :p
Edit:
As for your question in the text, try something like this...
#using (Ajax.BeginForm("SelectCustomer", "MyControllerName", FormMethod.Post, null))
{
#Html.DropDownListFor(m => m.SelectedCustomerId, Model.CustomerIDItem)
}
<script type="text/javascript">
$('#SelectedCustomerId').change(function () {
$(this).parents('form').submit();
});
</script>
[HttpPost]
public ActionResult SelectCustomer(int? selectedCustomerId)
{
// Stuff goes here.
}
You can make an ajax request to the partial view and get back just the HTML content of it. The key is using url: "#Url.Action("DefaultValuesPartialLayout")" to get the right URL to load your partial from.
<div id="divValues">
#{ Html.RenderPartial("_DefaultValuesPartialLayout");}
</div>
$(document).ready(function() {
$("##Html.IdFor(m => m.SelectedCustomerId)").change(function() {
var selectedCustomerId = $("##Html.IdFor(m => m.SelectedCustomerId)").val();
$.ajax({
url: "#Url.Action("DefaultValuesPartialView")",
method: "GET",
data: { SelectedCustomerId: selectedCustomerId },
success: function(data, status, xhr) {
$("#divValues").html(data);
}
});
})
});
I have two cascading dropdown boxes controlled with JQuery and Ajax objects. The first determines the values in the second. Then, once a selection is made in the second, the values from the two dropdowns would be used to find a record in an SQL table and display the record in an html table.
So far the dropdowns work correctly but I'm having difficulty getting the record from the database and then displaying it on screen. I've done this before by getting the database values, sending them to the view in a Json object, and using an Ajax object to to create the table with Jquery. However, in this case I don't mind if the page reloads and would like to use a simpler method.
What is a simple method of sending two values from two dropdowns to the controller, using those values to find a record in an sql table, sending the values from the record back to the view to be displayed? Also, I don't want anything to be displayed until the second dropdown box has a selection made.
Here is what I have so far:
Controller methods:
List<Car> GetCars()
{
using (var service = new Service())
{
return service.GetCars().OrderBy(x => x.CarName).Select(x => new Car
{
CarId = x.CarId,
CarName = x.CarName
}).ToList();
}
}
List<Color> GetColors(int carId)
{
using (var service = new Services())
{
return service.GetColors(carId).OrderBy(x => x.ColorName).Select(x => new Color
{
ColorId = x.ColorId,
ColorName = x.ColorName
}).ToList();
}
}
[HttpPost]
public ActionResult CurrentSaus(int townCode, int fiscalYear)
{
var colors = GetColors(carId);
return Json(new SelectList(colors, "ColorId", "ColorName"));
}
Jquery methods:
$(document).ready(function () {
$("#Car_CarId").change(function () {
var carId = $(this).val();
var carName = $(":selected", this).text();
// put the car name into a hidden field to be sent to the controller
document.getElementById("Car_CarName").value = carName;
getColors(carId);
})
});
function getColors(carId) {
if (carCode == "") {
$("#Color_ColorId").empty().append('<option value="">-- select color --</option>');
}
else {
$.ajax({
url: "#Url.Action("Colors", "HotWheels")",
data: { colorId: clrId },
dataType: "json",
type: "POST",
error: function () {
alert("An error occurred");
},
success: function (data) {
var colors = "";
var numberOfColors = data.length;
if (numberOfColors > 1) {
colors += '<option value="">-- select color --</option>';
}
else {
var colorId = data[0].Value;
var colorName = data[0].Text;
document.getElementById("Color_ColorName").value = colorName;
}
$.each(data, function (i, color) {
colors += '<option value="' + color.Value + '">' + color.Text + '</option>';
});
$("#Color_ColorId").empty().append(colors);
}
});
}
and some of the html:
#Html.HiddenFor(x => x.Car.CarName)
#Html.HiddenFor(x => x.Color.ColorName)
<table>
<tr>
<td> Select Car:</td>
<td style="text-align:left">
#Html.DropDownListFor(
x => x.Car.CarId,
new SelectList(Model.CarList, "CarId", "CarName"),
"-- select town --")
<br />
#Html.ValidationMessageFor(x => x.Car.CarId)
</td>
</tr>
<tr>
<td> Select Color:</td>
<td colspan="4">
#Html.DropDownListFor(
x => x.Color.ColorId,
new SelectList(Model.ColorList, "ColorId", "ColorName"),
"-- select color --")
<br />
#Html.ValidationMessageFor(x => x.Color.ColorId)
</td>
</tr>
</table>
}
The easiest method is to use an old fashion FORM element and POST the values of the two drop downs to an action in your controller. That action would expect a carId and a colorId and use them to retrieve a record from the DB and then pass the result to your 'view' where you would take care of render/display the result.
Of course using this method has some caveats:
The entire page will refresh after a user selects a value from the
second drop down.
You would have to POST the form using JavaScript
when the user picks the second option, or at least enable a button so
the form can be POSTed.
You would have to keep track of the carId and
colorId in your controller and view
Another option is to use AJAX to POST (send to the server) the carId and colorId where and action in a controller will take care of using those parameters to find a record in the DB and then return a JSON object with the result. The response will be handled by a 'success' handler where you will take care parsing the JSON object and add rows to a table.
So if you feel more comfortable working on the server side of the code pick the first option, however if you prefer to use AJAX and do this in the front end use the later.
Problem Statement: I want to change the display name of labels(#Html.LabelFor) in Razor view of MVC based on the display names which i get from db.
I have added the dropdown list of languages in the _Layout.cshtml
<li>#Html.Action("Index", "LanguageDropdown", new { languageid = Request["languageId"] })</li>
I have created one partial view for drop down:
#model ALCMS.Web.Models.Master_or_Configuration.LanguageDropdownModel
<script type="text/javascript">
function GetLanguage() {
var languageId = $('#LanguageId').val();
var Url = "#Url.Content("~/MasterConfigGeneral/GetLanguage")";
$.ajax({
url: Url,
dataType: 'json',
data: { LanguageId: languageId },
success: function (data) {
}
});
}
</script>
<div style="display:inline-block">
#Html.DropDownListFor(l => l.LanguageID, new SelectList(Model.Languages, "Value", "Text"), "Select Language", new { id = "LanguageId" ,onchange="GetLanguage()" })
</div>
Partial View Controller:
public ActionResult Index(string languageId)
{
//return View();
var languages = dbEntity.LookupLanguages;
var model = new LanguageDropdownModel
{
LanguageID = languageId,
Languages = languages.ToList().Select(l => new SelectListItem
{
Value = Convert.ToString(l.LanguageID),
Text = l.Name
})
};
return PartialView(model);
}
In Controller Json Result method:
public JsonResult GetLanguage(int languageID)
{
JsonResult jsResult = new JsonResult();
objdbGlobalTenant.ddlLanguage = (from lsr in dbEntity.LocaleStringResources
where lsr.LanguageID == languageID
select new SelectListItem()
{
Text = lsr.ResourceValue,
Value = lsr.ResourceName
}).Distinct().ToList<SelectListItem>();
//ViewBag.Language = objdbGlobalTenant.ddlLanguage;
jsResult.JsonRequestBehavior = JsonRequestBehavior.AllowGet;
return jsResult;
}
Now everything is working fine.I'm able to get the selected langaugeID in Json Result method in Controller based on the change event of Language dropdown. Based on this Language ID i'm getting display names(ResourceValue) which i need to apply for the particular view.
Problems:
1>After getting the display names from db how to change display names
of particular view when language change event triggers.?? For
ex:Currently i'm seeing the Create.CSHTML. Now if i change the
language dropdown it should trigger Json Event in controller and
after getting values it should apply the values on the view which it
got from db.
Note: Dropdown is in Layout.cshtml(like master in .aspx)
2>Drop-down which i placed in Layout.cshtml is getting refreshed
every time new view is loaded which inherits(layout.cshtml).How to
make the controller to retain it's state during postback??
3>How to get the selected drop-down item from the layout in multiple
Controllers,to change the display name in each view based on the langaugeid
of dropdown in layout
How to do this??If i'm doing wrong suggest me some other ways...
Below are the suggestions :
Issue 1 :
You may keep one attribute in each label which identifies them uniquely.
Your HTML should render like following
<!-- For English -->
<label label-unique-name="Name">Name</label>
<label label-unique-name="Surname">Surname</label>
<!-- For French -->
<label label-unique-name="Name">nom</label>
<label label-unique-name="Surname">nom de famille</label>
<!-- For Spanish -->
<label label-unique-name="Name">nombre</label>
<label label-unique-name="Surname">apellido</label>
Here label-unique-name is your attribute, which will remain fixed for each language. Now when you change the language from dropdown you will bring the values like below.
<!-- For English -->
<label-unique-name:"Name",label-value:"Name">;<label-unique-name:"Surname",label-value:"Surname">
<!-- For French -->
<label-unique-name:"Name",label-value:"nom">;<label-unique-name:"Surname",label-value:"nom de famille">
<!-- For English -->
<label-unique-name:"Name",label-value:"nombre">;<label-unique-name:"Surname",label-value:"apellido">
Please note : this is for understanding only, it's not a JSON.
Now using jQuery go through each label and replace the label's value. Hope it'll help you.
Issue 2 :
You can save the selected language's value in session, and generate your dropdown accordingly.
#Html.DropDownListFor(l => l.LanguageID, new SelectList(Model.Languages, "Value", "Text"), !string.isNullorEmpty(HttpContext.Current.Sessions["Language"]) ? HttpContext.Current.Sessions["Language"] : "Select Language", new { id = "LanguageId" ,onchange="GetLanguage()" })