List data from json on Sencha - json

i am trying to show data from webserver json and it is not shown in view. At first i tried to show message only but could not succed. following this link and sample provided by #rdougan i have been able to parse upto categories but unable parse latter value can any one guide me.
code i have done till now are as follow:
{
xtype: 'panel',
padding: '20px',
//height: 100,
styleHtmlContent:true,
store: 'TodaysWordStore',
models: 'TodaysWordModel',
tpl:
[
'<tpl for=".">',
'<ul class="parabox">',
'<li><h2 onclick = "ratingStar()">{message} </h2> ',
'<ul class="para-box-wrapper">',
'<li class="greenbox"><div class="paragraph-def">',
'{dictionaryDef}',
'<span class="authorBox">Author: {authorName}</span>',
'</div><div class="starBox">',
'{ratingBox}',
'</div></li>',
'</ul></li></ul>',
'</tpl>',
]
// '<div><strong>{dictionaryWord}</strong>, {dictionaryDef} <em class="muted">({role})</em></div></tpl>']
},
My store is
Ext.define('appname.store.TodaysWordStore',{
extend: 'Ext.data.Store',
config:
{
model: 'appname.model.TodaysWordModel',
autoLoad:true,
proxy:
{
type: 'ajax',
url : 'location' //Your file containing json data
reader:
{
type: 'json',
//rootProperty:'accountInfo'
}
}
}
});
My model is
Ext.define('appname.model.TodaysWordModel', {
extend: 'Ext.data.Model',
config: {
fields:[
{name: 'message', mapping: 'accountInfo.message'}
]
}
});
The json i want to parse
({"accountInfo":
{"expire_date":"2014-07-02 08:01:09",
"subscribe_date":"2013-07-02 08:01:09",
"time_remain":" 358 Days 1 Hour 24 Minutes",
"status":"not expired"},
"status":"TRUE",
"message":"Todays Word",
"data":
[{"name":"curtain",
"author":"admin",
"word_id":"35",
"category":"business",
"definition":
[{"rating":
{"red":"0",
"green":"1",
"yellow":"0",
"total_rating":1,
"final_rating":"Green"},
"defintion":"curtain",
"def_id":"11",
"example":"This is a sample example.",
"author":"admin"},
{"rating":
{"red":0,
"green":0,
"yellow":0,
"total_rating":0,
"final_rating":"This definition is not rated yet."},
"defintion":"to cover something",
"def_id":null,
"example":"This is curtain example.",
"author":"admin"}],
"is_favourite":"No"}]})
Help me

You are trying to use a panel, when you should be using a dataview. The tpl is meant to be used with the data config option when using an Ext.panel.Panel, where data is just an Object containing the data to be used by the tpl. However, when you are using a store for your data, you should use an Ext.view.view instead of the panel. See the docs here: http://docs.sencha.com/extjs/4.2.1/#!/api/Ext.view.View

