Using a controller and and view together - sapui5

I'm writing my first SAP app, and having gone through some of the tutorials, I understand that I need a controller for my view if I want it to do anything.
When I add the controllerName="./controller/login" (the controller's called 'login.controller.js'), it doesn't work, and I've tried variations of this.
The tutorials get me to copy code that uses the controller name, but they don't teach me anything about how to write the string for my own controller code.
How do I do this?
Controller code looks like this so far:
sap.ui.define([
"sap/ui/core/mvc/Controller"
], function(Controller) {
"use strict";
return Controller.extend("controller.Login", {
// controller logic goes here
});
});
and the view code looks like this:
<mvc:View
controllerName="controller.Login"
xmlns="sap.m"
xmlns:form="sap.ui.layout.form"
xmlns:mvc="sap.ui.core.mvc">
<Panel headerText="{/panelHeaderText}" class="sapUiResponsiveMargin" width="auto">
<form:SimpleForm editable="true" layout="ColumnLayout">
<Label text="User Name"/>
<Input value="{/firstName}" valueLiveUpdate="true" width="200px"/>
<Label text="Password"/>
<Input value="{/lastName}" valueLiveUpdate="true" width="200px"/>
<Button text="login" press=".onVisitHomePage"/>
</form:SimpleForm>
</Panel>
</mvc:View>
I'm going to add the .onVisitHomePage function to the controller but first I want to get this to work.

Like Julian Schmuckli already said you have to prefix the controller.login with your Namespace check you index.html where you initialize the sap-ui-core (see below).
<script src="resources/sap-ui-core.js" id="sap-ui-bootstrap"
data-sap-ui-theme="sap_bluecrystal" data-sap-ui-libs="sap.m"
data-sap-ui-bindingSyntax="complex" data-sap-ui-compatVersion="edge"
data-sap-ui-preload="async" data-sap-ui-async="true"
data-sap-ui-frameOptions="trusted" data-sap-ui-appCacheBuster="./"
data-sap-ui-resourceroots='{
"your.namespace": "./",
"sap.ui.demo.mock": "mockdata"
}'></script>
Here you have to take the string that is in place of the "your.namespace" and combine it with the controller.login to your.namespace.controller.login .
You have to do this in both the view and the controller file.

Related

How to make out of input field a hyperlink?

As the title states, I would like to make out of an input a clickable hyperlink.
Code:
<Label text="Stackoverflow" />
<Input enabled="true" editable="false" name="Stackoverflow" value="Example" />
Issue: I want to display Example in the input as value, however, when clicking on the Example - to take you to stackoverflow.com.
Question: How to make it possible?
Without knowing what the use of the links are, generally, sap.m.InputBase controls can contain links within the value state message (Since 1.78).
sap.ui.getCore().attachInit(() => sap.ui.require([
"sap/ui/core/Fragment"
], Fragment => Fragment.load({
definition: `<Input xmlns="sap.m"
width="12rem"
valueState="Information"
placeholder="Input with links"
class="sapUiTinyMargin">
<formattedValueStateText>
<FormattedText htmlText="See %%0 and %%1.">
<controls>
<Link text="Link 1" press="alert('Link 1 clicked!')" />
<Link text="Link 2" press="alert('Link 2 clicked!')" />
</controls>
</FormattedText>
</formattedValueStateText>
</Input>`,
}).then(control => control.placeAt("content"))));
<script id="sap-ui-bootstrap"
src="https://openui5.hana.ondemand.com/resources/sap-ui-core.js"
data-sap-ui-libs="sap.ui.core, sap.m"
data-sap-ui-async="true"
data-sap-ui-theme="sap_fiori_3"
data-sap-ui-compatversion="edge"
data-sap-ui-excludejquerycompat="true"
data-sap-ui-xx-waitfortheme="init"
></script>
<body id="content" class="sapUiBody"></body>
Even if a link or button would be the better solution, here is my suggestion:
XML with custom attribute "url"
<Input enabled="true" editable="false" id="idInputStack" name="Stackoverflow" value="Example">
<customData>
<core:CustomData key="url" value="https://www.stackoverflow.com" writeToDom="true" />
</customData>
</Input>
Controller:
var oInput = this.getView().byId("idInputStack");
oInput.addEventDelegate({
onclick: function() {
document.location.href = oInput.data("url"); //get custom attribute url
}
})
First we would provide an id to the Input control so that we could refer to the same from the controller.
<Input enabled="true" editable="false" name="Stackoverflow" value="Example" id="myInputLinkId"/>
Now we could add the typical user click event to the Input field by attaching a Browser event to the same and place it in the onInit() hook method so that it is always accessible.
onInit: function () {
this.getView().byId("myInputLinkId").attachBrowserEvent('click',function(){ window.open("https://stackoverflow.com/");});
}

