I am currently working on a project that implements ComponentOne studio's Wijmo frameworks and I have built a grid that uses data passed from a Model that basically builds some dummy data for an individual sale.
I am then calling the public static IEnumerable in my Controller file which is passing a value for the number of data entries to create. That is being passed to my view for my Index cshtml file, where the data grid is being built.
I am trying to then figure out how to call the data that has been created when I am writing a function in a JS file. I want to be able to take the collective data that was produced by the int value in my controller (say 100 entries) and then create a view of that data that I am filtering on. However, I can't figure out how to pass that initial data so that when I run the filter on it I can reference that data to save a view of the output and run a secondary filter.
I basically need to figure out how the reference in the JS calls not just the model, but the model with the int value from the controller.
Here is the model file:
using System;
using System.Collections.Generic;
using System.Linq;
namespace FilterPanel.Models
{
public class Sale
{
public int ID { get; set; }
public DateTime Start { get; set; }
public string Country { get; set; }
public string Product { get; set; }
public bool Active { get; set; }
private static List<string> COUNTRIES = new List<string> { "US", "UK", "Canada", "Japan", "China", "France", "German", "Italy", "Korea", "Australia" };
private static List<string> PRODUCTS = new List<string> { "Widget", "Gadget", "Doohickey" };
/// <summary>
/// Get the data.
/// </summary>
/// <param name="total"></param>
/// <returns></returns>
public static IEnumerable<Sale> GetData(int total)
{
var rand = new Random(0);
var dt = DateTime.Now;
var list = Enumerable.Range(0, total).Select(i =>
{
var country = COUNTRIES[rand.Next(0, COUNTRIES.Count - 1)];
var product = PRODUCTS[rand.Next(0, PRODUCTS.Count - 1)];
var startDate = new DateTime(dt.Year, i % 12 + 1, 25);
return new Sale
{
ID = i + 1,
Start = startDate,
Country = country,
Product = product,
Active = (i % 4 == 0)
};
});
return list;
}
}
}
I am then referencing this function in the controller file:
using FilterPanel.Models;
using System.Linq;
using System.Web.Mvc;
namespace FilterPanel.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
return View(Sale.GetData(100).ToList());
}
}
}
And finally trying to call that data in my JS file with "data" being a placeholder for the Sale.GetData(100) that I am trying to pass
var view = new wijmo.collections.CollectionView(data);
// create a second CollectionView based on the first one
var view2 = new wijmo.collections.CollectionView(view.items, {
collectionChanged: function(s) {
var cnt = document.getElementById('cnt');
cnt.textContent = wijmo.format('{length:n0}', s.items)
}
});
Related
I'm a novice in javascript, and a junior developper in OOP.
After many attempts and many google search I dind't make it to solve it.
I have a DropDownList and a Partial View. I want to give the selected value to the partial view controller. It works when I write the value directly in, but it doesn't if i try to catch the DropDownList value. For the moment the value returned is always empty.
Model
public partial class Clients
{
public int ClientID { get; set; }
public string Code { get; set; }
public string Nom { get; set; }
public string Adresse1 { get; set; }
public string Adresse2 { get; set; }
public string CP { get; set; }
public string Ville { get; set; }
public Nullable<System.DateTime> DateCreation { get; set; }
public Nullable<System.DateTime> DateModification { get; set; }
}
View
#Html.DropDownList("id", (IEnumerable<SelectListItem>)ViewData["oas"], new { #id = "ClientID" })
<div id="result"></div>
<script>
$(function () {
$('#ClientID').change(function () {
//var pid = $("#id").val();//$(this).data('id');
$('#result').load('#Url.Action("filter")',
{ id: $("#id").val() } //replacing $("#id").val() by "3" makes it work, but i of course don't a constant value here
);
});
});
Controller
public class OnePageController : Controller
{
Entities db = new Entities();
public ActionResult Index()
{
List<SelectListItem> list = new List<SelectListItem>();
list.Add(new SelectListItem { Text = "-Please select-", Value = "Selects items" });
var clts = (
from c in db.Clients
select c).ToArray();
for (int i = 0; i < clts.Length; i++)
{
list.Add(new SelectListItem
{
Text = clts[i].Nom,
Value = clts[i].ClientID.ToString(),
Selected = (clts[i].ClientID == 1)
});
}
ViewData["oas"] = list;
return View(/*db.Clients.ToList()*/);
}
[HttpPost]
public ActionResult Filter(string id)
{
var contact = from c in db.Contacts
where c.ClientID.ToString() == id
select c;
return PartialView(contact);
}
}
Any idea would be greatly appreciated, also i don't know how to debug javasript, i use the developper tools in my when browser to try to catch the values, but i don't really track the changes..
You should change a bit your script:
$(function () {
// You select the element with id = ClientID
var clientEle = $('#ClientID');
// You register an event handler for the change of the selected value
clientEle.change(function () {
// clientEle.val() would return the selected value
$('#result').load('#Url.Action("filter")',{ id: clientEle.val() });
});
});
Regarding how you should debug JavaScript I would suggest to write the following keyword a few lines before you want to start the debugging:
debugger;
Then open developer tools and refresh your page. When JavaScript engine hits the debugger would stop it's execution and from this moment you could examine you code line by line.
For a thorough understanding in how you could debug JavaScript, you could start by checking the following links
https://developers.google.com/web/tools/chrome-devtools/javascript/
https://developer.mozilla.org/en-US/docs/Mozilla/Debugging/Debugging_JavaScript
https://www.w3schools.com/js/js_debugging.asp
I am trying to get a json array as a string via a function on the server using signalR but I keep getting an object instead of a string.
This is the code that writes the json array.
SqlDataReader reader = cmd.ExecuteReader();
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
using (JsonWriter jsonWriter = new JsonTextWriter(sw))
{
jsonWriter.WriteStartArray();
while (reader.Read())
{
jsonWriter.WriteStartObject();
int fields = reader.FieldCount;
for (int i = 0; i < fields; i++)
{
jsonWriter.WritePropertyName(reader.GetName(i));
jsonWriter.WriteValue(reader[i]);
}
jsonWriter.WriteEndObject();
}
jsonWriter.WriteEndArray();
}
reader.Close();
con.Close();
return sb.ToString();
This is the result i got from this function:
{[{"ResponseCode":"","NodeName":"Test"}, {"ResponseCode":"00","NodeName":"Test"}]}
And my javascript code is:
var standetails = hub.server.stanDetails($(this).textContent);
//var x = JSON.parse(standetails)
the type of standetails in the browser is object and does not contain the json array
It is much simpler than you thought. SignalR is going to serialize the custom object sent as parameter from server to JS client.
Which means you can actually send a list of complex object and you are getting an array on the JS side.
A simple examlpe:
Let's say this is your complex class:
public class TestData {
public string p1 { get; set; }
public string p2 { get; set; }
public DateTime p3 { get; set; }
}
Let's make simple method which creates a list of this and sends
public class TestHub : Hub {
public void Send(string name, string message) {
List<TestData> testList = new List<TestData>();
testList.Add(new TestData { p1 = "AAA", p2 = "BBB", p3 = DateTime.Now });
testList.Add(new TestData { p1 = "CCC", p2 = "DDD", p3 = DateTime.Now });
Clients.All.sendMessage(testList);
}
}
javascript receiving this event:
var hub = $.connection.testHub;
hub.client.sendMessage = function (param) {
console.log(param);
}
test here is an array containing tow objects, see on the image.
I hope this helps.
EDIT
If you want to change the default serializer behavior, you can go by replacing the default JsonSerializer used, or the simple way would be to wrap in custom object.
Extending example with container class:
public class Container {
public string value { get; set; }
}
Sending as serialized string:
Clients.All.sendMessage(new Container { value = new JavaScriptSerializer().Serialize(testList) });
Receiving same javascript code.
Console log capture:
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 7 years ago.
Improve this question
I have a small test program in ASP.NET MVC4 which allows you to select items from a dropdown menu. It uses Json and JavaScript (I'm not familiar with these at all).
Here's the code I have at the moment:
HomeController:
public ActionResult CountryList()
{
IQueryable countries = Country.GetCountries();
if (HttpContext.Request.IsAjaxRequest())
{
return Json(new SelectList(
countries,
"CountryCode",
"CountryName"), JsonRequestBehavior.AllowGet
);
}
return View(countries);
}
public ActionResult StateList(string CountryCode)
{
IQueryable states = State.GetStates().Where(x => x.CountryCode == CountryCode);
if (HttpContext.Request.IsAjaxRequest())
return Json(new SelectList(
states,
"StateID",
"StateName"), JsonRequestBehavior.AllowGet
);
return View(states);
}
View:
#section scripts {
<script type="text/javascript">
$(function () {
$.getJSON("/Home/Countries/List", function (data) {
var items = "<option>---------------------</option>";
$.each(data, function (i, country) {
items += "<option value='" + country.Value + "'>" + country.Text + "</option>";
});
$("#Countries").html(items);
});
$("#Countries").change(function () {
$.getJSON("/Home/States/List/" + $("#Countries > option:selected").attr("value"), function (data) {
var items = "<option>---------------------</option>";
$.each(data, function (i, state) {
items += "<option value='" + state.Value + "'>" + state.Text + "</option>";
});
$("#States").html(items);
});
});
});
</script>
}
<h1>#ViewBag.Title</h1>
#using (Html.BeginForm())
{
<label for="Countries">Countries</label>
<select id="Countries" name="Countries"></select>
<br /><br />
<label for="States">States</label>
<select id="States" name="States"></select>
<br /><br />
<input type="submit" value="Submit" />
}
and finally the Models:
Country
public class Country
{
public string CountryCode { get; set; }
public string CountryName { get; set; }
public static IQueryable<Country> GetCountries()
{
return new List<Country>
{
new Country {
CountryCode = "CA",
CountryName = "Canada"
},
new Country{
CountryCode = "US",
CountryName = "United-States"
}
}.AsQueryable();
}
}
}
State:
public class State
{
public string CountryCode { get; set; }
public int StateID { get; set; }
public string StateName { get; set; }
public static IQueryable<State> GetStates()
{
return new List<State>
{
new State
{
CountryCode = "CA",
StateID=1,
StateName = "Ontario"
},
new State
{
CountryCode = "CA",
StateID=2,
StateName = "Quebec"
},
new State
{
CountryCode = "CA",
StateID=3,
StateName = "Nova Scotia"
// .. and so on
}.AsQueryable();
}
}
}
My question is: how do I make this solution work with a database table? What do I need to do in order to make this same dropdown work with fields from a database? Does anyone have any useful tutorials that they could recommend?
You need to choose how you will access your database. There are a lot of options, but I recommend you to use some kind of ORM. It's not easy to choose an ORM too. So you will need to do a research before and find one that fits your needs best. As you wrote in comment you are new to this, so I will provide few samples of how fetching of States might look in different ORM's.
Dapper - ORM used on this (SO) site.
using (var conn = new SqlConnection("CONN_STR"))
{
IList<State> states = conn
.Query<State>(
"select * States where CountryCode = #CountryCode",
new { CountryCode = countryCode })
.ToList();
}
As you can see here we just provide SQL and object with object with parameters and Dapper does all things for us. We get list of entities.
Entity Framework - ORM created by Microsoft.
IList<State> states =
DbContext.States.Where(state => state.CountryCode == countryCode).ToList();
You don't need to write any SQL at all, we are using pure LINQ syntax.
Of course all ORM's has their pros and cons, so again, you need to do a research before.
EDIT: It seems that you have problems with filling selects... Then first you will need to create correct models for EF. You can reuse your existing models, just add some attributes:
[Table("Countries")]
public class Country
{
public string CountryCode { get; set; }
public string CountryName { get; set; }
}
[Table("States")]
public class State
{
[Key]
public int StateID { get; set; }
public string StateName { get; set; }
public string CountryCode { get; set; }
}
In Table attribute you should use your real table names of course. Then you need to create DbContext:
public class MyDbContext : DbContext
{
public DbSet<Country> Countries { get; set; }
public DbSet<State> States { get; set; }
}
Don't forget to specify connection string in web.config like in tutorial.
I simplified methods for getting countries and states and now they return only JSON:
public ActionResult CountryList()
{
using (var db = new MyDbContext())
{
var countries = db.Countries.ToList();
return Json(
new SelectList(countries, "CountryCode", "CountryName"), JsonRequestBehavior.AllowGet);
}
}
public ActionResult StateList(string countryCode)
{
using (var db = new MyDbContext())
{
var states = !string.IsNullOrEmpty(countryCode)
? db.States.Where(state => state.CountryCode == countryCode).ToList()
: new List<State>();
return Json(
new SelectList(states, "StateID", "StateName"), JsonRequestBehavior.AllowGet);
}
}
It's a good idea to move DB access code to different class but I hope you can do it yourself.
You had some strange URl's in you javascript so here is working example:
$.getJSON("/Home/CountryList", function (data) {
// Same code that you have
});
$("#Countries").change(function () {
$.getJSON("/Home/StateList?countryCode=" + $("#Countries > option:selected").attr("value"), function (data) {
// Same code that you have
});
});
If you need to get the list of countries or states from a database then what you need to do is be able to query the database. See these examples of using ado.net to query a database. https://msdn.microsoft.com/en-us/library/vstudio/dw70f090%28v=vs.100%29.aspx
Then just change your .GetCountries and GetStates to get the list from the database. The code will look something like this (this is just pseudocode)
var List<States> l = new List<States>();
while(reader.read()){
var s = new State{
CountryCode = reader["cc_code"],
StateID=reader["stateId"],
StateName = reader["stateName"]
};
l.add(s);
}
return l;
I've updated to new version of breeze and ef 6. And after I did this, I get error
newValue.getProperty is not a function
Whenever I try to execute expand query. (for "normal" queries everything is fine )
So here is my model for Mucsle:
public int MuscleId { get; set; }
public string Name { get; set; }
public int MuscleGroupId { get; set; }
public MuscleGroup MuscleGroup { get; set; }
And for MuscleGroup:
public int MuscleGroupId { get; set; }
public string Name { get; set; }
public ICollection<Muscle> Muscles { get; set; }
Here is my DtabaseContext Configuration:
public WebDatabaseContext()
: base("DefaultConnection")
{
Configuration.LazyLoadingEnabled = false;
Configuration.ProxyCreationEnabled = false;
}
And I try to fetch data like this:
Function in dataService:
getAllIncluding: function(controllerAction, including) {
var query = breeze.EntityQuery.from(controllerAction).expand(including);
return manager.executeQuery(query).then(querySucceeded).fail(getFailed);
function querySucceeded(data) {
items = data.results;
return data.results;
}
}
Call of function:
$scope.getAllMuscles = function() {
adminCrudService.getAllIncluding("Muscles", "MuscleGroup")
.then(querySucceeded)
.fail(queryFailed);
};
With older version of breeze and EF5 this works, so I wonder what am I doing wrong ?
EDIT
I believe, I've found what causes problem, when I enter in url:
breeze/Service/Muscles?$expand=MuscleGroup
With "old" (older version of breeze, and EF 5) settings, output is this:
[{"$id":"1","$type":"Test.Domain.Model.MuscleGroupAggregate.Muscle, Test.Domain.Model","MuscleId":1,"Name":"Biceps","NameInLatin":"","ImageUrl":null,"MuscleGroupId":1,"MuscleGroup":null},
{"$id":"2","$type":"Test.Domain.Model.MuscleGroupAggregate.Muscle, Test.Domain.Model","MuscleId":3,"Name":"Triceps","NameInLatin":"","ImageUrl":null,"MuscleGroupId":1,"MuscleGroup":null},
And with EF 6 and latest version of breeze:
[{"$id":"1","$type":"System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[System.Object, mscorlib]], mscorlib","MuscleGroup":
{"$id":"2","$type":"System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[System.Object, mscorlib]], mscorlib","MuscleGroupId":1,"Name":"TestMuscleG1","Description":"","ImageUrl":null},"MuscleId":1,"Name":"Test2","NameInLatin":"","ImageUrl":null,"MuscleGroupId":1},
{"$id":"3","$type":"System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[System.Object, mscorlib]], mscorlib","MuscleGroup":
{"$id":"4","$type":"System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[System.Object, mscorlib]], mscorlib","MuscleGroupId":1,"Name":"TestMuscleG1","Description":"","ImageUrl":null},"MuscleId":2,"Name":"32r23r","NameInLatin":"","ImageUrl":null,"MuscleGroupId":1}]
So difference is in $type, and in "new" output, even tough, in database I have only two entries, I got 4 items.
Solved it !
So the problem was here:
[HttpGet]
[Queryable(AllowedQueryOptions = AllowedQueryOptions.Supported | AllowedQueryOptions.Expand)]
public IQueryable<Muscle> Muscles()
{
return _contextProvider.Context.Muscles;
}
When I removed this line:
[Queryable(AllowedQueryOptions = AllowedQueryOptions.Supported | AllowedQueryOptions.Expand)]
It worked like a charm,
Jay thanks for all the help :)
I need to visualize a huge set of data inside a timeline. I found 'verite Timeline' looks promising but I don't have any experience with it, using really many data sets. Is here anyone who could tell me about the performance of this tool or tell me about a better solution?
thnx!
As stated in their FAQ ( fourth question ):
How many entries will work best in TimelineJS?
Timeline is optimized for up to 100 entries preferably more like 20-30. Anything else may cause a loading issue.
Now maybe you could not respect their limit, but I do not think that using it with "lots of tons of data" would be a good experience. :) ( well, you could load only 100 entries at a time, but I'll leave this up to you )
I'm not able to suggest you an alternative, sorry.
Sorry ..
again, but in English ....
Verite timeline supports JSON as a data source, I have a project in MVC3 and route the data source to a controller. You obviously can do it differently for instance from a Web Service, or Ria, etc ....
To start the timeline you, put a timeline initial script in the head or body:
var timeline = new VMM.Timeline();
timeline.init("http://localhost:9306/TimeLine/Json");
You create classes to store the data structure, this will allow you to return the instance of the class in the same format json from the driver:
public class json
{
public timeLine timeline
{
get;
set;
}
}
public class timeLine
{
public string headline { get; set; }
public string type { get; set; }
public string startDate { get; set; }
public string text { get; set; }
public asset asset { get; set; }
public List<date> date { get; set; }
}
public class asset
{
public string media { get; set; }
public string credit { get; set; }
public string caption { get; set; }
}
public class date
{
public string startDate { get; set; }
public string endDate { get; set; }
public string headline { get; set; }
public string text { get; set; }
public asset asset { get; set; }
}
The controller:
public ActionResult Json()
{
json j = new json();
j.timeline = new timeLine();
j.timeline.headline = "TimeLine";
j.timeline.type = "default";
j.timeline.startDate = DateTime.Now.Year + "," + DateTime.Now.Month;
j.timeline.text = "<p>Time Line de todo el contenido.</p>";
j.timeline.asset = new asset();
j.timeline.asset.media = "";
j.timeline.asset.credit = "Desarrollador por Mauricio Farias www.ald.cl mfarias#ald.cl";
j.timeline.asset.caption = "Develop By Mauricio Farias";
j.timeline.date = new List<date>();
//for each de tiempos
for (int i = 0; i < 20; i++)
{
date d = new date();
d.startDate = DateTime.Now.Year + "," + DateTime.Now.Month + "," + i;
d.endDate = DateTime.Now.Year + "," + DateTime.Now.Month + "," + (i + 1);
d.headline = "Headline date for date in timeline";
d.text = "<p>text in date for date in timeline</p>";
d.asset = new asset();
d.asset.media = "";
d.asset.credit = "credit in asset for date in timeline";
d.asset.caption = "caption in asset for date in timeline";
j.timeline.date.Add(d);
}
return Json(j, JsonRequestBehavior.AllowGet);
}
At the hearing or in your case may be an aspx or html page (remember to put the css):
<div id="timeline">
</div>
<script src="../../Content/assets/js/timeline-min.js"></script>
<script src="../../Content/assets/js/script.js"></script>