UI-Grid gridOptions -> selectOptions as Variable not possible? - angularjs

I just tried to use this code:
field: 'field1',
filter: {
term: 1,
condition: uiGridConstants.filter.STARTS_WITH,
placeholder: 'starts with...',
ariaLabel: 'Starts with filter for field1',
flags: { caseSensitive: false },
type: uiGridConstants.filter.SELECT,
//selectOptions: [{ value: '1', label: 'male' }, { value: '2', label: 'female' }],
selectOptions: [$scope.DropdownEntries],
disableCancelFilterButton: false
}
The gridOptions selectOption array which come back form DropdownEntries is empty because the variables in DropdownEntries() are not accessible if gridOptions are not set, they come from a Webservice and it takes longer to load them as gridOptions are set.
Is there any possibility to "reload" the gridOptions after I`m sure that all variables are accessible ? Or is there another way to solve this problem
I am new in AngularJS and Ui-Grid thanks for helping me !

You can initialize the selectOptions with an empty array and reassign them when the data becomes available
See this question.

Then you should wait for that promise to be resolved and after that set selectOptions, something like this:
$http.get(url).then(function(response) {
gridOptions.filter.selectOptions = response.data.dropdownEntries;
})
Another possibility is to resolve that promise before entering the controller that sets ui-grid options.
https://docs.angularjs.org/api/ngRoute/service/$route#example

Related

How do I preselect a vue-multiselect option when options is an array of objects?

I want to pre-select a particular value in a select drop-down generated by vue-multiselect.
I can get this to work fine if I have a simple array of strings like the following:
['Test 1', 'Test 2', 'Test 3']
However, when I use an array of objects, I can't get this to work. For example, if I have the following:
<v-multiselect :options="[{id: 1, name: 'Test 1'}, {id: 2, name: 'Test 2'}, {id: 3, name: 'Test 3'}]"
label="name"
track-by="id"
v-model="test">
</v-multiselect>
No matter what I set the test data property that v-model is connected to, it won't preselect the value. I've tried 1, 2, 3, '1', '2' and '3' for test when track-by is id and 'Test 1', etc. when track-by is name but nothing seems to work.
What am I doing wrong here? I looked at the docs at https://vue-multiselect.js.org/#sub-single-select-object, but they don't seem to provide an example when you want to preset a value for an array of objects for the options. Googling has also not returned what I'm looking for.
On a related topic, once I get this working, what would I have to change to select multiple values for when I set the component to multiple? Thank you.
track-by usage
The docs indicate that track-by is "Used to compare objects. Only use if options are objects."
That is, it specifies the object key to use when comparing the object values in options. The docs should actually state that track-by is required when the options are objects because <vue-multiselect> uses track-by to determine which options in the dropdown are selected and to properly remove a selected option from a multiselect.
Without track-by, you'd see two buggy behaviors for object-options: (1) the user would be able to re-select already selected options, and (2) attempting to remove selected options would instead cause all options to be re-inserted.
Setting initial values
<vue-multiselect> doesn't support automatically translating a value array, but you could easily do that from the parent component.
Create a local data property to specify track-by and initial multiselect values (e.g., named trackBy and initialValues, respectively):
export default {
data() {
return {
//...
trackBy: 'id',
initialValues: [2, 5],
}
}
}
Bind <vue-multiselect>.track-by to this.trackBy and <vue-multiselect>.v-model to this.value:
<vue-multiselect :track-by="trackBy" v-model="value">
Create a watcher on this.initialValues that maps those values into an object array based on this.trackBy, setting this.value to the result:
export default {
watch: {
initialValues: {
immediate: true,
handler(values) {
this.value = this.options.filter(x => values.includes(x[this.trackBy]));
}
}
}
}
Vue.component('v-multiselect', window.VueMultiselect.default);
new Vue({
el: '#app',
data () {
return {
trackBy: 'id',
initialValues: [5,2],
value: null,
options: [
{ id: 1, name: 'Vue.js', language: 'JavaScript' },
{ id: 2, name: 'Rails', language: 'Ruby' },
{ id: 3, name: 'Sinatra', language: 'Ruby' },
{ id: 4, name: 'Laravel', language: 'PHP' },
{ id: 5, name: 'Phoenix', language: 'Elixir' }
]
}
},
watch: {
initialValues: {
immediate: true,
handler(values) {
this.value = this.options.filter(x => values.includes(x[this.trackBy]));
}
}
}
})
<script src="https://unpkg.com/vue#2.6.6/dist/vue.min.js"></script>
<script src="https://unpkg.com/vue-multiselect#2.1.0"></script>
<link rel="stylesheet" href="https://unpkg.com/vue-multiselect#2.1.0/dist/vue-multiselect.min.css">
<div id="app">
<v-multiselect :track-by="trackBy"
:options="options"
v-model="value"
label="name"
multiple>
</v-multiselect>
<pre>{{ value }}</pre>
</div>
Looks like a bug. The workaround is to use an actual reference to the object
Vue.component('v-multiselect', window.VueMultiselect.default);
let testOptions=[{id: 1, name: 'Test 1'}, {id: 2, name: 'Test 2'}, {id: 3, name: 'Test 3'}]
new Vue({
el: '#app',
data: function () {
return {
test: testOptions[1], // <- use an object ref here!
testOptions
};
}
});
The easiest way I found out is sending the whole object from BE, so it gets pre-selected. If you send the same object from BE will get pre-selected. But I don't know if your options are hard coded on FE or they are coming from a database or something. I had the same issue but my values were coming from my database, so it was easy to reproduce the object
In your question just :object="true" is missing actually they didn't know that it is of type string or object when we pass this it knows yes it is object and i need label="name" from v-model="test" and picks it and shows it as a preselected

How to update value in a nested Immutable map

I am new to immutable.js and trying to figure out a way to update a nested map
Here is my object
let state = OrderedMap({
'name': Map({ id: 'name', hint: 'Search by name', value: '' }),
'job': Map({ id: 'job', hint: 'Search by job title', value: ''}),
'state': Map({ id: 'state', hint: 'Search by state', value: ''})
});
I am trying to set value of the 'name' object using a setIn function
state.setIn(['name', 'value'], 'Test');
The value is not getting updated as expected. Am I missing anything here
setIn doesn't mutate the original state, however it returns you another one so you would essentially have
state = state.setIn(['name', 'value'], 'Test');
I've never used immutable, but it looks to me like the docs are saying you want something more like:
setIn(state, ['name', 'value'], 'Test');
Where you are passing in the collection rather than running a function on it with a dot operator.
https://facebook.github.io/immutable-js/docs/#/setIn
Instead of mutating the state you can use setIn as this will return you a fresh copy instead , So you can do something like :
state = state.setIn(['name', 'value'], 'Test');
You can read more on Facebook Github

Angular ui-grid editDropdownOptionsArray depending on current row

I want to have a different dropdown array for each row of my ui-grid. Therefore I need to access the current row. I had something like this in mind but I don't know how to access the current row within columnDefs. Is there an easy way to achieve this?
columnDefs: [
{ name: "id", field: "id"},
{ name: "firends", field: "friends", editableCellTemplate: 'ui-grid/dropdownEditor', editDropdownOptionsArray: findFriendsForId(row.id)
]
var findFriendsForId = function(id) {
// find friends and return them as array
}
Ok I figured it out by myself. There is a function called
editDropdownOptionsFunction.
Here is an example of it.

How to set date collection as a data source in AngularJs UI grid?

I need to display only a Date Collection object as a data source in my UI Grid.
Do I need to define a field under ColumnDefs in this case? Also, I need to include a column to delete that particular row, in this case Delete the current Date object.
How can I accomplish this? Below is my code
editor.mySeasonBreaks = {
data: "editor.mySeasons",
columnDefs:
[{ field: "????", visible: true, displayName: "Season Break" },
{
name: 'delete',
displayName: "",
cellTemplate: "<button ng-click="editor.delete(row.entity)" />"
}]
};
In the above code, editor.mySeasons is just a date array object.
Thanks in advance
You could create an object-array with your dates and define the columns as needed. This way you got more control and its easy to adjust/expand.
Now for your row-deletion I created a Plunkr thats showcases a possible solution.
As you suggest you need to add a cellTemplate that references your delete-function
cellTemplate: "<button ng-click=\"grid.appScope.delete(row)\">DELETE ROW</button>"
To access that function, you need to add it to your gridDefinition and ther property is called appScopeProvider
Possible setup would be
appScopeProvider: {
delete : function(row) {
editor.mySeasons.forEach(function(entry, index){
if(entry.myDate === row.entity.myDate) {
editor.mySeasons.splice(index, 1);
}
});
},
}
This is not recommended scenario, but you can use something like this:
$scope.myData=['2015-22-07', '2017-10-08', '2020-17-02'];
$scope.gridOptions = {
data: 'myData',
columnDefs: [
{
displayName: 'Date Array',
cellTemplate: '<div class="ngCellText ng-class="col.colIndex()">{{row.entity}}</div>'
}
]
};
You can test it here.
There are issues with sorting and probably something else.
It's better IMO to translate your array of dates to array of objects:
var res = [];
myData.forEach(function(el){
res.push({date: el});
});
Then specify column as usual:
{ field: 'date', visible: true, displayName: 'Season Break' }

How do I set a Ext Grid Filter Default?

I have a working sort-able grid using the ext 3.4 grid filter plugin. I would like to default the active column to filter true values. User who needs the inactive records could remove the filter. How do I specify a default filter column and value?
Thanks in advance!
colModel: new Ext.grid.ColumnModel({
defaults: {
sortable: true
// How do I specify a default filter value
//
// Only show active records unless the user changes the filter...
},
columns: [{
dataIndex:'f_uid',
id:'f_uid',
header:'ID',
hidden:true
}, {
dataIndex:'f_name',
id:'f_name',
header:'Name',
}, {
xtype:'booleancolumn',
dataIndex:'f_active',
id:'f_active',
header:'Active',
filterable:true,
trueText:'Active',
falseText:'Inactive'
}]
I realise this is an old question but it took me a while to find a solution, therefore I thought I would share.
1) The filter can be set using the value property in the filter.
filter: {
type: 'LIST',
value: ['VALUE TO FILTER']
}
2) In order to initially filter the data use the filterBy() method in the store. This could be defined in the onRender event handler.
this.getStore().load({
scope:this,
callback: function() {
// filter the store
this.getStore().filterBy(function(record, id) {
// true will display the record, false will not
return record.data.DATA_TO_FILTER == 'VALUE TO FILTER ';
});
}
});
The answer was in the Filter.js source code. The filter object within the column definition can be used to configure the default behavior.
}, {
xtype:'booleancolumn',
dataIndex:'f_active',
id:'f_active',
header:'Active',
trueText:'Active',
falseText:'Inactive',
filterable:true,
filter: {
value:1, // 0 is false, 1 is true
active:true // turn on the filter
}
}
I have encountered the same problem and I found that #John's answer is right, I can make it work with the sample http://dev.sencha.com/deploy/ext-4.0.0/examples/grid-filtering/grid-filter-local.html, for the grid-filter-local.js, just add the code like:
grid.getStore().load({
scope:this,
callback: function() {
// filter the store
grid.getStore().filterBy(function(record, id) {
// true will display the record, false will not
return record.data.size === 'small';
});
}
});
before the original code store.load(), and wipe off the store.load().
Then it will only show the record with size equals 'small' at the first load of the web page. Cheers!
I've made a universal helper class that allows you to set any default values in column definition.
https://gist.github.com/Eccenux/ea7332159d5c54823ad7
This should work with both remote and static stores. Note that this also works with filterbar plugin.
So your column item is something like:
{
header: 'Filename',
dataIndex: 'fileName',
filter: {
type: 'string',
// filename that starts with current year
value: Ext.Date.format(new Date(), 'Y'),
active:true
}
},
And then in your window component you just add something like:
initComponent: function() {
this.callParent();
// apply default filters from grid to store
var grid = this.down('grid');
var defaultFilters = Ext.create('Ext.ux.grid.DefaultFilters');
defaultFilters.apply(grid);
},

Resources