Flexible Column Layout Navigation (SAPUI5)

I've created an app with SAPUI5 that makes use of a Flexible Column Layout.
I'm trying to navigate between pages, but I'm having difficulty.
Here is the main xml view:
<mvc:View id="Main" controllerName="SAP.demo.controller.Main" xmlns:html="http://www.w3.org/1999/xhtml" xmlns:mvc="sap.ui.core.mvc"
displayBlock="true" xmlns="sap.f" xmlns:core="sap.ui.core" xmlns:m="sap.m">
<m:App id="idAppControl">
<m:pages>
<m:Page title="{i18n>title}">
<m:content>
<FlexibleColumnLayout id="fcl" initialMidColumnPage="start" layout="TwoColumnsBeginExpanded">
<beginColumnPages>
<m:Page title = "Master">
<m:content>
<Button text="Chart Button" press="displayChart"/>
</m:content>
</m:Page>
</beginColumnPages>
<midColumnPages>
<m:Page id="start" title = "Detail">
<m:content>
<core:Fragment fragmentName="SAP.demo.view.Start" type="XML"/>
</m:content>
</m:Page>
<m:Page id="charts" title="Charts">
<m:content>
<core:Fragment fragmentName="SAP.demo.view.Charts" type="XML"/>
</m:content>
</m:Page>
</midColumnPages>
</FlexibleColumnLayout>
</m:content>
</m:Page>
</m:pages>
</m:App>
I want to navigate from the start page to the charts page. The controller is as follows:
sap.ui.define([
"sap/ui/core/mvc/Controller"], function (Controller) {
"use strict";
return Controller.extend("SAP.demo.controller.Main", {
displayChart:function(oEvent){
this.byId("fcl").toMidColumnPage("charts");
}
});});
Can someone please advise as to what I'm doing wrong, because it stays on the start page even after I press the button.
This is because the real ID of the view is not "charts" but "__xmlview0--charts".
Be careful with the ID always and use the API method byId('theIDHere').
In your case use one of the following options:
displayChart:function(oEvent){
this.getView().byId("fcl").toMidColumnPage(this.getView().byId("charts"));
}
Or
displayChart:function(oEvent){
this.getView().byId("fcl").toMidColumnPage(this.getView().byId("charts").getId());
}
And also add the correct XML namespace to your button
<m:Button text="Chart Button" press="displayChart"/>
Managed to fix it with the following code:
displayChart: function () {
this.byId("fcl").toMidColumnPage(this.createId("charts"));
},

Concatenate data contained in a JSONModel

I am looking for a code, which allows me to concatenate two JSONModel attributes and then map to a table. For example if my JSON looks something like this.
[
{"FirstName","James", "LastName","Bond"},
{"FirstName","Robin", "LastName","Hood"},
{"FirstName","Peter", "LastName","Parker"}
]
I want my SAP UI table column to look something like
<table border=1>
<tr><th>Name</th></tr>
<tr><td>James Bond </td></tr>
<tr><td>Robin Hood </td></tr>
<tr><td>Peter Parker </td></tr>
</table>
First you have to put your json data into a model and assign that to your view or table (beware that your json data has syntax errors. below is the corrected version):
onInit:function(){
var data = [
{"FirstName":"James", "LastName":"Bond"},
{"FirstName":"Robin", "LastName":"Hood"},
{"FirstName":"Peter", "LastName":"Parker"}
];
this.getView().setModel(new sap.ui.model.json.JSONModel(data));
}
Second you need something like a table:
<t:Table rows="{/}">
<t:Column>
<Label text="Full Name"/>
<t:template>
<Label text="{FirstName} {LastName}"/>
</t:template>
</t:Column>
</t:Table>
The table binds its aggregation rows to your array (path '/'). For each item in the array the template will be cloned and displayed. The template is a label that displays firstname and lastname separated by space: Two databindings with relative path (relative to the array item of the row).
For this to work, you need to enable the "complex databinding" feature in the bootstrap script tag:
<script src="https://openui5.hana.ondemand.com/1.32.7/resources/sap-ui-core.js"
id="sap-ui-bootstrap"
data-sap-ui-theme="sap_bluecrystal"
data-sap-ui-libs="sap.m"
data-sap-ui-bindingSyntax="complex"></script>
You could also enable complex databinding by setting the required ui5 version to something up to date (or "edge" which is the newest available): data-sap-ui-compatVersion="edge"
sap.ui.core.mvc.Controller.extend("view1", {
onInit:function(){
var data = [
{"FirstName":"James", "LastName":"Bond"},
{"FirstName":"Robin", "LastName":"Hood"},
{"FirstName":"Peter", "LastName":"Parker"}
];
this.getView().setModel(new sap.ui.model.json.JSONModel(data));
}
});
var view = sap.ui.xmlview({viewContent: $("#view1").html()});
view.placeAt("content");
<script src="https://openui5.hana.ondemand.com/1.32.7/resources/sap-ui-core.js"
id="sap-ui-bootstrap"
data-sap-ui-theme="sap_bluecrystal"
data-sap-ui-libs="sap.m"
data-sap-ui-bindingSyntax="complex"></script>
<script type="sapui5/xmlview" id="view1">
<mvc:View xmlns="sap.m" xmlns:mvc="sap.ui.core.mvc" xmlns:t="sap.ui.table" controllerName="view1">
<t:Table rows="{/}">
<t:Column>
<Label text="Full Name"/>
<t:template>
<Label text="{FirstName} {LastName}"/>
</t:template>
</t:Column>
</t:Table>
</mvc:View>
</script>
<div id="content"></div>

