Serialize Collection To JavaScript - c#

I want to return serialized collection from code behind C# to javascript metod and then this javascript method to iterate normal all elements. I did this but the elements are iterated like normal string characters.
public string Alerts()
{
JavaScriptSerializer serializer = new JavaScriptSerializer();
IList<string> alerts = new List<string>();
alerts.Add("1");
alerts.Add("2");
string[] arrays = new string[] { "1", "2", "3" };
return serializer.Serialize(arrays);
}
<script type="text/javascript">
window.onload = function () {
alerts('<%= this.Alerts() %>');
};
</script>
I want the return value when iterates in js to be first index 1 second 2 thrit 3 etc. This here is not working normal.

You're encoding the serializer output:
public string Alerts()
will return
["1","2","3"]
When you go
alerts('<%= this.Alerts() %>');
You're saying
alerts('["1","2","3"]');
So skip the single quotes and you should be fine.

Try this
<script type="text/javascript">
window.onload = function () {
var arr = <%= this.Alerts() %>;
for (var i in arr)
alert(arr[i]); // Iterate over each element in array returned from C# code
};
</script>

Include jquery and try this
<script type="text/javascript">
window.onload = function () {
var arr = <%= this.Alerts() %>;
var arrList = JSON.parse(arr);
console.log(arrList);
};
</script>

Related

A Better way to get these JSON values from properties of a Class?

I need to grab specific variables from a Class called, Header. I have a List<Header> of all of these classes, and am currently doing it this way:
protected string _HrefsJson = string.Empty;
protected string _OnClicksJson = string.Empty;
protected string _TargetsJson = string.Empty;
protected string _TitlesJson = string.Empty;
protected string _CaptionsJson = string.Empty;
List<Header> _HomeHeaderList = _Home.HeaderList.FindAll(u => !string.IsNullOrEmpty(u.MobileImage));
IEnumerable<string> _Titles = _HomeHeaderList.Select(u => u.Title).ToList();
IEnumerable<string> _Captions = _HomeHeaderList.Select(u => u.Caption).ToList();
IEnumerable<string> _Targets = _HomeHeaderList.Select(u => u.LinkTarget).ToList();
IEnumerable<string> _OnClicks = _HomeHeaderList.Select(u => u.LinkOnClick).ToList();
IEnumerable<string> _Hrefs = _HomeHeaderList.Select(u => u.Link).ToList();
JavaScriptSerializer jss = new JavaScriptSerializer();
_TitlesJson = jss.Serialize(_Titles);
_CaptionsJson = jss.Serialize(_Captions);
_HrefsJson = jss.Serialize(_Hrefs);
_TargetsJson = jss.Serialize(_Targets);
_OnClicksJson = jss.Serialize(_OnClicks);
In my .ascx file, I am getting these strings like so, within a <script> tag:
var titles = <%=_TitlesJson %>,
captions = <%= _CaptionsJson %>,
hrefs = <%= _HrefsJson %>,
targets = <%= _TargetsJson %>,
onclicks = <%= _OnClicksJson %>;
Thing is, I need to Serialize these values to be passed into javascript as JSON Arrays, but I feel like I am creating to many strings, and doing too many Select Statements on the List here. Is there a way to simplify this for Performance and shorter code perhaps? Maybe a one-liner or close to it? I need to maintain index association, that is 0 to (_HomeHeaderList.Count - 1), so this is the only way I could think to do this. But it just seems sloppy to me.
The reason I need to maintain the indexes of each of these is because, in Javascript I am using these values of each index to write them as text.
Thanks
The values from the Json Arrays need to be inputted into this Html Structure:
<div class="mobile-text-wrapper" data-target="#mobileCarousel" role="overlay">
<div class="pnova-bold mobile-title"></div>
<div class="tisa-italic mobile-caption"></div>
</div>
<a class="mobile-overlay-link"></a>
The jQuery I'm using is like this:
<script>
var titles = <%=_TitlesJson %>,
captions = <%= _CaptionsJson %>,
hrefs = <%= _HrefsJson %>,
targets = <%= _TargetsJson %>,
onclicks = <%= _OnClicksJson %>,
slideIndex = 0;
jQuery(document).ready(function($) {
$(".mobile-title").text(titles[slideIndex]);
$(".mobile-caption").text(captions[slideIndex]);
$(".mobile-overlay-link").attr("href", hrefs[slideIndex]);
if (targets[slideIndex] != "")
$(".mobile-overlay-link").attr("target", targets[slideIndex]);
if (onclicks[slideIndex] != "")
$(".mobile-overlay-link").attr("onclick", onclicks[slideIndex]);
// On Slide Before
$('#mobileCarousel').bind('slide.bs.carousel', function (e) {
$(".mobile-text-wrapper").fadeOut("fast");
});
// On Slide After
$('#mobileCarousel').on('slid.bs.carousel', function (e) {
slideIndex = $('#mobileCarousel .active').index('#mobileCarousel .item');
$(".mobile-title").text(titles[slideIndex]);
$(".mobile-caption").text(captions[slideIndex]);
$(".mobile-overlay-link").attr("href", hrefs[slideIndex]);
if (targets[slideIndex] != "")
$(".mobile-overlay-link").attr("target", targets[slideIndex]);
if (onclicks[slideIndex] != "")
$(".mobile-overlay-link").attr("onclick", onclicks[slideIndex]);
$(".mobile-text-wrapper").fadeIn("slow");
});
});
</script>
Why not just serialise the List you're getting, then accessing each field in it?
JavaScriptSerializer jss = new JavaScriptSerializer();
_HomeHeaderJson = jss.Serialize(_HomeHeaderList);
Then in the .ascx file, you should be able to do:
var title = <%=_HomeHeaderJson[0].Title %>
Obviously, you'll need to add a loop in the ascx file to get each item in turn, but this approach keeps all the data together.
EDIT:
To update your javascript, you should be able to just use the slideIndex on the _HomeHeaderJson then get each field.
Eg.
var data = <%=_HomeHeaderJson %>
$(".mobile-title").text(data[slideIndex].Title);
$(".mobile-caption").text(data[slideIndex].Caption);
etc etc...

