Sorting JSON and displaying in Tree using DOJO - dojo

I am learning DOJO 1.6.
I have data
var data = [
{ FirstName: 'xyz', Lastname: 'QSD', rollNo: '1', EntryDate: '2012-09-11T17:35:31.835+02:00' },
{ FirstName: 'abc', Lastname: 'qgr', rollNo: '2', EntryDate: '2012-08-11T17:35:31.835+02:00' }
{ FirstName: 'ert', Lastname: 'fgd', rollNo: '3', EntryDate: '2012-18-11T17:35:31.835+02:00' }
];
I want to sort it with respect to Last name or EntryDate and display in a tree format.
Thanks in Advance.
Multiple root data
data: [
{ id: 'world', name:'The earth', type:'planet', population: '6 billion'},
{ id: 'AF', name:'Africa', type:'continent', population:'900 million', area: '30,221,532 sq km',
timezone: '-1 UTC to +4 UTC', parent: 'world'},
{ id: 'EG', name:'Egypt', type:'country', parent: 'AF' },
{ id: 'KE', name:'Kenya', type:'country', parent: 'AF' },
{ id: 'Nairobi', name:'Nairobi', type:'city', parent: 'KE' },
{ id: 'Mombasa', name:'Mombasa', type:'city', parent: 'KE' },
{ id: 'SD', name:'Sudan', type:'country', parent: 'AF' },
{ id: 'Khartoum', name:'Khartoum', type:'city', parent: 'SD' },
{ id: 'AS', name:'Asia', type:'continent', parent: 'world' },
{ id: 'CN', name:'China', type:'country', parent: 'AS' },
{ id: 'IN', name:'India', type:'country', parent: 'AS' },
{ id: 'RU', name:'Russia', type:'country', parent: 'AS' },
{ id: 'MN', name:'Mongolia', type:'country', parent: 'AS' },
{ id: 'OC', name:'Oceania', type:'continent', population:'21 million', parent: 'world'},
{ id: 'EU', name:'Europe', type:'continent', parent: 'world' },
{ id: 'DE', name:'Germany', type:'country', parent: 'EU' },
{ id: 'FR', name:'France', type:'country', parent: 'EU' },
{ id: 'ES', name:'Spain', type:'country', parent: 'EU' },
{ id: 'IT', name:'Italy', type:'country', parent: 'EU' },
{ id: 'NA', name:'North America', type:'continent', parent: 'world' },
{ id: 'SA', name:'South America', type:'continent', parent: 'world' }
],

