How to mix C# with javascript for changing html? - javascript

I'm trying to change a html DOM element. With data from asp.net. All the data from CSharp is in the ViewBags. ViewBag.Kenmerken is a list of Strings and ViewBag.Definities is a list a definition object with a variable 'variabel' and the variable 'kenmerk'. I have the following code:
#{
ViewBag.Title = "KenmerkSelectie";
}
<script type="text/javascript">
function Kenmerk1() {
var myselect = document.getElementById("kenmerk1");
var selectValue = myselect.options[myselect.selectedIndex].value;
var newOptions= "";
#foreach (var def in ViewBag.Definities) {
//#def.kenmerk is C# && selectValue is JS;
if(#def.Kenmerk == selectValue){
newOpstions= newOptions+ "<option value=\"#def.Variabel\"> #def.Variabel </option>";
}
}
document.getElementById("var1").innerHTML = newOptions;
}
<div class="kenmerk">
<h3>Kenmerk 1</h3>
<select id="kenmerk1" onchange="Kenmerk1()">
#foreach (var item in ViewBag.Kenmerken)
{
<option value="#item">
#item
</option>
}
</select>
<select id="var1" multiple="multiple">
<!-- add option from js function -->
</select>
</div>
EDIT:
Description: An error occurred during the compilation of a resource
required to service this request. Please review the following specific
error details and modify your source code appropriately.
Compiler Error Message: CS0103: The name 'selectValue' does not exist
in the current context
Source Error: if(#def.Kenmerk == selectValue){

You aren't properly escaping your " (quotations). This line:
newOptions = newOptions + "<option value="#def.Variabel"> #def.Variabel </option>";
Should be something like:
newOptions = newOptions + #"<option value=""#def.Variabel""> #def.Variabel</option>";
Though, for ASP.NET MVC design principles, I'd recommend not using the ViewBag. Use a model for passing in your data instead. http://tech.trailmax.info/2013/12/asp-net-mvc-viewbag-is-bad/
EDIT:
Also, it looks like you should convert your data to JSON so that you can compare your values on the JavaScript side. Since def.Kenmerk lives in C#, it won't be able to evaluate the JavaScript variable, selectValue on an == comparison.

Try using razors <text> Pseudo-element see also here
function Kenmerk1() {
var myselect = document.getElementById("kenmerk1");
var selectValue = myselect.options[myselect.selectedIndex].value;
var newOptionsInHtmlStyle = "";
#foreach (var def in ViewBag.Definities) {
<text>
//#def.kenmerk is C# && selectValue is JS;
if(#(def.Kenmerk) == selectValue){
newOptions = newOptions + '<option value="#(def.Variabel)"> #(def.Variabel) </option>';
}
</text>
}
document.getElementById("var1").innerHTML = newOptions;
}

Related

Viewbag in Javascript shows error Uncaught SyntaxError: Unexpected token '<'

I am fetching the data using API and assign it to VIEW BAG but at run time it shows me an error.
List<DevInfo> DevList = await RestApi.Instance.GetAllDevAsync();
var nameT = DevList.Select(a=>a.Name).ToList();
ViewBag.datasourceDevList = nameT;
And in the script.
var nameList = <%= new JavaScriptSerializer().Serialize("#ViewBag.datasourceDevList") %>;
I want to generate the dropdown list.
if (nameList != '') {
var tableHtml;
$.each(JSON.parse(nameList), function (index, value) {
//tableHtml += "<option value=" + value.Name + ">" + value.Name + "</option>";
console.log(value);
});
/*$("#selectTrainer").html(tableHtml);*/
$("#selectTrainer").append(tableHtml);
}
Instead of calling JavaScriptSerializer() in javascript which makes the code looks complex, you can achieve generating the options via these ways:
Solution 1: Using razor syntax
view
<select id="selectTrainer">
#if (ViewBag.datasourceDevList != null)
{
foreach(var option in ViewBag.datasourceDevList)
{
<option value="#option.Name">#option.Name</option>
}
}
</select>
Sample Solution 1
Solution 2: Pass IEnumerable<SelectListItem> to #Html.DropDownListFor
Set your ViewBag with IEnumerable<SelectListItem> element. #Html.DropDownListFor will generate the options based on list items.
controller
using System.Linq;
ViewBag.datasourceDevList = DevList
.Select(x => new SelectListItem { Text = x.Name, Value = x.Name } )
.ToList();
view
#Html.DropDownListFor(m => m.DevID,
(IEnumerable<SelectListItem>)ViewBag.datasourceDevList,
htmlAttributes: new
{
#id = "selectTrainer"
})
Sample Solution 2
References
DropDownList(HtmlHelper, String, IEnumerable)

DropDownList Change() doesn't seem to fire