pass multiple lists to javascript using invokescript using c#

I use a webbrowser control to call a javascript function in a html file using InvokeScript(). I would like to pass four lists as parameters so I can use the data in the javascript function.
pseudocode:
List<string> list1 = new List<string>();
list1.Add("foo");
list1.Add("bar");
List<string> list2 = new List<string>();
list2.Add("foo");
list2.Add("bar");
List<string> list3 = new List<string>();
list3.Add("foo");
list3.Add("bar");
List<string> list4 = new List<string>();
list4.Add("foo");
list4.Add("bar");
maps_webbrowser.Document.InvokeScript("initialize", list1.ToArray(), list2.ToArray() ,list3.ToArray() ,list4.ToArray());
I have read a post where a list is passed using a argument variable
How should an array be passed to a Javascript function from C#?
Here's an example JavaScript function:
function foo()
{
var stringArgs = [];
for (var i = 0; i < arguments.length; i++)
stringArgs.push(arguments[i]);
// do stuff with stringArgs
}
And you'd call it from C# like this:
List<string> arguments = new List<string>();
arguments.Add("foo");
arguments.Add("bar");
webBrowser.InvokeScript("foo", arguments.ToArray());
However, in this way only one list is passed.
The pseudocode I've wrote down does not work....
After a good night of sleep I've basically got it working :)
According to the msdn an object array has to be passed as parameter:
http://msdn.microsoft.com/en-us/library/cc452443(v=vs.110).aspx
C# code:
List<string> lat_waypoints = new List<string>();
lat_waypoints.Add("1.11111");
lat_waypoints.Add("2.12112");
List<string> lon_waypoints = new List<string>();
lon_waypoints.Add("34.1234");
lon_waypoints.Add("34.2345");
string lat_string = string.Join(",", lat_waypoints.ToArray());
string lon_string = string.Join(",", lon_waypoints.ToArray());
Object[] objArray = new Object[2];
objArray[0] = (Object)lat_string;
objArray[1] = (Object)lon_string;
maps_webbrowser.Document.InvokeScript("test", objArray);
Javascript:
<HTML>
<SCRIPT>
function test(lat, lon) {
var lat_split = lat.split(",");
var lon_split = lon.split(",");
alert("Lat: " +lat_split[0] + " lon: " + lon_split[0]);
}
</SCRIPT>
<BODY>
</BODY>
</HTML>
This solution works but it is not the nicest solution in my opinion......
The lat and lon values are originally stored in an list with doubles. However, I don't know how to pass an array of doubles directly without converting it to string first.
Anyone else with some ideas?

Dynamically add objects to javascript array with Razor C#

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

How to enter Razor within Javascript without quotes in ASP.NET MVC

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.

Iterate over Dictionary with java-script selector

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

Categories