Javascript Array has a native function, called sort. This will off-the-shelf sort the values alphabetically. For the purpose of sorting non-string-values, we need to supply a sortingfunction. Like so, in regards to Lastname:
data.sort(function(a,b) {
var _A=a.Lastname.toLowerCase(),
_B=b.Lastname.toLowerCase();
if (_A < _B) //sort string ascending
return -1
if (_A > _B)
return 1
return 0 //default return value (no sorting)
});
If youre sorting against a date, you would need to initialize _A and _B to a Date.
However, if youre aiming to represent the data in a dijit.Tree, there's inbuilt method for sorting the Store, lets wrap data into a dojo/data/ItemFileReadStore and show in a tree. Tree will have a model, using ItemFileWriteStore - so that items can be modified:
var sortableStore = new dojo.data.ItemFileReadStore({
data: {
identifier: 'rollNo',
items: data
},
comperatorMap: {
'EntryDate' : function(a,b) {
var _A = new Date(a), _B = new Date(b);
if(_A > _B) return 1;
else if(_A == _B) return 0;
else return -1;
}
});
Using 'store.fetch()' API while setting the 'sort' parameter, you control the order of returned items. The EntryDate you will have to create a comperatorMap of functions, as with Array.sort() in order to sort it properly. See the documentation.
var model = new dijit.tree.ForestStoreModel({
rootLabel: 'Names',
store: new dojo.data.ItemFileWriteStore({
data: {
identifier: 'rollNo',
items: data,
// blank, initially - can fill in with 'data' to show non-sorted items until sort is called
label: 'FirstName'
}
}) // blank itemsstore
});
var tree = new dijit.Tree({
model: model
});
OK, All set - but problem with .fetch is, it runs with callbacks (onComplete) and is difficult to control in a recursive manner. Instead, the functionality put in THIS FIDDLE duplicates the store data and then sorts it via native array sort - as opposed to using SimpleQueryEngine.
This will prove to give more reliable results - but does mess with DnD controllers and persist flag..
See how store can sort its items returned by fetch here: fiddle. This however only sorts one 'level' at a time and does not perform deep sorts.
IMO: The proper implementation of sort is a serverside sort, directly in the database query.
http://dojotoolkit.org/reference-guide/1.8/dojo/data/ItemFileReadStore.html#custom-sorting
http://dojotoolkit.org/reference-guide/1.8/dijit/Tree.html

Related

vuetable-2 select multiple sort items in same column

I need to filter data, including or excluding, multiple possible options in a column, but I don't know how to do it.
this only shows me a "single" select below the column name, with the possible options, but I can't select multiple of them, and I can't find an option to do that.
I need to filter by 2 rooms or multiple users, but the selection is not multiple, and there is no option to do it.
Now I have this HTML code:
<v-client-table id="messages" style="width:100%;" ref="table_reference" :options="table_options" :columns="table_fields" v-model="messages_array">
</v-client-table>
and this table configuration (messages, and other vars excluded):
const app2 = {
el: "#messages-container",
data() {
return {
table_options: {
filterByColumn: true,
texts: {
filterPlaceholder: ""
},
selectable: {
mode: 'single', // or 'multiple'
only: function(row) {
return true // any condition
},
selectAllMode: 'all',
programmatic: false
},
sortIcon: {
base: 'fa fas',
up: 'fa-long-arrow-alt-up',
down: 'fa-long-arrow-alt-down',
is: 'fa-sort'
},
listColumns: {
user_id: [],
room: [],
status: []
},
sortable: ['user_id', 'status', 'room', "created"],
filterable: ['user_id', "room", "status"],
headings: {
id: '#',
user_id: 'Name',
navigator_info: 'Details',
message: 'Message',
room: 'Room',
status: 'Status',
created: 'Date',
response_to: 'Actions'
}
},
table_fields: ["id", "user_id", "message", "room", "status", "created"],
}
}
};
I think this is a common use of a data table, and there should be a way to do it. I would appreciate your help. Thank you very much in advance!

Filter an array of dates (datetime) with GROQ (sanity) (React App)

I have a list of movies that could be shown more than once. I decided to provide a user with an option to select multiple dates for a single movie (sanity studio interface).
The schema for movies is as follows:
export default {
name: 'movie',
title: 'Movie',
type: 'document',
fields: [
{
name: 'title',
title: 'Title',
type: 'string'
},
{
name: 'dates',
title: 'Dates',
type: 'array',
of: [
{
type: 'datetime',
options: {
dateFormat: 'YYYY-MM-DD',
timeFormat: 'HH:mm',
timeStep: 15,
calendarTodayLabel: 'Today'
}
}
]
},
{
name: 'poster',
title: 'Poster',
type: 'image',
options: {
hotspot: true
}
},
{
name: 'body',
title: 'Body',
type: 'blockContent'
}
],
preview: {
select: {
title: 'title',
date: 'date',
media: 'poster'
}
}
}
Current query:
const query = groq`*[_type == "movie"]{
title,
dates,
poster,
body
}`
I need to filter the movie that has today's date in the dates array with GROQ
Maybe I'm overcomplicating this and someone will come up with a better way.
The idea is to avoid duplicates in the database (1 movie can be shown 3-6 times). That's the only reason I used an array
The solution for this should be:
const query = '*[_type == "movie" && dates match $today]{title, dates, poster, body}'
const today = new Date().toISOString().split('T')[0]
client.fetch(query, {today}).then(result => {
// movies which are showing today
})
However, there is currently a bug in the string tokenizer which cripples date string matching. In the meantime, I'm afraid your only option is to fetch all movies and filter client side. We're hoping to get this fixed as soon as possible.

Is it possible to add animations to dgrid rows?

We currently have a dgrid with a single column and rows like this:
Recently I added some code so that we can delete rows with the little X button that appears above the row when we hover them.
The handler calls this to delete the row:
this.grid.store.remove(rowId);
When we delete a row, since it's instantaneous and each row contains similar text, it's not always obvious to the user that something just happened.
I was wondering if it would be possible add some sort of dojo or css animation to the row deletion, like the deleted row fading or sliding out. This would make the row deletion more obvious.
Thanks
I have created a jsfiddle for animating(wipeOut) a selected row.
require({
packages: [
{
name: 'dgrid',
location: '//cdn.rawgit.com/SitePen/dgrid/v0.3.16'
},
{
name: 'xstyle',
location: '//cdn.rawgit.com/kriszyp/xstyle/v0.2.1'
},
{
name: 'put-selector',
location: '//cdn.rawgit.com/kriszyp/put-selector/v0.3.5'
}
]
}, [
'dojo/_base/declare',
'dgrid/OnDemandGrid',
'dgrid/Selection',
'dojo/store/Memory',
"dojo/fx",
'dojo/domReady!'
], function(declare, Grid, Selection, Memory,fx) {
var data = [
{ id: 1, name: 'Peter', age:24 },
{ id: 2, name: 'Paul', age: 30 },
{ id: 3, name: 'Mary', age:46 }
];
var store = new Memory({ data: data });
var options = {
columns: [
/*{ field: 'id', label: 'ID' },*/
{ field: 'name', label: 'Name' },
{ field: 'age', label: 'Age' }
],
store: store
};
var CustomGrid = declare([ Grid, Selection ]);
var grid = new CustomGrid(options, 'gridcontainer');
grid.on('dgrid-select', function (event) {
// Report the item from the selected row to the console.
console.log('Row selected: ', event.rows[0].data);
//WipeOut animation for selected row.
fx.wipeOut({ node: event.rows[0].element }).play();
});
});

How do I query for tag names with :find in SnapshotStore store config

I am trying to setup a filter that is similar to a defect view within a Trend chart. The filter in the defect view is:
(State < Closed) AND (Severity <= Major) AND (Tags !contains Not a Stop Ship)
I cannot seem to get the Tags find to work correctly. Any suggestions?
this.myTrendChart = Ext.create('Rally.ui.chart.Chart', {
storeType: 'Rally.data.lookback.SnapshotStore',
storeConfig: {
find: {
_TypeHierarchy: "Defect",
State: {
$lt: "Closed"
},
Severity: {
$lte: "Major"
},
Tags: {
$ne: "Not a Stop Ship"
},
_ProjectHierarchy: ProjectOid
},
hydrate: ["Priority"],
fetch: ["_ValidFrom", "_ValidTo", "ObjectID", "Priority"]
},
calculatorType: 'My.TrendCalc',
calculatorConfig: {},
chartConfig: {
chart: {
zoomType: 'x',
type: 'line'
},
title: {
text: 'Defects over Time'
},
xAxis: {
type: 'datetime',
minTickInterval: 3
},
yAxis: {
title: {
text: 'Number of Defects'
}
}
}
});
Based on reviewing the JSON messages, I figured out the tag needed to be the ObjectId. Once I found this, I replaced "Not a Stop Ship" with the ObjectId value and the filter worked correctly.

Creating sorted tree in DOJO 1.6?

I new to learn dojo and trying to learn by it using samples code.
Using dojo 1.6
With help of sample codes , I created a tree
now i want to apply sorting on root and also on child.
With the help of this sample code , i changed the code
Output is not sorted n but the root folder has changed their position and child is deleted.
Plz help me to resolve this.
My code :
dojo.require("dojo.data.ItemFileWriteStore");
dojo.require("dojo.data.ItemFileReadStore");
dojo.require("dijit.tree.ForestStoreModel");
dojo.require("dijit.Tree");
var data = [ { id: 1, name: "answerTypeLabel", type:'scenario', children:[{_reference: 2}]},
{ id: 2, name: "acceptRequestLabel", type:'paragraph', data: "acceptRequestLabel"},
{ id: 3, name: "rejectRequestLabel", type:'scenario', children:[{_reference: 5},{_reference: 6}]},
{ id: 4, name: "MoreInformationLabel", type:'scenario', children:[{_reference: 7},{_reference: 8}]},
{ id: 5, name: "rejectRequestStatusLabel", type:'paragraph', data: "rejectRequestStatusLabel"},
{ id: 6, name: "rejectRequestNotCoveredLabel", type:'paragraph', data: "rejectRequestNotCoveredLabel" },
{ id: 7, name: "MoreInformationDocumentLabel", type:'paragraph', data: "MoreInformationDocumentLabel"},
{ id: 8, name: "MoreInformationDataLabel", type:'paragraph', data: "MoreInformationDataLabel"}
];
dojo.addOnLoad(function() {
var sortableStore = new dojo.data.ItemFileReadStore({
data: {
identifier: 'id',
label: 'name',
items: data
}
});
var model = new dijit.tree.ForestStoreModel({
rootLabel: 'Names',
store: new dojo.data.ItemFileWriteStore({
data: {
identifier: 'id',
items: [],
label: 'name'
}
}) // blank itemsstore
})
var tree = new dijit.Tree({
model: model,
updateItems: function(items) {
var self = this;
console.log('pre', this.model.root.children);
dojo.forEach(items, function(newItem) {
console.log('add', newItem);
try {
self.model.store.newItem({
id: sortableStore.getValue(newItem, 'id'),
name: sortableStore.getValue(newItem, 'name'),
type: sortableStore.getValue(newItem, 'type'),
data: sortableStore.getValue(newItem, 'data'),
});
} catch (e) {
console.log(e);
}
});
console.log('post', this.model.root.children);
console.log("children: ", this.rootNode.getChildren());
},
});
tree.placeAt(dojo.body());
sortableStore.fetch({
query: {
type:'scenario'
},
sort: [{
attribute: "name"}],
onComplete: function(items) {
console.log(items, 'sorted');
tree.updateItems(items);
}
})
});
Output :
The 'Names' origins from you setting 'rootLabel'.
Btw, fiddles have revisions and is simply a paste-bin like feature :)
You need to use the tree model pasteItem to insert referenced items (the 'children' property of each 'newItem').
Otherwise, there's another approach, if you get rid of the '_reference' structure of your data. See: http://jsfiddle.net/GHFdA/1/