I solved it by adding an extra itemTpl. Since i had tpl for data only it was not able to fetch data from definitions node.
{
xtype: 'list',
store: 'ghak',
height: 140,
layout: 'fit',
scrollable: {
direction: 'vertical',
directionLock: true,
},
margin: '0 0 5px 0',
itemTpl: [
'<div>',
'<tpl for="data">',
'<ul class="parabox">',
'<li><h2 class="noStar" onclick = "addtofavourite({word_id})">{name} </h2>',
'<tpl for="definitions">',
'<ul class="para-box-wrapper">',
'<li class="{rating}"><div class="paragraph-def" onclick = "rating({def_id})">','{defintion}',
'<span class="authorBox">Author: {author}</span>',
'</li>' ,
'</div>',
'</ul></li>',
'</tpl>',
'</ul>',
'</tpl>',
'</div>'
].join('')
Hope it would help someone.
Thanks.

Related

How to update ng2-smart-table's custom part dynamically ?

In my angular 6 app, I have used ng2-smart-table. Now I need to show and hide custom action features based on their access rights.
I'm able to mange add, edir and delete part. With that I have also put some custom icons also for extra features.
custom: [
{ name: 'up', title: '<img src="/pathOfIcon" class="tableIcon up-arrow-true-icon">' },
{ name: 'up-cancel', title: '<img src="/pathOfIcon" class="tableIcon up-arrow-cancel-icon">' },
{ name: 'down', title: '<img src="/pathOfIcon" class="tableIcon down-arrow-true-icon">' },
{ name: 'down-cancel', title: '<img src="/pathOfIcon" class="tableIcon down-arrow-cancel-icon">' },
]
Now I need to manage this thing based on access.
So how could I enable and disable this icons.
Note: I can apply css on each row and then hide icon, But I need to do once not on each row.
You can add icons while add a icons in custom array...
Try this way
if(access){ // Set you access condition
this.settings.custom.push('{ name: 'up', title: '<img src="/pathOfIcon" class="tableIcon up-arrow-true-icon">' }');
this.settings.custom.push('{ name: 'up-cancel', title: '<img src="/pathOfIcon" class="tableIcon up-arrow-cancel-icon">' },');
}else{
this.settings.custom.push(' { name: 'down', title: '<img src="/pathOfIcon" class="tableIcon down-arrow-true-icon">' }');
this.settings.custom.push('{ name: 'down-cancel', title: '<img src="/pathOfIcon" class="tableIcon down-arrow-cancel-icon">' }');
}
This the simple way to add icons... Because custom is array so you can push icons in that...
Hope this may help you... :)

Sticky states are reinitializing controller

