I am passing an object(model) in View where I have javascript code written. The object has certain properties that I want to access in javascript in order to create a drop down list from the values of those properties.
Here is my object:
public class TestObject
{
public BuildData ExteriorColor { get; set; }
public BuildData InteriorColor { get; set; }
}
and
public class BuildData
{
public List<ExteriorInteriorData> Data { get; set; }
public bool isInstalled { get; set; }
public BuildData()
{
Data = new List<ExteriorInteriorData>();
}
}
Now in the View I have an object of TestObject through ViewData and I want to populate the values present in List<ExteriorInteriorData> in a select list.
Basically I want to do something like this:
for (var i = 0; i < data.ExteriorColor.Data.length; i++) {
$("#Exterior_Color").append($("<option " + (i == 0 ? "selected" : "") + "></option>").val(data.ExteriorColor.Data[i].ColorName + ", " + data.ExteriorColor.Data[i].RgbValue).html(data.ExteriorColor.Data[i].ColorName));
}
So, How do I access the object TestObject present in Viewdata inside of Javascript?
if you are writing JavaScript in same view then you just need to convert your model object in js object using this code.
var jsModel = #Html.Raw(Json.Encode(Model))
if you want in external file then create an html element and set this model in data- field and get this model in js like this
View
<div data-JsObject="#Html.Raw(Json.Encode(Model))" id="JSOBJ"> </div>
JS External file
var list = JSON.parse($("#JSOBJ").data("JsObject"))
I hope it'll work for you.
except of javascript you can use defualt razor helper for create dropdownlist :
#Html.DropDownListFor(model => model.ExteriorColor.Data, new SelectList(Model.ExteriorColor.Data, "Value", "Text"))
repale Value and Text By properties in ExteriorInteriorData
Try this. Use for loop within the tag.
#model [yourproject].Models.TestObject
<select id="Exterior_Color" name="Exterior_Color">
#foreach (var item in this.Model.ExteriorColor)
{
<option value="#item.RgbValue">#item.ColorName</option>
}
</select>
You can simply get selected item from javasrcipt
$("#Exterior_Color").val();
Related
How do I store a Model in a hidden input and access it in my javascript function?
I am storing the model in a hidden field as
string defaultFareListJson =
Newtonsoft.Json.JsonConvert.SerializeObject(#Model.DefaultFare);
#Html.Hidden("DefaultFareList", defaultFareListJson);
And in my Javascript function, I am trying to access it as:
function viewDefaultFareSchedule() {
var defaultFareObject = {}
defaultFareObject.Fares = jQuery.parseJSON($('#DefaultFareList').val());
alert(defaultFareObject.Fares[0].facility);
}
My ViewModel is as follows:
public class NavBarCallerViewModel
{
public FareSchedViewModel DefaultFare { get; set; } = new FareSchedViewModel();
}
public class FareSchedViewModel {
public string facility{get;set;}
}
NH
I was able to parse a hidden JSON string("DefaultFareList": converted from Model) as :
var defaultFareString = document.getElementById('DefaultFareList').value;
var defaultFare = JSON.parse(defaultFareString);
I am rendering my form using razor. I iterate over class .control_group that's inside a form and create objects that I need to send back to controller. My form has checkboxes and hidden input values. Problem I am facing now is this. Checkbox elements rendered by razor have two inputs, one is hidden and other one is shown. When I collect form data I am always getting last input value (hidden one, and it's always false) How can I get the true value?
Current data sent to controller (everything is false):
{"ajaxData":[{"Id":"1","RoleId":"1","R":"false","W":"false","E":"false","D":"false"},{"Id":"2","RoleId":"2","R":"false","W":"false","E":"false","D":"false"}]}
Collecting data like this (found similar problem here on SO):
var ajaxData = $('.control_group').map(function (i, group) {
var data = {};
$(group).find(':input').each(function () {
data[this.name] = this.value;
});
return data;
}).get();
ajaxData = JSON.stringify({ 'ajaxData': ajaxData });
console.log(ajaxData);
Controller looks like this:
public void SendData(List<SomeClass> ajaxData)
{
var data = ajaxData;
}
public class SomeClass
{
public int Id { get; set; }
public int RoleId { get; set; }
public bool R { get; set; }
public bool W { get; set; }
public bool E { get; set; }
public bool D { get; set; }
}
It is by design, you can read about this here: asp.net mvc: why is Html.CheckBox generating an additional hidden input
I can suggest you while iterating the elements do the following
if the form has another element with the same name, and it is not check box, skip it.
this way you can just collect the correct fields.
I am most certainly sure that you can handle this with JQUERY, if not, post a JSFIDDLE so we can help you.
Razor syntax always creates a hidden field for radio button & checkbox. You can change your :input selector to :input:checkbox to do your task.
var ajaxData = $('.control_group').map(function (i, group) {
var data = {};
$(group).find(':input:checkbox').each(function () {
data[this.name] = this.value;
});
return data;
}).get();
ajaxData = JSON.stringify({ 'ajaxData': ajaxData });
console.log(ajaxData);
I'm trying to dynamically create hidden fields for a set of properties, but I'm getting a 500 server error when I submit the form. I confirmed the following:
The properties I'm iterating over in the foreach statement are correct.
property.Name is a valid property name for the type retrieved by NewItem.GetType()
Here's what I have:
View
#model PaneViewModel
using (Ajax.BeginForm("AddItem", "Action", new AjaxOptions
{
UpdateTargetId = "tool-wrapper",
HttpMethod = "POST",
}))
{
// Some standard input fields here (these are working properly).
[...]
// Here's what's broken:
#foreach (var property in Model.NewItem.GetType().GetProperties().Where(<criteria here>))
{
#Html.HiddenFor(m => m.NewItem.GetType().GetProperty(property.Name), column.GetValue(Model.NewItem, null))
}
<button type="submit">Add</button>
}
ItemViewModel
public class ItemViewModel
{
public int SomeField { get; set; }
public int AnotherField { get; set; }
}
PaneViewModel
public class PaneViewModel
{
public ItemViewModel NewItem { get; set; }
}
Controller
[HttpPost]
public ActionResult AddItem([Bind(Prefix = "NewItem")] ItemViewModel model)
{
// Stuff here.
}
It's worth noting that the following generates the hidden fields with the correct names and values in the generated HTML, but the values of the hidden field aren't posted to the controller action:
#foreach (var property in Model.NewItem.GetType().GetProperties().Where(<criteria here>))
{
#Html.Hidden(property.Name, column.GetValue(Model.NewItem, null))
}
So it seems the problem is with the m => m.NewItem.GetType().GetProperty(property.Name) component
This type of logic does not belong in a view
Html.HiddenFor() expects an expression (Expression<Func<TModel,
TProperty>>) as the first parameter, but .GetProperty() returns
typeof PropertyInfo
You should not be generating multiple hidden inputs for properties
of your model, but rather use a view model to represent only what
you need to edit (it degrades performance by sending extra data to
the client and then posting it back again unchanged, and anyone
could use FireBug or similar tools to change the values and you
might be none the wiser.
However, if you do want to do this, the you could create a html helper that generates hidden inputs for all properties marked with the [HiddenInput] attribute (or modify this example to pass in some condition that filters the required properties)
public static MvcHtmlString HiddenForModel<TModel, TValue>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TValue>> expression)
{
StringBuilder html = new StringBuilder();
ModelMetadata metaData = ModelMetadata.FromLambdaExpression(expression, helper.ViewData);
var properties = metaData.Properties.Where(p => p.TemplateHint == "HiddenInput");
foreach(var property in properties)
{
html.Append(helper.Hidden(property.PropertyName));
}
return MvcHtmlString.Create(html.ToString());
}
Note this will also generate the id and data-val-* attributes which are probably unnecessary, so you could minimize the generated html by using
foreach(var property in properties)
{
TagBuilder input = new TagBuilder("input");
input.MergeAttribute("type", "hidden");
input.MergeAttribute("name", property.PropertyName);
input.MergeAttribute("value", string.Format("{0}", property.Model));
html.Append(input.ToString());
}
I have this modelView
public class Ue
{ public class uEkranModel
{
public List<Grup> Grup = new List<Grup>();
private List<Secim> _secim;
public List<Secim> secim
{
get
{
if (_secim == null)
_secim = new List<Secim>();
return _secim;
}
set { _secim = value; }
}
}
public class Secim
{
public Guid uGuid { get; set; }
public Guid fGuid { get; set; }
}
}
I need to fell the List secims items with JS and post it back to controller.
I have tried to :
1)initialize the list in the controller :
Controller :
gidecek.Data = new Models.Ucak.UcakDeneme.uEkranModel();
gidecek.Data.secim.Add(new Models.Ue.Secim { uGuid = new Guid() });
gidecek.Data.secim.Add(new Models.Ue.Secim { uGuid = new Guid() });
View :
#using (Html.BeginForm("deneme", "U", FormMethod.Post, new { id = "secimTamam", style = "display:none" }))
{
#Html.EditorFor(m => m.Data.secim[0])
#Html.TextBoxFor(m => m.Data.secim[0].uGuid, new {id="gidis" })
}
JS :
$("#Data_secim_0__ucusGuid").attr("value", index);
This way , when the code is executed the value field of the textboxfor is changed(when the JS fired) but when I check the post data in controller , it is NULL.
also tried :
$("#Data_secim_0__ucusGuid").val(index);
which doesnt cahnge the value of teh textbox.
What I need is to fill the model values with js and post the form with js as well.(The data user is selecting is different, I am just posting back the GUID of the items within a form.)
2 possible issues. Your getter is initializing a new List<Secim>. Try initializing it in the constructor
public class uEkranModel
{
public uEkranModel()
{
secim = new List<Secim>();
}
public List<Secim> secim { get; set;}
....
}
Also I have seen other posts on SO indicating problems posting back GUID's (and one solution that was accepted was to use a view model with the GUID's converted to strings)
I want to use my ViewBag in JavaScript array. I follow using viewbag with jquery asp.net mvc 3, and I think the following code is what I am looking for,
#model MyViewModel
<script type="text/javascript">
var model = #Html.Raw(Json.Encode(Model));
// at this stage model is a javascript variable containing
// your server side view model so you could manipulate it as you wish
if(model.IsLocal)
{
alert("hello " + model.FirstName);
}
</script>
But this code causes error for Json.Encode, then I add System.Runtime.Serialization.Json, but It also cause error for Encode, says no method for Encode, I already include Newtonsoft.Json, but still no result.
My ViewBag data ::
public ActionResult Dashboard()
{
ViewBag.inc = (from inc in db.Incident select inc.Title).ToList();
return View();
}
And I want to use this ViewBag.inc data in JavaScript array
As you said, you are already referencing the Newtonsoft Json.Net library, you can use this following code::
var inc = '#Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(ViewBag.inc))';
inc= JSON.parse(inc);
$.each(inc, function(index, data) {
//you next code
});
The snippet you are using does not use the ViewBag, but the Model. Regardless, if you want to print the serialisation of an object to the view, and you are already referencing the Newtonsoft Json.Net library (as you said you are), then you can do the following:
var model = #Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(Model));
If you want to use the item in the ViewBag instead, you can do:
var model = #Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(ViewBag.inc));
You can use like for ViewBag -
var mn = #{#Html.Raw(Json.Encode(ViewBag.ViewBagProperty));}
alert(mn.YourModelProperty);
And for Model -
var mn = #{#Html.Raw(Json.Encode(Model));}
alert(mn.YourModelProperty);
There is no need for NewtonSoft.Json, we can use default System.Web.Helpers.Json.
Update: Here goes the complete solution with Model, the same concept can be used with ViewBag too -
Lets say you have this Model -
public class XhrViewModel
{
public string data1 { get; set; }
public string data2 { get; set; }
}
Then in the controller action you are constructing the List of above Model in following way -
public ActionResult GetData()
{
List<XhrViewModel> model = new List<XhrViewModel>();
model.Add(new XhrViewModel() { data1 = "Rami", data2 = "Ramilu" });
return View(model);
}
Then on the View, you can have something like this -
#model IEnumerable<Rami.Vemula.Dev.Mvc.Controllers.XhrViewModel>
#{
ViewBag.Title = "GetData";
}
<h2>GetData</h2>
<script type="text/javascript">
var mn = #{#Html.Raw(Json.Encode(Model));}
alert(mn[0].data1);
</script>
And when you execute the page -