Timeline.js + MVC + JavaScript
I am having the following code on my view
#{
var objs = objstudent.Timelines.Where(x => x.StudentID == Sessions.objStudent.StudentID).AsQueryable();
}
<script type="text/javascript">
#{
#:var data = [];
foreach(Student.Models.Timeline student in objs)
{
#:data.push({start : new Date "#student.MeetingDate", content : "#student.Description" });
}
}
here I am trying to add details in data array which will be used for displaying details in timeline, but when I check data's value in browser it shows me undefined.
I have tried using but problem is same.
any solution ?
Never build javascript literals manually like this. Always use proper serializers. For example:
#{
var objs = objstudent.Timelines.Where(x => x.StudentID == Sessions.objStudent.StudentID).AsQueryable();
}
<script type="text/javascript">
var data = #Html.Raw(
Json.Encode(
objs.Select(x => new
{
start = x.MeetingDate,
content = x.Description
})
)
);
</script>
should end up with something along the lines of:
<script type="text/javascript">
var data = [
{ "start": "\/Date(1334655137358)\/", "content": "foo" },
{ "start": "\/Date(1334655137358)\/", "content": "bar" },
...
];
</script>
Notice that the DateTime fields are serialized using the /Date(Ticks) format. You could use various techniques to convert them to native javascript dates.
Related
I have a CSV file which needs to be converted into a Javascript object / JSON file. Doesn't really matter which since I'll be be handling the data in JS anyway and either is fine.
Data in csv:-
Name,Time,HeightOptions/WidthRange,HeightOptions/Options
EGBL,Today,12,12.13.14.15.16
,,26,12.13.14.15.16
Desired Output:-
{
Name:"EGBL",
Time:"Today",
HeightOptions : [
{WidthRange:"12",
Options:[12,13,14,15,16]},
{WidthRange:"26",
Options:[12,13,14,15,16]
}]
}
This is what I have came up with:
const CSV = (csv) => {
var attrs = csv.splice(0, 1);
console.log("attrsattrs", attrs);
var result = csv.map(function (row) {
var obj = {};
var rowData = row.split(",");
attrs[0].split(",").forEach(function (val, idx) {
obj = constructObj(val, obj, rowData[idx]);
});
return obj;
});
function constructObj(str, parentObj, data) {
if (str.split("/").length === 1) {
parentObj[str] = data;
return parentObj;
}
var curKey = str.split("/")[0];
if (!parentObj[curKey]) parentObj[curKey] = {};
parentObj[curKey] = constructObj(
str.split("/").slice(1).join("/"),
parentObj[curKey],
data
);
return parentObj;
}
console.log("resultresultresult", result);
};
But it returns like this:-
{
Name:"EGBL",
Time:"Today",
HeightOptions : [
{WidthRange:"12",
Options:"12.13.14.15.16"},
]
},{
Name:"",
Time:"",
HeightOptions : [
{WidthRange:"26",
Options:"12.13.14.15.16"
}]
}
So as you see code is reading through as rows and not combining in 1 object.
As far as possible I wish to have this done in vanilla JS without any other libraries.
Thanks folks.
Its the general way how the converter works. What you can do is, after getting the result in some JSON format, write another function that will convert to your final JSON format. Otherwise write your own CSV parser by reading it as raw text. Also you can play around by changing the csv format to different way so that you can get expected result (if possible).
I want to serialize a JSON string but when I pass JSON to view I see that my properties in code are in string format, that's probably why my code didn't work.
Serialization of my code in code behind:
var data = new ChartData
{
labels = new ChartLabels
{
labels = new string[3] {"Open", "Close", "Nothing"}
},
datasets = new ChartDatasets
{
data = new int[3] {20, 10, 3},
backgroundColor = new string[3] {"#ccf9d6", "#ccf9d6", "#ccf9d6"},
borderWidth = 1
}
};
var json = new JavaScriptSerializer().Serialize(data);
ScriptManager.RegisterStartupScript(
this,
GetType(),
"ServerControlScript",
"addChart(" + json + ");",
false);
And I want to use it in my JavaScript function:
function addChart(data) {
var ctx = document.getElementById("myChart");
var myChart = new Chart(ctx, data);
EDIT:
Json looks like below:
{"labels":
{
"fontSize":0,
"boxWidth":0,
"labels":["Open","Close","Nothing"]},
"datasets":{"label":null,"data":[20,10,3],
"backgroundColor":["#ccf9d6","#ccf9d6","#ccf9d6"],
"borderWidth":1
}
}
Is there any way to convert it to correct format? Or just put it to a JavaScript variable?
As stated on MDN,
The JSON.parse() method parses a JSON string, constructing the
JavaScript value or object described by the string.
Seeing as the addChart javascript method call is being executed, but is getting a string instead of the expected JSON object, that string has to be parsed.
Without knowing the broader context of the application it is hard to give a great answer as there are a few ways you could accomplish your goal. The simplest though would be to change the line "addChart(" + json + ");", to "addChart(JSON.parse(" + json + "));", so that when the application executes this javascript, the json string will be parsed by the javascript engine and made into a javascript object the addChart method is expecting.
I am not hip to the ScriptManager and I kind of like things to appear as I expect when I do my debugging in Chrome so this is how I would attack it using an asp:Literal on the page.
ASP Page:
<script src="assets/js/bootstrap.js" type="text/javascript">
</script>
<asp:Literal runat="server" ID="aspchartdata"></asp:Literal>
Code Behind:
var data = new ChartData
{
labels = new ChartLabels
{
labels = new string[3] {"Open", "Close", "Nothing"}
},
datasets = new ChartDatasets
{
data = new int[3] {20, 10, 3},
backgroundColor = new string[3] {"#ccf9d6", "#ccf9d6", "#ccf9d6"},
borderWidth = 1
}
};
aspchartdata.Text = "<script> var data=" + JsonConvert.SerializeObject(data); + "</script>";
Now you have a data variable in Javascript to use.
On the server side your literal is replaced by your new script to define the variable and now you can handle the onload running and such from within the ASPX page in a neat fashion.
Given the need to extract data from a viewdata into a javascript key/value object:
var stuff = {
something : [#someVar.Prop2, #someVar.Prop3, etc]
};
I want to make the key have the "name" of someVar.Prop1 so that:
var stuff = {
#someVar.Prop1 : [#someVar.Prop2, #someVar.Prop3, etc]
};
Yet when I use the form in the second code block above, I get a Expected identifier, string or number error at the colon:
#someVar.Prop1 : [#someVar.Prop2, etc]
---------------X (x marks the spot)
How do I need to format the razor code so that it knows what I'm trying to say?
You should definitely not be trying to build your JSON piece by piece in your Razor view. That can go wrong very easily.
To expand on #DLeh's answer, what you can do is build a dictionary of the values you want, serialize that into JSON right in your Razor view, and assign that to your variable as shown here:
#{
// Assume that someVar is provided from somewhere else;
// this is just for demonstration
var someVar = new { Prop1 = "My Prop", Prop2 = "Prop Value", Prop3 = 7 };
}
#{
var obj = new Dictionary<string, object>
{
{someVar.Prop1, new object[] { someVar.Prop2, someVar.Prop3 } }
};
}
<script>
var stuff = #Html.Raw(Json.Encode(obj));
</script>
Rendered output:
<script>
var stuff = {"My Prop":["Prop Value",7]};
</script>
You can surround razor expressions in quotes ' or " to have them output into a javascript block. If you need the type to be preserved properly, you can use methods like parseInt() or parseFloat() to do so.
Example:
var stuff = {
value1 : '#val1',
value2 : [ parseInt('#val2'), parseInt('#val3') ]
};
If you need to left side of the assignment to be variable, you will probably need to build a json string and then parse that into the object. Something like this, my quotes might be off.
var stuffJson = '{"#value1" : "#val1", "#value2" : "[ #val2, #val3 ]" }';
var stuff = JSON.parse(stuffJson);
If you're doing this a lot, you might want to consider using the Json() method in your controller to help you build these more easily. You could build a dictionary of key / value and have that output json:
public virtual ActionResult GetStuff()
{
string value1 = "key1",
value2 = "key2",
val1 = "str1",
val2 = "str2",
val3 = "str3";
var dict = new Dictionary<string, object>
{
{ value1, val1},
{ value2, new List<string> { val2, val3} },
};
return Json(dict, JsonRequestBehavior.AllowGet);
}
Output:
{"key1":"str1","key2":["str2","str3"]}
The answer is to ignore Visual Studio's complaint of the problem as the code runs and throws no error:
#country.CountryCode: ['#someVar.Prop1', '#someVar.Prop2', etc],
How to retrieve the value 100003119917070 and XgXELcliKMkSCcS from below document using preg match:
<script>
window.Env = window.Env || {};
(function(v) {
for (var k in v) { window.Env[k] = v[k]; }
})({
"user": "100003119917070",
"locale": "en_US",
"method": "GET",
"ps_limit": 5,
"ps_ratio": 4,
"svn_rev": 479734,
"static_base": "https:\/\/s-static.ak.facebook.com\/",
"www_base": "http:\/\/www.facebook.com\/",
"rep_lag": 2,
"post_form_id": "6cea66d4118fac268304a538a5004ed7",
"fb_dtsg": "AQAcBeoe",
"ajaxpipe_token": "AXgXELcliKMkSCcS",
"lhsh": "8AQGGa7eN",
"tracking_domain": "https:\/\/pixel.facebook.com",
"retry_ajax_on_network_error": "1",
"ajaxpipe_enabled": "1"
});
</script>
<script>
CavalryLogger=false;
window._incorporate_fragment = true;
window._script_path = "\/home.php";
window._EagleEyeSeed="Se1E";
</script>
Just access window.Env.user and window.env.ajax_token?
You've put(copy) the object into the window.Env, so you can run this code:
console.log(window.Env.user, window.Env.ajaxpipe_token)
and it will print values which you want on console.
Also, you can use window.Env['user'] to reference the value 100003119917070.
if use preg,
var preg_user= /"user":\s?"([0-9]+)/;
var preg_token = /"ajaxpipe_token":\s?"([\d\w]+)/;
and you can get value by:
var user = str.match(preg_user);
var token = str.match(preg_token);
May this can help you.
In the specific example given ajaxpipe_token does not contain values other than text and numbers, but, if your value can contain other values (like it can in facebook), change your match group to look for non-quotes, then terminate with the quotes. This is the full code for extracting the values from the document.
scriptxpath ='//script[contains(.,"ajaxpipe_token")]';
scriptrslt = document.evaluate(scriptxpath,document,null,XPathResult.ANY_TYPE,null);
scriptobj = scriptrslt.iterateNext()
scriptiHTML = script.innerHTML;
user_search = scriptiHTML.match(/"user":\s?"([0-9]+)"/);
ajaxpipe_token_search = script_iHTML.match(/"ajaxpipe_token":\s?"([^"]+)"/)
user = user_search[1];
ajaxpipe_token = ajaxpipe_token_search[1];
I can pass a variable from MVC ASP.NET by using this :
var lastCategoryId = '<%=Model.CS.LastSelectedCategory %>';
This work fine with string or integer but how do I do with an array of strings? I have tried to pass the array the same way but the variable is set to System.String[] ?
You could let .NET handle all the heavy lifting for you with this simple line of code.
This assumes you're using MVC Razor syntax.
var yourJavaScriptArray = #Html.Raw(Json.Encode(Model.YourDotNetArray));
For newer versions of MVC, use:
var yourJavaScriptArray = #Html.Raw(Json.Serialize(Model.YourDotNetArray));
You could JSON serialize it. This way could could pass even more complex values and not worry about escaping simple quotes, double quotes, etc :
var categoriesList = <%= new JavaScriptSerializer().Serialize(new[] { "value1", "value2" }) %>;
Writing an HTML helper to do this would be even better:
public static class HtmlExtensions
{
public static string JsonSerialize(this HtmlHelper htmlHelper, object value)
{
return new JavaScriptSerializer().Serialize(value);
}
}
and then in your view:
<script type="text/javascript">
var categoriesList = <%= Html.JsonSerialize(new[] { "value1", "value2" }) %>;
</script>
This should do
var someArray=[<%foreach (var s in myStringArray){%>'<%=s%>',<%}%>];
something like this:
<script type="text/javascript">
var myArr = [<%=string.Join(",", strArr.Select(o => "\"" + o + "\"")) %>];
</script>
One liner:
var data = [#Html.Raw(String.Join(",", Model.MyArray.Select(i => "'" + i + "'")))];
So easy, so simple
<script type="text/javascript">
var array = #Html.Raw(
Json.Encode(
(Model).Select(m=> new
{
id= m.ID,
name=m.Name
})
)
);
</script>
Output is:
[{"id":1,"name":"Name of 1"}, {"id":2,"name":"Name of 2"}, ...];
Using Json.NET
var yourlist = JSON.parse('#Html.Raw(JsonConvert.SerializeObject(Model.YourList))');
You need to format the array into a JavaScript array syntax.
var someArray = [<%= Model.SomeArray.Select(x => "'" + x +"'")
.Aggregate((x,y) => x + ", " + y); %>];
This will surround each entry by single quotes and then join them together with commas between square brackets.
Updated: removed extra parenthesis.
Just wanted to provide an answer using Razor syntax:
We have a Dictionary<int, int> that we are rendering for a jQuery Sparkline, in the form of "an array of arrays".
var usageData = [ #string.Join(",", Model.UsageData.Select(d => string.Format("[{0},{1}]", d.Key, d.Value)).ToArray()) ];
Which is used like so:
$('#sparkline').UsageSparkline(usageData, { tooltipFormatter: cachedTooltips });
This is what we get when viewing the source:
var usageData = [ [-13,0],[-12,1],[-11,0],[-10,0],[-9,1],[-8,1],[-7,0],[-6,2],[-5,2],[-4,0],[-3,0],[-2,9],[-1,3],[0,4] ];
$('#sparkline').UsageSparkline(usageData, { tooltipFormatter: cachedTooltips });