I have problems implementing sticky tabs where each tab can have multiple child states using ui-router-tabs and ui-router-extras.
When I open a state, move to annother and then go back to the first state, the corresponding controller is getting reinitialized (although the ui-router-extras debug output says it reactivated the state)
When I open another state of the same tab (sibling state), the debug output, the url and the request of the html template is telling me that the new state is loaded, but the tab is showing an empty content and the api call of the state is not executed
This is my state/route configuration:
$stateProvider
.state('home', {
url: '/',
templateUrl: 'modules/core/views/home.client.view.html'
})
.state('home.feed', {
abstract: true,
url: '',
template: '<div ui-view="list" ng-show="$state.includes(\'home.feed.list\')"/>'+
'<div ui-view="view" ng-show="$state.includes(\'home.feed.view\')"/>'+
'<div ui-view="profile" ng-show="$state.includes(\'home.feed.profile\')"/>',
data: {
roles: ['user', 'admin']
},
sticky: true,
deepStateRedirect: true
})
.state('home.feed.list', {
url: 'posts',
views: {
'list#home.feed': {
templateUrl: 'modules/posts/views/list-feed.client.view.html'
}
},
sticky: true
})
.state('home.feed.view', {
url: 'posts/:postId',
views: {
'view#home.feed': {
templateUrl: 'modules/posts/views/view-post.client.view.html'
}
},
sticky: true
})
.state('home.create', {
abstract: true,
url: '',
template: '<div ui-view="form" ng-show="$state.includes(\'home.create.form\')"/>',
data: {
roles: ['user', 'admin']
},
sticky: true,
deepStateRedirect: true
})
.state('home.create.form', {
url: 'create',
views: {
'form': {
templateUrl: 'modules/posts/views/create-post.client.view.html'
}
},
sticky: true
});
The "home" state is containing the ui-view for all tabs as well as the navigation bar. Each abstract state is representing a single tab and contains the named views for all its child states. The 3rd level of the states (e.g. home.feed.list) is representing the actual content.
//home
<div data-ng-controller="HomeController">
<ui-view></ui-view>
<div class="navbar navbar-fixed-bottom">
<tabs data="tabData" type="tabs" justified="true" template-url="modules/core/views/custom-tab-template.client.view.html"></tabs>
</div>
</div>
//home.feed.list
<section data-ng-controller="PostsController" data-ng-init="loadPosts()">
...
</section>
//home.feed.view
<section data-ng-controller="PostsController" data-ng-init="findOne()">
...
</section>
//home.create.form
<section data-ng-controller="PostsController">
...
</section>
The views are using the same controller, but I already tried to add a seperate controller for each view. Furthermore I tried to remove the ui-router-tabs and called the states by url, same result.
Example debug output for: home.feed.list -> home.create.form -> home.feed.list
(Sry not enough reputation to post pictures)
Current transition: : {}: -> home.feed.list: {}
Before transition, inactives are: : []
After transition, inactives will be: []
Transition will exit: []
Transition will enter: ["ENTER: home", "ENTER: home.feed", "ENTER: home.feed.list"]
SurrogateFromPath: []
SurrogateToPath: ["home", "home.feed", "home.feed.list"]
I am initializing PostsController
Current state: home.feed.list, inactive states: []
Views: (__inactives.locals) / (root.locals) / (home.locals: '#' (home)) / (home.locals: '#' (home)) / (home.feed.locals: '#home' (home.feed)) / (home.feed.list.locals: 'list#home.feed' (home.feed.list))
Current transition: home.feed.list: {}: -> home.create.form: {}
Before transition, inactives are: : []
After transition, inactives will be: ["home.feed", "home.feed.list"]
Transition will exit: ["(home)", "INACTIVATE: home.feed", "INACTIVATE: home.feed.list"]
Transition will enter: ["(home)", "ENTER: home.create", "ENTER: home.create.form"]
SurrogateFromPath: ["home", "inactivate:home.feed", "inactivate:home.feed.list"]
SurrogateToPath: ["home", "home.create", "home.create.form"]
I am initializing PostsController
Current state: home.create.form, inactive states: ["home.feed.list", "home.feed"]
Views: (__inactives.locals: '#home' (home.feed), 'list#home.feed' (home.feed.list)) / (root.locals) / (home.locals: '#' (home)) / (home.locals: '#' (home)) / (home.create.locals: '#home' (home.create)) / (home.create.form.locals: 'form#home.create' (home.create.form))
Current transition: home.create.form: {}: -> home.feed.list: {}
Before transition, inactives are: : ["home.feed.list", "home.feed"]
After transition, inactives will be: ["home.create", "home.create.form"]
Transition will exit: ["(home)", "INACTIVATE: home.create", "INACTIVATE: home.create.form"]
Transition will enter: ["(home)", "REACTIVATE: home.feed", "REACTIVATE: home.feed.list"]
SurrogateFromPath: ["home", "reactivate_phase1:home.feed", "reactivate_phase1:home.feed.list", "inactivate:home.create", "inactivate:home.create.form"]
SurrogateToPath: ["home", "reactivate_phase1:home.feed", "reactivate_phase1:home.feed.list", "reactivate_phase2:home.feed", "reactivate_phase2:home.feed.list"]
I am initializing PostsController
Current state: home.feed.list, inactive states: ["home.create.form", "home.create"]
Views: (__inactives.locals: '#home' (home.create), 'form#home.create' (home.create.form)) / (root.locals) / (home.locals: '#' (home)) / (home.locals: '#' (home)) / (home.feed.locals: '#home' (home.feed)) / (home.feed.list.locals: 'list#home.feed' (home.feed.list))
The same output is generated when I am using 3 different controllers ("I am initializing.." is executed on every controller).
I have found the mistakes:
Because the second level of states (home.feed and home.create) need to be sticky as well they need a named parent ui-view. I forgot to change the single ui-view inside of the home-html into two named ui-views.
And of course I had to adapt the state definitions:
.state('home.feed', {
url: '',
views: {
'feed#home': {
template: '<div ui-view="list" ng-show="$state.includes(\'home.feed.list\')"></div>'+
'<div ui-view="view" ng-show="$state.includes(\'home.feed.view\')"></div>'+
'<div ui-view="profile" ng-show="$state.includes(\'home.feed.profile\')"></div>'
}
},
data: {
roles: ['user', 'admin']
},
sticky: true,
deepStateRedirect: {
default: { state: "home.feed.list" }
}
})
.state('home.create', {
abstract: true,
url: '',
views: {
'create#home': {
template: '<div ui-view="form" ng-show="$state.includes(\'home.create.form\')"></div>'
}
},
data: {
roles: ['user', 'admin']
},
sticky: true,
deepStateRedirect: true
})
This issue was caused by using div's with included closing tag. I changed this to the standard definition with a starting and closing tag (difference of the template definition above).

How can i add a button on a div in my tpl inside a dataview?

