Selecting first item in ComboBox from ODATA call. UI5 - combobox

I have a combo box that gets populated by an odata call.
From the home page, I navigate to a page with this combo box, and I want this combo box to select the first item of of an ODATA call as the default/selected item.
I use bindAggregation to populate my Combo Box in the onInit() function
After the object is bound, I want to read the list and take the first one and select it.
bindComboBox: function() {
var comboBox = oView.byId("ComboBoxID");
comboBox.bindAggregation("items", {
path: path,
parameters: param,
sorter: sorter,
template: template,
filters: filter,
events: {
dataReceived: this.selectFirstItemFunction()
}
}
selectFirstItemFunction: function() {
var comboBox = oView.byId("ComboBoxID");
var comboBoxItems = comboBox.getItems(); // This ends up being undefined.
comboBox.setSelectedItem(comboBoxItems[0]);
}
When I'm doing this, var comboBoxItems in selectFirstItemFunction() is always empty/undefined.
I also tried putting selectFirstItemFunction() inside onAfterRendering() and that didn't work either.
If the page is already loaded, and I do selectFirstItemFunction() then the combo box works as intended.
Any thoughts on how to get the combo box loaded up correctly?

You are not attaching the "selectFirstItem" function to the event. You are directly calling it when executing the "bindComboBox".
Correct it with this:
dataReceived: this.selectFirstItemFunction.bind(this)
But be careful, because "dataReceived" may not be fired if the data is already cached. So maybe you want to use the "change" event
change: this.selectFirstItemFunction.bind(this)

Related

Knockout binding for gijgo treeview with checkbox

I like the gijgo treeview with checkbox as its clean and neat and it solves the purpose of showing the hierarchy information. Check below link for documentation.
https://gijgo.com/tree/demos/bootstrap-treeview-checkbox
Since knockout.js is preferred for the front end development hence its needed to develop a knockout binding for this particular requirement.
The idea is to populate the hierarchy data from the backend and bind it to the custom knockout binding.
The user selects/un-selects some checkboxes and then hits the save button. the selected/unselected data is again sent back to the server for the save.
The below code is the usage of the control in jquery.
The function tree.getCheckedNodes() returns the array of selected checkboxes.
How would one call the above function from an knockout binding.
ko.bindingHandlers.tree = {
init: function (element, valueAccessor, allBindingsAccessor) {
},
update: function (element, valueAccessor, allBindingsAccessor) {
var options = valueAccessor() || {};
var value = ko.utils.unwrapObservable(valueAccessor());
var tree = $(element).tree(value);
}
}
In the init method:
Unwrap the widget's initial data passed by your viewmodel from the valueAccessor
Convert the initial data to the format the tree widget understands
Initialize the widget with the correct settings $(element).tree({ /* ... */ })
Attach an event listener (.on("change", function() { }) to track user-input
In the event listener function, write back the data from the UI to the viewmodel (e.g. valueAccessor() (tree.getCheckedNodes()))
Optional: add custom disposal logic to clean up the widget if knockout removes it from the DOM
In the update method, which is called if your view model's value changes
Implement the logic that updates the widget based on your new settings. Probably something like tree.check(ko.unwrap(valueAccessor())). Make sure the update is "silent", if it would trigger a change event, you'd end up in an infinite loop.

UI grid unable to get selected rows in case of 2 grids(same grid repeated twice)

I have created two ui grids on the same html(both are same).
I'm trying to get selected row on click of submit button. I'm able to get selected row for second grid but not able to get it for the first grid.
I'm getting selected rows like this:
onRegisterApi: function(gridApi) {
$scope.gridApi = gridApi;
$scope.mySelectedRows = $scope.gridApi.selection.getSelectedRows();
}
Plunker: http://plnkr.co/edit/SgYh9QzjCQDOKMMXATlF?p=info
Is there any way to get selected row of both the grids?
Thanks in advance.
That is because the API registers when the grid loads in the DOM. Since you have two grids with the same scope, when the second loads, it's API becomes what is defined by $scope.gridApi. Therefore anything you do with that API is interacting with the second grid instance.
The solution here would be to separate the grids out, maybe $scope.gridOptions1, $scope.gridOptions2. For anything that must occur on both, you can call each API independently within the function.
This is what I would do:
http://plnkr.co/edit/nLLR63L4H4NqLoZsGpkS?p=preview
For your submit function, assuming you want a single array with the results, I've updated the function such that it provides one result:
$scope.submitData = function() {
var selectedRows1 = $scope.gridApi1.selection.getSelectedRows(),
selectedRows2 = $scope.gridApi2.selection.getSelectedRows(),
selectedRows = selectedRows1.concat(selectedRows2);
console.warn(selectedRows);
alert(selectedRows.length)
if (selectedRows.length === 0)
alert('Please select an item from grid');
else
alert(JSON.stringify(selectedRows));
}

Can I keep the model value when click browser back button with angularjs?

I am new to AngularJS, I have a dropdown and a link. When I click the link, Anagularjs will route a different view (for example, display a chart and table).
Then when I click browser's back button, the dropdown will show the default value, other than the value I selected before.
Is it possible to let AngularJS remember the selected value of my dropdown when the link is clicked when I click browser's back button?
<select ng-model="selectedManagerFilter" ng-init="selectedManagerFilter= selectedManagerFilter || '*'"
ng-options="item.Code as item.Name for item in ManagerFilters" id="lstManagementGroup" name="lstManagementGroup"></select>
Your scope will get cleared when you exit the page and recreated with the default values when you get back to it.
You have 2 options:
use a Service to keep this kind of information (like selectedItem from your dropdown) and other useful things. The option selected in the dropdown should be bound to the service object:
angular.module('shared').factory('UsefulService', function() {
var UsefulService = {};
UsefulService.myPageSettings = {
currentDropDownItem: 1, //this is what you need
otherSetting: "blah"
};
return UsefulService;
});
and in your controller you should bind the scope variable to it (don't forget to require the UsefulService in your controller's dependencies):
$scope.myDearSettings = UsefulService.myPageSettings;
and then access it with $scope.myDearSettings.currentDropDownItem;
you can set a hash on your route when the dropdown changes (bound to the value) so when you hit Back you will get to the same state because of the hash. Basically, the url in your address bar will look like: http://your_server:your_port/myPage#Today where Today is the selected item.
The most recommended solution is option #1.

Collection create function firing add event too quickly

(Using Backbone 0.9.10)
I have a list view of sorts where the user can click a button to show a modal view. The list view has a counter that shows the amount of items contained in the list. Clicking a button in the modal view executes create on a collection that is passed into both views. This fires the add event in the list view, which in turn runs this function:
renderCount: function () {
// Container for model count
var $num = this.$el.find('.num');
if ($num.length > 0) {
// 'count' is a value returned from a service that
// always contains the total amount of models in the
// collection. This is necessary as I use a form of
// pagination. It's essentially the same as
// this.collection.length had it returned all models
// at once.
$num.html(this.collection.count);
}
}
However, add seems to be fired immediately (as it should be, according to the docs), before the collection has a chance to update the model count. I looked into sync but it didn't seem to do much of anything.
How can I make sure the collection is updated before calling renderCount?
Here's the list view initialize function, for reference:
initialize: function (options) {
this.collection = options.collection;
this.listenTo(this.collection, 'add remove reset', this.renderCount);
this.render();
}
EDIT:
Turns out I was forgetting to refetch the collection on success in the modal view.
$num.html(this.collection.count);
shoule be:
$num.html(this.collection.size());
Backbone.Collection uses methods imported from underscore, here is list: http://backbonejs.org/#Collection-Underscore-Methods
Turns out I was forgetting to refetch the collection on success in the modal view.

ExtJS4 - how to get parent grid on selectionchange?

I have little experience with ExtJS3 and now starting with version 4.
In my controller, I have this:
init: function ()
{
this.control({
"userlist":
{
selectionchange: function (view, selected, opts)
{
//get to grid??
}
}
});
}
How can I access the grid that this event happened on, without using id's?
I want to enable/disable buttons on the grid toolbar (tbar) if there are items selected, but I don't want to give anything id's (not the bar, not the individual buttons)
EDIT: the solution was to use the refs property in the controller:
refs:
[
{
ref: "list",
selector: "userlist"
}
],
selectionchange: this.activateTbButtons
activateTbButtons: function (selected, opts)
{
if (selected.selected.length == 1)
{
var tb = this.getList().query("toolbar");
}
}
Just found out that you can use the attribute view, and views under Ext.selection.Model.
This can be useful in cases when you let's say open multiple instances of your objects.
So, to access the grid in your example:
selectionchange: function (view, selected, opts) {
//get to grid??
var grid = view.view.ownerCt;
}
Having the same problem and found the previous answers missing some points. In short, I recommend:
selectionchange: function (selModel, selected, eOpts) {
var grid = selModel.view.ownerCt;
}
This was already proposed by Adezj although it referred to the selectionchange event that has the view as the first argument, and is not applicable to ExtJS 4.0.7+. (Don't think that selectionchange ever had the view as an argument?)
Note that this might not be officially supported by ExtJS since the view property of the selection model is not mentioned in the API docs at all.
Another approach is to use Ext.ComponentQuery.query(...) or defining refs in the controller, as proposed by Arun V, which is basically just a handy wrapper for Ext.ComponentQuery.query(). This works fine if you only have individual instances of the grid class but you need to take care in case you have multiple instances of the same grid class. Simply doing Ext.ComponentQuery.query('xtype-of-your-grid') will return all instances of your grid and you will have lots of fun finding out in which one the user has selected something.
So, in general, I would highly recommend to always work your way up from the component or object that fired the event to be sure you are in the right branch of the component hierarchy unless you are sure you will never have more than one instance of that class you write a controller for.
EDIT
I took a look at the docs for the selectionChange event:
selectionchange( Ext.selection.Model this, Ext.data.Model[] selected, Object eOpts )
The view is not being passed in to the selectionchange handler. An easy way to handle this is to either use Ext.getCmp() or use refs as seen in the docs for Ext.app.Controller:
http://docs.sencha.com/ext-js/4-0/#!/api/Ext.app.Controller
//get grid
var grid = selectionModel.view.ownerCt.ownerCt;

Resources