I want to build project team-wise portfolio items
project -1
- Feature -1
- Feature -2
project - 2
- Feature -1
- Feature -2
I am unable to get project and features as children in rally tree builder, I have tried like below:
Rally.onReady(function() {
Ext.define('Rally.example.SimpleTreeGrid', {
extend: 'Rally.app.App',
componentCls: 'app',
launch: function() {
Ext.create('Rally.data.wsapi.TreeStoreBuilder').build({
models: ['PortfolioItem/Feature'],
autoLoad: true,
enableHierarchy: true
}).then({
success: this._onStoreBuilt,
scope: this
});
},
_onStoreBuilt: function(store) {
this.add({
xtype: 'rallytreegrid',
store: store,
context: this.getContext(),
enableEditing: false,
enableBulkEdit: false,
shouldShowRowActionsColumn: false,
enableRanking: false,
childEls: ["title"],
columnCfgs: [
'Name',
'State',
'Owner'
]
});
}
});
Rally.launchApp('Rally.example.SimpleTreeGrid', {
name: 'Simple Tree Grid Example'
});
});
Got it..! I have taken grouped by grid as reference and built the grid
_createGrid: function ()
{
var filter = Ext.create('Rally.data.wsapi.Filter', { property: 'Release.Name', operator: '=', value: ReleaseBoxValue });
if (!this.down('#storygrid'))
{
this.grid = this.add({
xtype: 'rallygrid',
itemId: 'storygrid',
columnCfgs: [
{
text: 'Formatted ID', dataIndex: 'FormattedID', xtype: 'templatecolumn',
tpl: Ext.create('Rally.ui.renderer.template.FormattedIDTemplate')
},
{
text: 'Name', dataIndex: 'Name'
},
{
text: 'Accepted', dataIndex: 'FormattedID',
renderer: function (value)
{
var Release = value;
var html = "";
var userStoriesCount = 0;
_.each(acceptedStories, function (record)
{
if (record.key == Release)
{
userStoriesCount++;
}
}, this);
html = '<span>' + userStoriesCount + '</span>';
return html;
}
},
{
text: 'Completed', dataIndex: 'FormattedID',
renderer: function (value)
{
var Release = value;
var html = "";
var userStoriesCount = 0;
_.each(completedPercentage, function (record)
{
if (record.key == Release)
{
userStoriesCount++;
}
}, this);
html = '<span>' + userStoriesCount + '</span>';
return html;
}
},
{
text: 'Defined', dataIndex: 'FormattedID',
renderer: function (value)
{
var Release = value;
var html = "";
var userStoriesCount = 0;
_.each(definedStories, function (record)
{
if (record.key == Release)
{
userStoriesCount++;
}
}, this);
html = '<span>' + userStoriesCount + '</span>';
return html;
}
},
{
text: 'Grooming', dataIndex: 'FormattedID',
renderer: function (value)
{
var Release = value;
var html = "";
var userStoriesCount = 0;
_.each(grommedStories, function (record)
{
if (record.key == Release)
{
userStoriesCount++;
}
}, this);
html = '<span>' + userStoriesCount + '</span>';
return html;
}
},
{
text: 'In-Progress', dataIndex: 'FormattedID',
renderer: function (value)
{
var Release = value;
var html = "";
var userStoriesCount = 0;
_.each(inProgressStories, function (record)
{
if (record.key == Release)
{
userStoriesCount++;
}
}, this);
html = '<span>' + userStoriesCount + '</span>';
return html;
}
},
{
text: 'Grand Total', dataIndex: 'FormattedID',
renderer: function (value)
{
var Release = value;
var html = "";
var userStoriesCount = 0;
_.each(totalStories, function (record)
{
if (record.key == Release)
{
userStoriesCount++;
}
}, this);
html = '<span>' + userStoriesCount + '</span>';
return html;
}
},
{
text: 'Optum Accepted Stories', dataIndex: 'FormattedID',
renderer: function (value)
{
var Release = value;
var html = "";
var userStoriesCount = 0;
_.each(acceptedStories, function (record)
{
if (record.key == Release)
{
userStoriesCount++;
}
}, this);
html = '<span>' + userStoriesCount + '</span>';
return html;
}
},
{
text: 'Stories yet to be accepted', dataIndex: 'FormattedID',
renderer: function (value)
{
var Release = value;
var html = "";
var userStoriesCount = 0;
_.each(completedPercentage, function (record)
{
if (record.key == Release)
{
userStoriesCount++;
}
}, this);
html = '<span>' + userStoriesCount + '</span>';
return html;
}
}
,
{
text: 'Total Stories', dataIndex: 'FormattedID',
renderer: function (value)
{
var Release = value;
var html = "";
var userStoriesCount = 0;
_.each(totalStories, function (record)
{
if (record.key == Release)
{
userStoriesCount++;
}
}, this);
html = '<span>' + userStoriesCount + '</span>';
return html;
}
}
,
{
text: 'Optum Accepted Stories (%)', dataIndex: 'FormattedID',
renderer: function (value)
{
var Release = value;
var html = "";
var accepetedCount = 0;
_.each(acceptedStories, function (record)
{
if (record.key == Release)
{
accepetedCount++;
}
}, this);
var totalStoriesCount = 0;
_.each(totalStories, function (record)
{
if (record.key == Release)
{
totalStoriesCount++;
}
}, this);
var decTotal = accepetedCount / totalStoriesCount;
if (!isNaN(decTotal))
{
html = '<span>' + Math.round((decTotal) * 100) + '%</span>';
}
else
{
html = '<span>0%</span>';
}
return html;
}
}
,
{
text: 'Stories yet to be accepted (%)', dataIndex: 'FormattedID',
renderer: function (value)
{
var Release = value;
var html = "";
var completedCount = 0;
_.each(completedPercentage, function (record)
{
if (record.key == Release)
{
completedCount++;
}
}, this);
var totalStoriesCount = 0;
_.each(totalStories, function (record)
{
if (record.key == Release)
{
totalStoriesCount++;
}
}, this);
var decTotal = completedCount / totalStoriesCount;
if (!isNaN(decTotal))
{
html = '<span>' + Math.round((decTotal) * 100) + '%</span>';
}
else
{
html = '<span>0%</span>';
}
return html;
}
}
],
context: this.getContext(),
features: [{
ftype: 'groupingsummary',
groupHeaderTpl: '{name} ({rows.length})'
}
],
filters: [filter],
storeConfig: {
model: 'portfolioitem/feature',
groupField: 'Name',
groupDir: 'ASC',
fetch: ['FormattedID', 'Name', 'Release', 'Project', 'UserStories', 'HierarchicalRequirement'],
filters: [filter],
getGroupString: function (record)
{
var owner = record.get('Project');
return (owner && owner._refObjectName) || 'No Name';
}
}
});
}
else
{
var filter = Ext.create('Rally.data.wsapi.Filter', { property: 'Release.Name', operator: '=', value: ReleaseBoxValue });
var treeGrid = this.down('rallygrid'),
treeStore = treeGrid.getStore();
treeStore.clearFilter(true);
treeStore.filter(filter);
}
}
Related
I have the code with showing data from json file, but i need update table single row data to the database. In my code I can update only angulajs table. So i need one more thing, need to update that one mysql also. hence, i need to know how data will pass mysql to using js& PHP, the code is given below.
Script.js
var app = angular.module('app',
[
'ui.grid',
'ui.grid.pagination',
'ui.grid.selection',
'ui.grid.cellNav',
'ui.grid.expandable',
'ui.grid.edit',
'ui.grid.rowEdit',
'ui.grid.saveState',
'ui.grid.resizeColumns',
'ui.grid.pinning',
'ui.grid.moveColumns',
'ui.grid.exporter',
'ui.grid.infiniteScroll',
'ui.grid.importer',
'ui.grid.grouping'
]);
app.filter('genderFilter', function () {
var genderHash = {
'M': 'male',
'F': 'female'
};
app.gridApi.core.on.rowsRendered(scope,() => {
if (!gridApi.grid.expandable.expandedAll && !initialized)
{
gridApi.expandable.expandAllRows();
initialized = true;
}
});
return function (input) {
var result;
var match;
if (!input) {
return '';
} else if (result = genderHash[input]) {
return result;
} else if ((match = input.match(/(.+)( \([$\d,.]+\))/)) && (result = genderHash[match[1]])) {
return result + match[2];
} else {
return input;
}
};
});
app.filter('maritalFilter', function () {
var genderHash = {
'M': 'Married',
'S': 'Single'
};
return function (input) {
var result;
var match;
if (!input) {
return '';
} else if (result = genderHash[input]) {
return result;
} else if ((match = input.match(/(.+)( \([$\d,.]+\))/)) && (result = genderHash[match[1]])) {
return result + match[2];
} else {
return input;
}
};
})
app.controller('gridCtrl', ['$scope', '$http', '$log', '$timeout', 'uiGridConstants', '$q', '$interval',
function ($scope, $http, $log, $timeout, uiGridConstants, $q, $interval) {
$scope.gridOptions = {
enableRowSelection: true,
enableSelectAll: true,
selectionRowHeaderWidth: 35,
rowHeight: 35,
showGridFooter: true
};
$scope.convertDate = function (str) {
var date = new Date(str),
mnth = ("0" + (date.getMonth() + 1)).slice(-2),
day = ("0" + date.getDate()).slice(-2);
return [date.getFullYear(), mnth, day].join("/");
};
var expandableScope = {};
$scope.gridOptions = {
enableFiltering:true,
expandableRowTemplate: '<div style="padding:5px;"><div ui-grid="row.entity.subGridOptions[0]" ui-grid-edit ui-grid-row-edit ui-grid-selection style="height:340px;display:inline-block;"></div></div>',
expandableRowHeight: 350,
columnDefs: [
{ name: 'Project', enableCellEdit: true, },
/* {
name: "",
field:"fake",
cellTemplate: '<div class="ui-grid-cell-contents" >' +
'<button value="Edit" ng-if="!row.inlineEdit.isEditModeOn" ng-click="row.inlineEdit.enterEditMode($event)">Delete</button>' +
'<button value="Edit" ng-if="!row.inlineEdit.isEditModeOn" ng-click="row.inlineEdit.enterEditMode($event)">Edit</button>' +
'<button value="Edit" ng-if="row.inlineEdit.isEditModeOn" ng-click="row.inlineEdit.saveEdit($event)">Update</button>' +
'<button value="Edit" ng-if="row.inlineEdit.isEditModeOn" ng-click="row.inlineEdit.cancelEdit($event)">Cancel</button>' +
'</div>',
enableCellEdit: false,
enableFiltering:false,
enableSorting: false,
showSortMenu : false,
enableColumnMenu: false,
}*/
/*{ name: 'managerid', enableCellEdit: true },
//{
// name: 'hiredate', enableCellEdit: true, type: "date", cellFilter: 'date:"yyyy/MM/dd"',
// cellTemplate: '<div class="ui-grid-cell-contents">{{grid.appScope.convertDate(row.entity[col.field])}}</div>'
//},
{
name: 'title', enableCellEdit: true,
cellTemplate: '<div class="ui-grid-cell-contents"><div ng-class="{\'viewr-dirty\' : row.inlineEdit.entity[col.field].isValueChanged }">{{row.entity[col.field]}}</div></div>'
},
// { name: 'birthdate', enableCellEdit: true, type: "date", cellFilter: 'date:"yyyy/MM/dd"' },
{
name: 'maritalstatus', enableCellEdit: true, cellFilter: "maritalFilter",
editableCellTemplate: 'ui-grid/dropdownEditor',
editDropdownValueLabel: 'maritalstatus',
editDropdownOptionsArray: [
{ id: 'M', maritalstatus: 'Married' },
{ id: 'S', maritalstatus: 'Single' }]
},
{
name: 'gender', enableCellEdit: true, cellFilter: 'genderFilter',
editableCellTemplate: 'ui-grid/dropdownEditor',
editDropdownValueLabel: 'gender',
editDropdownOptionsArray: [
{ id: 'M', gender: 'male' },
{ id: 'F', gender: 'female' }]
},*/
],
enableGridMenu: true,
virtualizationThreshold: 60,
expandableRowScope: {
subGridVariable: 'subGridScopeVariable'
}
}
//$scope.gridOptions.multiSelect = true;
$http.get('https://rawgit.com/msrikanth508/uiGridInlineEditPOC/master/data/employeeData.json')
.success(function (data) {
$scope.gridOptions.data = data.slice(0, 55);; //[data[0], data[1]];
});
$scope.info = {};
$scope.gridOptions.onRegisterApi = function (gridApi) {
//set gridApi on scope
$scope.gridApi = gridApi;
gridApi.selection.on.rowSelectionChanged($scope, function (row) {
var msg = 'row selected ' + row.isSelected;
$log.log(msg);
});
gridApi.selection.on.rowSelectionChangedBatch($scope, function (rows) {
var msg = 'rows changed ' + rows.length;
$log.log(msg);
});
gridApi.edit.on.afterCellEdit($scope, function (rowEntity, colDef, newValue, oldValue) {
var selectedRows = $scope.gridApi.selection.getSelectedRows();
if (newValue != oldValue) {
rowEntity.state = "Changed";
//Get column
var rowCol = $scope.gridApi.cellNav.getFocusedCell().col.colDef.name;
angular.forEach(selectedRows, function (item) {
item[rowCol] = rowEntity[rowCol];// $scope.convertDate(rowEntity[rowCol]);
item.state = "Changed";
item.isDirty = false;
item.isError = false;
});
}
});
gridApi.rowEdit.on.saveRow($scope, function (rowEntity) {
// create a fake promise - normally you'd use the promise returned by $http or $resource
//Get all selected rows
var selectedRows = $scope.gridApi.selection.getSelectedRows();
//var rowCol = $scope.gridApi.cellNav.getFocusedCell().col.colDef.name;
var promise = $q.defer();
$scope.gridApi.rowEdit.setSavePromise(rowEntity, promise.promise);
$interval(function () {
if (rowEntity.gender === 'male') {
promise.reject();
} else {
promise.resolve();
}
}, 3000, 1);
})
gridApi.expandable.on.rowExpandedStateChanged($scope, function (row) {
if (row.isExpanded) {
row.entity.subGridOptions =[{
virtualizationThreshold: 60,
enableFiltering:true,
// expandableRowTemplate: '<div style="padding:5px;"><div ui-grid="row.entity.subGridOptions[0]" ui-grid-edit ui-grid-row-edit ui-grid-selection style="height:340px;display:inline-block;"></div></div>',
//expandableRowHeight: 350,
columnDefs: [
{ name: 'firstname', enableCellEdit: true, width: 100},
{ name: 'Activity Description', width: 500 },
{ name: 'Start' },
{ name: 'Department' },
{ name: 'Remarks' },
{
name: "",
field:"fake",
cellTemplate: '<div class="ui-grid-cell-contents" >' +
'<button value="Edit" ng-if="!row.inlineEdit.isEditModeOn" ng-click="row.inlineEdit.enterEditMode($event)">Delete</button>' +
'<button value="Edit" ng-if="!row.inlineEdit.isEditModeOn" ng-click="row.inlineEdit.enterEditMode($event)">Edit</button>' +
'<button value="Edit" ng-if="row.inlineEdit.isEditModeOn" ng-click="row.inlineEdit.saveEdit($event)">Update</button>' +
'<button value="Edit" ng-if="row.inlineEdit.isEditModeOn" ng-click="row.inlineEdit.cancelEdit($event)">Cancel</button>' +
'</div>',
enableCellEdit: false,
enableFiltering:false,
enableSorting: false,
showSortMenu : false,
enableColumnMenu: false,
}
],
onRegisterApi: function (gridApi) {
$scope.text = gridApi;
gridApi.selection.on.rowSelectionChanged($scope, function (row) {
console.log(row);
});
gridApi.rowEdit.on.saveRow($scope, function (rowEntity) {
// create a fake promise - normally you'd use the promise returned by $http or $resource
//Get all selected rows
var selectedRows = $scope.text.selection.getSelectedRows();
//var rowCol = $scope.gridApi.cellNav.getFocusedCell().col.colDef.name;
var promise = $q.defer();
$scope.text.rowEdit.setSavePromise(rowEntity, promise.promise);
$interval(function () {
if (rowEntity.gender === 'male') {
promise.reject();
} else {
promise.resolve();
}
}, 3000, 1);
})
}
}],
$http.get('https://rawgit.com/msrikanth508/uiGridInlineEditPOC/master/data/employeeContact.json')
.success(function (data) {
row.entity.subGridOptions[0].data = data.slice(0, 45);
});
}
});
};
}]);
angular.module('ui.grid').factory('InlineEdit', ['$interval', '$rootScope', 'uiGridRowEditService',
function ($interval, $rootScope, uiGridRowEditService) {
function inlineEdit(entity, index, grid) {
this.grid = grid;
this.index = index;
this.entity = {};
this.isEditModeOn = false;
this.init(entity);
}
inlineEdit.prototype = {
init: function (rawEntity) {
var self = this;
for (var prop in rawEntity) {
self.entity[prop] = {
value: rawEntity[prop],
isValueChanged: false,
isSave: false,
isCancel: false,
isEdit: false
}
}
},
enterEditMode: function (event) {
event && event.stopPropagation();
var self = this;
self.isEditModeOn = true;
// cancel all rows which are in edit mode
self.grid.rows.forEach(function (row) {
if (row.inlineEdit && row.inlineEdit.isEditModeOn && row.uid !== self.grid.rows[self.index].uid) {
row.inlineEdit.cancelEdit();
}
});
// Reset all the values
for (var prop in self.entity) {
self.entity[prop].isSave = false;
self.entity[prop].isCancel = false;
self.entity[prop].isEdit = true;
}
},
saveEdit: function (event) {
event && event.stopPropagation();
var self = this;
self.isEditModeOn = false;
for (var prop in self.entity) {
self.entity[prop].isSave = true;
self.entity[prop].isEdit = false;
}
uiGridRowEditService.saveRow(self.grid, self.grid.rows[self.index])();
},
cancelEdit: function (event) {
event && event.stopPropagation();
var self = this;
self.isEditModeOn = false;
for (var prop in self.entity) {
self.entity[prop].isCancel = true;
self.entity[prop].isEdit = false;
}
}
}
return inlineEdit;
}]);
index.html
<html>
<head>
<link data-require="bootstrap-css#*" data-semver="3.3.6" rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.css" />
<link rel="stylesheet" href="style.css" />
<link rel="stylesheet" href="https://rawgit.com/msrikanth508/uiGridInlineEditPOC/master/Css/ui-grid.css" />
<script src="https://rawgit.com/msrikanth508/uiGridInlineEditPOC/master/Js/vendor/angular.js"></script>
<script src="https://rawgit.com/msrikanth508/uiGridInlineEditPOC/master/Js/vendor/ui-grid.js"></script>
<script src="script.js"></script>
</head>
<body ng-app="app" class="">
<div class="" ng-controller="gridCtrl">
<div ui-grid="gridOptions" ui-grid-move-columns="" ui-grid-edit="" ui-grid-row-edit="" ui-grid-selection="" ui-grid-expandable="" class="grid" style="height:800px"></div>
</div>
</body>
</html>
Thanks Advance
I have something similar to the JSFiddle mentioned here. The JSFiddle works fine, however, I am seeing a strange behaviour in my code. The description of very first
cell is always empty even though I am seeing that in the returned data (in JSON format) from the webservice, the description is present for each record. Please
take a look at the code below and let me know if I am missing anything:
this.processEmployees = function (data_, textStatus_, jqXHR_) {
var collection = data_.employees;
// A helper function used for employee codes below.
var isUsedKey = function (arrayOfObject, key) {
for (var i = 0; i < arrayOfObject.length; i += 1) {
if (arrayOfObject[i].key == key) {
return true;
}
}
return false;
};
var employeeCodes = [];
for (var i = 0; i < collection.length; i++) {
if (i == 0) {
var newItem = {};
newItem.key = collection[i].code_value;
newItem.dates = [collection[i].code_assignment_date];
newItem.description = collection[i].code_description;
newItem.hiringCriterion = collection[i].hiring_criteria;
newItem.name = collection[i].name;
console.log("Would like to check code_description for first item:",collection[i].code_description);
//debugger;
employeeCodes.push(newItem);
} else {
var item = collection[i];
var itemName = item.code_value;
var itemDate = item.code_assignment_date;
var itemDescription = item.code_description;
var hiringCriterion = item.hiring_criteria;
var itemCodeName = item.name;
if (isUsedKey(employeeCodes, itemName)) {
for (var j = 0; j < employeeCodes.length; j++) {
if (employeeCodes[j].key == itemName) {
var index = employeeCodes[j].dates.length;
employeeCodes[j].dates[index] = itemDate;
}
}
} else {
var nextNewItem = {};
nextNewItem.key = itemName;
nextNewItem.dates = [itemDate];
nextNewItem.code_description = itemDescription;
nextNewItem.hiring_criteria = hiringCriterion;
nextNewItem.name = itemCodeName;
employeeCodes.push(nextNewItem);
}
}
}
var newSource = {
localdata: employeeCodes,
datafields: [{
name: 'code_value',
type: 'string',
map: 'key'
},
{
name: 'code_assignment_date',
type: 'date',
map: 'dates>0'
},
{
name: 'name',
type: 'string'
},
{
name: 'code_description',
type: 'string'
},
{
name: 'hiring_criteria',
type: 'string'
}
],
datatype: "array"
};
var newAdapter = new $_.jqx.dataAdapter(newSource);
var iconrenderer = function (row, columnfield, value, defaulthtml, columnproperties) {
var icon = '';
if (employeeCodes[row].dates.length > 1) {
icon = '<img src="images/icon-down.png" style="position: absolute; right: 5px;" />';
}
return '<span style="position: relative; width: 100%; margin: 4px; float: ' + columnproperties.cellsalign + ';">' + newAdapter.formatDate(value, 'd') + icon + '</span>';
};
$_(self.gridSelector).jqxGrid({
source: newAdapter,
editable: true,
width: '600',
pageable: true,
sortable: true,
autoheight: true,
theme: 'classic',
height: '170',
columnsResize: true,
columns: [
{
text: 'Employee Name',
datafield: 'name',
width: 85,
},
{
text: 'Code Value',
datafield: 'code_value',
width: 75,
editable: false
},
{
text: 'Latest Date(s)',
datafield: 'code_assignment_date',
cellsformat: 'd',
columntype: 'combobox',
width: 100
createeditor: function (row, column, editor) {
var info = $_(self.gridSelector).jqxGrid('getrowdata', row);
console.log("length of info: " + info);
var groupName = info.code_value;
console.log("Contents of groupName: " + groupName);
var dates = [];
for (var i = 0; i < employeeCodes.length; i++) {
if (employeeCodes[i].key == groupName) {
dates = employeeCodes[i].dates;
}
}
editor.jqxComboBox({ autoDropDownHeight: false, source: dates, promptText: "Previous Date(s):", scrollBarSize: 10 });
},
initeditor: function (row, column, editor) {
var info = $_(self.gridSelector).jqxGrid('getrowdata', row);
var groupName = info.code_value;
var dates = [];
for (var i = 0; i < employeeCodes.length; i++) {
if (employeeCodes[i].key == groupName) {
dates = employeeCodes[i].dates;
}
}
editor.jqxComboBox({
autoDropDownHeight: false,
source: dates,
promptText: "Dates:",
width: 100,
scrollBarSize: 10,
renderer: function (index_, label_, value_) {
return formatDateString(value_);
},
renderSelectedItem: function (index, item) {
var records = editor.jqxComboBox('getItems');
var currentRecord = records[index].label;
return formatDateString(currentRecord);;
}
});
},
cellvaluechanging: function (row, column, columntype, oldvalue, newvalue) {
// return the old value, if the new value is empty.
if (newvalue == "") return oldvalue;
}
},
{
text: 'Description',
datafield: 'code_description'
},
{
text: 'Hiring Criterion',
datafield: 'hiring_criteria',
editable: false,
hidden: true
}
],
});
}; // End of processEmployees
For Example, if my JSON is the following:
{
"employees": [{
"code_value": "B1",
"code_assignment_date": "2016-12-13 23:04:00.0",
"code_type": 7,
"code_description": "This employee has received his salary",
"name": "Peter",
"hiring_criteria": null
}, {
"code_value": "A1",
"code_assignment_date": "2016-05-20 05:00:00.0",
"code_type": 7,
"code_description": "Employee has 5 vacation days left",
"name": "Jack",
"hiring_criteria": null
}],
"webServiceStatus": {
"status": "SUCCESS",
"message": "2 results"
}
}
I am not seeing the very first code_description value which is This employee has received his salary in the above JSON response whereas the following
line mentioned in the above code clearly shows it in the console panel:
console.log("Would like to check code_description for first item:",collection[i].code_description);
newItem.description = collection[i].code_description;
---Replace newItem.description to newItem.code_description in First object condition
newItem.hiringCriterion = collection[i].hiring_criteria;
---Replace newItem.hiringCriterion to newItem.hiring_criteria in First object condition
I'm working with ui-grid and server-side filtering. For each column I send a request to API with param based on filter value. By default param is empty
var filterOptions = {
filterBy: '&$filter=',
filterParam: ""
};
// and api call looks like
?$orderby=id-&pageSize=250&pageNbr=1&$filter=
if I setup any filter I send next request
param: filterOptions.filterParam = 'eventTypeId==' + evtTypeId
request: ?$orderby=id-&pageSize=250&pageNbr=1&$filter=eventTypeId==2
So what I want is pretty simple idea, I want to check if filter is already applied and send a request like
?$orderby=id-&pageSize=250&pageNbr=1&$filter=eventTypeId==2,studyId==1
but unfortunately I cannot catch any applied filters. I appreciate if somebody could help with my issue.
My code below
columnDef
$scope.gridOptions.columnDefs = [
{
field: 'title',
cellClass: getCellClass,
useExternalFiltering: true
}, {
field: 'description',
cellClass: getCellClass,
enableFiltering: true,
useExternalFiltering: true
}, {
displayName: 'Type',
field: 'eventType.name',
filter: {
selectOptions: $scope.eventType,
type: uiGridConstants.filter.SELECT
},
cellClass: getCellClass,
useExternalFiltering: true
}, {
displayName: 'Study Name',
field: 'study.name',
filter: {
selectOptions: $scope.study,
type: uiGridConstants.filter.SELECT
},
cellClass: getCellClass,
useExternalFiltering: true
}, {
displayName: 'Priority',
field: 'priority.name',
filter: {
selectOptions: $scope.priority,
type: uiGridConstants.filter.SELECT
},
cellClass: getCellClass,
useExternalFiltering: true
}, {
displayName: 'Severity',
field: 'severity.name',
filter: {
selectOptions: $scope.severity,
type: uiGridConstants.filter.SELECT
},
cellClass: getCellClass,
useExternalFiltering: true
}, {
displayName: 'Status',
field: 'status.name',
filter: {
selectOptions: $scope.status,
type: uiGridConstants.filter.SELECT
},
cellClass: getCellClass,
useExternalFiltering: true
}, {
displayName: 'Created',
field: 'occuredDate',
width: '12%',
filterHeaderTemplate: '<div class="row ui-grid-filter-container">' +
'<div ng-repeat="colFilter in col.filters" class="col-md-6 col-sm-6 col-xs-6">' +
'<div custom-grid-date-filter-header></div></div></div>',
filters: [
{
name: 'From',
condition: uiGridConstants.filter.GREATER_THAN_OR_EQUAL
},
{
name: 'To',
condition: uiGridConstants.filter.LESS_THAN_OR_EQUAL
}
],
cellFilter: 'date:"dd MMMM yyyy, h:mm:ss a"',
cellClass: getCellClass,
useExternalFiltering: false
}, {
displayName: 'Modified', field: 'createdDate',
width: '12%',
filterHeaderTemplate: '<div class="row ui-grid-filter-container">' +
'<div ng-repeat="colFilter in col.filters" class="col-md-6 col-sm-6 col-xs-6">' +
'<div custom-grid-date-filter-header></div></div></div>',
filters: [
{
name: 'From',
condition: uiGridConstants.filter.GREATER_THAN_OR_EQUAL
},
{
name: 'To',
condition: uiGridConstants.filter.LESS_THAN_OR_EQUAL
}
],
cellFilter: 'date:"dd MMMM yyyy, h:mm:ss a"',
cellClass: getCellClass,
useExternalFiltering: false
}
];
RegisterApi
$scope.gridOptions.onRegisterApi = function (gridApi) {
$scope.gridApi = gridApi;
gridApi.selection.selectRow($scope.gridOptions.data[0]);
gridApi.pagination.on.paginationChanged($scope, function (newPage, pageSize) {
paginationOptions.pageNbr = '&pageNbr=' + newPage ;
paginationOptions.pageSize = '&pageSize=' + pageSize;
getData();
});
gridApi.core.on.filterChanged( $scope, function() {
var grid = this.grid;
// Define behavior for cancel filtering
$scope.isfilterclear = true;
angular.forEach(grid.columns, function( col ) {
if(col.filters[0].term){
$scope.isfilterclear = false;
}
});
if($scope.isfilterclear) {
$timeout(function() {
$rootScope.refresh()
},500);
}
// Filter behavior
$scope.textFilter = grid.columns[1].filters[0].term;
if($scope.textFilter) {
$scope.$watch('textFilter', function (newVal, oldVal) {
filterOptions.filterParam = 'title==*' + newVal + "*";
}, true);
getData()
}
$scope.desFilter = grid.columns[2].filters[0].term;
if($scope.desFilter) {
$scope.$watch('desFilter', function (newVal, oldVal) {
filterOptions.filterParam = 'description==*' + newVal + "*";
}, true);
getData()
}
for (var et = 0; et < $scope.eventType.length; et ++){
var evtType = $scope.eventType[et].name;
var evtTypeId = $scope.eventType[et].id;
filterOptions.filterParam = 'eventTypeId==' + evtTypeId;
if( grid.columns[3].filters[0].term === evtType ) {
getData()
}
}
for (var stud = 0; stud < $scope.study.length; stud ++){
var study = $scope.study[stud].name;
var studyId = $scope.study[stud].id;
filterOptions.filterParam = 'studyId==' + studyId;
if( grid.columns[4].filters[0].term === study ) {
getData()
}
}
for (var pr = 0; pr < $scope.priority.length; pr ++){
var priority = $scope.priority[pr].name;
var priorityId = $scope.priority[pr].id;
filterOptions.filterParam = 'priorityId==' + priorityId;
if( grid.columns[5].filters[0].term === priority ) {
getData()
}
}
for (var sev = 0; sev < $scope.severity.length; sev ++){
var severity = $scope.severity[sev].name;
var severityId = $scope.severity[sev].id;
filterOptions.filterParam = 'severityId==' + severityId;
if( grid.columns[6].filters[0].term === severity ) {
getData()
}
}
for (var stat = 0; stat < $scope.status.length; stat ++){
var status = $scope.status[stat].name;
var statusId = $scope.status[stat].id;
filterOptions.filterParam = 'statusId==' + statusId;
if( grid.columns[7].filters[0].term === status ) {
getData()
}
}
});
Where getData() is
var getData = function () {
eventService.getEventsWithParams(
sortOptions.orderBy,
sortOptions.directions,
paginationOptions.pageSize,
paginationOptions.pageNbr,
filterOptions.filterBy,
filterOptions.filterParam
)
.then(function (data) {
$scope.gridOptions.data = data;
// ***
angular.forEach($scope.gridOptions.data, function (val) {
val.occuredDate = new Date(val.occuredDate);
});
// $interval whilst we wait for the grid to digest the data we just gave it
$interval(function () {
$scope.gridApi.selection.selectRow($scope.gridOptions.data[0]);
}, 0, 1);
});
};
my plunker
(unfortunately I cannot provide the real API, but hope it will help anyhow)
The working code is
gridApi.core.on.filterChanged( $scope, function() {
// Declare vars
var grid = this.grid;
var columns = grid.columns;
$scope.columnTitle = grid.columns[1].filters[0].term;
$scope.columnDesc = grid.columns[2].filters[0].term;
var columnType = grid.columns[3].filters[0].term;
var columnStudy = grid.columns[4].filters[0].term;
var columnPriority = grid.columns[5].filters[0].term;
var columnSeverity = grid.columns[6].filters[0].term;
var columnStatus = grid.columns[7].filters[0].term;
var columnCreatedDate = grid.columns[8].filters[0].term;
var columnModifiedDate = grid.columns[9].filters[0].term;
// Create request for selectable filters
var query = [];
var string;
function request (id, param) {
if(param === "title==" || param === "description=="){
query.push(param + "*" + id + "*")
} else {
query.push(param + id);
}
if (query.length <= 1){
return query
} else {
string = query.join(";");
return string;
}
}
// Define behavior for cancel filtering
$scope.isfilterclear = true;
angular.forEach(columns, function( col ) {
if(col.filters[0].term){
$scope.isfilterclear = false;
}
});
if($scope.isfilterclear) {
$timeout(function() {
$rootScope.refresh()
},500);
}
// Filter behavior for columns
if($scope.columnTitle) {
$scope.$watch('columnTitle', function (newVal, oldVal) {
filterOptions.filterParam = request(newVal, 'title==*');
}, true);
getData()
}
if($scope.columnDesc) {
$scope.$watch('columnDesc', function (newVal, oldVal) {
filterOptions.filterParam = request(newVal, 'description==');
}, true);
getData()
}
if(columnType) {
filterOptions.filterParam = request(columnType, 'eventTypeId==');
getData();
}
if(columnStudy) {
filterOptions.filterParam = request(columnStudy, 'studyId==');
getData();
}
if(columnPriority) {
filterOptions.filterParam = request(columnPriority, 'priorityId==');
getData();
}
if(columnSeverity) {
filterOptions.filterParam = request(columnSeverity, 'severityId==');
getData();
}
if(columnStatus) {
filterOptions.filterParam = request(columnStatus, 'statusId==');
getData();
}
if(columnCreatedDate){
filterOptions.filterParam = request($rootScope.setFilterDate, 'occuredDate>=');
getData()
}
if(columnModifiedDate){
filterOptions.filterParam = request($rootScope.setFilterDate, 'occuredDate>=');
getData()
}
});
As you can see, I declared custom function with two params where I'm providing my request param for each call, I'm not sure about elegancy of this way but for two week I didn't find better solution
I am using sencha navigation view in my sencha application .
my bug scenario
I have list view with images on home screen first time it's load 20 record then scroll to down record will be increase by 20 on every scroll when i click on any image and redirect to another view like image detail view or profile view and come back to home on pressing back button all the images overlapped.
please help i am trying to solve this bug before 10 day's but not get success :- before overlapping
1) I am using navigation view it's extend with "Ext.dataview.DataView" and there is using
useComponents: true,
defaultType: 'productlistitem'
2) In 'productlistitem' extend with 'Ext.dataview.component.DataItem' In this view I am using update method witch set the image and other component data and also using dynamically method for image width , height .
below you can check my all views code
A) Home.js
Ext.define('demo.view.home.Home', {
extend: 'Ext.dataview.DataView',
requires: [
'demo.view.product.ListItem',
'demo.view.layout.ColumnLayout'
],
xtype: 'home',
config: {
scrollable: true,
plugins: {
xclass: 'demo.plugin.DataViewPaging', // Reference plugin by class
autoPaging: true
},
autoDestroy: true,
store: 'LookStore',
margin:'2 0',
useComponents: true,
defaultType: 'productlistitem',
cls: 'wow-home',
layout: {
type: 'column',
columnCount: 2,
columnWidth: 160
}
}
});
B) ListItem.js
var listItemData=[];
Ext.define('demo.view.product.ListItem', {
extend: 'Ext.dataview.component.DataItem',
requires: ['demo.view.product.Item'],
xtype: 'productlistitem',
config: {
padding: 2,
zIndex:999,
items: [{
xtype: 'item'
}]
},
initialize: function() {
console.log('initing the list item ');
var me = this;
me.callParent(arguments);
this.on('heightchange', 'recalculateHeight', me, {
delegate: '> item'
});
},
recalculateHeight: function() {
var me = this;
me.setHeight(me.innerElement.getHeight());
},
updateRecord: function(record) {
if (!record) {
return;
}
var me = this,
item = me.down('item');
me.callParent(arguments);
if (item) {
item.updateRecord(record, me.getDataview());
}
listItemData.push(item.id);
}
});
c) Item.js
Ext.define('demo.view.product.Item', {
extend: 'Ext.Container',
xtype: 'item',
requires: [
'Ext.Carousel',
'demo.view.product.ItemImage',
'demo.view.product.UserInfo',
'demo.view.product.InfoLabel'
],
config: {
record: null,
baseCls: 'wow-item',
showDescription: false,
items: [{
xtype: 'itemimage',
width: '100%'
}, {
xtype: 'userinfo',
height: 40,
listeners: {
painted: function() {
if (!this.element.hasListener('tap')) {
this.element.on('tap', function(e) {
e.stopPropagation();
var record = this.scope.up('item').getRecord();
if (!this.scope.getHandleListeners()) {
if(Ext.ComponentQuery.query('main')[0].getActiveItem().xtype === "wardrobedrawer")
demo.app.getController('ProductController').openProductDetail('', '', '', record);
return;
}
if (record && !Ext.isEmpty(record.raw.product_id) && !Ext.isEmpty(record.raw.importer)) {
var brandMerchantProducts = this.scope.up('brandmerchantproducts');
if (brandMerchantProducts) {
var currentTitle = demo.app.getController('HomeController').getMain().getActiveItem().config.title;
var currentItem = this.scope.element.dom.textContent;
if (currentTitle.toUpperCase() !== currentItem.toUpperCase()) {
demo.app.getController('ProductController').showMerchantProducts(record);
}
return;
}
demo.app.getController('ProductController').showMerchantProducts(record);
} else {
var list = this.scope.up('list');
demo.app.getController('ProfileController').goToOtherUserProfile(list, null, null, record.get('merchantId'), e);
}
}, {
scope: this
});
}
}
}
},
{
xtype: 'container',
height: 40,
margin:'1 0 0 0',
name: 'infoContainer',
layout:'hbox',
defaults: {
xtype: 'infolabel',
flex: 1
},
items: [{
iconCls: 'icon-diamond',
text: '09',
itemId: 'wows',
listeners: {
painted: function() {
if (!this.element.hasListener('tap')) {
this.element.on('tap', function(e) {
e.stopPropagation();
var record = this.scope.up('item').getRecord();
if (record.get('type') == 'product') {
demo.app.getController('ProductController').wowOrUnwowHomeProduct(record, this.scope.up('item'));
}
if (record.get('type') === 'look') {
demo.app.getController('ProductController').wowOrUnwowHomeLook(record, this.scope.up('item'));
}
}, {
scope: this
});
}
}
}
}, {
iconCls: 'icon-drawer',
text: '11',
itemId: 'lookOrAdd',
listeners: {
painted: function() {
if (!this.element.hasListener('tap')) {
this.element.on('tap', function(e) {
e.stopPropagation();
var record = this.scope.up('item').getRecord();
if (record.get('type') == 'product') {
demo.addedProductItem = this.scope.up('item');
demo.app.getController('ProductController').addProduct(record);
}
if (record.get('type') === 'look') {
demo.app.getController('ProductController').addHomeLook(record, this.scope.up('item'));
}
}, {
scope: this
});
}
}
}
}]
}
]
},
initialize: function() {
var me = this;
me.callParent(arguments);
me.on('load', 'imageLoaded', me, {
delegate: 'itemimage'
});
},
imageLoaded: function() {
var me = this;
me.setHeight(me.element.getHeight());
},
updateRecord: function(item, dataview) {
if (!item) {
return;
}
if (dataview && dataview.config.showDescription) {
this.setShowDescription(true);
}
var me = this;
me.setRecord(item);
if (item) {
var itemImage = this.down('itemimage'),
images = item.get('images'),
wows = item.get('wows') + '',
adds = item.get('adds') + '',
userInfo = this.down('userinfo');
if (images && images.length) {
itemImage.setSrc(images[0].original);
}
var type = item.get('type');
var lookOrProduct = me.down('#lookOrAdd');
var added = item.get('added');
var icon;
if (type === 'product') {
icon = 'icon-add-drawer';
lookOrProduct.setIconCls(icon);
} else {
icon = added ? 'icon-counterlook' : 'icon-addlookbook';
lookOrProduct.setIconCls(icon);
}
if (!Ext.isEmpty(item.raw.product_id)) {
userInfo.setAvatar('');
} else { // USER
var importer = item.get('importer');
if (importer) {
var avatar = importer.avatar;
if (avatar) {
userInfo.setAvatar(avatar);
} else {
userInfo.setAvatar('resources/images/default/default_avatar.jpg');
}
}
}
me.down('#wows').setText(wows);
if (!item.get('wowed')) {
me.down('#wows').addCls('grayedout-cls');
} else {
me.down('#wows').removeCls('grayedout-cls');
}
lookOrProduct.setText(adds);
if (!item.get('added')) {
lookOrProduct.addCls('grayedout-cls');
} else {
lookOrProduct.removeCls('grayedout-cls');
}
var infoContainer = this.down('container[name=infoContainer]');
if (infoContainer && infoContainer.isHidden()) {
infoContainer.show();
}
var title = Ext.ComponentQuery.query('main')[0].getActiveItem().title;
var storeId = this._record.stores[0].getStoreId();
if (type === 'product' && !Ext.isDefined(title) && storeId !== 'WowedStore' && storeId !== 'SearchStore' && storeId !== 'BrandMerchatProducts') {
var homeUrl = this._record.stores[0].getProxy().getUrl();
if ((homeUrl === demo.model.Config.apiServerPath('home')) || (homeUrl === demo.model.Config.apiServerPath('home'))) {
var noOfProducts = Ext.ComponentQuery.query('#productsInTheListId').length;
if (noOfProducts === 1) {
userInfo.setUsername(item);
if (me.getShowDescription()) {
infoContainer.hide();
userInfo.setAvatar('');
userInfo.setUsername(item);
userInfo.setHandleListeners(false);
}
} else {
userInfo.setUsername(item.get('author'));
if (me.getShowDescription()) {
infoContainer.hide();
userInfo.setAvatar('');
userInfo.setUsername(item.get('description'));
userInfo.setHandleListeners(false);
}
}
} else {
userInfo.setUsername(item);
if (me.getShowDescription()) {
infoContainer.hide();
userInfo.setAvatar('');
userInfo.setUsername(item);
userInfo.setHandleListeners(false);
}
}
} else {
userInfo.setUsername(item.get('author'));
if (me.getShowDescription()) {
infoContainer.hide();
userInfo.setAvatar('');
userInfo.setUsername(item.get('description'));
userInfo.setHandleListeners(false);
}
}
}
},
updateColorOfItem: function(item) {
var me = this,
lookOrProduct = me.down('#lookOrAdd');
if (!item.get('wowed')) {
me.down('#wows').addCls('grayedout-cls');
} else {
me.down('#wows').removeCls('grayedout-cls');
}
if (!item.get('added')) {
lookOrProduct.addCls('grayedout-cls');
} else {
lookOrProduct.removeCls('grayedout-cls');
}
}
});
D) ItemImage.js
Ext.define('demo.view.product.ItemImage', {
extend: 'Ext.Img',
xtype: 'itemimage',
config: {
},
onLoad: function(event) {
var me = this,
width = me.getParent().element.getWidth(), // me.element.getWidth() should work but I have found that sometimes it gives a width of 0. Now I go with a width of the parent.
imageObject = me.imageObject,
naturalWidth = imageObject.width,
naturalHeight = imageObject.height,
naturalRatio = naturalHeight / naturalWidth,
newHeight = naturalRatio * width;
me.setHeight(newHeight);
//Ext.ComponentQuery.query('productlistitem')[0].setHeight(newHeight+84);
me.callParent(event);
}
});
E) UserInfo.js
Ext.define('demo.view.product.UserInfo', {
extend: 'Ext.Container',
requires: ['Ext.Img'],
xtype: 'userinfo',
config: {
avatar: null,
username: null,
baseCls: 'wow-user-info',
handleListeners: true
},
applyAvatar: function(avatar) {
if (Ext.isEmpty(avatar)) {
return null;
}
return Ext.factory({
src: avatar,
cls: 'wow-avatar',
docked: 'left'
}, 'Ext.Img');
},
updateAvatar: function(newAvatar, oldAvatar) {
if (newAvatar) {
this.add(newAvatar);
}
if (oldAvatar) {
oldAvatar.destroy();
}
},
applyUsername: function(item) {
if (Ext.isObject(item)) {
var price_value = "",
price_currency = "",
itemName = "";
if (Ext.isDefined(item.raw.price)) {
if (Ext.isDefined(item.raw.price.value)) {
price_value = item.raw.price.value.toString();
}
}
if (Ext.isDefined(item.raw.price)) {
if (Ext.isDefined(item.raw.price.currency)) {
price_currency = item.raw.price.symbol;
}
}
if (item.raw.description === null) {
var item = item.data.author;
} else {
var item = item.raw.description;
}
item = item.toLowerCase();
itemName = item.charAt(0).toUpperCase() + item.slice(1);
if (Ext.isDefined(price_currency) && Ext.isDefined(price_value) && (price_currency !== "") && (price_value !== "")) {
itemName = '<div class="itemNames"><span style="font-size:0.9em" >' + price_currency.bold() + ' ' + price_value.bold() + '</span>' + " " + '<span style=" font-size:0.8em" class="itemName">' + itemName + '</span>' + '</div>';
} else {
itemName = '<div class="itemNames"><span style=" font-size:0.8em" class="itemName">' + itemName + '</span></div>';
}
return Ext.factory({
html: itemName,
xtype: 'component',
cls: 'wow-username-product'
});
} else {
return Ext.factory({
html: item,
xtype: 'component',
cls: 'wow-username'
});
}
},
updateUsername: function(newUsername, oldUsername) {
if (newUsername) {
this.add(newUsername);
}
if (oldUsername) {
oldUsername.destroy();
}
}
});
F) InfoLabel.js
Ext.define('demo.view.product.InfoLabel', {
extend: 'Ext.Button',
xtype: 'infolabel',
config: {
iconAlign: 'left',
cls: 'wow-info-label'
},
initialize: function() {
// Do nothing stopping unnecessary event listeners being added.
}
});
I have a column with text and an image. I am trying to add an event to the image. The id is assigned dynamically. When I try to bind the event, the Ext.get("id") is returning a null. I can see renderer running after viewready because the screen is refreshing. Should I try different DOM events?
{
text: 'My Thing',
flex: 6,
sortable: true,
width: 40,
dataIndex: 'myThing',
renderer: function (val, metaData, record, rowIdx, colIdx, store, view) {
{console.log(evname, arguments);});
var returnStr = '<div>' + val + '</div>' + '<img id="image_' + record.data.myItem.id + '" src="/myThing/img/icon.png"/>';
console.log(returnStr);
return returnStr;
}
console.log('Im here');
for(var j=0; j<items.length; j++){
console.log(j)
var itemDesc = 'image_' + items[j].data.myItem.id;
var itemDescStr = items[j].data.lineItem.myItem.id;
console.log('itemDesc' + itemDesc)
console.log(Ext.get(itemDesc));
(function(itemDescStr) {
Ext.get(itemDesc).on('click', function(e,t){
console.log('image '+ itemDescStr + ' clicked');
});
})(itemDescStr);
}
"Ext.get(itemDesc)" is returning a null.
Edit:
My temporary solution was this:
{
text: 'My Thing',
flex: 6,
sortable: true,
width: 40,
dataIndex: 'myThing'
renderer: function (val, metaData, record, rowIdx, colIdx, store, view) {
var returnStr = '<div><img id="image_' + record.data.myItem.id;
returnStr = returnStr + '" src="/myApp/resources/app/img/myIcon.gif" ';
returnStr = returnStr + 'onclick="Ext.foo(' + rowIdx + ')" />';
returnStr = returnStr + ' ' + val + '</div>';
return returnStr;
}
},
Don't do it like that, use event delegation:
Ext.onReady(function() {
var grid = new Ext.grid.Panel({
width: 400,
height: 400,
renderTo: document.body,
store: {
fields: ['name'],
data: [{
name: 'Foo'
}, {
name: 'Bar'
}]
},
columns: [{
dataIndex: 'name',
renderer: function(v) {
return Ext.String.format('<div class="x">{0}</div><div class="y">{0}</div><div class="z">{0}</div>', v);
}
}],
listeners: {
cellclick: function(view, el, cellIdx, record, row, rowIdx, e) {
if (e.getTarget('.x')) {
console.log('x');
} else if (e.getTarget('.y')) {
console.log('y');
} else {
console.log('neither');
}
}
}
});
});