So, I have been bashing my head against the desk for a day now. I know this may be a simple question, but the answer is eluding me. Help?
I have a DropDownList on a modal that is built from a partial view. I need to handle the .Change() on the DropDownList, pass the selected text from the DropDownList to a method in the controller that will then give me data to use in a ListBox. Below are the code snippets that my research led me to.
all other controls on the modal function perfectly.
Can anyone see where I am going wrong or maybe point me in the right direction?
ProcessController
// I have tried with [HttpGet], [HttpPost], and no attribute
public ActionResult RegionFilter(string regionName)
{
// Breakpoint here is never hit
var data = new List<object>();
var result = new JsonResult();
var vm = new PropertyModel();
vm.getProperties();
var propFilter = (from p in vm.Properties
where p.Region == regionName && p.Class == "Comparable"
select p).ToList();
var listItems = propFilter.ToDictionary(prop => prop.Id, prop => prop.Name);
data.Add(listItems);
result.Data = data;
return result;
}
Razor View
#section scripts{
#Scripts.Render("~/Scripts/ui_PropertyList.js")
}
...
<div id="wrapper1">
#using (Html.BeginForm())
{
...
<div id="fancyboxproperties" class="content">
#Html.Partial("PropertyList", Model)
</div>
...
<input type="submit" name="bt_Submit" value="#ViewBag.Title" class="button" />
}
</div>
Razor (Partial View "PropertyList.cshtml")
...
#{ var regions = (from r in Model.Properties
select r.Region).Distinct(); }
<div>
<label>Region Filter: </label>
<select id="ddl_Region" name="ddl_Region">
#foreach (var region in regions)
{
<option value=#region>#region</option>
}
</select>
</div>
// ListBox that needs to update after region is selected
<div>
#Html.ListBoxFor(x => x.Properties, Model.Properties.Where(p => p.Class == "Comparable")
.Select(p => new SelectListItem { Text = p.Name, Value = p.Id }),
new { Multiple = "multiple", Id = "lb_C" })
</div>
...
JavaScript (ui_PropertyList.js)
$(function () {
// other events that work perfectly
...
$("#ddl_Region").change(function () {
$.getJSON("/Process/RegionFilter/" + $("#ddl_Region > option:selected").attr("text"), updateProperties(data));
});
});
function updateProperties(data, status) {
$("#lb_C").html("");
for (var d in data) {
var addOption = new Option(data[d].Value, data[d].Name);
addOption.appendTo("#lb_C");
}
}
The callback function passed to your $.getJSON method is wrong. You need to pass a reference to the function, not to invoke it.
Try this:
$.getJSON("/Process/RegionFilter/" + $("#ddl_Region > option:selected").text(), updateProperties);
Also, in order to get the text of the selected drop-down option, you need to use the text() function:
$("#ddl_Region > option:selected").text()
See Documentation

Change DropDownList data with Javascript

