dynamic columnDef in ng-Grid - javascript

I want to assign ng-grid columns name dynamically after value returned from database, but issue is that it get initialized before data return from ajax, and i am not able to recall gridOption so it showing balnk, so please help me that how can we construct a column name by ajax return value.
$scope.gridOptions =
{
data: 'data.Values',
columnDefs:
[
{ field: "ID", displayName: "Record Id" },
{ field: "Value", displayName: $scope.ColumnName, cellFilter: cellfilterType },
],
};
where $scope.ColumnName coming from below line...
RecordService.getRecords().then(function (data) {
$scope.ColumnName= data.something;
}
Thanks

Thanks Max for your help, I have done this with of help columnDef as below:
Step 1:
$scope.colDef = [];
Step 2:
RecordService.getRecords().then(function (data){
$scope.colDef=["ColumnName":data.something]
}
Step 3:
$scope.gridOptions = {
data: 'data.UdiValues',
columnDefs:'colDef',
filterOptions: $scope.filterOptions
};

Try to set first "default" value and after change it with promise
$scope.gridOptions =
{
data: 'data.Values',
columnDefs:
[
{
field: "ID",
displayName: "Record Id"
},
{ field: "Value",
displayName: "default",
cellFilter: cellfilterType
},
]
};
And now:
RecordService.getRecords().then(function (data) {
$scope.gridOptions.columnDefs[1].displayName = data.something;
}
The Service RecordService returns promise therefore we create promise factory like:
.factory('RecordService', ['$resource','$q', function($resource, $q) {
var data = { something: "from service" } ;
var factory = {
getRecords: function (selectedSubject) {
var deferred = $q.defer();
deferred.resolve(data);
return deferred.promise;
}
}
return factory;
}]);
Demo Fiddle

Something like this
Return json, play around, use GET mapping to strings etc?

i have done something like this :-
self.gridOptions.columnDefs = columnDefs(colDef,displayNames);
columnDef is :-
var columnDefs = function(data,cd){
var colDef= [];
var mi = null;
var colByOrder = sortedByOrder(data);
for(var i=0 ; i < colByOrder.length ; i++){
colDef.push({
width: width,
field: String(colByOrder[i][1].position),
menuItems: menuItems(this),
displayName: cd[colByOrder[i][1].position],
enableSorting: false,
type: 'string',
});
}
return colDef;
};

Related

Easy Autocomplete nested Json structure

I'm having a hard time to structure the list location for items array in order to access name attribute in search.js
Below is the nested JSON structure:
{
menus: [
{
name: "Summer ",
url: "/menus/2",
items: [
{
name: "man o man", //this is what I'm trying to access
url: "/menus/2/items/7"
}
]
]
}
So far I've tried in search.js:
document.addEventListener("turbolinks:load", function() {
$input = $("[data-behavior='autocomplete']")
var options = {
getValue: "name",
url: function(phrase) {
data = "/search.json?q=" + phrase;
return data;
},
categories: [
{
listLocation: "menus",
header: "--<strong>Menus</strong>--",
},
{
listLocation: "items", //this is where I'm having problem with
header: "--<strong>Items</strong>--",
}
],
list: {
onChooseEvent: function() {
var url = $input.getSelectedItemData().url
$input.val("")
Turbolinks.visit(url)
}
}
}
$input.easyAutocomplete(options)
})

REACTJS: obj.push() and obj.concat is not a function

I am having an error that my obj.push() and obj.concat() is not a function but I am not so sure why. Here is my code:
onSearch = () => {
var obj = {
product: [
{
field: "is_published",
filter_value: 1
},
{
field: "order_mode",
filter_array: [
"fcfs",
"purchase-order"
]
},
{
relationship: "store",
filter_object: {
field: "slug",
filter_value: "sample"
}
}
]
}
if (this.state.search !== "") {
obj.push(
{
field: "name",
text_search: this.state.search
}
)
}
var obj2 = {
taxonomies: [
[
{ field: "type",
filter_value: "seller"
},
{ field: "slug",
filter_value: "brand"
}
]
]
}
var conc = obj.concat(obj2);
var { getProductSearch } = this.props
getProductSearch(obj.concat(obj2))
}
product and taxonomies are stored in different variables but I need to pass them as one array to getProductSearch and for that, I need to use concat(). then I need to use push() because I want to add an object to the array obj. What am I doing wrong?
The simple answer is because you can't push onto an object. Push is used for arrays.
To make this work you could instead change your code to push onto the array in your object by doing.
obj.product.push(
{
field: "name",
text_search: this.state.search
}
)
If you are trying to make product dynamic where there are multiple products like [fruits, veggies, meat] then you could change it simply by doing
onSearch(productName)
obj[productName].push(
{
field: "name",
text_search: this.state.search
}
)
This would let you call onSearch(veggies) and push only to that array if you set it up that way.

How to make Angular ui grid expand rows initially based on data?

I am using ui-grid to show a list of data and on display of the grid I am trying to expand some of the rows depending on the data.
I am trying to do this in the onRegisterApi event:
scope.GridOptions = {
data: properties,
columnDefs:
[
{ name: "Full Address", field: "FullAddress" },
{ name: "Suburb", field: "Suburb" },
{ name: "Property Type", field: "PropertyType" },
{ name: "Price", field: "Price", cellFilter: 'currency'},
{ name: "Status", field: "Status" },
{ name: "Sale Type", field: "SaleType" },
{ name: "Date Created", field: "CreateDate", cellFilter: "date:'dd/MM/yyyy HH:mma'"}
],
expandableRowTemplate: 'template.html',
expandableRowHeight: 200,
onRegisterApi: (gridApi) =>
{
gridApi.expandable.expandAllRows();
}
};
The problem is gridApi.expandable.expandAllRows() expands all of the grouped sections. I see there is a expandRow function, but I am not sure how to use it in place of the expandAllRows function. I really would like to expand the group that has the column Status set to a particular value. Can someone help me figure this out?
Here is a way to handle expanding of selective rows. I have created a Plunker link (http://plnkr.co/edit/CSaROQqKxYnkoxm2Tl6b?p=preview) where I am expanding all the even rows. In a similar way, you can iterate over the array and expand the required rows.
Include:
"$timeout" dependency in the controller
To expand first row:
$timeout(function() {
var rows = $scope.gridApi.grid.rows;
var entity = (rows.length && rows[0]) ? rows[0].entity : null;
$scope.gridApi.expandable.toggleRowExpansion(entity);
});
May be I am late to answer.
But it may help others.
I have taken the same plunker example as SaiGiridhar posted, but modified
$timeout(function() {
var rows = $scope.gridApi.grid.rows;
for(var i=0; i < rows.length; i++){
if(i%2 === 0){
var entity = (rows.length && rows[i]) ? rows[i].entity : null;
$scope.gridApi.expandable.toggleRowExpansion(entity);
}
}
});
to
$scope.$$postDigest(function() {
var rows = $scope.gridApi.grid.rows;
for(var i=0; i < rows.length; i++){
if(i%2 === 0){
var entity = (rows.length && rows[i]) ? rows[i].entity : null;
$scope.gridApi.expandable.toggleRowExpansion(entity);
}
}
});

Dynamically update and check an array of Objects

So I have a callback function that returns a data object from the dom (there is a list of items and every time you select an item it returns it as an object). Here is the call back function:
$scope.fClick = function( data ) {
$scope.x = data;
}
The object returned from fClick looks like this when you select an item from the dropdown : { name: "English", ticked: true }
When you deselect it from the dropdown it would return something like this:
{ name: "English", ticked: false }
Now I keep an array something like $scope.output to maintain a list of the returned objects. However, what I want to do is add an object returned from scope.fClick to $scope.output only if there isn't an object in output already with the same property "name" value. So right now in my implementation both { name: "English", ticked: false } and { name: "English", ticked: true } get added to the array. Instead I want it to update the ticked property. So, for instance if if $scope.output = { name: "English", ticked: false } and then scope.fClick returns { name: "English", ticked: true}. When I push this value to $scope.output I want it to the update the existing object's tick property so $scope.output = { name: "English", ticked: false } becomes $scope.output = { name: "English", ticked: true }
This is what I have tried:
$scope.fClick = function( data ) {
$scope.x = data;
}
$scope.$watch(function () {
return $scope.y = $scope.x;
},function (newValue, oldValue) {
var id = $scope.output.indexOf(newValue);
if(id === -1){
$scope.output.push(newValue);
}
else {
$scope.output[id].tick = newValue.tick;
}
console.log($scope.output);
},true);
How do I make this work?
Set & Get selected values, name and text of Angularjs isteven-multi-select
<div isteven-multi-select
input-model="marks"
output-model="filters.marks"
button-label="name"
item-label="name"
tick-property="ticked"
selection-mode="multiple"
helper-elements="all none filter"
on-item-click="fClick( data )"
default-label="Select marks"
max-labels="1"
max-height="250px">
</div>
Add items
$scope.marks= [
{ name: 'Mark I', value: 'Mark i', text: 'This is Mark 1', ticked: true },
{ name: 'Mark II', value: 'Mark ii', text: 'This is Mark 2' },
{ name: 'Mark III', value: 'Mark iii', text: 'This is Mark 3' }
];
Get selected item (on change)
$scope.fClick = function (data) {
console.log(data.name);
console.log(data.value);
console.log(data.text);
return;
}
Select item (Dynamically)
$scope.abc = function (data) {
console.log(data.element1, data.element2);
angular.forEach($scope.marks, function (item) {
if (item.value == data.element1) {
item.ticked = true;
}
else {
item.ticked = false;
}
});
}
Deselect item
$scope.marks.map(function (item) {
if (item.value == "")
item.ticked = true;
else
item.ticked = false
});
You can do the following by "simulate" a key/value map.
Controller
(function(){
function Controller($scope) {
$scope.data = [
{name: 'English', ticked: true},
{name: 'French', ticked: false}
];
//Represent a map key - value
$scope.output = {};
$scope.update = function(index){
//Change the ticked value by opposite
$scope.data[index].ticked = !$scope.data[index].ticked;
//Set the value to our map
$scope.output[index] = $scope.data[index].ticked;
}
}
angular
.module('app', [])
.controller('ctrl', Controller);
})();
Here, when you will update $scope.output, if the key exist, it will erase it by the new value, instead of it will create a new key/value pair.
HTML
<body ng-app="app" ng-controller="ctrl">
<ul>
<li ng-repeat="item in data">{{item.name}} {{item.ticked}} <button type="button" ng-click="update($index)">update</button></li>
</ul>
</body>

ExtJS 4 writer for nested JSON with array

I'm trying to handle JSON with nested structure with ExtJS4. Please do not answer like here
because it's wrong answer. I use the expandData: true with model mappings and it works for me really fine.
The problem I expect is with one field that is array of objects. So, here is my code sample:
Ext.define('EdiWebUI.model.Document', {
extend: 'Ext.data.Model',
fields: [
{name: 'document_header_documentReceiveDateTime', mapping: 'document.header.documentReceiveDateTime', type: 'string'},
{name: 'document_header_documentProcessDateTime', mapping: 'document.header.documentProcessDateTime', type: 'string'},
{name: 'document_header_documentID', mapping: 'document.header.documentID', type: 'string'},
...
{name: 'lines', type: 'auto'},
...
{name: 'attachments_documentFile_fileName', mapping: 'attachments.documentFile.fileName', type: 'string'},
{name: 'attachments_documentFile_content', mapping: 'attachments.documentFile.content', type: 'string'}
],
hasMany: [
{model: 'DocumentLines', name: 'lines', associationKey: 'lines'}
],
proxy: {
type: 'rest',
url: '/document',
reader: {
type: 'json',
root: 'data'
},
writer: {
expandData: true,
writeAllFields: true,
nameProperty: 'mapping'
}
}
});
Ext.define('DocumentLines',{
extend: 'Ext.data.Model',
fields: [
{'name': 'line_lineItem_lineNumber', mapping: 'line.lineItem.lineNumber', type: 'string'},
{'name': 'line_lineItem_orderedQuantity', mapping: 'line.lineItem.orderedQuantity', type: 'string'},
{'name': 'line_lineItem_orderedUnitPackSize', mapping: 'line.lineItem.orderedUnitPackSize', type: 'string'},
...
});
So, it working well when reading JSON like this:
{
"data": {
"document": {
"header": {
"documentReceiveDateTime": "2014-03-25T08:34:24",
"documentProcessDateTime": "2014-03-25T08:44:51",
"documentID": "83701540",
...,
"lines": [
{
"line": {
"lineItem": {
"lineNumber": "1",
"orderedQuantity": "5.000",
"orderedUnitPackSize": "1.000"
}
}
},
{
"line": {
"lineItem": {
"lineNumber": "2",
"orderedQuantity": "4.000",
"orderedUnitPackSize": "1.000"
}
}
}
]
...
but I can't make writer to parse lines. When I'm truing to save my document I already have output like this:
{ lines:
[ { line_lineItem_lineNumber: 1,
line_lineItem_ean: '4352345234523',
line_lineItem_orderedQuantity: '45'} ],
(other parts of document are expanded well)
So, here is a question: Is there a way to make it works as I need?
...or I should make a trick on a server side (as I actually do now)...
Thanks in advance.
You have two choices here:
The proper way, which is to use the stores capabilities: define your dataWriter and code your own function in order to get the json you want.
Don't use the store to update your records, create the json you want and use an Ajax request to update the records you need to update.
Both ways uses Ajax anyway, the first one should be preferred.
I would define my writer in the same file as the store, something like:
Ext.define('MyApp.custom.Writer',{
/*
* Formats the data for each record before sending it to the server.
* This method should be overridden to format the data in a way that differs from the default.
*/
getRecordData: function(record) {
var data = {};
/*
* Parse your record and give it whatever structure you need here..
*/
data.lines = [];
return data;
}
});
Although you seem to have one extra level of indirection in your Json, the "lineItem" is not necessarly needed as you already have a one-to-one relationship between line <-> lineItem and lineItem <-> and the object defined by lineItem. But this is a different question.
I've used the answer above, but wanted to share the code to make it a little bit easier for people who try the same thing.
Dr. Leevsey's Code from above worked for me but had the disadvantag that it puts everything inside an array. For my project it worked better if it returned an object (with the child objects) and didn't return an array if the base object is not an array.
Here is the code:
Ext.define('MyApp.util.customWriter',
{
extend: 'Ext.data.writer.Json',
getRecordData: function (record, operation) {
var data = record;
var me = this;
var toObject = function (name, value) {
var o = {};
o[name] = value;
return o;
};
var itemsToObject = function (item) {
for (prop in item) {
if (Array.isArray(item[prop])) {
me.getRecordData(item[prop]);
}
else {
if (item.hasOwnProperty(prop)) {
var nameParts = prop.split('.');
var j = nameParts.length - 1;
if (j > 0) {
var tempObj = item[prop];
for (; j > 0; j--) {
tempObj = me.toObject(nameParts[j], tempObj);
}
item[nameParts[0]] = item[nameParts[0]] || {};
Ext.Object.merge(item[nameParts[0]], tempObj);
delete item[prop];
}
}
}
}
};
if (!Array.isArray(data)) {
data = data.getData();
itemsToObject(data);
}
else {
var dataLength = data.length;
for (var i = 0; i < dataLength; i++) {
itemsToObject(data[i]);
}
}
return data;
}
});

Categories

Resources