In an effort to learn more about Sencha Touch I am building a calendar webapp for our university. I have some scripts that work but the problem is when I try to update the listPanel with the JSON data from Events.php. I am getting the data from the page but the update command is not updating the listPanel and instead for some reason that I can't put my finger on is asking for the events variable which is commented out. Now if I uncomment that variable it will parse the JSON in that variable but for the life of me i have no idea why.
Here is the the index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Student Calendar</title>
<link rel="stylesheet" href="css/ext-touch.css" type="text/css"/>
<script type="text/javascript" src="js/ext-touch.js"></script>
<script type="text/javascript" src="js/calendar.js"></script>
<link rel="stylesheet" href="css/calendar.css" type="text/css"/>
</head>
<body>
<textarea id="eventList" class="x-hidden-display">
<ul id="eventsItems">
<tpl for=".">
<li class="date">
{date}
<li>
<tpl for="events">
<li>{title} - {location}</li>
</tpl>
</tpl>
</ul>
</textarea>
<textarea id="eventList" class="x-hidden-display">
<ul id="eventsDescriptionList">
<tpl for=".">
<li class="date">
{date}
<li>
<tpl for="events">
<li>{title} - {location}</li>
</tpl>
</ul>
</textarea>
<textarea id="eventDescription" class="x-hidden-display">
<tpl for=".">
<p>{title}</p>
<p>{description}</p>
<p>{location}</p>
<p>{startTime}</p>
</tpl>
</textarea>
</body>
</html>
Here is the calendar.js
Ext.setup({
onReady:function(){
eventListTemplate = Ext.XTemplate.from("eventList");
descriptionTemplate = Ext.XTemplate.from("eventDescription");
eventTapHandler = function(eventer,tapped){
tapID = tapped.id;
/*Pass Into The Ajax Portion for getting a events description*/
Ext.Ajax.request({
params:{
/*params are available inside of the Ajax request*/
needs:eventDescription,
panel:"descript",
id:tapID,
fails:rootPanel
},
url: 'Events.php',
method:'POST',
success: function(response, opts) {
/*Ext.uitl.JSON.decode() is used to change the response text to a JSON object*/
opts.params.needs.update(Ext.util.JSON.decode(response.responseText));
},
failure: function(response, opts) {
alert("Sorry There Was An Error");
opts.params.fails.setCard(0);
}
});
rootPanel.setCard(1);
}
eventBackHandler = function(){
rootPanel.setCard(0);
}
backButton = {
text:'Back',
ui:'back',
cls:'.backable',
handler:eventBackHandler
}
toolBarBack = new Ext.Toolbar({
dock:'top',
title:'Event Desciption',
cls:'toolBar',
items:[backButton],
});
listPanel = new Ext.Panel({
tpl:eventListTemplate,
scroll:'vertical',
tester:function()
{
alert('MAGIC');
},
getEvent:function(){
var currentPanel = this;
Ext.Ajax.request({
params:{
/*params are available inside of the Ajax request*/
panel:"list",
needs:currentPanel,
fails:rootPanel
},
url: 'Events.php',
method:'POST',
success: function(response, opts) {
var data = Ext.util.JSON.decode(response.responseText);
//opts.params.needs.tester();
/*Ext.uitl.JSON.decode() is used to change the response text to a JSON object*/
opts.params.needs.update(data);
},
failure: function(response, opts) {
alert("Sorry There Was An Error");
}
});
},
listeners: {el: {tap: eventTapHandler,delegate: '.touchable'}}
});
eventDescription = new Ext.Panel({
tpl:descriptionTemplate,
scroll:'vertical',
dockedItems:[toolBarBack]
});
rootPanel = new Ext.Panel({
fullscreen:true,
layout:"card",
animation: 'fade',
items:[listPanel,eventDescription]
});
//Offending Variable
//var events = [{id:1,title:'this is a title',location:'here and now',startTime:'Right behind you'},{id:2,title:'this is a title2',location:'here and now2',startTime:'Right behind you2'}]
//alert("done");
listPanel.getEvent();
}
});
Here is the events.php Sql and database names have been changed to protect the innocent
<?
$dbname = "magicalDatabase";
require_once("../../../db_setup.inc");
If($_POST['panel'] == "list" )
{
$currentMonth = date("m");
$currentYear = date("Y");
mysql_real_escape_string($currentMonth);
mysql_real_escape_string($currentYear);
$sql = "SELECT * FROM magicalcalendar WHERE calendar_start_year = '$currentYear' AND calendar_start_month = '$currentMonth' AND calendar_channel_guid = 'CurrentStudentsMain' ORDER BY calendar_start_month, calendar_start_day ASC";
$results = mysql_query($sql)or die(mysql_error()."------".__LINE__."-----$sql");
$dayCounts[01] = 31;
$dayCounts[02] = 29;
$dayCounts[03] = 31;
$dayCounts[04] = 30;
$dayCounts[05] = 31;
$dayCounts[06] = 30;
$dayCounts[07] = 31;
$dayCounts[08] = 31;
$dayCounts[09] = 30;
$dayCounts[10] = 31;
$dayCounts[11] = 30;
$dayCounts[12] = 31;
for($j=1;$j<$dayCounts[$currentMonth];$j++)
{
if($j<10)
{
$responce['0'.$j]['date'] = date(M)." - $j";
}
else{
$responce[$j]['date'] = date(M)." - $j";
}
}
while($event = mysql_fetch_array($results))
{
$responce[$event['calendar_start_day']]['events'][$event['calendar_id']]['id'] = $event['calendar_id'];
$responce[$event['calendar_start_day']]['events'][$event['calendar_id']]['title'] = $event['calendar_subject'];
$responce[$event['calendar_start_day']]['events'][$event['calendar_id']]['location'] = $event['calendar_location'];
$responce[$event['calendar_start_day']]['events'][$event['calendar_id']]['startTime'] = $event['calendar_start_month']."-".$event['calendar_start_day']."-".$event['calendar_start_year'];
}
echo json_encode($responce);
}
If($_POST['panel'] == "descript")
{
$id = $_POST['id'];
mysql_real_escape_string($id);
$sql = "SELECT * FROM magicalcalendar WHERE calendar_id = $id";
$results = mysql_query($sql)or die(mysql_error()."------".__LINE__."-----$sql");
$i=0;
while($event = mysql_fetch_array($results))
{
$responce['id'] = $event['calendar_id'];
$responce['description'] = $event['calendar_text'];
$responce['title'] = $event['calendar_subject'];
$responce['location'] = $event['calendar_location'];
$responce['startTime'] = $event['calendar_start_day']."-". $event['calendar_start_month']."-".$event['calendar_start_year'];
$i++;
}
echojson_encode($responce);
}
?>
Here is an example of the JSON data being sent
{
"05":{"events":{
"2856":{"id":"2856","title":"BSM Leadership Retreat","location":"Lake O' The Pines","startTime":"01-05-2011"}}},
"06":{"events":{
"2957":{"id":"2957","title":"Women's Basketball","location":"Brownwood, TX","startTime":"01-06-2011"},
"2958":{"id":"2958","title":"Men's Basketball","location":"Brownwood, TX","startTime":"01-06-2011"}}},
"08":{"events":{
"2959":{"id":"2959","title":"Women's Basketball","location":"Alpine, Tx","startTime":"01-08-2011"},
"2960":{"id":"2960","title":"Men's Basketball","location":"Alpine, TX","startTime":"01-08-2011"}}},
"11":{"events":{
"3052":{"id":"3052","title":"Theatre Auditions!","location":"Black Box Theatre","startTime":"01-11-2011"}}},
"12":{"events":{
"3054":{"id":"3054","title":"Welcome Back Party","location":"New Student Lounge","startTime":"01-12-2011"}}},
"13":{"events":{
"2961":{"id":"2961","title":"Women's Basketball","location":"Pineville, LA","startTime":"01-13-2011"},
"2962":{"id":"2962","title":"Men's Basketball","location":"Pineville, LA","startTime":"01-13-2011"}}},
"14":{"events":{
"3055":{"id":"3055","title":"Organizations Meeting","location":"Cornish Great room","startTime":"01-14-2011"}}},
"15":{"events":{
"2963":{"id":"2963","title":"Women's Basketball","location":"Clinton, MS","startTime":"01-15-2011"},
"2964":{"id":"2964","title":"Men's Basketball","location":"Clinton, MS","startTime":"01-15-2011"}}},
"20":{"events":{
"2965":{"id":"2965","title":"Women's Basketball","location":"ETBU\/Ornelas Gymnasium","startTime":"01-20-2011"},
"2966":{"id":"2966","title":"Men's Basketball","location":"Ornelas Gym\/ETBU","startTime":"01-20-2011"}}},
"21":{"events":{
"3056":{"id":"3056","title":"Karen Peck and New River","location":"Marshall Convention Center Auditorium","startTime":"01-21-2011"},
"3057":{"id":"3057","title":"Chamber Ensemble Recital","location":"Woods Great Room in OSC","startTime":"01-21-2011"}}},
"22":{"events":{
"2967":{"id":"2967","title":"Women's Basketball","location":"ETBU\/Ornelas Gymnasium","startTime":"01-22-2011"},
"2968":{"id":"2968","title":"Men's Basketball","location":"Ornelas Gym\/ETBU","startTime":"01-22-2011"}}},
"27":{"events":{
"2969":{"id":"2969","title":"Women's Basketball","location":"Clarksville, AR","startTime":"01-27-2011"},
"2970":{"id":"2970","title":"Men's Basketball","location":"Clarksville, AR","startTime":"01-27-2011"},
"3058":{"id":"3058","title":"CASL Conference","location":"Ornelas Student Center","startTime":"01-27-2011"}}},
"28":{"events":{
"2857":{"id":"2857","title":"ABIDE - A Reflective Prayer Conference","location":"TBD","startTime":"01-28-2011"},
"3059":{"id":"3059","title":"CASL Conference","location":"Ornelas Student Center","startTime":"01-28-2011"},
"3060":{"id":"3060","title":"ABIDE","location":"TBD","startTime":"01-28-2011"}}},
"29":{"events":{"2971":{"id":"2971","title":"Women's Basketball","location":"Richardson, TX","startTime":"01-29-2011"},
"2972":{"id":"2972","title":"Men's Basketball","location":"Richardson, TX","startTime":"01-29-2011"},
"3061":{"id":"3061","title":"CASL Conference","location":"Ornelas Student Center","startTime":"01-29-2011"},
"3062":{"id":"3062","title":"SAI Province Day","location":"JGMB and EDW","startTime":"01-29-2011"}}}
}
Also you can view the app here
It's best viewed in safari either mobile or desktop.
A much more effective way to bind, say, a list to a JSON data source is to use a Ext.data.Proxy which will take care of all the AJAX and asynchronous updating of the list.
I've taken the liberty of rewriting your app to demonstrate:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Scratch</title>
<script src="lib/touch/sencha-touch-debug.js" type="text/javascript"></script>
<link href="lib/touch/resources/css/sencha-touch.css" rel="stylesheet" type="text/css" />
<script>
Ext.setup({
onReady:function(){
//DATA
Ext.regModel('Event', {
fields: [
{name:'id'},
{name:'title'},
{name:'location'},
{name:'startTime'}
],
});
Ext.regStore('events', {
model: 'Event',
autoLoad: true,
proxy: {
type: 'ajax',
url: 'events.json',
reader: {
type: 'json',
root: 'events'
}
},
getGroupString: function(record) {
return record.get('startTime');
}
});
//UI
eventListToolbar = new Ext.Toolbar({
title: 'Events'
});
eventList = new Ext.List({
store: 'events',
itemTpl: Ext.XTemplate.from("eventList"),
listeners: {
selectionchange: function (selectionModel, records) {
if (records[0]) {
eventDescription.update(records[0].data);
eventDescriptionToolbar.setTitle(records[0].get('title'))
rootPanel.setActiveItem(eventDescriptionPanel, {type:'slide'});
}
}
},
grouped:true
});
eventListPanel = new Ext.Panel({
dockedItems: [eventListToolbar],
items: [eventList]
});
eventDescriptionToolbar = new Ext.Toolbar({
items: {
text:'Back',
ui: 'back',
listeners: {
tap: function () {
rootPanel.setActiveItem(eventListPanel, {type:'slide', direction:'right'});
}
}
}
});
eventDescription = new Ext.Panel({
tpl: Ext.XTemplate.from("eventDescription"),
padding:20,
});
eventDescriptionPanel = new Ext.Panel({
dockedItems: [eventDescriptionToolbar],
items: [eventDescription],
});
rootPanel = new Ext.Panel({
fullscreen:true,
layout:"card",
items:[
eventListPanel,
eventDescriptionPanel
]
});
}
});
</script>
</head>
<body>
<textarea id="eventList" class="x-hidden-display">
{title} - {location}
</textarea>
<textarea id="eventDescription" class="x-hidden-display">
<p>{title}</p>
<p>{description}</p>
<p>{location}</p>
<p>{startTime}</p>
</textarea>
</body>
</html>
This consumes JSON that looks like this:
{"events":[
{"id":"2856","title":"BSM Leadership Retreat","location":"Lake O' The Pines","startTime":"01-05-2011"},
{"id":"2957","title":"Women's Basketball","location":"Brownwood, TX","startTime":"01-06-2011"},
{"id":"2958","title":"Men's Basketball","location":"Brownwood, TX","startTime":"01-06-2011"},
{"id":"2959","title":"Women's Basketball","location":"Alpine, Tx","startTime":"01-08-2011"},
{"id":"2960","title":"Men's Basketball","location":"Alpine, TX","startTime":"01-08-2011"},
{"id":"3052","title":"Theatre Auditions!","location":"Black Box Theatre","startTime":"01-11-2011"},
{"id":"3054","title":"Welcome Back Party","location":"New Student Lounge","startTime":"01-12-2011"},
{"id":"2961","title":"Women's Basketball","location":"Pineville, LA","startTime":"01-13-2011"},
{"id":"2962","title":"Men's Basketball","location":"Pineville, LA","startTime":"01-13-2011"},
{"id":"3055","title":"Organizations Meeting","location":"Cornish Great room","startTime":"01-14-2011"},
{"id":"2963","title":"Women's Basketball","location":"Clinton, MS","startTime":"01-15-2011"},
{"id":"2964","title":"Men's Basketball","location":"Clinton, MS","startTime":"01-15-2011"},
{"id":"2965","title":"Women's Basketball","location":"ETBU\/Ornelas Gymnasium","startTime":"01-20-2011"},
{"id":"2966","title":"Men's Basketball","location":"Ornelas Gym\/ETBU","startTime":"01-20-2011"},
{"id":"3056","title":"Karen Peck and New River","location":"Marshall Convention Center Auditorium","startTime":"01-21-2011"},
{"id":"3057","title":"Chamber Ensemble Recital","location":"Woods Great Room in OSC","startTime":"01-21-2011"},
{"id":"2967","title":"Women's Basketball","location":"ETBU\/Ornelas Gymnasium","startTime":"01-22-2011"},
{"id":"2968","title":"Men's Basketball","location":"Ornelas Gym\/ETBU","startTime":"01-22-2011"},
{"id":"2969","title":"Women's Basketball","location":"Clarksville, AR","startTime":"01-27-2011"},
{"id":"2970","title":"Men's Basketball","location":"Clarksville, AR","startTime":"01-27-2011"},
{"id":"3058","title":"CASL Conference","location":"Ornelas Student Center","startTime":"01-27-2011"},
{"id":"2857","title":"ABIDE - A Reflective Prayer Conference","location":"TBD","startTime":"01-28-2011"},
{"id":"3059","title":"CASL Conference","location":"Ornelas Student Center","startTime":"01-28-2011"},
{"id":"3060","title":"ABIDE","location":"TBD","startTime":"01-28-2011"},
{"id":"2971","title":"Women's Basketball","location":"Richardson, TX","startTime":"01-29-2011"},
{"id":"2972","title":"Men's Basketball","location":"Richardson, TX","startTime":"01-29-2011"},
{"id":"3061","title":"CASL Conference","location":"Ornelas Student Center","startTime":"01-29-2011"},
{"id":"3062","title":"SAI Province Day","location":"JGMB and EDW","startTime":"01-29-2011"}
]}
Slightly rough and ready. But it looks like: http://cl.ly/46dH & http://cl.ly/46Rl
Not technically an answer to your question. But does that work?
Related
I have a drop down list in the form of the select tag as shown below:
<select id = "1">
<option>Amy</option>
<option>Gi-Anne</option>
</select>
I want to pass the selected option - either Amy or Gi Anne to this method of the controller.
public String name (string nameSelected)
{
var query = new NameQuery();
if(nameSelected.Equals('Amy'))
{run a specific query}
else if(nameSelected.Equals('Gi-Anne'))
{run a specific query}
}
How do I pass the parameter of the selected drop down list value to the controller? Appreciate your help and thanks in advance.
This is 'fairly' easy using AngularJS, see this Plunk for a (simulated) example.
The HTML changes to this:
<body ng-app="myApp">
<div ng-controller="myController">
State: {{onChangeText}}
<br/>
<select ng-model="selectedItemId" id="itemList" ng-change="onChange()">
<option value="{{item.id}}" ng-selected="{{item.id == selectedItemId}}" ng-repeat="item in items">{{item.name}}</option>
</select>
<br/>
{{selectedQuery}}
</div>
</body>
With a controller like this:
app.controller("myController", [
"$scope",
"$http",
function($scope, $http){
var self = {};
self.simulatedGetQuery = function() {
console.log($scope.selectedItemId);
$scope.selectedQuery = "";
switch($scope.selectedItemId) {
case "1":
$scope.selectedQuery = "Query Amy";
break;
case "2":
$scope.selectedQuery = "Query Gi-Anne";
break;
}
};
self.httpGetQuery = function() {
$http({
method: 'GET',
url: 'http://somehostname/action/' + $scope.selectedItemId
}).then(function successCallback(response) {
$scope.selectedQuery = response;
}, function errorCallback(response) {
});
};
// -- SCOPED -- //
$scope.selectedItemId = 0;
$scope.items = [
{
"id": 1,
"name": "Amy"
},
{
"id": 2,
"name": "Gi-Anne"
}
];
$scope.onChange = function() {
$scope.onChangeText = "simulated GET triggered.";
self.simulatedGetQuery();
// Use this for actual GET
// self.httpGetQuery
};
// --- //
$scope.onChangeText = "waiting for user input";
$scope.selectedQuery = "no query selected. Chose a person for a valid query.";
}]);
It would need to be fleshed out in a real environment, but I think it will do for a simulated test. Check the scripts in the Plunk for a more detailed perspective on how to do this. All of this is clientside.
The URL of the $http call would be to your backend (MVC or Web API) controller.
I've just started developing with Angular schema form and I'm struggling to write any tests for my custom field directive.
I've tried compiling the schema form html tag which runs through my directives config testing it's display conditions against the data in the schema. However it never seems to run my controller and I can't get a reference to the directives HTML elements. Can someone give me some guidance on how to get a reference to the directive? Below is what I have so far:
angular.module('schemaForm').config(['schemaFormProvider',
'schemaFormDecoratorsProvider', 'sfPathProvider',
function(schemaFormProvider, schemaFormDecoratorsProvider, sfPathProvider) {
var date = function (name, schema, options) {
if (schema.type === 'string' && schema.format == 'date') {
var f = schemaFormProvider.stdFormObj(name, schema, options);
f.key = options.path;
f.type = 'date';
options.lookup[sfPathProvider.stringify(options.path)] = f;
return f;
}
};
schemaFormProvider.defaults.string.unshift(date);
schemaFormDecoratorsProvider.addMapping('bootstrapDecorator', 'date',
'app/modules/json_schema_form/schema_form_date_picker/schema_form_date_picker.html');
}]);
var dateControllerFunction = function($scope) {
$scope.isCalendarOpen = false;
$scope.showCalendar = function () {
$scope.isCalendarOpen = true;
};
$scope.calendarSave = function (date) {
var leaf_model = $scope.ngModel[$scope.ngModel.length - 1];
var formattedDate = $scope.filter('date')(date, 'yyyy-MM-dd');
leaf_model.$setViewValue(formattedDate);
$scope.isCalendarOpen = false;
};
};
angular.module('schemaForm').directive('schemaFormDatePickerDirective', ['$filter', function($filter) {
return {
require: ['ngModel'],
restrict: 'A',
scope: false,
controller : ['$scope', dateControllerFunction],
link: function(scope, iElement, iAttrs, ngModelCtrl) {
scope.ngModel = ngModelCtrl;
scope.filter = $filter
}
};
}]);
<div ng-class="{'has-error': hasError()}">
<div ng-model="$$value$$" schema-form-date-picker-directive>
<md-input-container>
<!-- showTitle function is implemented by ASF -->
<label ng-show="showTitle()">{{form.title}}</label>
<input name="dateTimePicker" ng-model="$$value$$" ng-focus="showCalendar()" ng-disabled="isCalendarOpen">
</md-input-container>
<time-date-picker ng-model="catalogue.effectiveFrom" ng-if="isCalendarOpen" on-save="calendarSave($value)" display-mode="date"></time-date-picker>
</div>
<!-- hasError() defined by ASF -->
<span class="help-block" sf-message="form.description"></span>
</div>
And the spec:
'use strict'
describe('SchemaFormDatePicker', function() {
var $compile = undefined;
var $rootScope = undefined;
var $scope = undefined
var scope = undefined
var $httpBackend = undefined;
var elem = undefined;
var html = '<form sf-schema="schema" sf-form="form" sf-model="schemaModel"></form>';
var $templateCache = undefined;
var directive = undefined;
beforeEach(function(){
module('app');
});
beforeEach(inject(function(_$compile_, _$rootScope_, _$templateCache_, _$httpBackend_) {
$compile = _$compile_
$rootScope = _$rootScope_
$httpBackend = _$httpBackend_
$templateCache = _$templateCache_
}));
beforeEach(function(){
//Absorb call for locale
$httpBackend.expectGET('assets/locale/en_gb.json').respond(200, {});
$templateCache.put('app/modules/json_schema_form/schema_form_date_picker/schema_form_date_picker.html', '');
$scope = $rootScope.$new()
$scope.schema = {
type: 'object',
properties: {
party: {
title: 'party',
type: 'string',
format: 'date'
}}};
$scope.form = [{key: 'party'}];
$scope.schemaModel = {};
});
describe("showCalendar", function () {
beforeEach(function(){
elem = $compile(html)($scope);
$scope.$digest();
$httpBackend.flush();
scope = elem.isolateScope();
});
it('should set isCalendarOpen to true', function(){
var result = elem.find('time-date-picker');
console.log("RESULT: "+result);
));
});
});
});
If you look at the below example taken from the project itself you can see that when it uses $compile it uses angular.element() first when setting tmpl.
Also, the supplied test module name is 'app' while the code sample has the module name 'schemaForm'. The examples in the 1.0.0 version of Angular Schema Form repo all use sinon and chai, I'm not sure what changes you would need to make if you do not use those.
Note: runSync(scope, tmpl); is a new addition for 1.0.0 given it is now run through async functions to process $ref includes.
/* eslint-disable quotes, no-var */
/* disabling quotes makes it easier to copy tests into the example app */
chai.should();
var runSync = function(scope, tmpl) {
var directiveScope = tmpl.isolateScope();
sinon.stub(directiveScope, 'resolveReferences', function(schema, form) {
directiveScope.render(schema, form);
});
scope.$apply();
};
describe('sf-array.directive.js', function() {
var exampleSchema;
var tmpl;
beforeEach(module('schemaForm'));
beforeEach(
module(function($sceProvider) {
$sceProvider.enabled(false);
exampleSchema = {
"type": "object",
"properties": {
"names": {
"type": "array",
"description": "foobar",
"items": {
"type": "object",
"properties": {
"name": {
"title": "Name",
"type": "string",
"default": 6,
},
},
},
},
},
};
})
);
it('should not throw needless errors on validate [ノಠ益ಠ]ノ彡┻━┻', function(done) {
tmpl = angular.element(
'<form name="testform" sf-schema="schema" sf-form="form" sf-model="model" json="{{model | json}}"></form>'
);
inject(function($compile, $rootScope) {
var scope = $rootScope.$new();
scope.model = {};
scope.schema = exampleSchema;
scope.form = [ "*" ];
$compile(tmpl)(scope);
runSync(scope, tmpl);
tmpl.find('div.help-block').text().should.equal('foobar');
var add = tmpl.find('button').eq(1);
add.click();
$rootScope.$apply();
setTimeout(function() {
var errors = tmpl.find('.help-block');
errors.text().should.equal('foobar');
done();
}, 0);
});
});
});
I have a JsonResult method in my controller. I have pulled in data from my database and set to an object. The method will return this object. I am trying pass this data into AngularJS data source. I would like to display a DevExtreme bar chart. Here is code so far.
AngularJS file:
var app = angular.module('customApp', ['dx']);
app.controller("chartControl", function ($scope, $http) {
$scope.sizeSettings = {
dataSource: 'http://localhost:53640/Home/PostChart',
commonSeriesSettings: {
argumentField: 'product_id',
valueField: "product_id", name: "Product Cost",
type: "bar"
},
seriesTemplate: {
nameField: 'Source',
}
};
});
Home Controller:
public JsonResult PostChart(int product_id)
{
Object prod = null;
using (ProductOrderEntities db = new ProductOrderEntities())
{
var product = db.Products.FirstOrDefault(p => p.product_id == product_id);
prod = new {productID = product.product_id, productName = product.product_name, productPrice = product.product_cost, productDescription = product.product_type};
}
return Json(prod, JsonRequestBehavior.AllowGet);
}
}
HTML
<div ng-app="customApp">
<div ng-controller="chartControl">
</div>
</div>
Seems like you forget add markup for chart:
<div dx-chart="chartOptions"></div>
I've made a simple ASP.NET MVC application here https://www.dropbox.com/s/hk3viceoa2zkyng/DevExtremeChart.zip?dl=0
Open the start page http://localhost:56158/Default1/ to see chart in action.
See more information about using DevExtreme Charts in AngularJS app here http://js.devexpress.com/Documentation/Howto/Data_Visualization/Basics/Create_a_Widget/?version=14_2#Data_Visualization_Basics_Create_a_Widget_Add_a_Widget_AngularJS_Approach
This is how I solved it.
HTML
<div ng-app="customCharts">
<div ng-controller="ChartController">
<div dx-chart="productSettings"></div>
</div>
</div>
AngularJS
var app = angular.module('customCharts', ['dx']);
app.controller("ChartController", function ($scope, $http, $q) {
$scope.productSettings = {
dataSource: new DevExpress.data.DataSource({
load: function () {
var def = $.Deferred();
$http({
method: 'GET',
url: 'http://localhost:53640/Home/PostChart'
}).success(function (data) {
def.resolve(data);
});
return def.promise();
}
}),
series: {
title: 'Displays Product Costs for items in our Database',
argumentType: String,
argumentField: "Name",
valueField: "Cost",
type: "bar",
color: '#008B8B'
},
commonAxisSettings: {
visible: true,
color: 'black',
width: 2
},
argumentAxis: {
title: 'Items in Product Store Database'
},
valueAxis: {
title: 'Dollor Amount'
}
}
})
Controller
public JsonResult PostChart()
{
var prod = new List<Object>();
using (ProductOrderEntities db = new ProductOrderEntities())
{
var product = db.Products.ToList();
foreach (var p in product)
{
var thing = new { Name = p.product_name, Cost = p.product_cost };
prod.Add(thing);
}
}
return Json(prod, JsonRequestBehavior.AllowGet);
}
Hi I'm trying to programm my first app in Icentium. I want to store wisdoms in a json array. Depending on your level you get a new wisdom. Unfortunately I don't know why it is shwoing the whole json array.
This is the lessons.js
(function(global) {
var LessonsViewModel,
app = global.app = global.app || {};
LessonsViewModel = kendo.data.ObservableObject.extend({
lessonsDataSource: null,
init: function () {
var that = this,
dataSource;
kendo.data.ObservableObject.fn.init.apply(that, []);
dataSource = new kendo.data.DataSource({
transport: {
read: {
url: "data/lessons/lessons.json",
dataType: "json"
}
}
});
that.set("lessonsDataSource", dataSource);
}
});
app.lessonsService = {
viewModel: new LessonsViewModel()
};
This is the view
<!--Lessons-->
<div id="tabstrip-lesson"
data-role="view"
data-title="Lektion"
data-model="app.lessonsService.viewModel">
<div class="lesson">
<div class="separator">
<div class="dark"></div>
<div class="light"></div>
</div>
<ul class="forecast-list"
data-role="listview"
data-bind="source: lessonsDataSource"
data-template="lessons-template"><!-- Das unten stehende Kendo Template wird hier eingefügt-->
</ul>
</div>
</div>
<!--Lessons Kendo Template für oben-->
<script type="text/x-kendo-tmpl" id="lessons-template">
<div>
<h1>${dojoroom}</h1>
<p>${text}</p><!-- Text aus Json File wird ausgelesen-->
</div>
</script>
This is my json array:
[
{
"dojoroom": "Dojo - First Room",
"text": "Bla bla bla!"
},
{
"dojoroom": "Dojo - Second Raum",
"text": "More Bla"
}
]
So far what I tried according to the Kendo Documenation (http://docs.kendoui.com/api/framework/datasource):
LessonsViewModel = kendo.data.ObservableObject.extend({
lessonsDataSource: null,
init: function () {
var that = this,
dataSource;
kendo.data.ObservableObject.fn.init.apply(that, []);
dataSource = new kendo.data.DataSource({
transport: {
read: {
url: "data/lessons/lessons.json",
dataType: "json"
}
}
});
that.set("lessonsDataSource", dataSource.at(0));
}
});
But this doesn't show anything at all. I also tried dataSource[0] and the same approaches in the view.
And dataSource.fetch(function(){
var dojo = dataSource.at(0);
that.set("lessonsDataSource", dojo);
});
I need help with this, I can't see where is the problem.
When I set source for autocomplete in html file, it works fine, when I same source or database values print out in ajax.php and return it via ajax it doesn't work. What could be the problem? Help please.
Html :
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Auto complete</title>
<script type="text/javascript" src="jquery-1.7.1.min.js"></script>
<script type="text/javascript" src="jquery-ui-1.8.18.custom.min.js"></script>
<link rel="stylesheet" media="all" type="text/css" href="jquery-ui-1.8.custom.css" />
<style type="text/css">
.ui-autocomplete-loading {
background: url("images/loader.gif") no-repeat scroll right center white;
}
</style>
<script type="text/javascript">
jQuery(document).ready(function($){
$("#ac").autocomplete({
minLength: 2,
//source: [{"value":"Some Name","id":1},{"value":"Some Othername","id":2}]
source: function( request, response){
$.ajax({
type: 'GET',
url: 'ajax.php',
data: {
'term':request.term
},
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(data){
console.log('Success : ' + data);
},
error: function(message){
alert(message);
}
});
},
select: function( event, ui ) {
}
});
});
</script>
</head>
<body>
<input type="text" id="ac" name="ac" size="100" />
</body>
</html>
and my ajax.php file:
$dbhost = 'localhost';
$dbuser = 'root';
$dbpass = '';
$dbname = 'test_db';
$server = mysql_connect($dbhost, $dbuser, $dbpass);
$connection = mysql_select_db($dbname, $server);
$term = $_GET['term'];
$qstring = "SELECT user_id,tName FROM `csv_data` WHERE tName LIKE '%" . $term . "%'";
$result = mysql_query($qstring);
$return_arr = array();
$i = 0;
while ($row = mysql_fetch_array($result, MYSQL_ASSOC)) {//loop through the retrieved values
$row_a = array();
if ($row['tName'] != null) {
$i++;
$row_a['value'] = ($row['tName']);
$row_a['id'] = (int) $i;
array_push($return_arr, $row_a);
}
}
mysql_close($server);
header("Content-type: text/x-json");
/*$my_arr = array(
array("value" => "Some Name", "id" => 1),
array("value" => "Some Othername", "id" => 2)
);*/
//echo json_encode($return_arr);
print json_encode($return_arr);
//print json_encode($my_arr);
This is response from firebug(generated from database).
[{"value":"4 erste Spiele","id":1},{"value":"Meine ersten Spiele \"Blinde Kuh\"","id":2},{"value":"4 erste Spiele","id":3},{"value":"Meine ersten Spiele \"Blinde Kuh\"","id":4},{"value":"4 erste Spiele","id":5},{"value":"Meine ersten Spiele \"Blinde Kuh\"","id":6},{"value":"Maxi Kleine Spielewelt","id":7}]
The parameter response is actually a callback tthat you have to call - passing it your data - to display the result popup menu. Simply call it in the "success" callback:
source: function(request, response) {
$.ajax({
...
success: function(data) {
// pass your data to the response callback
response(data);
},
error: function(message) {
// pass an empty array to close the menu if it was initially opened
response([]);
}
});
},