How can I put icon and text in select items

I have an sap.m.Select control for a list of countries and I need to put flag near everyone. How can I do it? In XML, if it's possible.
Here is my XML code:
<m:Label text="{i18n>COUNTRY}" />
<m:Select width="100px"
fieldWidth="60%"
class="xcuiInputNoMargin"
enabled="{Edit>/EditOn}"
items="{countryList>/}"
>
<core:Item
key="{countryList>Country}"
text="{countryList>Country} - {countryList>Name}"
/>
</m:Select>
The sap.m.Select Object is restricted to display text (or Like #Jasper_07 said) icon only.
I think that the best solution for your problem is to use another object instead of your select. You can use Select Dialog and put inside whatever you want, like listItem with image.
This is an example:
<SelectDialog
noDataText="No Products Found"
title="Select Product"
search="handleSearch"
confirm="handleClose"
close="handleClose"
items="{
path: '/ProductCollection'
}" >
<StandardListItem
title="{Name}"
description="{ProductId}"
icon="{ProductPicUrl}"
iconDensityAware="false"
iconInset="false"
type="Active" />
</SelectDialog>
see link bellow
As of UI5 version 1.62, the following controls support displaying the icon on the left side.
sap.m.Select
sap.m.SelectList
And other controls based on the above mentioned ones, such as sap.m.ComboBox.
Here is an example:
sap.ui.getCore().attachInit(() => sap.ui.require([
"sap/ui/core/mvc/XMLView",
], XMLView => XMLView.create({
definition: `<mvc:View xmlns:mvc="sap.ui.core.mvc" height="100%">
<Select xmlns="sap.m" xmlns:core="sap.ui.core" class="sapUiTinyMargin">
<core:ListItem text="Paper plane" icon="sap-icon://paper-plane" />
<core:ListItem text="Stop Watch" icon="sap-icon://fob-watch" />
<core:ListItem text="Umbrella" icon="sap-icon://umbrella" />
</Select>
</mvc:View>`
}).then(view => view.placeAt("content"))));
<script id="sap-ui-bootstrap"
src="https://openui5nightly.hana.ondemand.com/resources/sap-ui-core.js"
data-sap-ui-libs="sap.ui.core, sap.m"
data-sap-ui-preload="async"
data-sap-ui-async="true"
data-sap-ui-theme="sap_belize"
data-sap-ui-compatversion="edge"
data-sap-ui-xx-waitfortheme="true"
data-sap-ui-xx-xml-processing="sequential"
></script>
<body id="content" class="sapUiBody sapUiSizeCompact"></body>
Keep in mind to use sap.ui.ListItem as an aggregation child in this case, instead of sap.ui.core.Item.
Limitation
Currently, the icon property only allows resource paths from "sap-icon://*". I.e. images, that are not icons such as country flags, are not possible. A possible workaround would be to make use of emoji flags as additionalText.
Otherwise, I'd recommend to look for alternative controls as shmoolki suggested.
from the documentation of sap.m.Select
The URI to the icon that will be displayed only when using the
IconOnly type
seems limiting, but try
<m:Select
type="sap.m.SelectType.IconOnly"
icon="sap-icon://cart">
</m:Select>

Strange sap.m.TextArea behavior inside a sap.m.List

