I'm trying to make an export of my model which consists out of employees, some properties and a Date.
Visualisation of my model
var myModel= {
employees: [{
pentagram: oMyData.Pentagram,
records: [{
Date: oMyData.Date,
GC: oMyData.Lunch,
CheckIn: oMyData.CheckedIn,
CheckOut: oMyData.CheckedOut
}]
}]
};
Purpose of my application
My app is used to log which employee is in the building by letting them check in and out at the front door. This is registered to a HanaXS database. Each day when an employee checks in, a record is created with the corresponding properties. So if the decide not to eat at the office, they will click on the GC button (which stands for 'no consumption' in dutch).
So in a nutshell. Each employee has their own record per date in the database.
What do I want to do
I want to make an excel sheet which will cover a month.
The most left column will cover the names of the employee's (Pentagram). After that all the columns will be a day in the corresponding month in chronological order.
The content should be an X when they pressed the GC button. Otherwise the cell should be empty.
My problem
I have no clue how to get the dates as columns while keeping the binding with the employees. I've already searched a lot on exporting of the model and of tables but nothing is actually near to what I need.
If anyone has some experience or done this before I would be really gratefull for some help.
Thanks in advance
Hi you can use the following libraries
'sap/ui/core/util/Export',
'sap/ui/core/util/ExportTypeCSV',
This is the sample code you can refer to suit your needs
generateExcel: function(oData, that) {
var oModel = new JSONModel();
oModel.setData(oData); //oData is the model data which is binding to the table
var oTable = this.getViewById("yourTableName").getTable();
var aColumns = oTable.getColumns();
var aItems = oTable.getItems();
var aTemplate = [];
for (var i = 0; i < aColumns.length; i++) {
var oColumn = {
name: aColumns[i].getHeader().getText(),
template: {
content: {
path: null
}
}
};
if (aItems.length > 0) {
oColumn.template.content.path = aItems[0].getCells()[i].getBinding("text").getPath();
}
aTemplate.push(oColumn);
}
var oExport = new Export({
// Type that will be used to generate the content. Own ExportType’s can be created to support other formats
exportType: new ExportTypeCSV({
separatorChar: ",",
charset: "utf-8"
}),
// Pass in the model created above
models: oModel,
// binding information for the rows aggregation
rows: {
path: "/results"
},
// column definitions with column name and binding info for the content
columns: aTemplate
});
oExport.saveFile().always(function() {
this.destroy();
});
}
Hi you can use custom formatter for columns depending on types like below an example
var oColumn = {
name: aColumns[i].getHeader().getText(),
template: {
content: {
path: null,
formatter: function(value) {
if (value instanceof(Date)) {
//Convert to user date format
var oFormat = DateFormat.getDateInstance({
style: "short"
});
value = oFormat.format(value);
} else {
value = (value === null) ? "" : value;
}
return value;
}
}
}
};
Related
I'm stuck in developing a filter for a list.
My list displays in the item an icon depending on two entries from the actual data record.
new sap.ui.core.Icon({
src : {
parts : [
{ path : "Model>date" },
{ path : "Model>inventory" }
],
formatter : function(date, inventory) {
if (!inventory) {
return "sap-icon://decline";
}
if (date != "31.12.9999") {
return "sap-icon://decline";
}
return "sap-icon://accept";
}
}
})
Now i will implement a filter for this information:
a) show all entries with the decline-icon
b) show all entries with the accept-icon
My problem is that the filter is accepting only one path-element.
var dateFilter =new sap.ui.model.Filter({
path : "date",
test : function(date) {
//pseudo code
if(#filter-true)
show entries with accept;
else
show entries with decline;
}
});
aFilters.push(dateFilter)
But actual i've no idea for implementing this filter.
Can someone help me please?
PS: I know that my grammar is not the best ;)
You can combine multiple filters that rely on different paths.
var oDateFilter = new sap.ui.model.Filter({
path : "date",
test : function(sDate) {
if(sDate === "31.12.9999"){
return true;
}
return false;
}
});
The code above creates a filter that operates using the "date" property of your model.
var oInventoryFilter = new sap.ui.model.Filter({
path : "inventory",
test : function(bInventory) {
if(bInventory !== true){
return false;
}
return true;
}
});
The code above creates a filter using the "inventory" property. Now, we are combining it via the following code:
var oCombinedFilter = new sap.ui.model.Filter({
filters: [oDateFilter, oInventoryFilter],
and: true
});
This filter returns true for all elements that got the inventory property set to true (make sure that the parameter is a boolean!) and the date set to "31.12.9999".
For more information see sap.ui.model.Filter.
I'm using arcgis javascript api 3.19 which includes dojo. I'm trying to display some data in a grid and edit it. Right now, the data won't display in the grid.
I'm using the tutorial to learn how to use this grid, [http://dgrid.io/js/dgrid/demos/laboratory/][http://dgrid.io/js/dgrid/demos/laboratory/]
I've embedded their sample code in my widget and it doesn't work.
(Rather than include my whole widget, I'll just show the sample code.)
It doesn't find the dgrid/Editor, but it can find dgrid/editor.
The grid header and an empty box for the data shows up, but no data.
require([
'dojo/_base/declare',
'dstore/Memory',
'dstore/Trackable',
'dgrid/OnDemandGrid',
'dgrid/Keyboard',
'dgrid/CellSelection',
'dgrid/Editor' // I have to use dgrid/editor for this to be found
], function (declare, Memory, Trackable, OnDemandGrid, Keyboard, CellSelection, Editor) {
var store = new (declare([Memory, Trackable]))({
data: createData()
});
// Instantiate grid
var grid = new (declare([OnDemandGrid, Keyboard, CellSelection, Editor]))({
collection: store,
columns: {
First_Name: {
label: 'First Name',
editor: 'text'
},
Last_Name: {
label: 'Last Name'
}
}
}, 'grid');
grid.startup();
function createData() {
var data = [];
var column;
var i;
var item;
for (i = 0; i < 50; i++) {
item = {};
for (column in { First_Name: 1, Last_Name: 1 }) {
item.id = i;
item[column] = column + '_' + (i + 1);
}
data.push(item);
}
return data;
}
});
Ok, I found the answer.
Esri has two directories in their javascript api, dgrid and dgrid1.
And the files in them are largely the same (by filename at least)
Apparently the "correct" classes are in dgrid1, not dgrid.
I suppose there might be a good reason for putting the code in a differently named directory than the documentation, but from where I'm sitting, not knowing that reason, I can only say "Thanks for letting me beat my head against a wall for two days on this. Thanks so very much."
I'm using vuejs for this project, but this problem is not necessarily connected - but if there is a vue-way, I would prefer that.
I'm building a table, that enables the user to have per-column-filters (in this case simple inputs). The columns are dynamic, so is the amount of data (thousands of rows, but less than 100.000 entries).
// example data
var columns = ['id', 'title', 'date', 'colour']
var data = [{ id: 1, title: 'Testentry 1', date: '2017-02-21T07:10:55.124Z', colour: 'green'}]
Here is the problem: I'm iterating over the columns, checking if a search-input exists, and if so, I try to filter the data based on the searchquery. In case of the ID, the time complexity is O(n). If I know search for a title additionally, I can reuse the result of the first searchquery, dramatically reducing the amount of data has to be looked at.
The searchqueries are stored in an object search, and the filtered data is a computed property, that gets updated whenever search changes. The way how that works though is, that if I change the searchquery for title, it would re-evaluate the searchquery even for the ID, although the searchquery for that didn't change.
This would require some kind of caching of data filtered for each column. And only the proceeding columns need to be queried upon.
edit: added code for the filtering:
filteredRows () {
var rows = this.data
for (var i = 0; i < this.columns.length; i++) {
var column = this.columns[i].name
var search = this.tSearch[column]
if (!search && search.length === 0) continue
console.log(column + ': ' + ' (' + search + ') -> ' + rows.length)
rows = _.filter(rows, (row) => {
var value = '' + row[column]
value.search(search) > -1
})
}
return rows
}
Just a suggestion, but did you try to use a watcher to get old and new value of input.
data: function() {
return {
propertyToWatch: 'something'
}
},
computed: {
...
},
watch: {
'propertyToWatch': function (val, oldVal) {
console.log(oldVal); // logs old value
console.log(val); // logs current value
// here you can call a function and send both of these args and detect diff
}
},
....
I have a dynamic ngTable for which I created a custom datetime filter like this:
// Generate table columns.
function generateColumns(sampleData) {
var colNames = Object.getOwnPropertyNames(sampleData);
var cols = colNames.map(function (name, idx) {
if (name == 'date') {
var filter = {};
filter[name] = 'partials/dateFilter.tpl.html';
return {
title: name,
sortable: name,
filter: filter,
filterOptions: { filterFn: dateFilter },
filterLayout: "horizontal",
show: true,
field: name
};
}
...
This way in my table, on the correct column I can see a datepicker instead of the usual text input for a filter.
My table data is initialized by simply doing:
// Initialize table parameters.
$scope.tableParams = new NgTableParams({
page: 1, // show first page.
count: 25 // counts per page.
}, {
filterDelay: 0,
dataset: $scope.testDataList
});
What I dont know how to do though is actually filter the data once I pick a date. My dateFilter function right now only contains a log message, but it is never called.
Basically the fact that I will change the date on my element but ngTable does not react in some way is by biggest issue.
How can I filter the table content based on the selected date?
I am new to backbone js. I am trying to create an application that displays certain data and allows users to filter them with certain attributes and narrow down results. My fetched data has three fields : Organisation name, Organisation type and Country. Users can apply filter on Organisation type and Country by selecting them from drop down list. The Organisation type and Country could be multiple. I used jQuery's select2 to allow users to select multiple organisation types and countries. The Organisation name is filtered on each keystroke on the input field. I managed to create a filter that filters the record based on all three attributes separately. Here's my collection along with my filter function:
var OrganisationCollection = Backbone.PageableCollection.extend({
model: Organisation,
state: {pageSize: 20},
mode: "client",
queryParams: {
currentPage: "current_page",
pageSize: "page_size"
},
filterBy: function(organisationName, organisationType, countryName){
var matchingModels;
var filterFunction = function(model) {
var check = (model.get('name').indexOf(organisationName)>-1);
return check;
}
collectionToFilter = this;
matchingModels = filteredCollection(collectionToFilter, filterFunction);
function filteredCollection(original, filterFn) {
var filtered;
// Instantiate new collection
filtered = new original.constructor();
// Remove events associated with original
filtered._callbacks = {};
filtered.filterItems = function(filter) {
var items;
items = original.filter(filter);
filtered._currentFilter = filterFn;
return filtered.reset(items);
};
// Refilter when original collection is modified
original.on('reset change destroy', function() {
return filtered.filterItems(filtered._currentFilter);
});
return filtered.filterItems(filterFn);
};
collectionToFilter = new OrganisationCollection(matchingModels);
return collectionToFilter;
}
});
Now, this filter function only filters the collection based on organisation name. If I were to filter my collection based on organisation type, my filterBy function would be:
filterBy: function(organisationName, organisationType, countryName){
var matchingModels;
var filterFunction = function(model) {
var check = typeof organisationType=='string' ? (model.get('type').indexOf(organisationType)>-1) : (_.indexOf(organisationType, model.get('type')) > -1);
return check;
}
collectionToFilter = this;
matchingModels = filteredCollection(collectionToFilter, filterFunction); // filterFunction would be same as above
collectionToFilter = new OrganisationCollection(matchingModels);
return collectionToFilter;
}
My filterBy country function would be similar to above.
Now my problem is that these three functions work fine separately. But I am unable to merge these three functions to narrow down the results. i.e. when a user filters with countries USA and Australia, types corporate and multilateral, only those organisations from countries USA and Australia having types corporate and multilateral are supposed to show. And again, among those results, if the user types 'A' in Organisation name input field, only those organisations from previous results starting with alphabet 'A' are supposed to show. I have no idea how to implement that.
Here's my function that triggers the filter:
$(document).ready(function(){
var country = $("#filter-country").val();
var countryName = country ? country : '';
var type = $("#filter-org-type").val();
var orgType = type ? type : '';
var orgName = '';
$("#filter").on('input',function(e){
var orgFilter = $('#filter').val();
orgName = orgFilter ? orgFilter : '';
orgCollection.trigger("filter-by-organisation",orgName, orgType, countryName);
});
// Users can select countries from select field #filter-country and types from select field #filter-org-type and click on button #apply-filters to trigger filter function
$(document).on('click', '#apply-filters', function(){
orgCollection.trigger("filter-by-organisation",orgName, orgType, countryName);
});
});
Please help me with this. Thanks
I might not have understood your problem very well, but you could simply do something like this:
var OrganisationCollection = Backbone.PageableCollection.extend({
model: Organisation,
filterBy: function(organisationName, organisationType, countryName) {
var organisationNameResults = this.filter(function(model) {
// your logic for filtering based on organisationName
});
var organisationTypenResults = _.filter(organisationNameResults, function(model) {
// your logic for filtering based on organisationType
});
var countryNameResults = _.filter(organisationTypenResults, function(model) {
// your logic for filtering based on countryName
});
this.reset(countryNameResults);
}
});
It can be refactored, this is just to give you an idea