I have a page where a user can select if the transaction type is an inter accounts transfer, or a payment.
The model I pass in had two lists.
One is a list of SelectListItem
One is a list of SelectListItem
One of the lists is populated like this:
var entities = new EntityService().GetEntityListByPortfolio();
foreach (var entity in entities.Where(x=>x.EntityTypeId == (int)Constants.EntityTypes.BankAccount))
{
model.BankAccounts.Add(new SelectListItem
{
Value = entity.Id.ToString(CultureInfo.InvariantCulture),
Text = entity.Description
});
}
If the user selects 'Inter account transfer', I need to:
Populate DropdownA with the list from Accounts, and populate DropdownB with the same list of Accounts
If they select "Payment", then I need to change DrowdownB to a list of ThirdParty.
Is there a way, using javascript, to change the list sources, client side?
function changeDisplay() {
var id = $('.cmbType').val();
if (id == 1) // Payment
{
$('.lstSource'). ---- data from Model.ThirdParties
} else {
$('.lstSource'). ---- data from Model.Accounts
}
}
I'd prefer not to do a call back, as I want it to be quick.
You can load the options by jquery Code is Updated
Here is the code
You will get everything about Newton Json at http://json.codeplex.com/
C# CODE
//You need to import Newtonsoft.Json
string jsonA = JsonConvert.SerializeObject(ThirdParties);
//Pass this jsonstring to the view by viewbag to the
Viewbag.jsonStringA = jsonA;
string jsonB = JsonConvert.SerializeObject(Accounts);
//Pass this jsonstring to the view by viewbag to the
Viewbag.jsonStringB = jsonB;
You will get a jsonstring like this
[{"value":"1","text":"option 1"},{"value":"2","text":"option 2"},{"value":"3","text":"option 3"}]
HTML CODE
<button onclick="loadListA();">Load A</button>
<button onclick="loadListB();">Load B</button>
<select name="" id="items">
</select>
JavaScript Code
function option(value,text){
this.val= value;
this.text = text;
}
var listA=[];
var listB=[];
//you just have to fill the listA and listB by razor Code
//#foreach (var item in Model.ThirdParties)
//{
// <text>
// listA.push(new option('#item.Value', '#item.Text'));
// </text>
// }
//#foreach (var item in Model.Accounts)
// {
// <text>
// listA.push(new option('#item.Value', '#item.Text');
// </text>
// }
listA.push(new option(1,"a"));
listA.push(new option(2,"b"));
listA.push(new option(3,"c"));
listB.push(new option(4,"x"));
listB.push(new option(5,"y"));
listB.push(new option(6,"z"));
function loadListA(){
$("#items").empty();
listA.forEach(function(obj) {
$('#items').append( $('<option></option>').val(obj.val).html(obj.text) )
});
}
function loadListB(){
$("#items").empty();
listB.forEach(function(obj) {
$('#items').append( $('<option></option>').val(obj.val).html(obj.text) )
});
}
NEW Javascript Code fpor Json
var listA=[];
var listB=[];
var jsonStringA ='[{"val":"1","text":"option 1"},{"val":"2","text":"option 2"},{"value":"3","text":"option 3"}]';
var jsonStringB ='[{"val":"4","text":"option 4"},{"val":"5","text":"option 5"},{"value":"6","text":"option 6"}]';
//you just have to fill the listA and listB by razor Code
//var jsonStringA = '#Viewbag.jsonStringA';
//var jsonStringB = '#Viewbag.jsonStringB';
listA = JSON.parse(jsonStringA);
listB = JSON.parse(jsonStringB);
function loadListA(){
$("#items").empty();
listA.forEach(function(obj) {
$('#items').append( $('<option></option>').val(obj.val).html(obj.text) )
});
}
function loadListB(){
$("#items").empty();
listB.forEach(function(obj) {
$('#items').append( $('<option></option>').val(obj.val).html(obj.text) )
});
}
Here is the fiddle http://jsfiddle.net/pratbhoir/TF9m5/1/
See the new Jsfiddle for Json http://jsfiddle.net/pratbhoir/TF9m5/3/
ofcourse you can so that
try
var newOption = "<option value='"+"1"+'>Some Text</option>";
$(".lstSource").append(newOption);
or
$(".lstSource").append($("<option value='123'>Some Text</option>");
Or
$('.lstSource').
append($("<option></option>").
attr("value", "123").
text("Some Text"));
Link for reference
B default, I don't think the concept of "data-source" means something in html/javascript
Nevertheless, the solution you're looking for is something like knockoutjs
You'll be able to bind a viewmodel to any html element, then you will be able to change the data source of your DropDownList
see : http://knockoutjs.com/documentation/selectedOptions-binding.html

MVC 4 - Cascading Dropdown Lists - Issue with Ajax JavaScript Call

I have an MVC 4 app with a View containing two dropdown lists. The user selects a value in the first dropdown and then an Ajax call is made to populate the second dropdown based on the contents of the first.
My JavaScript code looks as follows and gets called when the user selects an item in the first dropdown:
function GetAutoModel(_manufacturerId) {
var autoSellerListingId = document.getElementById("AutoSellerListingId").value;
$.ajax({
url: "/AutoSellerListing/GetAutoModel/",
data: { manufacturerId: _manufacturerId, autoSellerListingId: autoSellerListingId },
cache: false,
type: "POST",
success: function (data) {
var markup = "<option value='0'>-- Select --</option>";
for (var x = 0; x < data.length; x++) {
**if (data[x].Selected) {**
markup += "<option selected='selected' value=" + data[x].Value + ">" + data[x].Text + "</option>";
}
else
markup += "<option value=" + data[x].Value + ">" + data[x].Text + "</option>";
}
$('#autoModel').html(markup).show();
},
error: function (reponse) {
alert("error : " + reponse);
}
});
}
The Ajax call works correctly. However, the data that gets returned for the second dropdown contains a selected item and I'm trying to detect the selected item (via the 'if' statement), and render the HTML appropriately. The problem is that 'Selected' doesn't seem to be a property of 'data' because each value evaluates to false, even though one of the values is true.
Am I doing something wrong? Or is there a better way to do this?
The following is the controller code:
[HttpPost]
public ActionResult GetAutoModel(int manufacturerId, int autoSellerListingId)
{
int modelId = 0;
// Get all the models associated with the target manufacturer
List<AutoModel> modelList = this._AutoLogic.GetModelListByManufacturer(manufacturerId);
// If this is an existing listing, get the auto model Id value the seller selected.
if (autoSellerListingId > 0)
modelId = this._systemLogic.GetItem<AutoSellerListing>(row => row.AutoSellerListingId == autoSellerListingId).AutoModel.AutoModelId;
// Convert all the model data to a SelectList object
SelectList returnList = new SelectList(modelList, "AutoModelId", "Description");
// Now find the selected model in the list and set it to selected.
foreach (var item in returnList)
{
if (item.Value == modelId.ToString())
item.Selected = true;
}
return Json(returnList);
}
Try this instead (add modelId to constructor of SelectList, and remove the foreach block):
// Convert all the model data to a SelectList object
SelectList returnList = new SelectList(modelList, "AutoModelId", "Description", modelId);
return Json(returnList);

django Javascript dropdown

Am new to programming in Python and Javascript and I have been learning Python for few months now and love it. I have been playing with django which is cool I was wondering how I can make this model work with a Iavascript. I'll like someone to explain as much as the code involved as I just what to have a full understanding of the process from django to Javascript.
I want to dynamically is CarModel.objects.filter(make ='somename') or just 'somename'.
This is a test model am using since its similar to the Javascript I use for tutorial from online (YouTube) the scripts is below as well:
class Make(models.Model):
name = models.CharField(max_length=50,blank=True,null = True)
#so so so so
class CarModel(models.Model):
name = models.CharField(max_length=50,blank=True,null = True)
make = models.ForeignKey(Make,blank=True,null = True)
Now how will you pass say something like this to your Javascript?
class Model(ModelForm):
make = forms.ModelChoiceField(queryset= Model.objects.none(), required=True)
def __init__(self, somemake,*args, **kwargs):
super(Model, self).__init__(*args, **kwargs)
self.fields['property'].queryset = Model.objects.filter(make = somemake)
class Meta:
model = Model
exclude= ('make')
<script type="text/javascript">
function populate(s1,s2){
var s1 = document.getElementById(s1);
var s2 = document.getElementById(s2);
s2.innerHTML = "";
if(s1.value == "Chevy"){var optionArray = ["|","camaro|Camaro","corvette|Corvette","impala|Impala"];
}
else if(s1.value == "Dodge"){
var optionArray = ["|","avenger|Avenger","challenger|Challenger","charger|Charger"];
} else if(s1.value == "Ford"){
var optionArray = ["|","mustang|Mustang","shelby|Shelby"];
}
for(var option in optionArray){
var pair = optionArray[option].split("|");
var newOption = document.createElement("option");
newOption.value = pair[0];
newOption.innerHTML = pair[1];
s2.options.add(newOption);
}
}
</script>
and html here
Choose Car Make:
<select id="slct1" name="slct1" onchange="populate(this.id,'slct2')">
<option value=""></option>
<option value="Chevy">Chevy</option>
<option value="Dodge">Dodge</option>
<option value="Ford">Ford</option>
</select>
Choose Car Model:
<select id="slct2" name="slct2"></select>
If you want to do in JS, this is how I would solve the problem.
First create a template that contains the following for the 2 select lists.
<html>
<head>
<script>
var json = {
"Chevy": ["chev1", "chev2", "chev3"],
"Dodge": ["dodge1", "dodge2", "dodge3"],
"Ford": ["ford1", "ford2", "ford3"]
};
function carMake () {
select = document.getElementById('slct1');
select.options.length = 0;
for(make in json) {
select.options[select.options.length] = new Option(make, make);
}
}
function carModel(sel) {
var car_make = sel.options[sel.selectedIndex].value
select = document.getElementById('slct2');
select.options.length = 0;
for(var i=0;i<json[car_make].length;i++) {
select.options[select.options.length] = new Option(json[car_make][i], i);
}
}
</script>
</head>
<body>
Choose Car Make:
<select id="slct1" onchange="carModel(this)"></select>
<script> carMake(); </script>
Choose Car Model:
<select id="slct2" name="slct2"></select>
</body>
</html>
The above JS will read in the JSON object and update the Car Make when ever the dynamically populated Car Model select field is changed.
To generate the JSON object using your supplied Model you need to do the following:
In the view.py file:
from <your-app>.models import Make
from <your-app>.models import Model
import json
json_dict = {}
for car_make in Make.objects.all():
json_dict[car_make] = Model.objects.filter(make=car_make)
json_data = json.dumps(json_dict)
Then you take json_data and and add that to your response render context.
Finally alter the above template so that the JS variable json will be rendered to contain the JSON object passed from the view to the template.
You don't need javascript to do some fancy dropdown. You can use Django Forms to do it for you. All you need is to provide forms.py some information about the choices that a user can make and you will have your form rendered without you having to do anything more.
Look at my forms.py to see how I have done it.
You should convert query set to list before using json.dumps otherwise it will give you an error which is "NOT JSON SERIALIZABLE"
from <your-app>.models import Make
from <your-app>.models import Model
import json
json_dict = {}
for car_make in Make.objects.all():
json_dict[car_make] = list(Model.objects.filter(make=car_make).value())
json_data = json.dumps(json_dict)

Categories