I'm using sap.m.TextArea control inside sap.m.List where the values of each TextArea were mapped to a JSONModel. Here is the xml-view code:
<List id="otherPicList" growing="true" items="{ path : 'newRequest>/OtherPic' }" >
<items>
<CustomListItem type="Inactive">
<Image id="otherPic" src="{newRequest>pic}" width="90px" height="60px" />
<VBox>
<TextArea value="{newRequest>text}"/>
</VBox>
</CustomListItem>
</items>
</List>
When I start to type inside the sap.m.TextArea it freezes after the first character. I can only type one more character if I click outside the control and inside again. I think this bug happen because of the data binding inside a sap.m.List control.
If I set the value property without the model binding it works just fine. Is this a known bug or am I using wrong the control?
Data binding and growing list are not smart enough:
After the value of text area is changed and updated on the input event (after the key stroke), data binding is updated with the following diff:
1 item is deleted
2 item is updated
Growing List listens to data model change and does exactly the same: it deletes the changed item and creates it again.
When the text area inside of list item is deleted from DOM, focus is lost. The new text area does not get focus and any subsequent keystroke goes to nowhere.
I will report this issue to development.
It is working for my code snippet. Please run and check. Maybe there is something else causing your issue.
<script src="https://openui5.hana.ondemand.com/resources/sap-ui-core.js" id="sap-ui-bootstrap" data-sap-ui-theme="sap_bluecrystal" data-sap-ui-libs="sap.m,sap.ui.commons"></script>
<!-- define an XMLView - normally done in a separate file -->
<script id="view1" type="sapui5/xmlview">
<mvc:View xmlns:core="sap.ui.core" xmlns:layout="sap.ui.commons.layout" xmlns:mvc="sap.ui.core.mvc" xmlns="sap.m"
controllerName="my.own.controller" xmlns:html="http://www.w3.org/1999/xhtml">
<List id="otherPicList" items="{/test}" >
<items>
<CustomListItem type="Inactive">
<Image id="otherPic" src="{pic}" width="90px" height="60px" />
<VBox>
<TextArea value="{text}"/>
</VBox>
</CustomListItem>
</items>
</List>
</mvc:View>
</script>
<script>
sap.ui.controller("my.own.controller", {
onInit:function() {
var data = {test:[{text:"123",pic:"https://www.gravatar.com/avatar/e25560c87abbbb90143653d98c9924dc?s=128&d=identicon&r=PG"},{text:"456",pic:"https://www.gravatar.com/avatar/e25560c87abbbb90143653d98c9924dc?s=128&d=identicon&r=PG"},{text:"789",pic:"https://www.gravatar.com/avatar/e25560c87abbbb90143653d98c9924dc?s=128&d=identicon&r=PG"},{text:"101112",pic:"https://www.gravatar.com/avatar/e25560c87abbbb90143653d98c9924dc?s=128&d=identicon&r=PG"}]};
var oModel = new sap.ui.model.json.JSONModel();
oModel.setData(data);
this.getView().setModel(oModel);
}
});
var myView = sap.ui.xmlview("myView", {viewContent:jQuery('#view1').html()}); //
myView.placeAt('content');
</script>
<body class='sapUiBody'>
<div id='content'></div>
</body>
I found out the problem, check out your code snippet including the property growing="true" inside the sap.m.List control. This property cause the strange behavior I was talking about.
<script src="https://openui5.hana.ondemand.com/resources/sap-ui-core.js" id="sap-ui-bootstrap" data-sap-ui-theme="sap_bluecrystal" data-sap-ui-libs="sap.m,sap.ui.commons"></script>
<!-- define an XMLView - normally done in a separate file -->
<script id="view1" type="sapui5/xmlview">
<mvc:View xmlns:core="sap.ui.core" xmlns:layout="sap.ui.commons.layout" xmlns:mvc="sap.ui.core.mvc" xmlns="sap.m"
controllerName="my.own.controller" xmlns:html="http://www.w3.org/1999/xhtml">
<List id="otherPicList" growing="true" items="{/test}" >
<items>
<CustomListItem type="Inactive">
<Image id="otherPic" src="{pic}" width="90px" height="60px" />
<VBox>
<TextArea value="{text}"/>
</VBox>
</CustomListItem>
</items>
</List>
</mvc:View>
</script>
<script>
sap.ui.controller("my.own.controller", {
onInit:function() {
var data = {test:[{text:"123",pic:"https://www.gravatar.com/avatar/e25560c87abbbb90143653d98c9924dc?s=128&d=identicon&r=PG"},{text:"456",pic:"https://www.gravatar.com/avatar/e25560c87abbbb90143653d98c9924dc?s=128&d=identicon&r=PG"},{text:"789",pic:"https://www.gravatar.com/avatar/e25560c87abbbb90143653d98c9924dc?s=128&d=identicon&r=PG"},{text:"101112",pic:"https://www.gravatar.com/avatar/e25560c87abbbb90143653d98c9924dc?s=128&d=identicon&r=PG"}]};
var oModel = new sap.ui.model.json.JSONModel();
oModel.setData(data);
this.getView().setModel(oModel);
}
});
var myView = sap.ui.xmlview("myView", {viewContent:jQuery('#view1').html()}); //
myView.placeAt('content');
</script>
<body class='sapUiBody'>
<div id='content'></div>
</body>