How to highlight the selected tab in sap.m.IconTabBar? - sapui5

Dear SAPUI5 developers,
I have a sap.m.IconTabBar and I set the active tab by the code when the user switch between pages. I used the following code:
sap.ui.getCore().byId(this.createId("iconTabBar")).setSelectedKey("1");
The problem is that it switch the selected tab correctly to the first tab. But it does not show the blue line under the tab that shows it is selected.
Please look at the following images:
What shows when I select the first tab by code:
But what it shows when I press the tab by the mouse it shows a blue line under the icon like the following:

As #Ash said in the comments you need to call fireSelect but this works just if user the second tab at first. If the user is on the first tab and switches between the pages then fireSelect does not act properly. Thus you need to select the second tab at first then it will works almost all times.
sap.ui.getCore().byId(this.createId("iconTabBar")).setSelectedKey("2");
sap.ui.getCore().byId(this.createId("iconTabBar")).setSelectedKey("1");
sap.ui.getCore().byId(this.createId("iconTabBar")).fireSelect();

Ok I had a look into the IconTabBar source Code and theres something I dont really get why but here is how it proceeds :
when you call IconTabBar.setSelectedKey(key), it calls IconTabHeader.setSelectedKey(key)
then internally the IconTabBarHeader calls setSelectedItem(item, true)
the 'true' here is important, the parameter is named 'bAPIchange' in the setSelectedItem function, and it is used as condition for the fireSelect() :
if (!bAPIchange) {
// fire event on iconTabBar
if (bIsParentIconTabBar) {
oParent.fireSelect({
selectedItem: this.oSelectedItem,
selectedKey: sSelectedKey,
item: this.oSelectedItem,
key: sSelectedKey
});
} else {
// fire event on header
this.fireSelect({
selectedItem: this.oSelectedItem,
selectedKey: sSelectedKey,
item: this.oSelectedItem,
key: sSelectedKey
});
}
}
Which explains why the event is not fired in your case

Related

How to force the order of UIKit pop up menu button items?

I have a couple of UIKit pop-up menu buttons with identical menu items on the same screen in a Swift app. The buttons are built by calling a function that uses an array of strings to create the list of menu items.
The problem is that depending on the button's vertical position on the screen, the menu items may appear in the order specified by the function, or reversed. If the button is in the upper half of the screen, the menu items are listed in the correct order. If the button is in the lower half of the screen the menu items are listed in reverse order.
I would prefer the menu items to appear in the same order regardless of the button's position on the screen. I could check the button location and have the menu creation function reverse the order, but that seems kind of clunky. I am hoping there's a cleaner way to override this behaviour.
The code and array used to create the button menus:
let buttonMenuItems = ["Spring","Summer","Autumn","Winter"]
func createAttributeMenu(menuNumber: Int)->UIMenu {
var menuActions: [UIAction] = []
for attribute in buttonMenuItems {
let item = UIAction(title: attribute) { action in
self.updateMenu(menuID: menuNumber, selected: attribute)
}
menuActions.append(item)
}
return UIMenu(title: "", children: menuActions)
}
The result is this:
Versions I'm using now in testing: Xcode 14.1, iOS 16.1, but I have seen this behaviour on earlier versions as well. (back to iOS 14.x)
Starting with iOS 16, there is a .preferredMenuElementOrder property that can be set on the button:
case automatic
A constant that allows the system to choose an ordering strategy according to the current context.
case priority
A constant that displays menu elements according to their priority.
case fixed
A constant that displays menu elements in a fixed order.
Best I can tell (as with many Apple definitions), there is no difference between .automatic and .priority.
From the .priority docs page:
Discussion
This ordering strategy displays the first menu element in the UIMenu closest to the location of the user interaction.
So, we get "reversed" order based on the position of the menu relative to the button.
To keep your defined order:
buttonNearTop.menu = createAttributeMenu(menuNumber: 1)
buttonNearBottom.menu = createAttributeMenu(menuNumber: 2)
if #available(iOS 16.0, *) {
buttonNearBottom.preferredMenuElementOrder = .fixed
buttonNearTop.preferredMenuElementOrder = .fixed
} else {
// out of luck... you get Apple's "priority" ordering
}

$ionicHistory.goBack() not working correctly with ion tabs

My page contains 3 tabs, if i forward to next page from tab3 and then coming back from that page using $ionicHistory.goBack() it redirects to tab1. how to make it redirects to tab3 itself
function sample($scope,$ionicHistory){
$ionicHistory.goBack();
};
}
I'm not sure it's possible to do that just through $state. I'm new to Ionic myself as I had my first peek back in December (2016). However, I happened to have this exact scenario. This is how I solved it.
In my case, I was not using tabs. Instead, I had three different DIVs that were visible depending on the "tab number". When initializing the view, I set it to "1" and used the property to control what code is executed.
I'm guessing that the control you're using has a property like that to identify and set the particular tab you need, as this is the most likely way to change tabs on tab-click. Consider putting the value of that property "tab #" into the appropriate service used by the controller. This is a stripped-down version of actual code in one of my services defined via Factory.
YourService.js:
// controllers are instances. When navigating away, state is lost. This
// tracks the tab we wish to view when we load the home page.
var activeHomePageTab = 1;
var service = {
getActiveTab: getActiveTab,
setActiveTab: setActiveTab,
...
};
return service;
////////////////
function getActiveTab() { return activeHomePageTab; }
function setActiveTab(num) { activeHomePageTab = num; }
...
Here, the functions are private. In your controller, when you set your tab, also set this property. As a singleton, this will remain in effect as long as your application is running.
Next, in your init() routine, when the controller is loaded, check for this property and set the tab if it is defined:
function init() {
var tab = YourService.getActiveTab();
if (tab !== undefined) {
setTab(tab);
} else {
setTab(1)
}
...
}
Of course, there are other ways - maybe using Value or a property on a Constant object.

