I have a controller and a method called "CreateGAStatisticsReport" that is returning a list with data from google analytics. In the controller I also have two ActionResults, "GaStatistics" that returns a "ListModel" which is used to add controls to the view and "GetData" which returns the data from "CreateGAStatisticsReport" to the view.
In the view I have some JavaScript that draws charts from Google Charts API, i also have some controls that are not currently being used except the DropDownList which is populated with some selectables.
I'm wondering how to connect the button to the method ""CreateGAStatisticsReport"", I simply want this method to run and load the report/charts after the user has clicked the button. I've tried using [HttpPost] and I've also made some JavaScript for the button but I can't get it to work. How do I approach this?
Controller:
[AdminAuthorize]
public class GAStatisticsController : Controller
{
//GET: /ShopStatistics/
[HttpPost]
public ActionResult GetData()
{
return Json(CreateGAStatisticsReport(), JsonRequestBehavior.AllowGet);
}
public ActionResult GAStatistics()
{
return View(new GAStatisticsListModel());
}
private List<GAStatistics> CreateGAStatisticsReport()
{
var serviceAccountEmail = "xxxxxxxxx#developer.gserviceaccount.com";
var certificate = new X509Certificate2(#"C:\Users\Desktop\NopCommerce\Presentation\Nop.Web\key.p12", "notasecret", X509KeyStorageFlags.Exportable);
var credential = new ServiceAccountCredential(
new ServiceAccountCredential.Initializer(serviceAccountEmail)
{
Scopes = new[] { AnalyticsService.Scope.Analytics }
}.FromCertificate(certificate));
// Create the service.
var GoogleAnalyticsService = new AnalyticsService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "MyApp",
});
var request = GoogleAnalyticsService.Data.Ga.Get("ga:xxxxxxxx", "2014-01-24", "2014-01-30", "ga:visitors");
//Specify some addition query parameters
request.Dimensions = "ga:date";
request.Sort = "-ga:date";
request.MaxResults = 10000;
//Execute and fetch the results of our query
Google.Apis.Analytics.v3.Data.GaData d = request.Execute();
List<GAStatistics> ListGaVisitors = new List<GAStatistics>();
foreach (var row in d.Rows)
{
GAStatistics GaVisits = new GAStatistics(row[0], row[1]);
ListGaVisitors.Add(GaVisits);
}
return ListGaVisitors;
}
}
View:
#model GAStatisticsListModel
#using Nop.Admin.Models.GAStatistics;
#using Telerik.Web.Mvc.UI;
#using Nop.Admin.Controllers;
#using System.Web.Mvc.Html;
#{
ViewBag.Title = "GAStatistics";
Layout = "~/Administration/Views/Shared/_AdminLayout.cshtml";
}
<h2>Google Analytics statistics</h2>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load("visualization", "1", { packages: ["corechart"] });
google.load("visualization", "1", { packages: ["treemap"] });
google.setOnLoadCallback(drawChart);
function drawChart() {
$.get('/GAStatistics/GetData', {},
function (data) {
var tdata = new google.visualization.DataTable();
tdata.addColumn('date', 'Datum');
tdata.addColumn('number', 'Besökare');
//tdata.addColumn('number', 'Expense');
for (var i = 0; i < data.length; i++) {
var dateStr = data[i].Date.substr(0, 4) + "-" + data[i].Date.substr(4, 2) + "-" + data[i].Date.substr(6, 2);
tdata.addRow([new Date(dateStr), parseInt(data[i].Visitors)]);
}
var options = {
title: "Antal unika besökare per datum"
};
var chart1 = new google.visualization.AreaChart(document.getElementById('chart_div1'));
var chart2 = new google.visualization.LineChart(document.getElementById('chart_div2'));
//var chart3 = new google.visualization.PieChart(document.getElementById('chart_div3'));
var chart4 = new google.visualization.ColumnChart(document.getElementById('chart_div4'));
chart1.draw(tdata, options);
chart2.draw(tdata, options);
//chart3.draw(tdata, options);
chart4.draw(tdata, options);
});
}
$(function () {
$('GAStatisticsReport-Submit').click(function () {
$.post("#Url.Action("GetData","GAStatistics")");
});
});
</script>
<table class="adminContent">
<tr>
<td class="adminTitle">
#Html.NopLabelFor(model => model.StartDate):
</td>
<td class="adminData">
#Html.EditorFor(model => model.StartDate)
</td>
</tr>
<tr>
<td class="adminTitle">
#Html.NopLabelFor(model => model.EndDate):
</td>
<td class="adminData">
#Html.EditorFor(model => model.EndDate)
</td>
</tr>
<tr>
<td class="adminTitle">
#Html.NopLabelFor(model => model.GAStatisticsId ):
</td>
<td class="adminData">
#Html.DropDownList("GAStatisticsId", Model.AvailableGAStatistics)
<input type="button" id="GAStatisticsReport-Submit" class="t-button" value="#T("Admin.Common.Search")" />
</tr>
</table>
<div class="t-widget t-grid">
<table cellspacing="0">
<thead class="t-grid-header">
<tr>
<th class="t-header" scope="col">
<span class="t-link">Yt-Diagram</span>
</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<div id="chart_div1" style="width: 900px; height: 500px;"></div>
</td>
</tr>
</tbody>
</table>
</div>
<div class="t-widget t-grid">
<table cellspacing="0">
<thead class="t-grid-header">
<tr>
<th class="t-header" scope="col">
<span class="t-link">Linje-Diagram</span>
</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<div id="chart_div2" style="width: 900px; height: 500px;">
</div>
</td>
</tr>
</tbody>
</table>
</div>
<div class="t-widget t-grid">
<table cellspacing="0">
<thead class="t-grid-header">
<tr>
<th class="t-header" scope="col">
<span class="t-link">Stapel-diagram</span>
</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<div id="chart_div4" style="width: 900px; height: 500px;">
</div>
</td>
</tr>
</tbody>
</table>
</div>
You cannot call the private method as Actions in MVC
You should return MVC supported ViewResult
All you need is you simply call GetData action which does everything for you, But remove JsonRequestBehavior.AllowGet, since you are decorated with [HttpPost]
Make sure you are making POST request
Related
I have a view which shows the list of files from a folder and the file count may differ for every user
my view is as follows
<div class="container" style="padding-top:10px; height:100%; width:100%;padding:0;margin:0;">
<table class="table table-bordered table-striped">
<thead>
<tr style="text-align:center;">
<th>File Name</th>
<th>Download</th>
</tr>
</thead>
<tbody>
#foreach (handbook.Data.EmpDoc files in Model)
{
<tr style="text-align:center;">
<td>
<input type="checkbox" id="chk(#files.Filename)" />
</td>
<td>#files.Filename</td>
<td class="text-nowrap">#Html.ActionLink("Download", "DownloadFile", new { fileName = files.Filename, id = files.EmployeeId })</td>
</tr>
}
</tbody>
</table>
</div>
and this is the script i am using to check if the check box is checked
<script>
// this is the scrpt for checkbox
$(document).on("click", "[type='checkbox']", function (e) {
if (this.checked) {
$(this).attr("value", "1");
} else {
$(this).attr("value", "0");
}
});
</script>
I am able to generate id for each file like chkDocs or chkpayslip but when i click in it, it sends value =0 to the controller
please help
I am quite new to ASP.NET with razor, I think I may have gotten a concept wrong.
All I am doing is instantiating my model, letting it retrieve data from the local db and returning it to the view.
The code is working fine, but when I put a stop point into the beginning of the GET it runs into that stoppoint literally hundreds of times before coming to a result.
This of course impacts performance massively.
Let me show you what I have done (briefly):
My controller has one ref to the model:
public class GlobalTaggingController : BaseCmsEditorController
{
public GlobalTaggingViewModel model = new GlobalTaggingViewModel();
public ActionResult Index(string searchword = "")
{
return View(model);
}
// ... cut for brevity
}
The viewmodel looks like that:
public class GlobalTaggingViewModel : BaseViewModel
{
public List<NodeModel> MainNodes
{
get
{
var globalTaggingLocalizedManager = new GlobalTaggingLocalizationManager();
var manager = new GlobalTaggingManager();
var mainlevel = manager.GetAllItemsOnLevel(0);
var subLevel = manager.GetAllItemsOnLevel(1);
var subsubLevel = manager.GetAllItemsOnLevel(2);
var resMainCat = new List<NodeModel>();
// ... cut for brevity
}
}
}
This is my view (which is very long and has many loops):
#model Application.Areas.Administration.Models.GlobalTaggingViewModel
#{
ViewBag.Title = "Administration - Video";
var positionNr = 0;
}
<form action="#Url.Action("Index")" method="POST" id="mainForm">
<div class="divHeader Administration">
<div class="divHeaderInner">
for (int i = 0; i < Model.MainNodes.Count(); i++)
{
string catId = "CatId" + i.ToString();
string classToHideCatId = "classToHideCatId" + i.ToString();
string rowCounter = "rowCounter" + i.ToString();
<tr class="mainCatRow">
<td>
<table class="mytable">
<thead>
</thead>
<tr class="#rowCounter rowHeight">
<td class="column0">
<div>
<img src="#Url.Content("~/Content/images/icons/icon-open.png")" id="#catId" class="buttonLayoutMain" />
</div>
</td>
<td class="column1">
<table class="tableInCol1">
<tr>
<td class="editButtonClassLeft">
<div class="mainCat">
#Model.MainNodes[i].name
</div>
</td>
<td class="editButtonClassRight">
<div>
<a onclick="javascript:Base.Popup.Open('#Url.Action("Index", "GlobalTaggingEditor", new {area = "Cms", id = Model.MainNodes[i].Id})', 1236, 800); return false;" href="#" class="ButtonEdit"><span class="mif-pencil"></span></a>
</div>
</td>
</tr>
</table>
<td>
<td>
<div class="mainCat mainCol">
#Model.MainNodes[i].nameEng
</div>
<td>
<td>
<div class="mainCat mainCol">
#Model.MainNodes[i].name
</div>
<td>
<td>
<div class="mainCat mainCol">
#Model.MainNodes[i].nameSpanisch
</div>
<td>
<td>
<div class="mainCat mainCol">
#Model.MainNodes[i].nameFra
</div>
<td>
<td>
<div class="mainCat mainCol">
#Model.MainNodes[i].namePort
</div>
<td>
<td>
<div class="mainCat mainCol">
#Model.MainNodes[i].nameRuss
</div>
<td class="column9">
Again this is working code, but it is called over and over and over again.
Did I maybe set something up wrong?
EDIT:
Going through my code in single steps, I found out that my model is recreated again once I am going through the razor page.
Specifically here:
<td class="column1">
<table class="tableInCol1">
<tr>
<td class="editButtonClassLeft">
<div class="mainCat">
#Model.MainNodes[i].name
</div>
</td>
<td class="editButtonClassRight">
<div>
<a onclick="javascript:Base.Popup.Open('#Url.Action("Index", "GlobalTaggingEditor", new {area = "Cms", id = Model.MainNodes[i].Id})', 1236, 800); return false;" href="#" class="ButtonEdit"><span class="mif-pencil"></span></a>
</div>
</td>
</tr>
</table>
Why would that start the model over again?
Ok, so as I put everything inside the GET of the model, intead of doing it over a constructor, I was able to get around this issue.
I created a simple table in Vue.js that displaying all data in my database and I want to have a sorting function.
It should be triggered when I click on the table header ('Jenis Barang'). Is it possible? This is the table
This is the service in C#:
(It fetches all data from database)
public async Task<List<JenisBarangModel>> GetAllJenisBarang(int pageIndex, int itemPerPage, string filterByJenisBarang)
{
var query = this._timurRayaDbContext
.TbJenisBarang
.AsQueryable();
if (string.IsNullOrEmpty(filterByJenisBarang) == false)
{
query = query
.Where(Q => Q.NamaJenisBarang.ToLower().Contains(filterByJenisBarang));
}
var jenisBarangData = await query
.Select(Q => new JenisBarangModel
{
IDJenisBarang = Q.IdjenisBarang,
NamaJenisBarang = Q.NamaJenisBarang
})
.Skip((pageIndex - 1) * itemPerPage)
.Take(itemPerPage)
.AsNoTracking()
.ToListAsync();
return jenisBarangData;
}
The template part
<template>
<div>
<div>
<br />
<h3 class="text-center">List Jenis Barang</h3>
<button class="btn btn-success float-left" type="button" #click="addNewJenisBarang">
<fa-icon icon="plus-square"></fa-icon>
Input Jenis Barang Baru
</button>
</div>
<br />
<div>
<h6 class="text-right">
Tampilkan <select v-model="pageSizes"> </select> jenis barang per halaman
</h6>
<table class="table table-bordered table-hover">
<thead class="thead-dark">
<tr>
<th scope="col" class="text-center">No.</th>
<th scope="col" class="text-center">Jenis Barang</th>
<th scope="col" class="text-center">Ubah</th>
<th scope="col" class="text-center">Hapus</th>
</tr>
<tr class="thead-light">
<th colspan="4" class="text-center">
<span>Cari: </span>
<input class="col-md-4" placeholder="Cari berdasarkan jenis barang" type="text" v-model="filterByJenisBarang" #change="fetch()" />
</th>
</tr>
</thead>
<tbody>
<tr class="text-center" v-for="(jenisBarang,index) in jenisBarangList" :key="index">
<td>{{index + 1}}</td>
<td>{{jenisBarang.namaJenisBarang}}</td>
<td>
<a class="btn btn-warning" :href="'/update-jenis-barang?idJenisBarang='+jenisBarang.idJenisBarang">
<fa-icon icon="edit"></fa-icon>
</a>
</td>
<td>
<button class="btn btn-danger" #click="deleteJenisBarang(jenisBarang)">
<fa-icon icon="trash"></fa-icon>
</button>
</td>
</tr>
</tbody>
</table>
<div class="row">
<div class="col-md-10">
<ul class="pagination">
<li v-for="page in totalPage" class="page-item">
<button #click="changePage(page)">{{page}}</button>
</li>
</ul>
</div>
</div>
</div>
</div>
</template>
The script part
<script lang="ts">
import Vue from 'vue';
import Component from 'vue-class-component';
import { TimurRayaService, JenisBarangModel } from '../services/NSwagService';
import { ValidationObserver } from 'vee-validate';
import swal from 'sweetalert2';
#Component({
created: async function (this: JenisBarang) {
await this.fetch();
}
})
export default class JenisBarang extends Vue {
service: TimurRayaService = new TimurRayaService();
jenisBarangList: JenisBarangModel[] = [];
newJenisBarang: JenisBarangModel = {
idJenisBarang: 0,
namaJenisBarang: ''
}
filterByJenisBarang = '';
pageIndex = 1;
itemPerPage = 5;
totalData = 1;
totalPage = 1;
async fetch(): Promise<void> {
this.totalData = await this.service.getTotalJenisBarang();
this.totalPage = Math.ceil(this.totalData / this.itemPerPage);
this.jenisBarangList = await this.service.getJenisBarang(this.pageIndex, this.itemPerPage, this.filterByJenisBarang);
}
async changePage(page: number): Promise<void> {
this.pageIndex = page;
await this.fetch();
}
}
</script>
Any help would be meaningful, thank you!
You can sort in backend with .OrderBy(x => x.NamaJenisBarang). You can do very similar things in front-end also
jenisBarangList.sort() and also you can use a custom function for sorting jenisBarangList.sort(function(a, b){return a-b})
I would create a computed property which sorts acending or decending based on a boolean. Then use the computed property in your template. Something like this:
<script>
export default {
data () {
return {
sortDesc: true
};
},
computed: {
sortedList () {
return this.jenisBarangList
.sort((a,b) => this.sortDesc ? a.key - b.key : b.key - a.key)
}
},
methods: {
toggleSort () {
this.$set(this, 'sortDesc', !this.sortDesc)
}
}
}
</script>
I have this view that loops a collection so that, using KO, it can do very basic pagination. Now, the last column for the table is just a bunch of actions for the record in each row. If this were simple MVC generated table, they would carry the proper Id in the generated URL.
Not anymore.
#using Newtonsoft.Json
#model IEnumerable<SensorSauce.Models.Business>
#{
ViewBag.Title = "Business Manager";
}
<h2>Business Manager</h2>
<table class="table table-striped table-bordered">
<thead>
<tr>
<td><strong>#Html.DisplayNameFor(model => model.Name)</strong></td>
<td><strong>#Html.DisplayNameFor(model => model.ServiceType)</strong></td>
<td><strong>#Html.DisplayNameFor(model => model.Specialties)</strong></td>
<td><strong>Actions</strong></td>
</tr>
</thead>
<tbody data-bind="foreach:currentBusinesses">
<tr>
<td data-bind="text:Name"></td>
<td data-bind="text:ServiceType"></td>
<td data-bind="text:Specialties"></td>
<td >
|
|
|
</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="4">
<span data-bind="click:previousPage,visible:currentPage() > 1" class="glyphicon glyphicon-circle-arrow-left" style="cursor: pointer"></span>
Page #: <span data-bind="text:currentPage"></span>
<span data-bind="click:nextPage,visible:currentPage() < lastPage" class="glyphicon glyphicon-circle-arrow-right" style="cursor: pointer"></span>
</td>
</tr>
<tr>
<td >
<span class="glyphicon glyphicon-plus-sign"></span> Create Business
</td>
<td></td>
<td></td>
<td></td>
</tr>
</tfoot>
</table>
And here is the script after the above table:
<script src="~/Scripts/knockout-3.3.0.js"></script>
<script>
function BusinessViewModel() {
var self = this;
// properties
self.businesses = #Html.Raw( JsonConvert.SerializeObject(Model, new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore }));
self.pageSize = 10;
self.currentPage = ko.observable(1);
self.lastPage = Math.ceil(self.businesses.length / self.pageSize);
self.currentBusinesses = ko.computed(function() {
var startIndex = (self.currentPage() - 1) * self.pageSize;
var endIndex = startIndex + self.pageSize;
return self.businesses.slice(startIndex, endIndex);
});
// methods
self.nextPage = function() {
self.currentPage(self.currentPage() + 1);
};
self.previousPage = function() {
self.currentPage(self.currentPage() - 1);
};
}
ko.applyBindings(new BusinessViewModel());
</script>
The action for Edit, Delete, and Details etc require the parameter to be passed to the controller's action. Rendering the table like above creates an issue that the actions such as Details never receives the ID parameter.
I need to bind something to the Id property of the Model and combine it with the Url.Action() method's generated Url. Or so i understand.
Any suggestions?
You can use the attr binding and combing the URL generated by the URL.Action with the businessId (I am assuming that is what you are calling your Business Model's Id) just like the sample below ...
<a data-bind="attr: { href: '#Url.Action("MapLocation", "Business")'+'?BusinessId='+BusinessId()" class="glyphicon glyphicon-map-marker"></a>
I have an ActionResult with httpPost -attribute. If I'm not mistaken I need this attribute when the user are choosing a date from a DateTimePicker. In my case I have 2 Datetimepickers av type #html.EditorFor. These datepickers represent the DateTime properties StartDate and EndDate from my view model. These dates are suposed to be able for usage in the Controller and CreateGAStatisticsReport method after clicking "GAStatisticsReport-Submit" button as CreateGAStatisticsReport has the model as parameeter. However after I have chosen StartDate and EndDate nothing happens.
If I remove the HttpPost attribute from ActionResult GetData the method runs as expected except StartDate and EndDate will be Null. I don't know if the problem is model binding, HttpPost, html.BeginForm or the javascript logic for the submit button. Tried all kinds of things.
What am I missing here?
CreateGAStatisticsListModel:
[NopResourceDisplayName("Admin.GAStatistics.GAStatistics.StartDate")]
[UIHint("DateNullable")]
public DateTime? StartDate { get; set; }
[NopResourceDisplayName("Admin.GAStatistics.GAStatistics.EndDate")]
[UIHint("DateNullable")]
public DateTime? EndDate { get; set; }
GaStatisticsController (GetData is run when i click submitbutton):
[HttpPost]
public ActionResult GetData(GAStatisticsListModel model)
{
return Json(CreateGAStatisticsReport(model), JsonRequestBehavior.AllowGet);
}
public ActionResult GAStatistics()
{
return View(new GAStatisticsListModel());
}
public List<GAStatistics> CreateGAStatisticsReport(GAStatisticsListModel model)
{
var serviceAccountEmail = "xxxxxxxxxxxxxx#developer.gserviceaccount.com";
var certificate = new X509Certificate2(#"C:\Users\user\Desktop\NopCommerce\Presentation\Nop.Web\key.p12", "notasecret", X509KeyStorageFlags.Exportable);
var credential = new ServiceAccountCredential(
new ServiceAccountCredential.Initializer(serviceAccountEmail)
{
Scopes = new[] { AnalyticsService.Scope.Analytics }
}.FromCertificate(certificate));
// Create the service.
//Twistandtango
var GoogleAnalyticsService = new AnalyticsService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "Twist",
});
string start = model.StartDate.ToString(); //<----- The model date values are needed here
model.StartDate = DateTime.ParseExact(start, "yyyy-MM-dd", CultureInfo.InvariantCulture);
string end = model.EndDate.ToString(); //<----- The model date values are needed here
model.EndDate = DateTime.ParseExact(end, "yyyy-MM-dd", CultureInfo.InvariantCulture);
var request = GoogleAnalyticsService.Data.Ga.Get("ga:xxxxxxxx", start, end, "ga:visitors");
//Specify some addition query parameters
request.Dimensions = "ga:date";
request.Sort = "-ga:date";
request.MaxResults = 10000;
//Execute and fetch the results of our query
Google.Apis.Analytics.v3.Data.GaData d = request.Execute();
List<GAStatistics> ListGaVisitors = new List<GAStatistics>();
foreach (var row in d.Rows)
{
GAStatistics GaVisits = new GAStatistics(row[0], row[1]);
ListGaVisitors.Add(GaVisits);
}
return ListGaVisitors;
}
View (The problem might be here in the view, need to tell the button to store the dates choosen in the DateTimePickers so I can use them in the controller):
#model GAStatisticsListModel
#using Nop.Admin.Models.GAStatistics;
#using Telerik.Web.Mvc.UI;
#using Nop.Admin.Controllers;
#using Telerik.Web.Mvc.UI.Html;
#using System.Web.Mvc;
#using System.Linq;
#{
ViewBag.Title = "GAStatistics";
Layout = "~/Administration/Views/Shared/_AdminLayout.cshtml";
}
#using (Html.BeginForm())
{
<h2>Google Analytics Statistic Reports</h2>
<table class="adminContent">
<tr>
<td class="adminTitle">
#Html.NopLabelFor(model => model.StartDate):
</td>
<td class="adminData">
#Html.EditorFor(model => model.StartDate)
</td>
</tr>
<tr>
<td class="adminTitle">
#Html.NopLabelFor(model => model.EndDate):
</td>
<td class="adminData">
#Html.EditorFor(model => model.EndDate)
</td>
</tr>
<tr>
<td class="adminTitle">
#Html.NopLabelFor(model => model.GAStatisticsId ):
</td>
<td class="adminData">
#Html.DropDownList("GAStatisticsId", Model.AvailableGAStatistics)
<input type="button" id="GAStatisticsReport-Submit" class="t-button" value="#T("Admin.Common.Search")" />
</tr>
</table>
<div class="t-widget t-grid">
<table cellspacing="0">
<thead class="t-grid-header">
<tr>
<th class="t-header" scope="col">
<span class="t-link">Area Chart</span>
</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<div id="chart_div1" style="width: 900px; height: 500px;"></div>
</td>
</tr>
</tbody>
</table>
</div>
<div class="t-widget t-grid">
<table cellspacing="0">
<thead class="t-grid-header">
<tr>
<th class="t-header" scope="col">
<span class="t-link">Line Chart</span>
</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<div id="chart_div2" style="width: 900px; height: 500px;"></div>
</td>
</tr>
</tbody>
</table>
</div>
<div class="t-widget t-grid">
<table cellspacing="0">
<thead class="t-grid-header">
<tr>
<th class="t-header" scope="col">
<span class="t-link">Column Chart</span>
</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<div id="chart_div4" style="width: 900px; height: 500px;"></div>
</td>
</tr>
</tbody>
</table>
</div>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript" src="/Scripts/jquery.min.js"></script>
<script type="text/javascript">
//Submit button
$('#GAStatisticsReport-Submit').click(function () {
var grid = $('#GetData').data('tGrid');
function onDataBinding(e) {
var searchModel = {
StartDate: $('##Html.FieldIdFor(model => model.StartDate)').val(),
EndDate: $('##Html.FieldIdFor(model => model.EndDate)').val(),
};
e.data = searchModel;
}
$("#GAStatisticsReport-Submit").click(function () {
if ($("select[name='GAStatisticsId'] option:selected").text() == "Visitors")
drawChart()
})
google.load("visualization", "1", { packages: ["corechart"] });
google.load("visualization", "1", { packages: ["treemap"] });
function drawChart() {
$.get('/GAStatistics/GetData', {},
function (data) {
var tdata = new google.visualization.DataTable();
tdata.addColumn('date', 'Date');
tdata.addColumn('number', 'Visitors');
for (var i = 0; i < data.length; i++) {
var dateStr = data[i].Date.substr(0, 4) + "-" + data[i].Date.substr(4, 2) + "-" + data[i].Date.substr(6, 2);
tdata.addRow([new Date(dateStr), parseInt(data[i].Visitors)]);
}
var options = {
title: "Antal unika besökare per datum"
};
var chart1 = new google.visualization.AreaChart(document.getElementById('chart_div1'));
var chart2 = new google.visualization.LineChart(document.getElementById('chart_div2'));
var chart4 = new google.visualization.ColumnChart(document.getElementById('chart_div4'));
chart1.draw(tdata, options);
chart2.draw(tdata, options);
chart4.draw(tdata, options);
});
}
</script>
}
Sorry for all the text. Anny help would be greatly appreciated.
Using $.get( will issue an HttpGet request. The target in your code is '/GAStatistics/GetData' which is the action GetData in your GAStatistics controller. However, that method is marked with [HttpPost] and thus is not exposed to get requests.
Either use $.post( or mark the action with [HttpGet].