Unable to Show Data insde dojox.grid.DataGrid with dojo.data.ItemFileReadStore - dojo

I am using DOJO ItemFileReadStore with dojox.grid.DataGrid to show Data Inside a Grid
Please see the Image here
http://imageshare.web.id/viewer.php?file=kdfvrkmn6k7xafmi4jdy.jpg
EMployee.Java
public class Employee {
String name;
String dept;
// Setters and Getters
}
This is My Servlet
response.setContentType("text/x-json;charset=UTF-8");
response.setHeader("Cache-Control", "no-cache");
PrintWriter out = response.getWriter();
List list = new ArrayList();
Employee emp1 = new Employee();
Employee emp2 = new Employee();
emp1.setDept("CSE");
emp1.setName("Vamsi");
emp2.setDept("EEE");
emp2.setName("Raju");
list.add(emp1);
list.add(emp2);
List jsonresponse = new ArrayList();
for (int i = 0; i < list.size(); i++) {
JSONObject nextObject = new JSONObject();
nextObject.put("name", list.get(i));
jsonresponse.add(nextObject);
}
JSONObject json = new JSONObject();
json.put("label", "name");
json.put("items", jsonresponse.toArray());
response.getWriter().write(json.toString());
}
This is MY JSP Page
<body class=" claro ">
<span dojoType="dojo.data.ItemFileReadStore" jsId="store1" url="http://localhost:8080/Man/MyServlet2"></span>
<table dojoType="dojox.grid.DataGrid" store="store1"
style="width: 100%; height: 500px;">
<thead>
<tr>
<th width="150px" field="name">Name</th>
<th width="150px" field="dept">Dept</th>
</tr>
</thead>
</table>
Please see the Image here
http://imageshare.web.id/viewer.php?file=kdfvrkmn6k7xafmi4jdy.jpg
Please help , Thank you .

+1 for posting the server output (firebug screenshot) in your question. This makes a lot easier for people to help you - for example I can easily see that the data format is still not quite right. You are getting better at both dojo and stackoverflow, it seems!
Remember that the ItemFileReadStore expects the data to be in a particular format. Your servlet is producing:
{label: "name", items: [
{name: {dept: "CSE", name: "Vansi"}},
{name: {dept: "ABC", name: "Abcd"}}
]}
You see you are telling the store that each item's "name" is an object with some properties ("dept" and "name"). This is why the grid shows object Object in the name column. It should be:
{label: "name", items: [
{dept: "CSE", name: "Vansi"},
{dept: "ABC", name: "Abcd"}
]}
I'm not very good with java, but I believe only a small change in your servlet is required:
// The for loop that adds employees to jsonresponse.
for (int i = 0; i < list.size(); i++)
{
// Instead of adding the
Emloyee e = (Employee)list.get(i);
JSONObject nextObject = new JSONObject();
nextObject.put("name", e.getName());
nextObject.put("dept", e.getDept());
jsonresponse.add(nextObject);
}
In fact, it's possible that you can just do json.put("items", list.toArray()); instead of adding each employee to jsonresponse.

Related

Angular Material Table Dynamic Columns without model