Initializing input data

Where, and how do I clear out the input date on a view....
E.g. when the data is saved, and I access my page from the menu, the old data is still displayed in the input boxes.
I've tried the onInit() function but that only fires the first time into the view.
The navto call is in the BaseController which calls the defaultTimes page (view/controller).
onNavToDefaultTimes : function(oEvent) {
this.getRouter().navTo("defaultTimes");
}
My clear code was in the _onRouteMatched function of detaultTimes.....
_onRouteMatched : function(oEvent) {
var view = this.getView();
view.byId("shopInput").setValue("");
view.byId("effectiveDateFrom").setValue("");
view.byId("shop24Hrs").setSelected(false);
view.byId("shopClosed").setSelected(false);
},
The problem is though, _onRouteMatched is also callled from navBack of the page following default times. And I don't want to clear the fields in this case.
How do I implement the clear from the onNavToDefaultTimes function of the base Controller only?
Can you give an example.
Let's say the name of the view in which your input field is created is test.js, then whenever you are navigating to the view or navigating from the view, you can use invalidate view like below
sap.ui.getCore().byId("test").invalidate();
this makes the view to be rendered again when you are coming back to the view and onBeforeRendering() is triggered
You can choose one of the following options, and put one of them, after the code to save is executed:
Option 1:
var yourInput = this.getView().byId("yourInputID");
yourInput.setValue("");
Options 2 (Try someone):
var yourInput = this.getView().byId("yourInputID");
yourInput.unbindValue();
yourInput.unbindElement();
yourInput.unbindObject();
Or put the code in the following method, which is executed every time the view is displayed:
onAfterRendering: function(){
//Option choosed
}

ExtJS 4: Prevent changing tab using TabBar

I don't use tab panel just tab bar, and have to prevent changing tab by some criteria.
In ExtJS docs I found change event for Ext.tab.Bar, but it fires when tab is already changed. So preventDefault() and return false are not working in this case.
Second I tried is set Ext.tab.Tab.handler property when tabs were initialized, but it fires when tab button is already clicked. So preventDefault() and return false don't work too.
Can ony body help with this? How can I prevent changing tabs using only Ext.tab.Tab and Ext.tab.Bar?
Thx.
I think you can use the 'beforetabchange' event on the tab panel itself.
From sencha docs: http://docs.sencha.com/ext-js/4-0/#!/api/Ext.tab.Panel-event-beforetabchange .
Return false in any listener to cancel the tabchange.
Edit
Maybe you could then extend the Ext.tab.Bar component and register the beforechange event by modifying the setActiveTab method, I think it's a pretty easy modification
setActiveTab: function(tab) {
//test the beforechange return
if (tab.disabled && me.fireEvent('beforechange', tab) === false) {
return;
}
var me = this;
if (me.activeTab) {
me.previousTab = me.activeTab;
me.activeTab.deactivate();
}
tab.activate();
if (me.rendered) {
me.layout.layout();
tab.el && tab.el.scrollIntoView(me.layout.getRenderTarget());
}
me.activeTab = tab;
me.fireEvent('change', me, tab, tab.card);
}
Add a controller action "beforeshow" on the tab panel container and disable the listeners. Allows the tabs to behave normally without clickability.
component.down("#tabPanel").tabBar.clearListeners();

ui.tabs add callback not able to set tab

I am trying to get jQuery tabs to behave like IE and Firefox. I have a few tabs with an "addtab" at the end. When this tab is clicked a new tab is added, this is fine. But i want to select the second last tab. This is proving to be quite difficult.
my init code is
$tabs =$("#tabs").tabs({
add: function(event, ui) {
$tabs.tabs('select', $tabs.tabs( 'length' ) -2);
alert ("after setting tab");
}
});
my add tab code is
$("#addtab").click(function(){
showcal();
// The first thing to do is to deselect all the other selections
$("#tabs .ui-corner-top").each (function () {
$(this).removeClass ("ui-tabs-selected ui-state-active").addClass ("ui-state-default");
});
$tabs.tabs('add','#extra','Generate Report', ($tabs.tabs('length')-1));
tabContainerTabCount++;
});
however in the add callback the following line is resetting the selected tab
self._trigger('select', null, self._ui(this, $show[0])) === false)
If anyone has any solution or reason why this is done, can you let me know
Thanks
John
I was pointed to the answer at the following web page
http://forum.jquery.com/topic/ui-tabs-unable-to-set-index-after-add#14737000000698077
thanks tsukasa1989