By default the View displays a sorted table which is great but cannot Sort the table columns by clicking on the table headers in ascending or descending order. The header column arrows goes up and down on clicks but the data stays the same. I am using jQuery jTable and sorting is enabled by default.
Is is possible to do this by using a jQuery?
Here's my code for your inspection:
View:
$(document).ready(function () {
$('#TopPlayedInVenueContainer1').jtable({
title: 'Top Tracks Played Records',
paging: true,
pageSize: 100,
sorting: true,
defaultSorting: 'Date ASC',
actions: {
listAction: '#Url.Action("TopPlayedInVenueList1")'
},
fields: {
TrackID: {
title: 'Track ID',
key: true,
create: false,
edit: false,
resize: false,
tooltip: 'Track Name',
sorting: true //This column is not sortable!
},
Date: {
title: 'Date',
type: 'date',
displayFormat: 'dd - mm - yy',
tooltip: 'DD - MM - YY',
list: true,
sorting: true //This column is not sortable!
},
TrackName: {
title: 'Track Name',
key: true,
create: false,
edit: false,
resize: false,
tooltip: 'Track Name',
sorting: true //This column is not sortable!
},
ArtistName: {
title: 'Artist Name',
key: true,
create: false,
edit: false,
resize: false,
tooltip: 'Track Name',
sorting: true //This column is not sortable!
},
Times: {
title: 'Times',
tooltip: 'Artist Name',
sorting: false //This column is not sortable!
}
}
});
// All
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
var todayDate = new Date();
var endDate = todayDate.getDate() + '/' + (todayDate.getMonth() + 1) + '/' + (todayDate.getFullYear() + 100);
var d = new Date();
var st = d.setDate(todayDate.getDate() - 111365);
var startDate = d.getDate() + '/' + (d.getMonth() + 1) + '/' + d.getFullYear();
$('#allrecordsstart').val(startDate);
$('#allrecordsend').val(endDate);
$('#TopPlayedInVenueContainer1').jtable('load', {
StartDate: startDate,
EndDate: endDate
});
$('#allrecords').click(function (e) {
e.preventDefault();
var startDate = $('#allrecordsstart').val();
var endDate = $('#allrecordsend').val();
$('#TopPlayedInVenueContainer1').show(0).delay(0).fadeIn(1000).jtable('load', {
StartDate: startDate,
EndDate: endDate
});
});
Controller: Edit for #CHash_Mile.. thanks a lot :) here's the code: EDIT: 15/04/2014
[HttpPost]
public JsonResult TopPlayedInVenueList1(string StartDate = "", string EndDate = "", int jtStartIndex = 0, int jtPageSize = 0, string jtSorting = null)
{
try
{
if (Request.IsAuthenticated == true)
{
string Path = #"C:\\5Newwithdate-1k.xls";
OleDbConnection con = new OleDbConnection(#"Provider=Microsoft.Jet.OLEDB.4.0;Data Source= '" + Path + "';Extended Properties=" + (char)34 + "Excel 8.0;IMEX=1;" + (char)34 + "");
OleDbDataAdapter da = new OleDbDataAdapter("select * from [Sheet1$]", con);
con.Close();
System.Data.DataTable data = new System.Data.DataTable();
da.Fill(data);
List<TopPlayed> daa = new List<TopPlayed>();
foreach (DataRow p in data.Rows)
{
TopPlayed top = new TopPlayed()
{
TrackID = Convert.ToInt32(p.Field<double>("TrackID")),
Date = p.Field<DateTime>("DateTimes"),
TrackName = p.Field<string>("TrackName"),
ArtistName = p.Field<string>("ArtistName"),
Times = Convert.ToInt32(p.Field<double>("Times"))
};
daa.Add(top);
}
var listOrder = daa.Where(i => i.Date >= Convert.ToDateTime(StartDate) && i.Date <= Convert.ToDateTime(EndDate)).ToList();
if (jtStartIndex + 150 > listOrder.ToList().Count)
{
int val = listOrder.ToList().Count - jtStartIndex;
jtPageSize = val;
}
var newlist = listOrder.OrderByDescending(i => i.Times).ToList().GetRange(jtStartIndex, jtPageSize);
if (string.IsNullOrEmpty(jtSorting)) { jtSorting = "Date ASC"; }
SortDirection sortDirection = jtSorting.ToLower().Contains("desc") ? SortDirection.DESC : SortDirection.ASC;
string sortExpression = sortDirection == SortDirection.DESC ? jtSorting.ToLower().Replace(" desc", "") : jtSorting.ToLower().Contains(" asc") ? jtSorting.ToLower().Replace(" desc", "") : jtSorting;
if (sortDirection == SortDirection.ASC)
{
newlist = newlist.OrderBy(item => GetPropertyValue(item, sortExpression)).ToList();
}
else
{
newlist = newlist.OrderByDescending(item => GetPropertyValue(item, sortExpression)).ToList();
}
return Json(new { Result = "OK", Records = newlist, TotalRecordCount = listOrder.ToList().Count });
}
return Json(new { Result = "ERROR" });
}
catch (Exception ex)
{
return Json(new { Result = "ERROR", Message = ex.Message });
}
}
Debugged using Step Over line by line and seems to be this line of the code is the culprit:
newlist = newlist.OrderBy(item => GetPropertyValue(item, sortExpression)).ToList();
Because after this line I get error message on the View in browser:
Object reference not set to an instance of an object.
Images: Edit for #CHash_Mile.. thanks a lot man :) screenshots of the debug:
sortExpression ---------- URL
newList ---------- URL
I'm sorry for taking your time soo much and really appreciate in what you're doing for me!
Check this
Sorting using Jtable example
I see you are not using variable jtSorting for sorting. this gives property with which sorting needs to be done. Try with below code after loading newlist.
SortDirection sortDirection = jtSorting.ToLower().Contains("desc") ? SortDirection.DESC : SortDirection.ASC;
string sortExpression = sortDirection == SortDirection.DESC ? jtSorting.ToLower().Replace(" desc", "") : jtSorting.ToLower().Contains(" asc") ? jtSorting.ToLower().Replace(" desc", "") : jtSorting;
if (sortDirection == SortDirection.ASC)
{
newlist = newlist.OrderBy(item => GetPropertyValue(item, sortExpression))).ToList();
}
else
{
newlist = newlist.OrderByDescending(item => GetPropertyValue(item, sortExpression))).ToList();
}
Add below method -
public static object GetPropertyValue(object obj, string propertyName)
{
return obj == null ? null : obj.GetType().GetProperty(propertyName).GetValue(obj, null);
}
Add below enum inside your class -
internal enum SortDirection
{
ASC,
DESC
}
Related
i am workning with google charts and i'am try to do timeline chart but i have this error(Invalid data table format: column #1 must be of type 'date,number,datetime) where i retrieve the data from my web service my data like(Name,StartDate,EndDate)
google.charts.load('current', { 'packages': ['timeline'] });
google.charts.setOnLoadCallback(draw_Charts);
function draw_Charts() {
var options = {
backgroundColor: 'transparent',
width: '100%',
height: 400,
title: '',
titleTextStyle: {
fontSize: 20,
},
legend: { position: 'left', textStyle: { fontSize: '40%' } },
colors: ['#4285F4', '#007E33', '#ffbb33']
};
$.ajax({
type: "POST",
url: "Project_Data.asmx/GetChartData",
data: '{}',
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (r) {
var data = google.visualization.arrayToDataTable(r.d);
var chart = new google.visualization.Timeline($("#timeline")[0]);
chart.draw(data, options);
},
failure: function (r) {
alert(r.status + " - " + r.statusText);
},
error: function (r) {
alert(r.status + " - " + r.statusText);
}
});
}
this my methode from my web service to retrieve data it's working fine and when calling this method get data like this example "Nam1","2020-09-01","2020-09-30"
public List<object[]> GetChartData()
{
string query = #"My query";
List<object[]> chartData = new List<object[]>();
using (SqlConnection con = new SqlConnection("Data Source=.\\SQLEXPRESS;Initial Catalog=MyDatabase;Integrated Security=True"))
{
using (SqlCommand cmd = new SqlCommand(query))
{
cmd.CommandType = CommandType.Text;
cmd.Connection = con;
con.Open();
using (SqlDataReader sdr = cmd.ExecuteReader())
{
while (sdr.Read())
{
var date = DateTime.Parse(sdr[3].ToString()).ToString("yyyy-MM-dd"); ;
var date2 = DateTime.Parse(sdr[4].ToString()).ToString("yyyy-MM-dd");
chartData.Add(new object[]
{
sdr[0],date,date2
});
}
sdr.Close();
}
con.Close();
return chartData;
}
}
}
please someone have any idea ?
the error occurs because the date values are coming across as strings in the JSON.
"2020-09-01"
need to convert to actual date objects, before building the google data table.
new Date("2020-09-01");
you can use the following to convert the values for each row, replace...
var data = google.visualization.arrayToDataTable(r.d);
with...
var data = google.visualization.arrayToDataTable(r.d.map(function (row, rowIndex) {
if (rowIndex === 0) {
// column headings
return row;
} else {
// column values
return row.map(function (col, colIndex) {
if (colIndex === 0) {
// name column
return col;
} else {
// date column
return new Date(col);
}
});
}
}));
see following working example...
google.charts.load('current', {
packages: ['timeline']
}).then(function () {
var options = {
backgroundColor: 'transparent',
width: '100%',
height: 400,
title: '',
titleTextStyle: {
fontSize: 20,
},
legend: { position: 'left', textStyle: { fontSize: '40%' } },
colors: ['#4285F4', '#007E33', '#ffbb33']
};
var r = {};
r.d = [
["name","start","end"],
["Nam1","2020-09-01","2020-09-30"],
["Nam2","2020-09-14","2020-09-30"]
];
var data = google.visualization.arrayToDataTable(r.d.map(function (row, rowIndex) {
if (rowIndex === 0) {
// column headings
return row;
} else {
// column values
return row.map(function (col, colIndex) {
if (colIndex === 0) {
// name column
return col;
} else {
// date column
return new Date(col);
}
});
}
}));
var chart = new google.visualization.Timeline($("#timeline")[0]);
chart.draw(data, options);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="timeline"></div>
Okey problem is i have ajax call and when any property is null ajax is working correctly but when all properties okey ajax say "404 not found".And there is a funny thing that the problem only happens on server.On my localhost there is not any problem.
$(".add-button").click(function (e) {
e.preventDefault();
var id = "#";
var langId = $(".select-language").val();
id += langId;
var realpartno = $(id+" .input-tags").val();
var value = [];
var newRealPart ="";
for (var i = 0; i < realpartno.length; i++) {
if (realpartno[i] != ",") {
newRealPart += realpartno[i];
}
else {
value.push(newRealPart);
newRealPart = "";
}
if (i == realpartno.length - 1) {
value.push(newRealPart);
}
}
var formData = new FormData();
formData.append("Description", $(id + " .description").val());
formData.append("SubCategory", $(id + " .subcategory").val());
formData.append("RealPartNos", value);
formData.append("Categories", $(id +" .category").val());
formData.append("Photo", $(id + " .product_photo").get(0).files[0]);
formData.append("LanguageId", $(".select-language").val());
$(id + " .error_view").empty();
$(id + " .error_view").text("Zehmet Olmasa Gozleyin Sorgu Icra Edilir ...")
$.ajax({
url: "/Admin/Home/Add/",
type: "post",
dataType: "json",
data: formData,
cache: false,
contentType: false,
processData: false,
success: function (response) {
if (response.status == 200) {
swal({
title:"Success",
icon: "success",
text: response.message,
buttons: ["Siyahiya Kec", "Yeni Mehsul Elave Et"]
});
ClearArea("#description");
ClearArea("#product_photo");
ClearElement(".input-tags .item");
var a = document.createElement("a");
a.href = "/Admin/Home/Index";
a.innerText = "Siyahiya Qayit";
a.className = "btn btn-success my-2";
a.style.color = "#fff";
$(id + " .error_view").empty();
$(id + " .error_view").append(a);
} else {
swal({
title: "Error",
icon: "error",
text: response.errorMessage
});
}
}
});
})
Why there is not any problem on my localhost and only problem on server when everyrthing okey.and that is my action
[HttpPost]
public async Task<JsonResult> Add(ProductViewModel model)
{
//Check All Models
foreach (string item in model.Categories)
{
if (item == null)
{
return Json(new { status = 400, errorMessage = "En azi 1 category elave edin" });
}
}
if (model.Description == "")
{
return Json(new { status = 400, errorMessage = "Description elave edin" });
}
if (model.SubCategory == "")
{
return Json(new { status = 400, errorMessage = "En azi 1 Subcategory elave edin" });
}
if (model.Photo == null)
{
return Json(new { status = 400, errorMessage = "Sekil elave edin" });
}
foreach (string item in model.RealPartNos)
{
if (item == null)
{
return Json(new { status = 400, errorMessage = "En azi 1 realpartno elave edin" });
}
}
if (model.LanguageId == "")
{
return Json(new { status = 400, errorMessage = "Dil elave edile bilmir" });
}
//Find Language
Language language = db.Languages.Where(l => l.Key == model.LanguageId).FirstOrDefault();
var sub = model.SubCategory;
var description = model.Description;
//Make Category and RealPartNo Arrays
List<string> categories = MakeArray(model.Categories);
List<string> realPartNos = MakeArray(model.RealPartNos);
//Upload Photo
var photo = model.Photo;
var file_name = photo.FileName;
var path = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "Uploads", "Products", file_name);
if (MyFile.isImage(photo))
{
await MyFile.Upload(photo, path);
}
//Create Product
Product product = new Product();
product.SubCategory = await db.SubCategories.Where(s => s.Name == sub).FirstOrDefaultAsync();
product.PhotoPath = photo.FileName;
//Creat RealPartNo
foreach (var realPartNo in realPartNos)
{
RealPartNo number = new RealPartNo();
number.Name = realPartNo;
number.Product = product;
await db.RealPartNos.AddAsync(number);
}
//Create Category
foreach (var item in categories)
{
if (item != null)
{
Category category = await db.Categories.Where(c => c.Name == item).FirstOrDefaultAsync();
ProductCategory productCategory = new ProductCategory();
productCategory.Category = category;
productCategory.Product = product;
db.ProductCategories.Add(productCategory);
}
}
//Create MultiLanguage Product
ProductLanguage productLanguage = new ProductLanguage();
productLanguage.LanguageId = language.Id;
productLanguage.Product = product;
productLanguage.Description = model.Description;
await db.ProductLanguages.AddAsync(productLanguage);
await db.Products.AddAsync(product);
await db.SaveChangesAsync();
return Json(new { status = 200, message = "Mehsul Elave Edildi" });
}
I am trying to render a bar chart using Flot Chart JS. The data is dynamically change according to database. When I debug, the data is not rendered out. I tried to breakpoint in line(var data = strdata;) to find out what is going on with my data. End up the data only consists of one set of data value such as "[0, 5]". It seems like the strings are failed to join in the foreach loop.
Update: Ok. I have known that string cannot be concatenate within a loop. I have edited the action code and put my previous line in comment. The data and tick's content are correct but the chart is still without data.
Controller:
string strdata;
string strtick;
[HttpGet]
public ActionResult GetTestData()
{
string name;
int count;
int i = 0;
var list1 = dbContext.Collections.ToList();
foreach (Collection coll in list1)
{
name = coll.Name.ToString();
var list2 = dbContext.Item.Where(x => x.Name == name).ToList();
count = list2.Count();
displaydata = "[" + i + "," + collcount + "],";
displaytick = "[" + i + "," + collname + "],";
strdata += displaydata;
strtick += displaytick;
//strdata = string.Join(",", "[" + i + "," + count + "]");
//strtick = string.Join(",", "["+ i + "," +name+"]");
//i++;
}
var data = strdata;
var ticks = strtick;
var result = new {data = data, ticks = ticks };
return Json(result, JsonRequestBehavior.AllowGet);
}
View:
$.ajax({
type: "GET",
contentType: 'application/json; charset=utf-8',
dataType: 'json',
url: '/Home/GetTestData/',
error: function () {
alert("An error occurred.");
},
success: function (data) {
//alert("Success.");
var dataset = [{ label: "2012 Average Temperature", data: [data.data], color: "#5482FF" }];
var ticks = [data.ticks];
var options = {
series: {
bars: {
show: true
}
},
bars: {
align: "center",
barWidth: 0.5
},
xaxis: {
axisLabel: "World Cities",
axisLabelUseCanvas: true,
axisLabelFontSizePixels: 12,
axisLabelFontFamily: 'Verdana, Arial',
axisLabelPadding: 10,
ticks: ticks
},
legend: {
noColumns: 0,
labelBoxBorderColor: "#000000",
position: "nw"
},
grid: {
hoverable: true,
borderWidth: 2,
backgroundColor: { colors: ["#ffffff", "#EDF5FF"] }
}
};
$.plot($("#flot-dashboard5-chart"), dataset, options);
}
});
So, i made a dashboard that uses ajax,sqlconnection to sqlserver 2008 and SignalR for realtime data.
Here is an example of the ajax i made that is in a javascript method which is called by the button:
$.ajax({
url: '../api/values',
type: 'GET',
datatype: 'json',
success: function (data) {
var totalLabel = [];
var totalValue = [];
var totalLabel2 = [];
var totalValue2 = [];
var cityValue = [];
var cityValue2 = [];
var cityName = [];
var numIndex = [];
var barColor = "";
var cityString = "";
for (var j = 1; j < cityList.length; j++)
{
cityString = cityString + "||" + " data[i].Names==\"" + cityList[j] + "\"";
}
cityString = "data[i].Names==\"" + cityList[0] + "\""+cityString;
for (var i = 0; i < data.length; i++) {
totalLabel.push(data[i].Names);
totalValue.push(data[i].ValuesDouble);
totalLabel2.push(data[i].Names2);
totalValue2.push(data[i].ValuesDouble2);
//alert(cityString);
if (eval(cityString)) {
numIndex.push(i);
}
}
for (var k = 0; k < numIndex.length; k++) {
cityValue.push(data[numIndex[k]].ValuesDouble);
cityValue2.push(data[numIndex[k]].ValuesDouble2);
cityName.push(data[numIndex[k]].Names);
}
if (numIndex.length > 0) {
for (var h = 0; h < numIndex.length - 1; h++) {
barColor = barColor + "{y:" + cityValue2[h] + ",color:'" + setGraphColor(cityValue2[h], cityValue[h]) + "'}" + ",";
}
barColor = "[" + barColor + "{y:" + cityValue2[numIndex.length-1] + ",color:'" + setGraphColor(cityValue2[numIndex.length-1],cityValue[numIndex.length-1]) + "'}" + "]";
}
else {
barColor = "[" + barColor + "{y:" + data[numIndex[0]].ValuesDouble2 + ",color:'" + setGraphColor(data[numIndex[0]].ValuesDouble2, data[numIndex[0]].ValuesDouble) + "'}" + "]";
}
$(function () {
Highcharts.chart('container', {
chart: {
type: 'column',
backgroundColor: 'black'
},
tooltip: {
formatter: function () {
var s = '<b>' + this.x + '</b><br/><div>__________________________</div><hr>';
$.each(this.points, function () {
s += '<br/><span style="color:' + this.series.color + '">\u25CF</span><b>' + this.series.name + '</b>: ' + this.y;
});
return s;
},
shared: true
},
title: {
text: ''
},
xAxis: {
categories: cityName,
},
yAxis: {
min: 0,
tickInterval: 500,
title: {
text: ''
}
},
legend: {
verticalAlign: 'top',
reversed: false,
backgroundColor: 'lightgrey'
},
plotOptions: {
series: {
stacking: 'normal'
}
},
series: [{
name: 'Daily Schedule',
data: eval(barColor)
},
{
name: 'Actual Delivery',
data: cityValue,
color: '#33FF66'
},
{
name: '0%-69%',
//data: cityValue,
color: '#FF3366'
},
{
name: '70%-89%',
// data: cityValue,
color: '#FFCC33'
},
{
name: '90%-100%',
// data: cityValue,
color: '#003DF5'
}]
});
});
}
})
and here is the example of my Repository to connect to the SQL Server:
public class LocationInfoRepository
{
public IEnumerable<LocationInfo> GetData()
{
using (var connection = new SqlConnection(ConfigurationManager.ConnectionStrings["Database"].ConnectionString))
{
connection.Close();
connection.Open();
using (SqlCommand command = new SqlCommand(#"
SELECT ... ", connection))
{
command.Notification = null;
SqlDependency dependency = new SqlDependency(command);
dependency.OnChange += new OnChangeEventHandler(dependency_OnChange);
if (connection.State == ConnectionState.Closed)
{ connection.Open(); }
using (var reader = command.ExecuteReader())
{
return reader.Cast<IDataRecord>().Select(x => new LocationInfo()
{
Names = x.GetString(2),
Values = Math.Round(x.GetDouble(3), 2).ToString("#,##0.00"),
ValuesDouble = x.GetDouble(3),
Values2 = Math.Round(x.GetDecimal(4), 2).ToString("#,##0.00"),
ValuesDouble2 = x.GetDecimal(4)
}).ToList();
}
/*
using (var reader2 = command.ExecuteReader())
{
reader2.NextResult();
return reader2.Cast<IDataRecord>().Select(x => new LocationInfo()
{
SumVol = x.GetString(0)
}).ToList();
}*/
}
}
}
private void dependency_OnChange(object sender, SqlNotificationEventArgs e)
{
MyHub.Show();
}
}
I dont know why every time i click a button that calls the ajax, the dashboard lags even more.Is it the ajax, or the sqlconnection,or even signalR itself.Please help! Thank you in advance.
Hi I have a mDataProp DateTime formatting issue. Basically I want to display the date in one column and the time in another.
But as I understand it the mDataProp is directly related to your model, which does not have a time property just a adate......
Controller
var result = from a in data
select new
{
appointmentDate = a.AppointmentDate.ToShortDateString(),//.ToString("g"),
appointmentTime = a.AppointmentDate.ToLocalTime().ToString("t"),
appointmentName = a.AppointmentType.AppName,
appointmentID = a.AppointmentID
};
//Return Json data for Datatable
return Json(new
{
sEcho = param.sEcho,
iTotalRecords = total,
iTotalDisplayRecords = total,
aaData = result
});
View
<script>
$(document).ready(function () {
var urlRequest = $('#apptTable').data("request-url");
var detailRequest = $('#apptTable').data("detail-url");
$('#apptTable').dataTable({
"bSort": false,
"bServerSide": true,
"sAjaxSource": urlRequest,
"sServerMethod": "POST",
"bProcessing": true,
"bFilter": false,
"aoColumns": [
{ "mDataProp": "appointmentDate" },
{ "mDataProp": "appointmentDate" },
{ "mDataProp": "appointmentName" },
{
"mDataProp": "appointmentID",
"fnRender": function (oObj) {
return 'Details';
}
}
]
});
});
</script>
I cannot create a second variable called appointmentDate in the controller, so I'll have to format in the view.
Any ideas?