I need to use angular material table without model, because I don't know what will come from service.
So I am initializing my MatTableDataSource and displayedColumns dynamically in component like that :
TableComponent :
ngOnInit() {
this.vzfPuanTablo = [] //TABLE DATASOURCE
//GET SOMETHING FROM SERVICE
this.listecidenKisi = this.listeciServis.listecidenKisi;
this.listecidenVazife = this.listeciServis.listecidenVazife;
//FILL TABLE DATASOURCE
var obj = {};
for (let i in this.listecidenKisi ){
for( let v of this.listecidenVazife[i].vazifeSonuclar){
obj[v.name] = v.value;
}
this.vzfPuanTablo.push(obj);
obj={};
}
//CREATE DISPLAYED COLUMNS DYNAMICALLY
this.displayedColumns = [];
for( let v in this.vzfPuanTablo[0]){
this.displayedColumns.push(v);
}
//INITIALIZE MatTableDataSource
this.dataSource = new MatTableDataSource(this.vzfPuanTablo);
}
The most important part of code is here :
for( let v in this.vzfPuanTablo[0]) {
this.displayedColumns.push(v);
}
I am creating displayedColumns here dynamically, it means; even I don't know what will come from service, I can show it in table.
For example displayedColumns can be like that:
["one", "two" , "three" , "four" , "five" ]
or
["stack","overflow","help","me]
But it is not problem because I can handle it.
But when I want to show it in HTML, I can't show properly because of
matCellDef thing:
TableHtml :
<mat-table #table [dataSource]="dataSource" class="mat-elevation-z8">
<ng-container *ngFor="let disCol of displayedColumns; let colIndex = index" matColumnDef="{{disCol}}">
<mat-header-cell *matHeaderCellDef>{{disCol}}</mat-header-cell>
<mat-cell *matCellDef="let element "> {{element.disCol}}
</mat-cell>
</ng-container>
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
<mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row>
</mat-table>
My problem is here:
<mat-cell *matCellDef="let element "> {{element.disCol}} < / mat-cell>
In fact, I want to display element."disCol's value" in the cell, but I don't know how can I do that.
Otherwise, everything is ok except this element."disCol's value" thing.
When I use {{element.disCol}} to display value of element that has disCols's value , all cells are empty like that:
Other example that using {{element}} only:
Also as you can see:
Table datasource is changing dynamically. It means I can't use {{element.ColumnName}} easily, because I don't know even what is it.
First Example's displayedColumns = ['Vazife', 'AdSoyad', 'Kirmizi', 'Mavi', 'Yesil', 'Sari'];
Second Example's displayedColumns = ['Muhasebe', 'Ders', 'Egitim', 'Harici'];
matHeaderCellDef is correct , because it is using {{disCol}} directly.
But I need to read disCol's value, and display element.(disCol's value) in the cell.
How can I do that ?
I found solution :)
It is very very easy but i could't see at first :)
only like that :
<mat-cell *matCellDef="let element "> {{element[disCol]}}
</mat-cell>
I must use {{element[disCol]}} only in HTML.
Now , everything is ok:)
For a full working example based on #mevaka's
Where jobDetails$ is the array of items.
columns$ is equvilent to Object.keys(jobDetails$[0]) so is just a string[]
<table mat-table [dataSource]="jobDetails$ | async">
<ng-container *ngFor="let disCol of (columns$ | async); let colIndex = index" matColumnDef="{{disCol}}">
<th mat-header-cell *matHeaderCellDef>{{disCol}}</th>
<td mat-cell *matCellDef="let element">{{element[disCol]}}</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="(columns$ | async)"></tr>
<tr mat-row *matRowDef="let row; columns: (columns$ | async)"></tr>
</table>
I've tried my best to boil a dynamic table down to the minimum. This example will display any columns given an array of flat objects with any keys. Note how the first object has an extra "foo" property that causes an entire column to be created. The DATA const could be some data you get from a service. Also, you could add a "column ID -> label" mapping into this if you know some common property names you'll be getting the JSON. See the stachblitz here.
import {Component, ViewChild, OnInit} from '#angular/core';
const DATA: any[] = [
{position: 1, name: 'sdd', weight: 1.0079, symbol: 'H', foo: 'bar'},
{position: 2, name: 'Helium', weight: 4.0026, symbol: 'He'},
{position: 3, name: 'Lithium', weight: 6.941, symbol: 'Li'},
{position: 4, name: 'Beryllium', weight: 9.0122, symbol: 'Be'},
{position: 5, name: 'Boron', weight: 10.811, symbol: 'B'},
{position: 6, name: 'Carbon', weight: 12.0107, symbol: 'C'}
];
#Component({
selector: 'dynamic-table-example',
styleUrls: ['dynamic-table-example.css'],
templateUrl: 'dynamic-table-example.html',
})
export class DynamicTableExample implements OnInit {
columns:Array<any>
displayedColumns:Array<any>
dataSource:any
ngOnInit() {
// Get list of columns by gathering unique keys of objects found in DATA.
const columns = DATA
.reduce((columns, row) => {
return [...columns, ...Object.keys(row)]
}, [])
.reduce((columns, column) => {
return columns.includes(column)
? columns
: [...columns, column]
}, [])
// Describe the columns for <mat-table>.
this.columns = columns.map(column => {
return {
columnDef: column,
header: column,
cell: (element: any) => `${element[column] ? element[column] : ``}`
}
})
this.displayedColumns = this.columns.map(c => c.columnDef);
// Set the dataSource for <mat-table>.
this.dataSource = DATA
}
}
<mat-table #table [dataSource]="dataSource">
<ng-container *ngFor="let column of columns" [cdkColumnDef]="column.columnDef">
<mat-header-cell *cdkHeaderCellDef>{{ column.header }}</mat-header-cell>
<mat-cell *cdkCellDef="let row">{{ column.cell(row) }}</mat-cell>
</ng-container>
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
<mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row>
</mat-table>

