Okay so I'm working with MVC4 in C# and I have to fill a javascript array with elements from the view's model. I'm trying to dynamically populate a Chart.js pie chart. This is my example code:
<script src="~/Scripts/Chart.js"></script>
<script type="text/javascript">
var data = [
{
value: 30,
color: "#F38630"
},
{
value: 50,
color: "#E0E4CC"
},
{
value: 100,
color: "#69D2E7"
}
]
//Get the context of the canvas element we want to select
var ctx = document.getElementById("myChart").getContext("2d");
var myNewChart = new Chart(ctx).Pie(data);
//Get context with jQuery - using jQuery's .get() method.
var ctx = $("#myChart").get(0).getContext("2d");
//This will get the first returned node in the jQuery collection.
var myNewChart = new Chart(ctx);
new Chart(ctx).Pie(data, options);
</script>
I want to be able to add elements to the data array in a for loop. I tried using .push like this
data.push([{
value: 30,
color: "#F38630"
}]);
But it stops the chart from being created entirely. Any idea how I can do something like:
foreach (var item in Model.List) {
data.add(item.value)
}
You can be even more awesome than that.
Create your own basic type to represent you Value/Color pair.
public class MyType
{
public string Value {get;set;}
public string Color {get;set;}
}
In your razor (or code behind) create an array for that type:
#{
var values = new List<MyType>();
// populate with some values.
JavaScriptSerializer js = new JavaScriptSerializer();
string json = js.Serialize(keyValues.ToArray());
}
Then in your Javascript:
<script type="text/javascript">
var data = #json; // TADA!!
//Get the context of the canvas element we want to select
var ctx = document.getElementById("myChart").getContext("2d");
var myNewChart = new Chart(ctx).Pie(data);
//... etc.
</script>
If you come across any problems serializing that list, I recommend using Json.Net to improve C# native serializers.
Your data is an array (see the brackets []).
Now you try to add an array with a single object to the array:
[{ value...
Just change it to an object {} and you will be fine.
{ value ... }
Related
I have a graph in my view which looks like this:
var hourlyGraph = Morris.Bar({
element: 'graph_bar',
data: [
#foreach (var item in ViewBag.HourlyGraph)
{
#:{device: '#item.Hour.ToString("D2"):00', geekbench:#item.Sales },
}
],
xkey: 'device',
ykeys: ['geekbench'],
labels: ['Sold'],
barRatio: 0.4,
barColors: ['#0A4D70', '#34495E', '#ACADAC', '#3498DB'],
xLabelAngle: 35,
hideHover: 'auto',
resize: true
});
This is a morris chart. Note how the data is set up here:
[
#foreach (var item in ViewBag.HourlyGraph)
{
#:{device: '#item.Hour.ToString("D2"):00', geekbench:#item.Sales },
}
]
And now I need to fill the chart with new data. In my Action I have created a list which contains 2 properties:
public int Hour {get;set;}
public int Sales {get;set;}
And they are stored into a list typed of:
var HourlyGraph = new List<HourlyGraph>();
Now I'd like to convert this list into a JSON format which would look something like this:
[
{device: '0', geekbench:5 },
{device: '1', geekbench:13 },
{device: '2', geekbench:25 },
{device: '3', geekbench:14 },
{device: '4', geekbench:16 },
]
Where value for device would be = hour, and geekbench = sales ...
How could I do this in C#?
With Json.Net and Linq it's easy:
string myJson =
JsonConvert.SerializeObject(mylist.Select(item=>
new {device=item.Hour, geekbench=item.Sales}));
You project an anonymous type with the fields and names that you'd like, and let Newtonsoft.Json do the rest.
since you are using mvc why not use return Json() it will convert the object to json string you can use it like
public ActionResult Myaction()
{
var HourlyGraph = new List<HourlyGraph>();
return Json(HourlyGraph.Select(x => new {Hour=x.Hour,Sales=x.Sales }));
}
You can achieve the desired output by using LINQ Anonymous Type
As per example following is class
public class HourlyGraph
{
public int Hour { get; set; }
public int Sales { get; set; }
}
Import Namespace System.Web.Script.Serialization which is a Microsoft's Inbuilt Class for dealing with JSON. You will need to refer additional assembly named System.Web.Extensions using 'Add References'.
using System.Web.Script.Serialization;
Declare List and Convert into customized JSON Format
var listHourlyGraph = new List<HourlyGraph>();
//Adding some Sample Values
listHourlyGraph.Add(new HourlyGraph() { Hour = 0, Sales = 5 });
listHourlyGraph.Add(new HourlyGraph() { Hour = 1, Sales = 10 });
//Declaring JavaScriptSerialzer Object
var serialzer = new JavaScriptSerializer();
//Using Serialize Method which returns back a JSON String
//We are using LINQ SELECT Method to create a new anonymous return type which contains our custom return types
string s = serialzer.Serialize(listHourlyGraph.Select(x => new { device = x.Hour, geekbench = x.Sales } ));
You will get the following output in 's' variable
[{"device":0,"geekbench":5},{"device":1,"geekbench":10}]
Note: If you want to get performance optimizations then you are better using Newtonsoft JSON Library instead of Microsoft's Default JSON Library.
I have following input field.
<input class="book_now_modal BClick" type="text" id="destinationFrom_modal" name="destinationFrom_modal" placeholder="#ViewBag.AmritsarList[0].Destination">
time to time I want to change the value inside the view bag.is there a way to give dynamic value to the viewbag item.I have tried with jquery as below.
$(".AClick").click(function () {
//$(".BClick").attr("placeholder"," ");
var s = parseInt($(this).attr('id'));
var neededVAl = "##ViewBag.AmritsarList"+"["+s+"]"+".Destination";
alert(neededVAl);
var b = $(".BClick");
$(this).attr("placeholder",neededVAl);
});
like this I replace the placeholder as an alert it gives #ViewBag.AmritsarList[1].Destination but it didn't change the placeholder.how can I do that.
var neededVAl = "##ViewBag.AmritsarList"+"["+s+"]"+".Destination";
You can't access the ViewBag using above statement, since it accessible on server side. Your JavaScript statement is executed on the client side and can't directly access it.
However, You can use Json.Encode Method converts a data object to a string that is in the JavaScript Object Notation (JSON) format.
var jsObject = #Html.Raw(Json.Encode(ViewBag.AmritsarList));
$(".AClick").click(function () {
var s = parseInt($(this).attr('id'));
var neededVAl = jsObject[s].Destination;
alert(neededVAl);
$(this).attr("placeholder",neededVAl);
});
I'm serializing my model:
<script type="text/javascript">
var Model = '#Model.ToJson()';
</script>
the ToJson is an extension method:
public static string ToJson(this object obj)
{
var serializer = new JavaScriptSerializer();
var val = serializer.Serialize(obj);
return val;
}
Now I want to access my model in other javascript files by doing:
var hello = Model.id;
The problem is that it doesn't serialize correctly when I use '#Model.ToJson()' because of the quotes.
The serialized object looks like this:
var Model = "{ "id": "2231f87c-a62c-4c2c-8f5d-b76d11942301" }";
But in order for me to access id by Model.id it should look like this:
var Model = { "id": "2231f87c-a62c-4c2c-8f5d-b76d11942301" };
How can I enter razor syntax without quotes? Using asp.net syntax I think it's:
var Model = <%=Model.ToJson() %>
How do I do the same with razor? Thanks!
If you use this JSON plugin you can do it all on the client and simply things. If you push up a JSON string, in javascript you could then do:
<script type="text/javascript">
var Model = JSON.parse("#Model.JsonString");
</script>
Since Razor by default escapes out the quotes, you need to use Html.Raw:
var Model = #Html.Raw(Model.ToJson());
It will turn that into:
var Model = {"id":"whatever"};
which is valid javascript.
I have a Dictionary in my view, there are
[inputID, tooltip].
Also i have a set of id's of my input elements in this page.
I need to iterate through the dictionary with my elements ids:
#{
Dictionary<string, string> questionMarks =
ViewBag.QuestionMarks as Dictionary<string, string>;
#}
<script type="java-script">
$(document).ready(function () {
var inputs = $('input,select[type!="hidden"]');
$.each(inputs, function(i, val) {
if ($(val).attr('id')) {
var id = $(val).attr('id');
var iter_string = '#questionMarks' + "[" + id + "]";
alert(iter_string); // [1]
alert('#questionMarks["cvc"]'); // here i got tooltip
}
});
</script>
[1] i have System.Collection.Generic.Dictionary`2[System.String, System.String][cvc]
Thanks to Jan Jongboom,
Finally i got that i wanted:
#using System.Web.Script.Serialization
#{
Dictionary<string, string> questionMarks = ViewBag.QuestionMarks as Dictionary<string, string>;
JavaScriptSerializer jss = new JavaScriptSerializer();
#}
<script type="text/javascript">
var questionMarks = #Html.Raw(jss.Serialize((Dictionary<string, string>)ViewBag.QuestionMarks));
$(document).ready(function () {
for ( keyVar in questionMarks ) {
$('#' + keyVar).attr('original-title', questionMarks[keyVar]);
$('#' + keyVar).tipsy({ gravity: 'w' });
}
});
</script>
Do something like
<script>
var questionMarks = #new JavaScriptSerializer().Serialize((Dictionary<string, string>)ViewBag.QuestionMarks) ;
</script>
Now you have a javascript variable called questionMarks that you can iterate over.
No, you can't iterate from the client side code through server variable. You can generate initialization code from JS variable (like JSON) or generate necessary html on the server side. Also you can requests for such data on from jsavascript via ajax request.
Attatching data attributes to the inputs as they are drawn should help you with this one.
Example: http://jsfiddle.net/Krch9/
$(document).ready(function(e) {
var inputs = $("input", "#container");
$.each(inputs, function(i, val) {
var ToolTipText = $(this).data('tooltiptext');
/// Run your tooltip plugin here ...
$("#output").html($("#output").html() + "<br>" + $(this).attr('id') + " : " + ToolTipText);
});
});
Using MVC helpers you can easily add them:
#Html.TextBoxFor(x => x.Field, new { data_tooltiptext = "Blah blah"});
The markup would end up looking something like this:
<input type="text" id="Field" data-tooltiptext="Blah blah">
Edit: Extra help
I.E Loop through your elements
foreach( var question in questionMarks) {
#Html.TextBox(question.Key, new { data_tooltiptext = question.Value} );
}
Then use the javascript example (Youll need to modify it to your needs ...) to run the plugin on the elements
To remove the quotes, use Html.Raw()
var questionMarks = '#Html.Raw(jss.Serialize((Dictionary<string, string>)ViewBag.QuestionMarks))';
I want to pass values from the VIEWBAG as an array of LatLons from my Model in C#. I am not sure how to dynamically loop the Viewbag array and add these cordinates to my javascript array to pass to:
// Create an instance of Google map
var map = new GMap2(document.getElementById("map"));
// Tell the map where to start
map.setCenter(new GLatLng(59.3324, 17.8857), 9);
// Create an array with points
var points = [
new GLatLng(59.6919, 17.8582),
new GLatLng(59.3030, 18.0395),
new GLatLng(58.9789, 17.5341)
];
// Create a new polyline
var polyline = new GPolyline(points, '#ff0000', 5, 0.7);
// Add the polyline to the map using map.addOverlay()
map.addOverlay(polyline);
I want to do something like the above, but without the static array.
Thanks in advance!
EDIT:
currently I have:
var points = [];
#foreach (var item in ViewBag.LatLons)
{
<text>
points.push(new GLatLng(#item.Latitude, #item.Longitude);
</text>
}
But the google map will not show up when this is added, However the points are correctly iterated through from the viewbag data.
Instead of the ViewBag, if you were to use a view model, you could use something like the following:
// Create an array with points
var points = [];
<% foreach (var item in Model.Coords)
{%>
points.push(new GLatLng(<%= item.lat %>, <%= item.lng %>));
<%} %>
which should output into your view as:
var points = [];
points.push(new GLatLng(59.6919, 17.8582));
points.push(new GLatLng(59.3030, 18.0395));
points.push(new GLatLng(58.9789, 17.5341));
//...et cetera
The view data is inherently an object and doesn't support an iterator, so you would have to cast. This saves the need for the cast in the view by having a typed collection. This example could use a simple model like this:
public class CoordsModel
{
public List<CoOrd> Coords {get; set;}
}
public class CoOrd
{
public decimal lat {get; set;}
public decimal lng {get; set;}
}