Chart.js in MVC application - asp.net-mvc

I have an MVC application with CHart.js.
Iam able to load the CHart.js on the View load event.
I want the Chart.js to be loaded on a html button click event.
On button click the controller is invoked and based on the search condition data is filtered.
I want this filtered content to be displayed on the chart.js.
How do i invoke the javascript function to load the chart on button click after the controller process is done on button click.
Flow should be
1. Enter the filter conditions
2. click button
3. controller fetches the data from the database based on filters
4. then the javascript function in the view is invoked to load the chart.js
Let me know how it has to be done.

For displaying data returned from your Controller in JavaScript you have two options:
The First:
using the razor syntax inside your View to refer to the model returned by the controller. This means that your JavaScript would also be written inside your View.
#model 'yourViewModel'
<div>
//your view html code
</div>
<script>
document.getElementById("button").click(function() {
var chartData= #Html.Raw(Json.Serialize(Model.'nameOfYourModel'));
var ctx = document.getElementById("myChart").getContext('2d');
var myLineChart = new Chart(ctx, {
type: 'line',
data: chartData,
options: options
});
</script>
The Second:
Retrieve the data from your controller trough AJAX, for this I would recommend using the jQuery library. As it makes the syntax easier to write and understand.
var chartData;
$('.button').click(function() { //your button
$.ajax({ // Invoke controller action to retrieve data
url: "path to your controller and its action",
type: 'GET',
success: function(data){
chartData = data;
}
});
var ctx = $("myChart").getContext('2d');
var myLineChart = new Chart(ctx, {
type: 'line',
data: chartData,
options: options
});
}
With this approach you call the controller action that returns your chart data in JSON format.

Related

changing data with respect to time and/or any action in MVC 5 and Entity Framework

I want some data to be modified on the base of time. For example if some data remains in database for longer time its priority field should be changed and It should appear automatically in existing view page without refreshing.
Thank you!
You can achieve this using JQuery AJAX
Controller
This is my controller, here I am passing current date and time as a model to the partial view
public PartialViewResult GetCurrentDateTime()
{
return PartialView("UpdateDate",DateTime.Now);
}
JQuery
In JQuery using window.setInterval function, I have call the action in particular time interval. And bind the partial view result to the div
$(function () {
window.setInterval(yourfunction, 1000);
function yourfunction() {
var name = $(this).find(".name").html();
$.ajax({
url: '/Home/GetCurrentDateTime',
async: false,
cache: false,
success: function (result) {
$("#updateContainer").html(result);
}
});
}
});
In every second the GetCurrentDateTime will get call and display the current date and time. Instead of passing date and time you can pass your model

Synchronize objects across $scope without a service

I am trying to get a piece of code to work where I don't have total control over half of the code. In short, there is 1 main controller that has an object that is then obtained from a second controller. When main controller 1 updates the object, controller 2 never sees it. I think this is because the 2 controllers aren't watching the object/properties (copies?). If you notice, the Angular Binding to {{Title}}, this is where the issue is visible as the "Title" never gets updated in the second controller.
Here is some sample code that shows the problem. Currently, the code does a 3 seconds loop to get the object again, and reassign it to the second controller.
The code here I can't really touch. I have source, but it spaghetti and I am just generalizing what is here.
// html I can't really change, outside my world.
<div id="mainApp" ng-app="MainApp" ng-controller="mainController">
</div>
// code I can't "really" change, non-angular (can't use $http).
$ajax(get...)
.success(function (result) {
$('#element').html(result);
})
The code below is fairly separated and I can tinker with it. The HTML is returned from a service called by the $ajax call above.
// code I can change (the "result", or html returned from the service)
// containerController.js
var containerController = function ($scope, $timeout) {
$scope.models = {
item: null;
}
$scope.getItem = function() {
var mainAppScope = angular.element($('#mainApp')).scope();
$scope.models.item = mainAppScope.GetItem();
}
$scope.getItem();
// HACK WORK AROUND
// Get the item from the mainController.
var itemSync = setInterval(function () {
$scope.getItem();
$scope.$apply();
}, 3000);
}
The HTML returned from the service (it's really an ASP.NET MVC Partial View)
// HTML
<div id="container" ng-app="containerApp" ng-controller="containerController">
<!-- This will bind the first time, but won't syncronize when other controller updates -->
<!-- the controller is currently doing a loop to do so, not good. -->
<div>{{models.item.Title}}</div>
</div>
<script type="text/javascript" src="~/Scripts/controllers/containerController.js"></script>
<script type="text/javascript">
// This will inject the controller and new app into angular.
var container = document.getElementById('container');
var containerApp = angular.module('containerApp', []);
containerApp.controller('containerController', ['$scope', containerController]);
angular.bootstrap(angular.element(container), ['containerApp']);
</script>
You could change hacky part to use $interval which will manage to run digest cycle after each interval
var itemSync = $interval(function () {
$scope.getItem();
}, 3000);
To sync object from parent controller to child controller you could use object structure of model, that will is nothing but Javascript prototypal & will update data.
$scope.pageData = {}; //declare this in parent controller
$scope.pageData.title = 'Title 1' //use this where you want to change in child controller

Single page application using mvc3 knockout.js and sammy.js

I'm stuck on one particular part of my project which consists of the components mentioned in the title.
I currently have a proof of concept that works the way I want it to work:
Sammy is integrated into the knockout viewmodels (as per the tutorial
on the knockout site)
the views are loaded on demand by a controller
(so I don't have to define every single view on the application page)
In my current situation I instance the viewmodels when the application starts (if I don't instance them, Sammy will not handle the routing). The problem is where the view is loaded and swapped by Sammy. I have to make a call to ko.applyBindings for KO to bind to the view. But its bad practice to repeatedly call applybingings.
My question, how do I bind to my views that are loaded on demand? I can't call ko.applybindings since that would create a memoryleak when the view is loaded more than once.
Here is an example VM with the offending ko.applyBindings:
function serviceInfoVm() {
var self = this;
self.ObjectKey = ko.observable();
self.Service = ko.observable();
self.LoadService = function () {
$.get('ServiceData/Detail', { serviceId: self.ObjectKey() }, function (data) {
self.Service(data);
});
};
$.sammy('#content', function () {
this.get('#/service/:id', function (context) {
var ctx = context;
self.ObjectKey(this.params['id']);
self.LoadService();
$.get('Content/ServiceInfo', function (view) {
ctx.app.swap(view);
ko.applyBindings(self);
});
});
}).run();
};
Anyone with some pointers and/or solutions to this problem?
You have the Sammy code in the viewmodel, which can work great if that viewmodel will be present and you want sub viewmodels and views to be loaded. So I assume that is what you are trying to do. Food for thought ... separate the sammy code into its own module (I call mine router in router.js) and let it manage the navigation separate from any viewmodel.
But back to your code ... you could set up your subviews and subviewmodels and use applybindings on them prior to the sammy.get being called. Basically, you are registering your routes in advance. Then the sammy.get just navigates to the new view, which is already data bound.
Not a solution but another approach:
Ended up abandoning the idea of loading the views dynamically.
Now my views are always present in the page and the visibility is triggered by this code:
var app = function () {
var self = this;
self.State = ko.observable('home');
self.Home = ko.observable(new homepageVm());
self.User = ko.observable(new userInfoVm());
$.sammy(function () {
this.get('#/', function (context) {
self.State('home');
});
this.get('#/info/:username', function (context) {
self.State('user');
self.User().UserName(context.params['username']);
self.User().LoadInfo();
});
}).run();
};
And the div visibility is triggered this way:
<div id="homeView" data-bind="with: Home, visible: State() === 'home'">
This way the ko.applyBindings only needs to be called once when the app starts.
The viewmodel above is bound to our shell page.
More on this here
Calling applyBindings on the specific element in the returned template is an option:
ko.applyBindings(viewModel, htmlNode)
Also see this question with regard to lazy loading templates: knockout.js - lazy loading of templates
And docs here for applyBindings: http://knockoutjs.com/documentation/observables.html

Backbone reset event bound to collection not firing when collection is loaded with data

I am new to Backbone and started by working through the Todos example. After that I created a new version of the example, for Contacts rather than Todos, that uses a Ruby on Rails web app and and it's associated REST API rather than localstorage for persistence. After making the modifications I am able to successfully have the Backbone app update the Rails app but I cannot get the Backbone views to render the data that the Backbone app receives from the Rails REST API. I have stepped through the code in the debugger and can see that:
the events that call the functions to populate the views are being bound to the collection of models
when I fetch the model data the collection is getting updated with the data from the server
however, the reset event bound to the collection does not fire
Can anybody point me to what might be causing the reset event to not fire? My code is below:
Collection:
var ContactsList = Backbone.Collection.extend({
model: Contact,
url: 'http://localhost:3000/contacts.json',
});
var Contacts = new ContactsList;
AppView:
var AppView = Backbone.View.extend({
el: $("#contactapp"),
events: {
"keypress #new-contact": "createOnEnter"
},
initialize: function() {
this.input = this.$("#new-contact");
Contacts.bind('add', this.addOne, this);
Contacts.bind('reset', this.addAll, this);
Contacts.bind('all', this.render, this);
Contacts.fetch();
},
addOne: function(contact) {
var view = new ContactView({model: contact});
this.$("#contact-list").append(view.render().el);
},
addAll: function() {
Contacts.each(this.addOne);
},
createOnEnter: function(e) {
if (e.keyCode != 13) return;
if (!this.input.val()) return;
Contacts.create({first_name: this.input.val()});
this.input.val('');
},
});
var App = new AppView;
You're probably getting an empty jQuery selector returned by the el: $("#contactsapp") configuration in your view.
http://lostechies.com/derickbailey/2011/11/09/backbone-js-object-literals-views-events-jquery-and-el/
don't use jQuery selectors as object literal values. with Backbone's view, you can just provide the selector string:
el: "#contactsapp"
but this is a bad idea anyways. you should let the view render it's own el, and use other code to populate the "#contactsapp" element with the view:
$(function(){
view = new AppView();
view.render();
$("#contacts").html(view.el);
});
See the above link for more info.
After much debugging I found that the bound reset event was not being fired because I was using an old version of backbone.js. In the version I was using the refresh event was being fired not the reset event. Once I upgraded to the newer version of backbone.js the reset event fired

How do you capture the response text for an ajax:success event handler?

I am probably missing something obvious, but I'm new to Prototype, coming from jQuery. I have a link created using link_to and remote=>true that output an AJAX link that is working.
Here is the JS I have:
Event.observe(window, 'load', function() {
$$('.checkoff-link').each(function(element) {
element.observe('ajax:success', successfulCheckOff);
});
});
// when they tick it off, check it off
function successfulCheckOff(e) {
// shrink and strike out the text
var element = e.element();
var label = $(getLabelIdFromLinkId(element.id));
label.addClassName('strikeout');
}
How do I get the responseText of the ajax request? I'm trying to pass data back from my controller on success, and I don't know how to capture it in the JS tier.
I figured this out using this handy tutorial:
https://github.com/rails/prototype-ujs
Essentially, all of the response information is stored in event.memo, so you can use code like this:
var response = e.memo;
To then access everything you need.
And you can get the HTML/Text/JSON from the response using the responseText method:
var html_return = e.memo.responseText;

Resources