Riot API With Angular 2

I trying to use the Riot API for Champions in this code
--Service
#Injectable()
export class ChampionService {
private riotUrl = 'https://br1.api.riotgames.com/lol/static-
data/v3/champions?api_key=myApiKey';
constructor(private _http: Http) { }
getChampion(): Observable<Champion[]> {
return this._http.get(this.riotUrl)
.map((res:Response) => <Champion[]>[res.json()])
.do(data => console.log(JSON.stringify(data)));
}}
-- Component
export class ChampionListComponent{
errorMessage: string;
champions: Champion[];
constructor(private _ChampionService: ChampionService){}
ngOnInit():void{
this._ChampionService.getChampion()
.subscribe(champions => this.champions = champions,
error => this.errorMessage = <any>error);}
--HTML
<table class="table">
<thead>
<tr>
<th>Id</th>
<th>Name</th>
</tr>
</thead>
<tbody>
<tr *ngFor='let champion of champions'>
<td>{{champion.id}}</td>
<td>{{champion.name}}</td>
</tr>
</tbody>
</table>
In the console that's appears correctly.. but nothing happen with my table
--- My Console Show This
Angular is running in the development mode. Call enableProdMode() to enable the production mode.
champion-list.service.ts:18 [{"type":"champion","version":"7.8.1","data":{"Jax":{"id":24,"key":"Jax","name":"Jax","title":"o Grão-Mestre das Armas"},"Sona":{"id":37,"key":"Sona","name":"Sona","title":"a Mestra das Cordas"},"Tristana":{"id":18,"key":"Tristana","name":"Tristana","title":"a Artilheira Yordle"},"Varus":{"id":110,"key":"Varus","name":"Varus","title":"a Flecha da Vingança"},"Fiora":{"id":114,"key":"Fiora","name":"Fiora","title":"a Grande Duelista"},"Singed":{"id":27,"key":"Singed","name":"Singed","title":"o Químico Louco"},"TahmKench":{"id":223,"key":"TahmKench","name":"Tahm Kench","title":"o Rei do Rio"},"Leblanc":{"id":7,"key":"Leblanc","name":"LeBlanc","title":"a Farsante"},"Thresh":{"id":412,"key":"Thresh","name":"Thresh","title":"o Guardião das Correntes"},"Karma":{"id":43,"key":"Karma","name":"Karma","title":"a Iluminada"},"Jhin":{"id":202,"key":"Jhin","name":"Jhin","title":"o Virtuoso"},"Rumble":{"id":68,"key":"Rumble","name":"Rumble","title":"a Ameaça Mecânica"},"Udyr":{"id":77,"key":"Udyr","name":"Udyr","title":"o Andarilho Espiritual"},"LeeSin":{"id":64,"key":"LeeSin","name":"Lee Sin","title":"o Monge Cego"},"Yorick":{"id":83,"key":"Yorick","name":"Yorick","title":"Pastor de Almas"},"Kassadin":{"id":38,"key":"Kassadin","name":"Kassadin","title":"o Andarilho do Vazio"},"Sivir":{"id":15,"key":"Sivir","name":"Sivir","title":"a Mestra da Batalha"},"MissFortune":{"id":21,"key":"MissFortune","name":"Miss Fortune","title":"a Caçadora de Recompensas"}...
someone can help me ? Sorry for the long post
Even though you are setting your response in an array:
.map((res:Response) => <Champion[]>[res.json()])
This still means that your array just contains one object, that contains objects (which you want to iterate). So first let's remove the assignment to an array, and instead step into the JSON and extract the object that contains your objects that you want:
.map((res:Response) => res.json().data)
This means you end up with an object with your objects. Since object cannot be iterated, we need to use a pipe:
#Pipe({ name: 'keys', pure: false })
export class KeysPipe implements PipeTransform {
transform(value: any, args?: any[]): any[] {
// create instance vars to store keys and final output
let keyArr: any[] = Object.keys(value),
dataArr = [];
// loop through the object,
// pushing values to the return array
keyArr.forEach((key: any) => {
dataArr.push(value[key]);
});
// return the resulting array
return dataArr;
}
}
Then apply that pipe in your template:
<tr *ngFor='let champion of champions | keys'>
<td>{{champion.id}}</td>
<td>{{champion.name}}</td>
</tr>
That should do the trick! :)
As a sidenote, this means your response is not an Array of Champion, so assigning it <Champion[]> is inaccurate. However your interface is built, you need to make the appropriate changes.
Demo

How to get element with specific value in htmlagilitypack

I have ASP.NET MVC4 project where try to parse html document with HtmlAgilityPack. I have the following HTML:
<td class="pl22">
<p class='pb10 pt10 t_grey'>Experience:</p>
<p class='bold'>any</p>
</td>
<td class='pb10 pl20'>
<p class='t_grey pb10 pt10'>Education:</p>
<p class='bold'>any</p>
</td>
<td class='pb10 pl20'>
<p class='pb10 pt10 t_grey'>Schedule:</p>
<p class='bold'>part-time</p>
<p class='text_12'>2/2 (day/night)</p>
</td>
I need to get values:
"any" after "Experience:"
"any" after "Education:"
"part-time", "2/2 (day/night)" after "Schedule:"
All what I imagine is that
HtmlNode experience = hd.DocumentNode.SelectSingleNode("//td[#class='pl22']//p[#class='bold']");
But it get me different element, which place in the top of the page. My Experience, Education and Schedule is static values. In additional my any, any part-time day/night is the dynamic values. Can anybody help me?
Below is an alternative which is more focused on the table headers (Experience, Education and Schedule), instead of the node classes:
private static List<string> GetValues(HtmlDocument doc, string header) {
return doc.DocumentNode.SelectNodes(string.Format("//p[contains(text(), '{0}')]/following-sibling::p", header)).Select(x => x.InnerText).ToList();
}
You can call that method like this:
var experiences = GetValues(doc, "Experience");
var educations = GetValues(doc, "Education");
var schedules = GetValues(doc, "Schedule");
experiences.ForEach(Console.WriteLine);
educations.ForEach(Console.WriteLine);
schedules.ForEach(Console.WriteLine);
You could do it something like this if you want to keep the XPath
var html = "<td class='pl22'><p class='pb10 pt10 t_grey'>Experience:</p><p class='bold'>any</p></td><td class='pb10 pl20'><p class='t_grey pb10 pt10'>Education:</p><p class='bold'>any</p></td><td class='pb10 pl20'><p class='pb10 pt10 t_grey'>Schedule:</p><p class='bold'>part-time</p><p class='text_12'>2/2 (day/night)</p></td> ";
var doc = new HtmlDocument
{
OptionDefaultStreamEncoding = Encoding.UTF8
};
doc.LoadHtml(html);
var part1 = doc.DocumentNode.SelectSingleNode("//td[#class='pl22']/p[#class='bold']");
var part2 = doc.DocumentNode.SelectNodes("//td[#class='pb10 pl20']/p[#class='bold']");
foreach (var item in part2)
{
Console.WriteLine(item.InnerText);
}
var part3 = doc.DocumentNode.SelectSingleNode("//td[#class='pb10 pl20']/p[#class='text_12']");
Console.WriteLine(part1.InnerText);
Console.WriteLine(part3.InnerText);
Output :
any
part-time
any
2/2 (day/night)

Knockout Table View of Array list without Names

I'm new to knockout and JS programming. I have a JSON result set returned, that would be two nested arrays, like this wherein each array could be variable in size:
listToReturn
[0] Count:4 -------> [0] "CHANNEL", [1] "HOUR", [2] "DATE", [3] "TRANSACTION_CNT"
[1] Count:122 ----->
[0] 101, [1] 11, [2] 03/01/2014, [3] 400,
[4] 101, [5] 6, [7] 03/12/2014, [8] 232
(these are the individual values for the rows above that repeat)
I want to build table that displays these nicely. Essentially, that will handle any result set that comes back with variable number of columns and data that will be populated in the table, like this:
CHANNEL HOUR DATE TRANSACTION_CNT
101 12 03/01/2014 400
101 6 03/12/2014 232
I have the first part working for the column headers:
Within ViewModel:
$.ajax({
type: 'get',
url: 'Reports/GetReportData',
data: { requestObj: req },
contenttype: 'application/json',
datatype: 'json',
success: function(result) {
if (result) {
document.getElementById("reportOutputfieldSet").style.display = "block";
ko.utils.arrayForEach(result[0], function (data) {
self.cnames.push(data.replace(",", " "));
});
ko.utils.arrayForEach(result[1], function (data) {
self.cdata.push(data.replace(",", " "));
});
In the View:
<tr data-bind="foreach: cnames" style="color: white; background-color: #003399; font-weight: bold; width: 600px">
<td data-bind="text: $data" style="width: 25%"></td>
</tr>
After several different attempts to properly construct a display for the data, I'm coming up empty handed. I first tried going through and getting the unique values for each one and displaying them in the UI, but that didn't work. :(
var noColumns = result[0].length;
var thisArray = function () {
if (result[1].length === 0)
return [];
for (var column = 0; column < result[0].length - 1; column++) {
for (var row = column; row < result[1].length - 1; row++) {
if (row % noColumns == 0) {
switch (column) {
case 0:
self.columnOne.push(result[1][row]);
break;
case 1:
self.columnTwo.push(result[1][row]);
break;
}
}
}
}
return self.columnOne();
};
In the View:
<tbody>
<!-- ko foreach: columnOne -->
<tr style="border-bottom: solid 1px #003399;">
<td data-bind="text: $data" style="width: 25%"></td>
<!-- ko foreach: columnTwo -->
<td data-bind="text: $data" style="width: 25%"></td>
<!-- /ko -->
</tr>
<!-- /ko -->
</tbody>
I have a feeling I need a custom ko.binding, but really at a loss as to how to get started with it. Anyone's help is greatly appreciated. Thanks in advance!

Srpy dataset if decision based on value from different dataset

Many thanks for reading this.
I have asked as well in Adobe forums with no luck.
I am building a small library application for school books.
I have created a database with lets say 2 tables
Books ( ID_Book , Writer , Title , Copies) and
Loans ( ID_Book , Load_ID , Loan_Date ) etc
I have used correctly spry to create easily a table which print the book list in a table
with pagination .
var ds1 = new Spry.Data.XMLDataSet("ajaxquery.php", "root/row", {sortOnLoad: "Writer", sortOrderOnLoad: "ascending"});
ds1.setColumnType("ID_Book", "number");
var pv1 = new Spry.Data.PagedView( ds1 ,{ pageSize:10 });
var pv1PagedInfo = pv1.getPagingInfo();
pv1.setColumnType("ID_Book", "number");
I have made the necessary declarations to produce the dataset for the Loans
var ds3 = new Spry.Data.XMLDataSet("ajaxallloans", "root/row", {sortOnLoad: "ID_Book", sortOrderOnLoad: "ascending"});
ds3.setColumnType("ID_Book", "number");
ds3.setColumnType("ID_Dan", "number");
I would like to find a way to change the table row color for the BOOKS table IF an ID_Book is within the Loans table - ds3.
The table is created
<div spry:region="pv1" id="bibliapv">
<div spry:state="loading" class="loading" >Loading...</div>
<div spry:state="ready">
<table>
<tr >
<th width="75" spry:sort="ID_Book"> Book No</th>
<th width="123" spry:sort="Writer">Writer </th>
etc...
</tr>
<tr spry:repeat="pv1" spry:select="mySelectClass" spry:hover="hover">
<td >{ID_Book}</td>
<td>{writer}</td>
etc ..
</tr>
</table>
</div>
</div>
<div>
Many thanks again.
Dinos - Greece
Many thanks again for reading .
I found a solution based on the ideas drawn from
labs.adobe.com/technologies/spry/samples/data_region/CustomColumnsSam ple.html
I have added the following code:
created a css rule
lets say
.match {
background-color: #0CF;
}
In spry:region add the class {cssrule} which is added dynamically shortly after <tr class="{cssrule}" spry:repeat="pv1" spry:select="mySelectClass" spry:hover="hover">
3.
Then just before closing tag added (you could put it earlier in code)
<script type="text/javascript">
ds2.addObserver({
onPostLoad:function( ds2, data ){
var data = ds2.getData();
var pv1data = pv1.getData();
for( var i = 0; i < pv1data.length; i++ )
{
for (var j =0 ; j< data.length ; j++)
{ if ((data[j].Writer).toString()== (pv1data[i].Writer).toString() ) //or whatever you like!
{pv1data[i].cssrule="match"; }
}
}
}
});
</script>