I am trying to fetch data from gridmvc and show graphs using chart.js its working fine but issue is that its showing just with pages. Because i have enabled paging in grid and when i click on next page then next grid data page graphs show, but i want to show graph of complete grid data includes all pages.
<div class="panel-body">
#await Html.Grid(Model).Columns(columns =>
{
columns.Add(c => c.ID).Titled("StudentID").Filterable(true);
columns.Add(c => c.Name).Titled("Name").Filterable(true);
columns.Add(c => c.Major).Titled("Major").Filterable(true);
columns.Add(c => c.Minor).Titled("Minor").Filterable(true);
columns.Add(c => c.Email).Titled("Email").Filterable(true);
columns.Add(c => c.Address).Titled("Address").Filterable(true);
columns.Add(c => c.GPA).Titled("GPA").Filterable(true);
}).Searchable(true, false, true).WithPaging(10).ChangePageSize(true).Sortable(true).EmptyText("No data found").Named("GridSearch").RenderAsync()
</div>
Javascript
function LoadChart() {
debugger;
var chartType = parseInt($("#rblChartType input:checked").val());
var items = $(".grid-mvc").find(".grid-table > tbody").children();
var json = [];
$.each(items, function (i, row) {
$col1=$(row).children()[0].innerText;
$col2 = $(row).children()[1].innerText;
$col3 =$(row).children()[2].innerText;
$col4 =$(row).children()[3].innerText;
$col5 =$(row).children()[4].innerText;
$col6 =$(row).children()[5].innerText;
$col7 =$(row).children()[6].innerText;
json.push({ 'StudentID': $col1, 'Name': $col2, 'Major': $col3, 'Minor': $col4, 'Email': $col5, 'Address': $col6, 'GPA': $col7
})
// Map JSON values back to label array
var labels = json.map(function (e) {
return e.Name;
});
console.log(labels); // ["2016", "2017", "2018", "2019"]
// Map JSON values back to values array
var values = json.map(function (e) {
return e.GPA;
});
var chart=BuildChart(labels, values, "Students Name by GPA");
I want to show graphs which include complete data in gridmvc not just on current page.
but issue is that its showing just with pages. Because i have enabled
paging in grid and when i click on next page then next grid data page
graphs show, but i want to show graph of complete grid data includes
all pages.
var items = $(".grid-mvc").find(".grid-table > tbody").children();
var json = [];
$.each(items, function (i, row) {
$col1=$(row).children()[0].innerText;
$col2 = $(row).children()[1].innerText;
$col3 =$(row).children()[2].innerText;
$col4 =$(row).children()[3].innerText;
$col5 =$(row).children()[4].innerText;
$col6 =$(row).children()[5].innerText;
$col7 =$(row).children()[6].innerText;
json.push({ 'StudentID': $col1, 'Name': $col2, 'Major': $col3, 'Minor': $col4, 'Email': $col5, 'Address': $col6, 'GPA': $col7
})
The issue relates the above scripts, since you implement paging, when using the above code to get the table resource, it only gets the current page records, then display the page grahps.
To solve this issue, you could get the records from the page model (Model) or create an action method to get all records, then, use JQuery Ajax method to call this method and get the grid data.
To get records from the page model, in your Asp.net Core MVC application, you could use the Json.Serialize() method to convent the Model to JSON string first, then use JSON.parse() method convent the JSON string to JavaScript Object, then loop through the Object and get all data.
Code like this (Index.cshtml)
#model List<StudentViewModel>
#section Scripts{
<script>
$(function () {
LoadChart();
});
function LoadChart() {
debugger;
//var chartType = parseInt($("#rblChartType input:checked").val());
//var items = $(".grid-mvc").find(".grid-table > tbody").children();
var json = [];
var items = JSON.parse('#Json.Serialize(Model)');
$.each(items, function (index, item) {
json.push({ 'StudentID': item.id, 'Name': item.name, 'Major': item.major, 'Major': item.major, 'Email': item.email, 'Address': item.address, 'GPA': item.gpa });
});
//show graphs based on the json array.
The screenshot like this:
Related
I have a project foreign key in by Phase model. I'm having hard time Create a dependent drop-down list inside my Django admin page.
I want to when user select a project from (project drop-down) phase of that project show in second dop-down
What would be the best way to achieve this?
It would be great if the dropdowns filter items based on the value of its parent.
class Project(models.Model):
name = models.CharFieldmax_length = 100, unique= True)
short_name = models.CharField(max_length= 4, unique= True)
slug = models.SlugField(max_length= 100, allow_unicode=True, null=True, editable= False)
location = models.OneToOneField(Location, on_delete = models.SET_NULL, null= True, blank= False, verbose_name= 'موقعیت')
start_date = models.DateField(default= timezone.now, null= True, blank= True)
end_date = models.DateField(default= timezone.now, null= True, blank= True)
duration = models.IntegerField(default= 0, editable= False)
class Phase(models.Model):
title = models.CharField(max_length= 20)
class ProjectPhase(models.Model):
project = models.ForeignKey(Project, on_delete= models.CASCADE, related_name= 'phase')
phase = models.ForeignKey(Phase, on_delete=models.CASCADE, related_name= 'project')
start_date = models.DateField(default= timezone.now)
end_date = models.DateField(default= timezone.now)
duration = models.IntegerField(default= 0, editable= True)
1. import a js media file in ModelAdmin for Generaldata:
class YourModelAdmin(admin.ModelAdmin):
form = YourModelForm
#list_display = ['your fields',]
class Media:
js = ("yourapp/selectajax.js",)
admin.site.register(YourModel, YourModelAdmin)
2. create a new js file which saved yourproject/yourapp/static/yourapp/ directory or another proper directory.
jQuery(function($){
$(document).ready(function(){
$("#id_project_select").change(function(){
// console.log(obj.currentTarget.value);
$.ajax({
url:"/get_phases/",
type:"POST",
data:{project: $(this).val(),},
success: function(result) {
console.log(result);
cols = document.getElementById("id_phase_select");
cols.options.length = 0;
for(var k in result){
cols.options.add(new Option(k, result[k]));
}
},
error: function(e){
console.error(JSON.stringify(e));
},
});
});
});
});
3. create a view to process ajax
#login_required
def get_phases(request):
project = request.POST.get('project')
phases = {}
try:
if project:
prophases = Project.objects.get(pk=int(project)).phase
phases = {pp.phase.title:pp.pk for pp in prophases}
except:
pass
return JsonResponse(data=phases, safe=False)
4. add 'get_phases/ to urlpatterns.
Notice that you should modify some codes as your need.
The answer by Blackdoor is a good approach and it's the one we just implemented, but it has a couple of problems:
It's only executed when you change the main select, and I wanted the dependant select to be filtered also on page load.
Does not keep que selected item in the dependant select.
In his solution, in step 2, replace his code with this one and adapt the names (I'm using service and sub_service instead of project / phase):
jQuery(function($){
$(document).ready(function(){
var clone = document.getElementById("id_sub_service").cloneNode(true);
$("#id_service").change(function(){
update_sub_services($(this).val(), clone)
});
update_sub_services($("#id_service").val(), clone)
});
function update_sub_services(service, clone) {
$.ajax({
url:"/chained_dropdowns/get_sub_services/",
type:"GET",
data:{service: service,},
success: function(result) {
var cols = document.getElementById("id_sub_service");
cols.innerHTML = clone.innerHTML
Array.from(cols.options).forEach(function(option_element) {
var existing = false;
for (var k in result) {
if (option_element.value == k) {
existing = true
}
}
if (existing == false) {
$("#id_sub_service option[value='"+option_element.value+"']").remove();
}
})
},
error: function(e){
console.error(JSON.stringify(e));
},
});
}
});
As you can see, now instead of removing all the items from the dependant select and then refilling it (which leaves you without the selected property and any other custom property), it removes the options that should not be there.
I'm not a JS developer and I don't know jQuery so my modifications are in native JS, please feel free to improve it :)
I have JSON data gets Vedios data of youtube list. And the following link display structure of my JSON.
<a href="https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&playlistId=UUbW18JZRgko_mOGm5er8Yzg&key=AIzaSyDGm1uzuqPPUGzG-qN7u6gTaS8ApXBJYvw">
Click me to get all list videos ID ...
</a>
And here is the channel with its ID
After analyses of my JASON, I have JSON array named "items" (row 9).
Now all I need to get specific information from all units included with this array "items".
All I need to make a query using JavaScript or c# to return JSON with this specific data
title
description
thumbnails - standard
videoId
Finally, I found a solution for my problem. Not very professional but good for now.
I used Jquery selectors to extract data from my JSON object as following.
$(document).ready(function () {
var jsonLink = "https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&playlistId=PL0zTBP9-UnPaIurxKLr3rfPZwHrFl2mEq&key=AIzaSyDGm1uzuqPPUGzG-qN7u6gTaS8ApXBJYvw&maxResults=50";
$.getJSON(jsonLink).done(function (data) {
var items = [];
$.each(data.items, function (i, item) {
items.push("<li>" + item.snippet.title + "</li>");
if (i === 5) {
return false;
}
});
$("<ul/>", {
"class": "my-new-list",
html: items.join("")
}).appendTo("body");
});
});
On one of my pages I have a for loop to iterate through a list of "Projects" (which is the main model for my website) and display some of their data. The following code is nested in a table and the middle cells removed for redundancy.
foreach (var item in Model.Projects)
{
<tr>
<td>#Html.DisplayFor(modelItem => item.SubmissionNumber)</td>
<td>#Html.DisplayFor(modelItem => item.Status)</td>
<!-- and so on -->
<td>#Html.ActionLink("Detail", "DisplayDetails", new { id = item.ProjectID })</td>
</tr>
}
The "Detail" link in the last cell will ideally make a box pop up (I'm thinking of using a Modal via Bootstrap) containing all of the data for the project. The "DisplayDetails" controller action returns a partial view that presents this information, but since I'm not using JavaScript or anything to render the partial view on the current page it renders it as it's own unformatted page. This is the controller action:
[HttpGet]
public ActionResult DisplayDetails(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Project project = db.Projects.Find(id);
if (project == null)
{
return HttpNotFound();
}
return PartialView("~/Views/Projects/_Detail.cshtml", project);
}
Ideally I would pass the ID to the controller using AJAX like I did below (which is code from another page of my website, again edited to remove redudancy):
$("#show").on("click", function () {
$.ajax({
url: '/Projects/SearchTable',
type: "GET",
data: {
Line1: $('#' + '#Html.IdFor(m => m.Project.ProjectAddress.Line1)').val(),
// and so on
County: $('#' + '#Html.IdFor(m => m.Project.ProjectAddress.County)').val(),
}
}).done(function(partialViewResult) {
$(".wrapper").html(partialViewResult);
$(".wrapper").css('display', 'block');
});
});
And by doing this I can embed the partial view onto the current page instead of it opening as a new page. I'm just not sure how to pass the project ID for a specific row in the table as data to the controller. Is this even possible? If not is there another way to achieve the same result?
You can replace your ActionLink with this:
<td>Details</td>
Then,
$(".details").on("click", function (e) {
e.preventDefault();
var projectId = $(this).data('id');
// Make the AJAX call here...
});
I have two cascading dropdown boxes controlled with JQuery and Ajax objects. The first determines the values in the second. Then, once a selection is made in the second, the values from the two dropdowns would be used to find a record in an SQL table and display the record in an html table.
So far the dropdowns work correctly but I'm having difficulty getting the record from the database and then displaying it on screen. I've done this before by getting the database values, sending them to the view in a Json object, and using an Ajax object to to create the table with Jquery. However, in this case I don't mind if the page reloads and would like to use a simpler method.
What is a simple method of sending two values from two dropdowns to the controller, using those values to find a record in an sql table, sending the values from the record back to the view to be displayed? Also, I don't want anything to be displayed until the second dropdown box has a selection made.
Here is what I have so far:
Controller methods:
List<Car> GetCars()
{
using (var service = new Service())
{
return service.GetCars().OrderBy(x => x.CarName).Select(x => new Car
{
CarId = x.CarId,
CarName = x.CarName
}).ToList();
}
}
List<Color> GetColors(int carId)
{
using (var service = new Services())
{
return service.GetColors(carId).OrderBy(x => x.ColorName).Select(x => new Color
{
ColorId = x.ColorId,
ColorName = x.ColorName
}).ToList();
}
}
[HttpPost]
public ActionResult CurrentSaus(int townCode, int fiscalYear)
{
var colors = GetColors(carId);
return Json(new SelectList(colors, "ColorId", "ColorName"));
}
Jquery methods:
$(document).ready(function () {
$("#Car_CarId").change(function () {
var carId = $(this).val();
var carName = $(":selected", this).text();
// put the car name into a hidden field to be sent to the controller
document.getElementById("Car_CarName").value = carName;
getColors(carId);
})
});
function getColors(carId) {
if (carCode == "") {
$("#Color_ColorId").empty().append('<option value="">-- select color --</option>');
}
else {
$.ajax({
url: "#Url.Action("Colors", "HotWheels")",
data: { colorId: clrId },
dataType: "json",
type: "POST",
error: function () {
alert("An error occurred");
},
success: function (data) {
var colors = "";
var numberOfColors = data.length;
if (numberOfColors > 1) {
colors += '<option value="">-- select color --</option>';
}
else {
var colorId = data[0].Value;
var colorName = data[0].Text;
document.getElementById("Color_ColorName").value = colorName;
}
$.each(data, function (i, color) {
colors += '<option value="' + color.Value + '">' + color.Text + '</option>';
});
$("#Color_ColorId").empty().append(colors);
}
});
}
and some of the html:
#Html.HiddenFor(x => x.Car.CarName)
#Html.HiddenFor(x => x.Color.ColorName)
<table>
<tr>
<td> Select Car:</td>
<td style="text-align:left">
#Html.DropDownListFor(
x => x.Car.CarId,
new SelectList(Model.CarList, "CarId", "CarName"),
"-- select town --")
<br />
#Html.ValidationMessageFor(x => x.Car.CarId)
</td>
</tr>
<tr>
<td> Select Color:</td>
<td colspan="4">
#Html.DropDownListFor(
x => x.Color.ColorId,
new SelectList(Model.ColorList, "ColorId", "ColorName"),
"-- select color --")
<br />
#Html.ValidationMessageFor(x => x.Color.ColorId)
</td>
</tr>
</table>
}
The easiest method is to use an old fashion FORM element and POST the values of the two drop downs to an action in your controller. That action would expect a carId and a colorId and use them to retrieve a record from the DB and then pass the result to your 'view' where you would take care of render/display the result.
Of course using this method has some caveats:
The entire page will refresh after a user selects a value from the
second drop down.
You would have to POST the form using JavaScript
when the user picks the second option, or at least enable a button so
the form can be POSTed.
You would have to keep track of the carId and
colorId in your controller and view
Another option is to use AJAX to POST (send to the server) the carId and colorId where and action in a controller will take care of using those parameters to find a record in the DB and then return a JSON object with the result. The response will be handled by a 'success' handler where you will take care parsing the JSON object and add rows to a table.
So if you feel more comfortable working on the server side of the code pick the first option, however if you prefer to use AJAX and do this in the front end use the later.
I am working on twitter bootstrap typeahead and i am stuck as i am not getting any error and yet the auto complete is not working.
this is my input field
<input type="text" id="autocomplete" />
and this is my script
<script>
$('#autocomplete').typeahead({
source: function(process) {
var data = <?php Widgets::allProducts() ?>;
process(data);
},
matcher: function(item) {
return
item.name.toLocaleLowerCase()
.indexOf(this.query.toLocaleLowerCase()) != -1;
},
highlighter: function(item) {
return item.name;
},
updater: function (item) {
alert(JSON.parse(item).value);
return JSON.parse(item).name;
}
});
</script>
this is how my var data looks like
var data = [{"name":"Acne.org","id":"5"},{"name":"AcneFree","id":"6"},{"name":"Alpha Hydrox","id":"16"},{"name":"AmLactin","id":"17"},{"name":"Astara","id":"21"}];
What i want to do is get the product name listed (which is name in var data ) and upon selecting the product redirect the user to product page (with the help of product id which i am getting in var data as id).
I am just lost at this stage as i am not getting any error. I will appreciate any push to right direction.