I see this example
https://openui5.hana.ondemand.com/explored.html#/entity/sap.ui.unified.Shell/samples
Now I have a root view (this.app) and all works fine.
return this.app;
Now I want include the root app in a shell container..
I try to do this:
var oShell= new sap.m.Shell("idShell", {
title: "Test App",
logo:"https://dl.dropboxusercontent.com/u/7546923/OpenUI5/SAPUI5.png",
headerRightText: "This is a sap.m.Shell",
logout: function() {alert("Logout button was pressed");}
});
oShell.setApp(this.app);
return oShell;
But in this way I can't see the bar on the top. (I see only the app limited in width and the logo out of the app, on left)
I try to do this:
var oShell= new sap.m.Shell("idShell", {
title: "Test App",
logo:"https://dl.dropboxusercontent.com/u/7546923/OpenUI5/SAPUI5.png",
headerRightText: "This is a sap.m.Shell",
logout: function() {alert("Logout button was pressed");}
});
oShell.setApp(sap.ui.xmlview("view.shell")); //the view of the example in the documentation
return oShell;
In this way I can see the bar but I can't associate the root app in the content of shell
Now I use sap.ui.unified.Shell
jQuery.sap.require("sap.ui.unified.Shell");
jQuery.sap.require("sap.ui.unified.ShellHeadItem");
this.shell = new sap.ui.unified.Shell('');
var logout=new sap.ui.unified.ShellHeadItem({
tooltip: "Logout",
icon: "sap-icon://menu2"
});
this.shell.addHeadItem(logout);
this.shell.addContent(this.app);
How can I use a MVC pattern to manage the shell bar content? I want use an XML-view. And how can I avoid to write
jQuery.sap.require("sap.ui.unified.Shell");
jQuery.sap.require("sap.ui.unified.ShellHeadItem");
?
This works for me:
new sap.m.Shell("Shell", {
app: sap.ui.jsview("RootView", "my-app.view.App")
}).placeAt("root");
While the root control of my-app.view.App is a sap.m.SplitApp (or sap.m.App). Note that the sap.m.Shell is just providing a frame it is NOT providing any NavContainer, Page or similar concept you usually use in sap.m. What is the root control in your view.shell? From the docs:
getApp() : sap.ui.core.Control
Getter for aggregation app. A Shell contains an App or a SplitApp
(they may be wrapped in a View). Other control types are not allowed.
Btw: Your example link is not working for me.
BR
Chris
Related
i have this requirement on IBM Content Navigator about a personalized (feature) homepage with various buttons used to switch between feature; i've made all works except for the one linked to the Home feature (favorites)
i've already tried to call the feature with thoose params:
params.repositoryId="FNOSARCHIVIO";
params.application="navigator";
params.desktop="OneFile";
params.userid="sys.filenetsvil";
but with no success, the feature is switched (after the button press it switch to the home feature) but it does not load the favorites of the user
here is my switch-feature method (taken for the ibm icn redbook + some modification)
switchFeature: function (featureIdToSwitch) {
//get layout from destop
var layout = ecm.model.desktop.getLayout();
// get the corresponding button of the LaunchBar Container
var feaButt = layout.launchBarContainer.getFeatureButtonByID(featureIdToSwitch);
var params = {};
// params.repositoryId="FNOSARCHIVIO";
// params.application="navigator";
// params.desktop="OneFile";
// params.userid="sys.filenetsvil";
// switching to the target feature
// feaButt.child.loadContent;
layout.launchBarContainer.selectContentPane(feaButt, featureIdToSwitch, params);
}
on the frontend i have 4 simple dojo buttons with onClick action, nothing special.
i use this feature id:
switchToHome: function () {
this.switchFeature('favorites');
},
this is what i mean when i say "it switch the feature but do not load the favorites:"
Home feature called from my button:
https://ibb.co/GMW7L2x
Home feature called from the standard toolbar:
https://ibb.co/BBgr36L
looks like it is loading the feature but it is not calling the listFavorites()
i cannot find any help on IBM docs or forum, any help here ? thanks!
At least i managed to do it, i post it here, hope helps someone:
1- override the default favorite feature (the java class), using the same js plugin, overriding this:
#Override
public String getContentClass() {
return "ecm.widget.layout.HomePane";
}
and set it to preLoaded:
#Override
public boolean isPreLoad() {
return true;
}
then, on the frontend, retrive the js feature, and load the content:
var targetFeature = layout.launchBarContainer.getContentPaneByID(featureIdToSwitch);
targetFeature.loadContent()
you can call the loadContent() only if the feature has been preLoaded or alredy invoke at leat once
I have a SAPUI5 application and I need to open a view (View2) by passing some query string parameters from another view (View1) by writing a method in View1 controller.
So far I've done it like below and it works fine when I run the application through webIDE. But when I deploy the application to the cloud platform it gives an error.
Controller js function
handleDetailNavPress: function(oEvent) {
var viewModel = this.getModel();
var headerInfo = viewModel.getProperty("/HeaderInfo");
var navUrl = "#detailscreen/params?docNo=" +
headerInfo.DocNo+ "&docName=" + headerInfo.DocName";
var url = window.location.href.split('#')[0] + navUrl;
//Navigate to second view
sap.m.URLHelper.redirect(url, true);
}
Routing settings in manifest
"routing": { "routes": [
{
"pattern": "viewone",
"name": "viewone",
"target": "viewone"
},
{
"pattern": "viewtwo/params:?query:",
"name": "viewtwo",
"target": "viewtwo"
} ],
Error I got after deploying
viewSample:112 Uncaught TypeError: Cannot read property '6' of null
at getIntentParameter (qcmanager:112)
at Object.requestSite (qcmanager:352)
at Object.getSiteJson (qcmanager:500)
at Object.loadAppSite (qcmanager:567)
at qcmanager:745
at qcmanager:746
What is the issue. Is there another way to navigate within same app by opening a new tab.
If you want to open a Vi 2 in new tabe there are two options:
Either crate a saperate inde.html for that new view and include that view in that index.html (It's basically will work like a saperate SAP UI5 application for user)
But i will not recomend this one
The other solution is
Instead of Using "sap.m.URLHelper", user:
window.open('[PAth to you Application index file]/[url]', '_blank');
For Example: window.open('https://www.mysapui5app/#podetailscreen/params?docNo=...', '_blank');
*Remember, _blank is madatory to open view in new tab.
When you deploy your application the launchpad the link changes, the second view comes like current URL + &/, so you need to check your URL and pass it correctly.
Just change these two variables accordingly:
navUrl
URL
Also, I would suggest to do cross app navigation as it will be more safer.
I would like to create a multiple step modal dialog - like a wizard. A series of screens that follow on from one another.
I'm using the code from NativeScript's site to display a modal (https://docs.nativescript.org/core-concepts/navigation#modal-pages)
var modalPageModule = "./modal-views-demo/login-page";
var context = "some custom context";
var fullscreen = true;
mainPage.showModal(modalPageModule, context, function closeCallback(username, password) {
// Log the user in...
}, fullscreen);
The code works, but I'm unsure how to change the modalPageModule once the modal is displayed.
Possible duplicate
Nativescript: How to use navigation in modals
https://github.com/NativeScript/NativeScript/issues/3753
I have used unified Shell control in order to implement the facebook-like swipe menu and I integrated in it a list so that I can enter menu items. The idea is that when a user clicks on a certain list item in the menu he will get redirected to a new view. I tried to implement it by using bus.publish("nav", "to" {id:..}) but it's not working. (I have put the menu in the Curtain Pane of the Unified Shell) Can anybody help me?
You can find below the respective code snippets of the view and controller.
var oListTemplate = new sap.m.StandardListItem({
title: "{title}",
icon: "{icon}",
description: "{description}",
type: sap.m.ListType.Navigation,
customData: new sap.ui.core.CustomData({
key: "targetPage",
value: "{targetPage}"
})
});
var oList = new sap.m.List({
selectionChange: [oController.doNavOnSelect, oController],
mode: sap.m.ListMode.SingleSelectMaster
});
oList.bindAggregation("items", "/Menu", oListTemplate);
The controller:
onInit: function() {
this.getView().setModel(new sap.ui.model.json.JSONModel("model/menu.json"));
this.bus = sap.ui.getCore().getEventBus();
},
doNavOnSelect: function(event){
if (sap.ui.Device.system.phone) {
event.getParameter("listItem").setSelected(false);
}
this.bus.publish("nav", "to", {
id: event.getParameter('listItem').getCustomData()[0].getValue()
});
Navigation via the sap.ui.core.EventBus is obsolete.
Please have a look at "Navigation and Routing" https://help.sap.com/docs/SAP_NETWEAVER_AS_ABAP_FOR_SOH_740/468a97775123488ab3345a0c48cadd8f/688f36bd758e4ce2b4e682eef4dc794e.html?locale=en-US
A new Routing mechanism was introduced to SAPUI5 in release 1.16. For in-app navigation, this supersedes previous techniques such as using the sap.ui.core.EventBus or sharing navigation-container specific controller code amongst aggregated pages.
Solution: Replace bus.publish with app.to
doNavOnSelect: function(event){
if (sap.ui.Device.system.phone) {
event.getParameter("listItem").setSelected(false);
}
app.to(event.getParameter('listItem').getCustomData()[0].getValue());
}
So I have a tab-component that has 3 items:
React.DOM.ul( className: 'nav navbar-nav',
MenuItem( uid: 'home')
MenuItem( uid: 'about')
MenuItem( uid: 'contact)
)
And in the .render of MenuItem:
React.DOM.li( id : #props.uid, className: #activeClass, onClick: #handleClick,
React.DOM.a( href: "#"+#props.uid, #props.uid)
)
Every time I click an item, a backbone router gets called, which will then call the tab-component, which in turn will call a page-component.
I'm still trying to wrap my head around the fact there's basically a one-way data-flow. And I'm so used to manipulating the DOM directly.
What I want to do, is add the .active class to the tab clicked, and make sure it gets removed from the inactive ones.
I know the CSS trick where you can use a data- attribute and apply different styling to the attribute that is true or false.
The backbone router already has already gotten the variable uid and calls the right page. I'm just not sure how to best toggle the classes between tabs, because only one can be active at the same time.
Now I could keep some record of which tab is and was selected, and toggle them etc. But React.js already has this record-keeping functionality.
The #handleClick you see, I don't even want to use, because the router should tell the tab-component which one to give the className: '.active' And I want to avoid jQuery, because React.js doesn't need direct DOM manipulation.
I've tried some things with #state but I know for sure there is a really elegant way to achieve this fairly simple, I think I watched some presentation or video of someone doing it.
I'm really have to get used to and change my mindset towards thinking React-ively.
Just looking for a best practice way, I could solve it in a really ugly and bulky way, but I like React.js because it's so simple.
Push the state as high up the component hierarchy as possible and work on the immutable props at all levels below. It seems to make sense to store the active tab in your tab-component and to generate the menu items off data (this.props in this case) to reduce code duplication:
Working JSFiddle of the below example + a Backbone Router: http://jsfiddle.net/ssorallen/4G46g/
var TabComponent = React.createClass({
getDefaultProps: function() {
return {
menuItems: [
{uid: 'home'},
{uid: 'about'},
{uid: 'contact'}
]
};
},
getInitialState: function() {
return {
activeMenuItemUid: 'home'
};
},
setActiveMenuItem: function(uid) {
this.setState({activeMenuItemUid: uid});
},
render: function() {
var menuItems = this.props.menuItems.map(function(menuItem) {
return (
MenuItem({
active: (this.state.activeMenuItemUid === menuItem.uid),
key: menuItem.uid,
onSelect: this.setActiveMenuItem,
uid: menuItem.uid
})
);
}.bind(this));
return (
React.DOM.ul({className: 'nav navbar-nav'}, menuItems)
);
}
});
The MenuItem could do very little aside from append a class name and expose a click event:
var MenuItem = React.createClass({
handleClick: function(event) {
event.preventDefault();
this.props.onSelect(this.props.uid);
},
render: function() {
var className = this.props.active ? 'active' : null;
return (
React.DOM.li({className: className},
React.DOM.a({href: "#" + this.props.uid, onClick: this.handleClick})
)
);
}
});
You can try react-router-active-componet - if you working with boostrap navbars.
You could try to push the menu item click handler up to it's parent component. In fact I am trying to do something similar to what you are doing.. I have a top level menubar component that I want to use a menubar model to render the menu bar and items. Other components can contribute to the top level menubar by adding to the menubar model... simply adding the top level menu, the submenuitem, and click handler (which is in the component adding the menu). The top level component would then render the menubar UI and when anything is clicked, it would use the "callback" component click handler to call to. By using a menu model, I can add things like css styles for actice/mouseover/inactive, etc, as well as icons and such. The top level menubar component can then decide how to render the items, including mouse overs, clicks, etc. At least I think it can.. still working on it as I am new to ReactJS myself.