i have a problem trying to add a button in a tpl. i have this inside a panel. I want to upload a file trough this button. the record its getting in the itemClick listener, and i can edit and save the record in the db, but i want to upload a file with this.
items:{
height: 310,
bind: '{somestore}',
id: 'somestore-panel',
xtype: 'dataview',
columnWidth: '100',
tpl: [
'<tpl for="." >',
'<div id="upload-button" ></div>',
'</tpl>'
]
cls: 'div-selection',
overItemCls: 'over-selection',
listeners: {
'itemclick': 'onClickDataButton',
afterrender:function(){
var button = new Ext.Button({
renderTo:'upload-button',
xtype: 'filefield',
text:'Vote',
width:100,
id:'upload-form',
handler:function(){
alert('Vote Button is clicked');
}
})
console.log(button);
}
}
}
and its returning a
Cannot read property 'dom' of null
All the store its getting correct and all its fine if i dont use a button, i dont know if there is a better way to add a component.

How do I dynamically change ng-grid table size when parent containing div size changes?

I am changing the size of the containing div using ng-class and an expression that evaluates whether or not an edit form is displayed. If the edit form is displayed I want to change the size of the div containing the ng-grid and the ng-grid itself.
<div class=" row-fluid">
<div ng-class="{'span7' : displayEditForm == true, 'span12': displayEditForm == false}" >
<ul class="nav nav-tabs" style="margin-bottom: 5px;">
<li class="active">Activities Needing My Approval</li>
<li>My Activities Needing Approval </li>
<li>My Activities</li>
</ul>
<div class="edus-admin-manage-grid span12" style="margin-left:0;" ng-grid="gridOptions"></div>
</div>
<div class="span5" ng-show="displayEditForm">
<div class="edus-activity-container">
<div class="edus-admin-activities-grid">
<div ng-include="'/partials/' + activity.object.objectType + '.html'" class="edus-activity"></div>
<!-- <div ng-include="'/partials/admin-activity-actions.html'"></div>-->
</div>
</div>
<div ng-include="'/partials/admin-edit-activity-grid-form.html'"></div>
</div>
</div>
The div containing the navbar and grid changes size via ng-class (from span12 to span7), but the ng-grid does not refresh. How can I trigger the refresh of ng-grid given the change in the parent div?
I've included my gridOptions below:
$scope.gridOptions = {
plugins: [gridLayoutPlugin],
data : 'activities',
showFilter: true,
/* enablePaging: true,*/
showColumnMenu: true,
/* showFooter: true,*/
rowHeight: 70,
enableColumnResize: true,
multiSelect: false,
selectedItems: $scope.selectedActivities,
afterSelectionChange: function(rowItem,event){
if($scope.selectedActivities && $scope.selectedActivities.length > 0){
$scope.activity = $scope.selectedActivities[0];
$scope.activityViewState.index = $scope.activities.indexOf($scope.activity);
$scope.displayEditForm = true;
console.log("DEBUG :::::::::::::::: updated displayEditForm.", $scope.displayEditForm);
if($scope.activity.ucdEdusMeta.startDate) {
// $scope.activity.ucdEdusMeta.startDate = new Date($scope.activity.ucdEdusMeta.startDate);
$scope.edit.startDate = moment($scope.activity.ucdEdusMeta.startDate).format("MM/DD/YYYY");
$scope.edit.startTime = moment($scope.activity.ucdEdusMeta.startDate).format("hh:mm A");
}
if($scope.activity.ucdEdusMeta.endDate) {
// $scope.activity.ucdEdusMeta.endDate = new Date($scope.activity.ucdEdusMeta.endDate);
$scope.edit.endDate = moment($scope.activity.ucdEdusMeta.endDate).format("MM/DD/YYYY");
$scope.edit.endTime = moment($scope.activity.ucdEdusMeta.endDate).format("hh:mm A");
}
}
},
/* pagingOptions: { pageSizes: [5, 10, 20], pageSize: 10, totalServerItems: 0, currentPage: 1 },*/
columnDefs: [
{field: 'title', displayName: 'Title', width:'15%',
cellTemplate: '<div class="ngCellText", style="white-space: normal;">{{row.getProperty(col.field)}}</div>'},
{field: 'actor.displayName', displayName: 'DisplayName', width:'10%',
cellTemplate: '<div class="ngCellText", style="white-space: normal;">{{row.getProperty(col.field)}}</div>'},
{field: 'object.content', displayName:'Content', width:'35%',
cellTemplate: '<div class="ngCellText", style="white-space: normal;">{{row.getProperty(col.field)}}</div>'},
{field: 'ucdEdusMeta.startDate', displayName: 'Start Date', width:'20%',
cellTemplate: '<div class="ngCellText" ng-class="col.colIndex()"><span ng-cell-text>{{row.getProperty(col.field) | date:"short"}} </span></div>'},
{field: 'ucdEdusMeta.endDate', displayName: 'End Date', width:'20%',
cellTemplate: '<div class="ngCellText" ng-class="col.colIndex()"><span ng-cell-text>{{row.getProperty(col.field) | date:"short"}} </span></div>'}
// {field: '', displayName: ''},
]
};
Here's the CSS used by the grid:
.edus-admin-manage-grid {
border: 1px solid rgb(212,212,212);
width: 100%;
height: 700px
}
You can use ng-grid's layout plugin (ng-grid-layout.js). It should come with ngGrid located at:
ng-grid/plugins/ng-grid-layout.js
(UPDATED: now at https://github.com/angular-ui/ng-grid/blob/2.x/plugins/ng-grid-layout.js)
You will have to include an additional script tag pointing to this js file in your main index.html file. And the order of including this versus ng-grid.js is important.
You would have to set a watch on displayEditForm and then call the plugin's updateGridLayout() function.
So it would be something like:
var gridLayoutPlugin = new ngGridLayoutPlugin();
// include this plugin with your grid options
$scope.gridOptions = {
// your options and:
plugins: [gridLayoutPlugin]
};
// make sure grid redraws itself whenever
// the variable that ng-class uses has changed:
$scope.$watch('displayEditForm', function() {
gridLayoutPlugin.updateGridLayout();
});
From my understanding, watches generally belong in the link function rather than the controller but it will work in either spot. You could also go a bit further and say:
$scope.$watch('displayEditForm', function(newVal, oldVal) {
if (newVal !== undefined && newVal !== oldVal) {
gridLayoutPlugin.updateGridLayout();
}
});
To make sure this only fires when the data switches from true/false. This would matter if your data is initially undefined and you waste time calling grid redraw before you give it an initial value.

Dojo Grid reload data file upon button click

I know there maybe similar questions out there, but I still cannot find the answer. Much appropriate anyone who can help me.
There are 5 departments, and each department has 4 products. So I created 5 buttons and 4 tabs, each tab contains a grid. By default the department A is loaded, user can switch tabs to see different products information from this department. By click another button B, department B's information will loaded to all 4 tabs.
Click each button will send a ajax request to the back end PHP code, PHP will read XML file do calculation and write data to "data\productA.json", "data\productB.json" , "data\productC.json" , "data\productD.json" files, respect to product A to product D for that specific department. Note that the first tab always read from "data\product A" file, no matter which button you clicked, same for other tabs.
Then the JavaScript will read from the "data\product?.json" file and present data in the grid.
When the page loads, first department's information is correctly loaded into the grid. However, if I change to another department (click button), the grid won't reload data from the json files.
Here is JS part:
dojo.addOnLoad(function() {
//init the first main column when load the page.
getDepartmentA();
var layout = [[
new dojox.grid.cells.RowIndex({ width: 5 }),
{name: 'Name', field: 'name'},
{name: 'Count', field: 'count'},
{name: 'Percent', field: 'percent'}
]];
var store = new dojo.data.ItemFileReadStore( { url: "data/productA.json" } );
var grid = new dojox.grid.DataGrid( { store: store, rowsPerPage: 200, style: "height:600px; width:874px;", structure: layout},
dojo.byId("grid1"));
grid.startup();
dojo.connect( dijit.byId("column3"),"onShow", dojo.partial( createGrid, "3") );
dojo.connect( dijit.byId("column4"),"onShow", dojo.partial( createGrid, "4") );
dojo.connect( dijit.byId("column5"),"onShow", dojo.partial( createGrid, "5") );
});
function getDepartmentA() {
dojo.xhrGet( {
url: "department_A_process.php",
handleAs: "json",
load: function(response) {
var tempgrid = grids[0];
var tempresponse = eval("("+response+")");
var tempstore = new dojo.data.ItemFileReadStore({url: "data/productA.json" }); //updated store!
var tempModel = new dojox.grid.data.DojoData(null, tempstore, {query:{productName:'*'}, clientSort: true});
tempgrid.setaModel(tempModel);
tempgrid.refresh();
console.dir(response); // Dump it to the console
}
});
}
function createGrid( id ) {
console.log("Calling createGrid function now!");
var layout = [[
new dojox.grid.cells.RowIndex({ width: 5 }),
{name: 'Name', field: 'name'},
{name: 'Count', field: 'count'},
{name: 'Percent', field: 'percent'}
]];
if (! grids[id] ) {
if (id =="1"){
var store = new dojo.data.ItemFileReadStore( { url: "data/productA.json" } );
console.log( "I am in tab1");
} else if (id =="3"){
var store = new dojo.data.ItemFileReadStore( { url: "data/productB.json" } );
console.log( "I am in tab3");
} else if (id =="4"){
var store = new dojo.data.ItemFileReadStore( { url: "data/productC.json" } );
console.log( "I am in tab4");
} else if (id =="5"){
var store = new dojo.data.ItemFileReadStore( { url: "data/productD.json" } );
console.log( "I am in tab5");
}
var grid = new dojox.grid.DataGrid( { store: store, rowsPerPage: 200, style: "height:600px; width:874px;", structure: layout},
dojo.byId("grid" + id ));
grid.startup();
grids[id] = grid;
console.log( grid );
}
}
My index page is like:
<div id="mainTabContainer" dojoType="dijit.layout.TabContainer" doLayout="false">
<div id="column1" dojoType="dijit.layout.ContentPane" title="Label by Brand" selected="true">
<h1>Label by Brand</h1>
<div class="partsContainer">
<div id="grid1" class="gridContainer">
</div>
</div>
</div>
<div id="column3" dojoType="dijit.layout.ContentPane" title="Session Types">
<h1>Session Types</h1>
<div class="partsContainer">
<div id="grid3" class="gridContainer">
</div>
</div>
</div>
<div id="column4" dojoType="dijit.layout.ContentPane" title="Labels by Session">
<h1>Labels by Session</h1>
<div class="partsContainer">
<div id="grid4" class="gridContainer">
</div>
</div>
</div>
<div id="column5" dojoType="dijit.layout.ContentPane" title="Monthly Report">
<h1>Monthly Report</h1>
<div class="partsContainer">
<div id="grid5" class="gridContainer">
</div>
</div>
</div>
</div>
The JSON file looks like:
{
identifier: "productName",
label: "productName",
items: [
{ "productName" : "p1", "count" : 3362, "percent" : "32.8" },
{ "productName" : "p2", "count" : 421, "percent" : "4.1" },
{ "productName" : "p3", "count" : 526, "percent" : "5.1" },
{ "productName" : "p4", "count" : 1369, "percent" : "13.4" },
...
{ "productName" : "Total", "count" : 10242, "percent" : "100" }
]
}
Anyone can help out, how to reload the file that generated by PHP to the grid? Thank you.
I don't see any code involving a button or requesting new data for a store in your code...
To fix your issue, try adding clearOnClose:true to your store initializations. You may also need urlPreventCache:true. Firebug or any sort of net monitor will tell you if this is needed.
When the button is pressed, get the reference to the store for each grid and call store.close() then store.fetch(). This should accomplish what you are looking for by refreshing the data in the store. After this it may be necessary to call grid.render() or something similar.
One thing I should note here just to save you a possible headache later: Unless you have some sort of user hash for the directory structure and security measures in place, the way your PHP behaves by creating a single set of files for each department is likely going to result in problems with multi-user support and security issues where you can read another person's JSON responses.
Found the info here : http://livedocs.dojotoolkit.org/dojo/data/ItemFileReadStore. Search for clearOnClose for the approximate area to look for information.