How to use Angular ui-grid with array of string - javascript

I have used Angular ui-grid to represent an array of json objects from response. However, my current use case returns an array of string values in the response. In such as case, how should the grid be configured?
$http.get(url)
.success(function(data) {
if(data.length <= 0 && data != undefined) {
$scope.noDataGridEpr="Data is not Available";
console.log("Data is not Available");
}
console.log("Data is" + data);
$scope.prList = data;
console.log("prList is" + $scope.prList); //an array of strings
$scope.dataLoadedEpr=true;
return true;
})
.error(function(data, status) {
console.log("Error from controller. Could not query.");
return false;
})
This prints
prList is[A/DN,B/LCK,10,10,same,match,match],
[B/DN,D/LCK,10,10,same,mismatch,match],
[G/DN,D/LCK,10,10,same,mismatch,mismatch]
Here is how my current grid configuration looks
$scope.prGrid = {
data: 'prList',
columnDefs: [
{field: 'DPin', displayName: 'DPin', width: "5%"},
{field: 'CPin', displayName: 'CPin', width: "5%"},
{field: 'slack1', displayName: 'slack1', width: "5%"},
{field: 'slack2', displayName: 'slack2', width: "5%"},
{field: 'cComp', displayName: 'cComp', width: "10%"},
{field: 'dComp', displayName: 'dComp', width: "5%"},
{field: 'gComp', displayName: 'dComp', width: "5%"}
enableFiltering: true,
multiSelect: false,
enableGridMenu: true,
enableRowHeaderSelection: false,
enableSorting: true,
enableColumnResizing: true
};
I understand the field config above is incorrect. Given I have an array of string as i/p, can someone guide me on how to set the array of string in the grid, each representing a row?
Thanks.

Follow this->binding to 2D array
Example:Check this plnkr.
app.controller('TwoDimensionCtrl', ['$scope','$timeout','uiGridConstants', function ($scope,$timeout,uiGridConstants) {
$scope.data=[
["Cox", "Carney", "Enormo", true],
["Lorraine", "Carney", "Comveyer", false],
["Nancy", "Waters", "Fuelton", false]
];
$scope.gridOptions = {
enableSorting: true,
columnDefs: [
{ name: "firstName", field: "0" },
{ name: "lastName", field: "1" },
{ name: "company", field: "2" },
{ name: "employed", field: "3" }
],
data : $scope.data
};
$timeout(function () {
$scope.data[0][0]="TestMod";
},5000);
}]);

Followed this ->I need to display an array of strings within ui-grid. Single column, one string per row
Tried this to create/set the json object thats consumed by ui-grid. This works.
$scope.prList = convertArrayOfStringsToGridFriendlyJSON(data);
function convertArrayOfStringsToGridFriendlyJSON(arr) {
var out = [];
arr.forEach(function(entry){
entry = entry.replace('[' , '')
entry = entry.replace(']' , '')
entry = entry.split(',')
var obj = {}; //json object
var DPin= "DPin"; //keys
var CPin= "CPin";
obj[DPin] = entry[0];
obj[CPin] = entry[1];
out.push(obj);
});
return out;
};

Related

ExtJS Add filtering in Grid for hasMany association

I have a data model that I want to be able to add a generic amount of filters to. I am specifying a name and a value. How can I add these hasMany associated fields as filters to my grid? I have attempted to write custom filtering option, but I can't have filters show up without an attached dataIndex, which is not available for the hasMany association.
Ext.define('AirGon.model.Project', {
extend: 'Ext.data.Model',
fields: [
{ name: 'Link', type: 'string' },
{ name: 'Title', type: 'string' },
{ name: 'Description', type: 'string' },
{ name: 'MappedMetadata', mapping: 'Metadata'},
{ name: 'XMax', type: 'float' },
{ name: 'XMin', type: 'float' },
{ name: 'YMax', type: 'float' },
{ name: 'YMin', type: 'float' }
],
hasMany: { model: 'Metadata', name: 'Metadata', associationKey: 'Metadata' }
});
Ext.define('Metadata', {
extend: 'Ext.data.Model',
fields: ['Name', 'Value']
});
This is my custom filtering attempt. I am getting the DataStore from the main store and then adding custom rendering, but I can't filter or sort this column because of the lack of a dataIndex.
var column = {
header: 'Meta',
//?????????dataIndex: 'MappedMetadata[0]',?????
sortable: true,
filterable: true,
filter: {
type: 'string'
},
renderer: function (value, meta, record) {
console.log(record.MetadataStore.data.items[index].data)
return record.MetadataStore.data.items[index].data.Value;
}
}
Data. The data is modeled so that a variable amount of metadata can be entered and the 'tag' will not be known by the system.
{
"Link": "link.com",
"Title": "project",
"Description": "descript",
"State": "",
"Metadata": [
{
"Name": "County",
"Value": "32"
},
{
"Name": "Info",
"Value": "info"
},
{
"Name": "State",
"Value": "TN"
}
],
"XMin": "-1",
"XMax": "-1",
"YMin": "1",
"YMax": "1"
}
I was able to solve this by dynamically flattening the data model and adding columns once the store has been loaded. Although this breaks the MVC structure this was the best solution I came up with so it might be able to help you.
var defaultColumns = [];
var store = Ext.getStore('store');
store.on('load', function (store) {
var model = store.model;
var fields = model.getFields();
store.getAt(0).MetadataStore.data.items.forEach(function (item, index) {
var header = item.data.Name;
//isField returns a boolean if the field is already part of the data model
if (!isField(fields, header)) {
//Add a new metadata field to the data model
var field = { name: header, mapping: 'Metadata[' + index + '].Value' }
fields.push(field)
//Add a new metadata column
var column = {
header: header,
dataIndex: header,
sortable: true,
filterable: true,
filter: {
type: 'list'
},
flex: 0.2
}
defaultColumns.push(column);
}
});
model.setFields(fields);
//reload the grid after adding columns
var gridView = Ext.ComponentQuery.query('gridpanel')[0];
gridView.reconfigure(store, defaultColumns);
});
//reload the data after creating new fields
store.load();
I then set the columns of the grid to defaultColumns.
{
xtype: 'grid',
store: 'Projects',
overflowX: 'auto',
autoScroll: true,
features: [filters],
columns: defaultColumns
}

Format multiple columns depending on the value of one

Can I use a custom formatter on a cell A to modify a cell B ?
Your original demo http://jsfiddle.net/fo3wb58w/12/ shows what you want. In general, you use already one formatter function shared by multiple columns. If you would click on the column header of the column PLA, MCO, SUP or REX you will see nothing happens. The problem is: you use datatype: "local", which holds the internal data of the grid in the data and _index parameters. The data will be used during sorting and filtering/searching of the local data. Formatting is just the form to display the corresponding data. Thus I would recommend you to fill the column data for every column first and only then format the data. It will saves correct data in the data parameter and will allows to sort and filter the data.
The simplest modification of the demo will consist from including localReader
localReader: {
repeatitems: true,
cell: function (item) {
var rowData = $.parseJSON(item.data);
rowData.data = item.data; // include the original data too
return rowData;
}
}
and modification of your custom formatter to the following, for example,
function format (cellvalue) {
if (cellvalue !== undefined) {
return '<div class="led-box"><div class="' +
(cellvalue !== null ? 'led-green' : 'led-red') +
'"></div></div>';
} else {
return '';
}
}
See http://jsfiddle.net/OlegKi/fo3wb58w/14/. Now we will fill the data, which allows us to sort there. I use in the demo the latest version of free jqGrid because jqGrid 4.6, which you used in the original demo has the bug with processing of localReader which has repeatitems: true.
More deep modification will be http://jsfiddle.net/OlegKi/fo3wb58w/15/
var mydata = [
{ data: "{\"pla\":1,\"mco\":null,\"sup\":null}" },
{ data: "{\"pla\":null,\"mco\":1,\"sup\":1}" },
{ data: "{\"pla\":1,\"rex\":null}" }
],
sortRedGreen = function (value) {
switch (value) {
case 1:
return 2;
case null:
return 1;
default:
return 0;
}
},
formatRedGreen = function (cellvalue) {
if (cellvalue !== undefined) {
return '<div class="led-box"><div class="' +
(cellvalue !== null ? 'led-green' : 'led-red') +
'"></div></div>';
} else {
return '';
}
},
templateRedOrGreen = {
width: 48,
sorttype: sortRedGreen,
stype: "select",
searchoptions: { value: "undefined:Undef;null:Null;1:1", noFilterText: "Any"},
formatter: formatRedGreen
};
$("#grid").jqGrid({
data: mydata,
autoencode: true,
colModel: [
{ name: 'data', width: 250, search: false },
{ label: 'PLA', name: 'pla', template: templateRedOrGreen },
{ label: 'MCO', name: 'mco', template: templateRedOrGreen },
{ label: 'SUP', name: 'sup', template: templateRedOrGreen },
{ label: 'REX', name: 'rex', template: templateRedOrGreen }
],
localReader: {
repeatitems: true,
cell: function (item) {
var rowData = $.parseJSON(item.data);
rowData.data = item.data; // include the original data too
return rowData;
}
},
iconSet: "fontAwesome",
caption: "Stack Overflow Example"
}).jqGrid("filterToolbar");
It uses custom sorttype function which allow to reorder the possible value undefined, null and 1 during sorting. It uses filterToolbar with
stype: "select",
searchoptions: { value: "undefined:Undef;null:Null;1:1", noFilterText: "Any"}
to simplify filtering of the data.

Javascript - How to return a partial array from a function?

I would like to insert in the middle of a columns array, many elements based on a parameter returned by the function getSpecificColumns(parameter).
The first one is working cause it is returning a single object, but is there any way to return many elements in the middle of the array?
$scope.getSpecificColumns = function (myParam) {
return { field: "SpecificField1", format: "{0:c}" };
}
$scope.getSpecificColumnsNotWorking = function (myParam) {
return { field: "SpecificField2", format: "{0:c}" },
{ field: "SpecificField3", format: "{0:c}" };
}
$scope.positionMontantNavGridOptions = {
height: 630,
filterable: {
mode: "row"
},
pageable: true,
columns: [
{ field: "Field1", width: "200px" },
{ field: "Field2", title: "Field 2", width: "80px" },
getSpecificColumns(parameter),
{ field: "Field4" }
]
}
If you want to return an array, return an array:
$scope.getSpecificColumnsNotWorking = function (myParam) {
return [{ field: "SpecificField2", format: "{0:c}" },
{ field: "SpecificField3", format: "{0:c}" }];
}
A expression such as:
{ field: "SpecificField2", format: "{0:c}" },{ field: "SpecificField3", format: "{0:c}" };
evaluates to the former of the comma delimeted "sub-expressions", for example:
var a = 1, b = 2;
var c = a, b;
alert(c === a);
and in your original code this directly translates to the first literal object being returned from the function while the later is "discarded".
(By the way, if you're not using the myParam argument you might as well not define it and not pass it in the call)
First return array, then use Array.prototype.concat to flaten it into array.
Is this a suitable solution for your problem?
$scope.getSpecificColumnsNotWorking = function (myParam) {
return [
{ field: "SpecificField2", format: "{0:c}" },
{ field: "SpecificField3", format: "{0:c}" }
];
}
columns: [].concat(
{ field: "Field1", width: "200px" },
{ field: "Field2", title: "Field 2", width: "80px" },
getSpecificColumnsNotWorking (parameter),
{ field: "Field4" });

Iterate JSON array in angular controller

I am trying to iterate through the array in Json and display the values in front end. I have given my code but I could not figure out where exactly I am wrong. I am not able to retrieve the values(startDate, endDate) inside the array and show them at front end.
JSON
"reportTypeObligationTypes": [{
"reportTypeId": null,
"consolidationScopeId": 4009,
"startDate": "2014-01-01",
"endDate": "9999-12-31",
"frequencyCode": "Q",
"reportTypeLabel": null,
"reportTypeCode": null,
"consolidationScopeCode": "C",
"frequencyLabel": "Quarterly"
}]
Angular controller
xxxApp.controller('reportListController', function ($scope, $http, $location, $routeParams) {
var service_url = "/mdmservice/services/reportTypeEntities/" + $routeParams.id;
$http.get(service_url).success(
function (data, status, headers, config) {
$scope.reportTypeEntities = data;
angular.forEach($scope.reportTypeEntities, function (item) {
console.log(item.reportTypeObligationTypes);
})
});
$scope.gridOptions = {
paginationPageSizes: [25, 50, 100, 200, 300, 400, 500, 1000],
paginationPageSize: 25,
};
$scope.gridOptions.data = 'reportTypeEntities';
$scope.gridOptions.enableFiltering = true;
$scope.gridOptions.enableGridMenu = true;
$scope.gridOptions.fastWatch = true;
$scope.gridOptions.columnDefs = [{
name: "entityName",
width: "35%",
cellTemplate: '<div style="margin-left: 5px;">' + ' {{row.entity.entityName}}' + '</div>'
}, {
name: "entityCode",
width: "15%"
}, {
name: "codeType"
}, {
name: "Entity Type",
field: "entityType.entityTypeName"
}, {
name: "reportingId"
}, {
name: "Country",
field: "country.countryName"
}, {
name: "startDate",
field: "reportTypeObligationTypes.startDate"
}, {
name: "endDate",
field: "reportTypeObligationTypes.endDate"
}, {
name: "consolidationScopeCode",
field: "reportTypeObligationTypes.consolidationScopeCode"
}, {
name: "frequencyLabel",
field: "reportTypeObligationTypes.frequencyLabel"
}, {
name: "Delete",
cellTemplate: '<div style="margin-left: 5px;">' + ' Delete' + '</div>',
enableFiltering: false,
enableSorting: false
}];
})
HTML Page - Angular UI grid
<div ng-app="xxxApp" ng-controller="reportListController">
<p class="heading">Entities with Reporting Obligation</p>
<!-- Entities list data table using - 'ui-grid' module -->
<div ui-grid="gridOptions" class="myGrid" ui-grid-pagination
ui-grid-selection ui-grid-resize-columns ui-grid-move-columns
ui-grid-cellNav ui-grid-exporter></div>
In your controller, assign $scope.reportTypeObligationTypes = [{JSON}];
Your tag or directive ex:
<div ng-repeat="item in reportTypeObligationTypes">
<div>{{item.startDate}}</div>
<div>{{item.endDate}}</div>
</div>
'item' will represent each JSON object in the array and you can use item.(property). To reference each object property.
EDIT:TRY:
$scope.gridOptions = {
data: $scope.myData,
columnDefs: [
{ name: 'field1', displayName: 'pretty display name' },
{ name: 'field2', visible: false }
]
};

Type Error when trying to preserve filter state - Kendo UI Grid

I'm working with Kendo UI's Grid and attempting to add some code which preserves the grid's filter/grouping/etc by way of a cookie. It works in the example, but not at all in my code.
Example: http://www.kendoui.com/code-library/web/grid/preserve-grid-state-in-a-cookie.aspx
My Code: http://jsfiddle.net/PwajE/
For whatever reason (I'm sure it's a simple one) I keep getting type errors. Two hours later... here I am.
As always, any help is appreciated.
#RRfive
<script>
var data = [{"name":"John Smith","email":"test#test.com","permission":"admin","costRate":"60","dt":"2013-02-02 10:26:29","memberID":"M0000001"},{"name":"Test Simple","email":"test#jones.com","permission":"user","costRate":"40","dt":"2013-02-02 00:00:00","memberID":"M0000002"}];
$(document).ready(function() {
$("#grid").kendoGrid({
dataSource: {
data: data,
//transport: {
// read: "assets/data/data.users.php",
//},
schema: {
data: function(result) {
return result.data || result;
},
total: function(result) {
var data = this.data(result);
return data ? data.length : 0;
},
model:{
id:"memberID",
fields:{
dt:{ type:"date" },
costRate:{ type:"number" }
}
}
},
pageSize: 10,
},
sortable: {
mode: "single",
allowUnsort: true,
},
pageable: {
input: true,
numeric: false
},
reorderable: true,
resizable: true,
filterable: {
extra:false,
operators: {
string:{
contains: "Contains",
}
}
},
columnMenu: false,
groupable: true,
dataBound: function(e){
var grid = this;
var dataSource = this.dataSource;
var state = kendo.stringify({
page: dataSource.page(),
pageSize: dataSource.pageSize(),
sort: dataSource.sort(),
group: dataSource.group(),
filter: dataSource.filter()
});
$.cookie("employeesState",state);
if($.cookie('empRows')){
$.each(JSON.parse($.cookie('empRows')),function(){
var item = dataSource.get(this);
var row = grid.tbody.find('[data-uid='+item.uid+']');
row.addClass('k-state-selected');
})
}
},
change:function(){
var grid = this;
var ids = grid.select().map(function(){
return grid.dataItem($(this)).Id
}).toArray();
$.cookie('empRows',JSON.stringify(ids));
},
columns: [
{ field: "name", title:"Name" },
{ field: "email", title:"Email/Username" },
{ field: "costRate", title:"Cost Rate (p/hr)", template: '#= kendo.toString(costRate, "c") #', },
{ field: "permission", title:"Permission", template: "#= (permission == 'admin') ? 'Administrator' : 'User' #" },
{ field: "dt", title:"Registered", template: '#= kendo.toString(dt,"d-M-yyyy") #' },
{ field: "memberID", title:" ", width: "83px", filterable: false, sortable: false, template: '<a class="k-button k-button-icontext k-grid-edit" href="manage_admin.php?form=editMember&ID=#= kendo.toString(memberID, "n2")#"><span class=\"k-icon k-edit\"></span>Edit</a>'},
]
});
var state = JSON.parse($.cookie("employeesState"));
if(state){
if(state.filter){
parseFilterDates(state.filter, grid.dataSource.options.schema.model.fields);
}
grid.dataSource.query(state);
}
else{
grid.dataSource.read();
}
});
function parseFilterDates(filter, fields){
if(filter.filters){
for(var i = 0; i < filter.filters.length; i++){
parseFilterDates(filter.filters[i], fields);
}
}
else{
if(fields[filter.field].type == "date"){
filter.value = kendo.parseDate(filter.value);
}
}
}
</script>
If you debug that fiddle you would see that the following line throws the error:
grid.dataSource.query(state);
The reason for this is that grid is not an instance of Kendo Grid but the div elemen with id='grid'. The fix is simple - initialize the grid variable prior to using it:
var grid = $("#grid").data('kendoGrid');
grid.dataSource.query(state);

Categories