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

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)

Related

How can I populate a dropdownlist based on the selected value of another dropdownlist? MVC

I am currently trying to populate the values for a car's model based on the selected make in a dropdownlist. I am new to coding so I am not sure what my mistake is. The project doesn't give me any errors but no values are displayed when I selected the make.
This is my Partial View that I am adding into my Create View.
#model IgnitionHubPractice.Models.MakeModelDorpdownView
<div class="form-horizontal">
<div class="form-group">
#if (ViewBag.MakeList != null)
{
#Html.DropDownListFor(m => m.MakeID, ViewBag.MakeList as SelectList, "--Select Make--", new { #class = "form-control" })
}
</div>
<div class="form-group">
#Html.DropDownListFor(m => m.ModelID, new SelectList(" "), "--Select Model--", new { #class = "form-control" })
</div>
</div>
<script>
$(document).ready(function () {
$("#MakeID").change(function () {
$.get("/Cars/GetModelList",{ MakeID: $("MakeID").val() }, function (data) {
$("#ModelID").empty();
$.each(data, function (index, row) {
$("#ModelID").append("<option value ='" + row.ModelID + "' >" + row.Name + </option>")
});
});
})
});
</script>
This is my controller
public ActionResult Create([Bind(Include = "CarID,Year,Color,Mileage,Cost,MarketValue,BodyType,Drive,Notes,Available,VinNumber,CarLotID,ModelID")] Car car, [Bind(Include ="MakeID,Name")] Make make)
{
if (ModelState.IsValid)
{
db.Cars.Add(car);
db.SaveChanges();
return RedirectToAction("Index");
}
List<Make> MakeList = db.Makes.ToList();
ViewBag.MakeList = new SelectList(db.Makes, "MakeID", "Name", make.MakeID);
ViewBag.ModelID = new SelectList(db.Models, "ModelID", "Name", car.ModelID);
ViewBag.CarLotID = new SelectList(db.CarLots, "CarLotID", "LotName", car.CarLotID);
return View(car);
}
public JsonResult GetModelList(int MakeID)
{
db.Configuration.ProxyCreationEnabled = false;
List<Model> ModelList = db.Models.Where(x => x.MakeID == MakeID).ToList();
return Json(ModelList, JsonRequestBehavior.AllowGet);
}
Please help, thanks in advance.
In MVC you try to create a cascading drop down. So for easy understanding you can check the below link. It contanin detailed information for controller and View with Jquery part.
Please visit this link: Cascading Drop down List With MVC And AJAX

How to marked checkbox in function jquery

I have a listbox in view.
This Listbox use template
Listbox
<div id="UsersLoad" style="width: 50%">
#Html.EditorFor(i => i.Users, "UsersForEdit")
</div>
Template UserForEdit (Part of the code)
#model string[]
#{
if (this.Model != null && this.Model.Length > 0)
{
foreach(var item in this.Model)
{
listValues.Add(new SelectListItem { Selected = true, Value = item, Text = item });
}
}
else
{
listValues = new List<SelectListItem>();
}
}
<div class="field-#size #css">
<h3>#Html.LabelFor(model => model):</h3>
#Html.ListBoxFor(model => model, listValues, new { id = id })
</div>
In another view div "Users" is called.
function LoadUsersCheckBox() {
$("#UsersLoad").load('#Url.Action("LoadUsers", "User")' + '?idUser=' + idUser);
}
LoadUsers Controller
public JsonResult LoadUsers(int? idUser)
{
var users = Service.GetSystemUsers(idUser);
var model = users.Select(x => new
{
Value = x,
Description = x
});
return this.Json(model, JsonRequestBehavior.AllowGet);
}
The controller method returns what I want.
But instead of it select the items in the listbox it overwrites the listbox with only the text of found users.
How to mark the items in the listbox on the function LoadUsersCheckBox?
Sorry for my bad English
The jQuery load() method "loads data from the server and places the returned HTML into the matched element." Note the words "the returned HTML". See http://api.jquery.com/load/
To select existing items, you should try get() instead (http://api.jquery.com/jQuery.get/). In the success callback handler, you will need to parse the returned data to an array. Then use an iterator to go over the items in the listbox, and if they exist in the parsed array, mark them as selected. Something like:
$.get("action url", function(data) {
var users = $.parseJSON(data);
$("#UsersLoad option").each(function() {
var opt = $(this),
value = opt.attr("value");
opt.removeAttr("selected");
if (users.indexOf(value) > -1) {
opt.attr("selected", "selected");
}
});
});

How to mix C# with javascript for changing html?

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

How to create Telerik MVC Combobox via JavaScript

I want to implement the ability to dynamically add comboboxes and I have to use Telerik ComboBox for that. I put this logic into button click.
$('#add-presenter').click(function (e) {
e.preventDefault();
var combobox = '#(Html.Telerik().ComboBox()
.Name("Presenters[" + (Model.Count) + "]")
.BindTo(new SelectList(LeaderList, "ID", "Value"))
.ClientEvents(ev => ev.OnChange("onSelect"))
.DataBinding(bnd => bnd.Ajax().Select("_LoadJournalist", "MonitoringFRadio"))
.Filterable(filter => filter.FilterMode(AutoCompleteFilterMode.StartsWith))
.HtmlAttributes(new { style = "width:320px;vertical-align:middle;" }))';
combobox = combobox.split('Presenters[' + index + ']').join('Presenters[' + (index + 1) + ']');
index++;
$('#presenters-block').append(combobox);
}
This code renders in browser as this:
$('#add-presenter').click(function (e) {
e.preventDefault();
var combobox = '<div class="t-widget t-combobox t-header" style="width:320px;vertical-align:middle;"><div class="t-dropdown-wrap t-state-default"><input class="t-input" id="Presenters[0]-input" name="Presenters[0]-input" type="text" /><span class="t-select t-header"><span class="t-icon t-arrow-down">select</span></span></div><input id="Presenters[0]" name="Presenters[0]" style="display:none" type="text" /></div>';
combobox = combobox.split('Presenters[' + index + ']').join('Presenters[' + (index + 1) + ']');
index++;
$('#presenters-block').append(combobox);
combobox = $('#Presenters\\['+index+'\\]').data('tComboBox');
});
The problem is in data-binding. This code generates proper HTML, but newly added list doesn't "drop"
When I do combobox = $('#Presenters\\['+index+'\\]').data('tComboBox'); for newly added item I get undefined (it exists, but data isn't set), so combobox.dataBind(dataSource) approach doesn't work.
Ok, I tried, but failed to do this without postback. Here's rough solution to the problem: do ajax request and replace content with partial view:
The Partial view:
#model List<int>
#{
var LeaderList = ViewData["LeaderList"] as List<ListItem>;
}
<div id="presenters-ajax-wrapper">
<div id="presenters-block">
#(Html.Telerik().ComboBox()
.Name("Presenters[0]")
.BindTo(new SelectList(LeaderList, "ID", "Value"))
.ClientEvents(ev => ev.OnChange("onSelect"))
.DataBinding(bnd => bnd.Ajax().Select("_LoadJournalist", "MonitoringFRadio"))
.Filterable(filter => filter.FilterMode(AutoCompleteFilterMode.StartsWith))
.HtmlAttributes(new { style = "width:320px;vertical-align:middle;" }))
#for(int i=1; i<Model.Count; i++)
{
var item = LeaderList.FirstOrDefault(l => l.ID == Model[i]);
var value = item != null ? item.Value : "";
#(Html.Telerik().ComboBox()
.Name("Presenters[" + i + "]")
.Value(value)
.BindTo(new SelectList(LeaderList, "ID", "Value"))
.ClientEvents(ev => ev.OnChange("onSelect"))
.DataBinding(bnd => bnd.Ajax().Select("_LoadJournalist", "MonitoringFRadio"))
.Filterable(filter => filter.FilterMode(AutoCompleteFilterMode.StartsWith))
.HtmlAttributes(new { style = "width:320px;vertical-align:middle;" }))
}
</div>
<button id="add-presenter" class="t-button">+</button>
<script type="text/javascript">
var index = #(Model.Count == 0 ? 0 : Model.Count-1);
$('#add-presenter').click(function (e) {
e.preventDefault();
index++;
var msg = $('#monitForm').serialize();
$.ajax({
url: '#Url.Action("_GetPresenters","MonitoringFRadio")'+'?count='+(index+1),
data: msg,
type: 'POST',
success: function(data) {
$('#presenters-ajax-wrapper').html(data);
}
});
});
</script>
</div>
Action:
[HttpPost]
public virtual ActionResult _GetPresenters(EditableMonitoring model, int count)
{
//some logic here...
return PartialView("EditorTemplates/Presenters", model.Presenters);
}
Well, probably it would be better to create another partial view which would render a single combobox, instead of redrawing all of them...

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

Categories