The scrollToSection method does not scroll - sapui5

I have a ObjectPageLayout that is divided two sections, that it looks like:
<Page id="floatingFooterPage" enableScrolling="false" showNavButton="true" navButtonPress="onNavButtonPress">
<content>
<uxap:ObjectPageLayout id="ClassDetail" showHeaderContent="true">
<uxap:headerTitle>
<uxap:ObjectPageHeader></uxap:ObjectPageHeader>
</uxap:headerTitle>
<uxap:headerContent>
<f:SimpleForm editable="false" layout="ResponsiveGridLayout" singleContainerFullSize="false">
<f:content>
<Label text="{i18n>charsClass}"/>
<Text text="{ClassInfo>/classNum} {ClassInfo>/classNumDescr}"/>
<Label text="{i18n>charsClassType}"/>
<Text text="{ClassInfo>/classType} {ClassInfo>/classTypeText}"/>
</f:content>
</f:SimpleForm>
</uxap:headerContent>
<uxap:sections>
<uxap:ObjectPageSection title="{i18n>charsCharsSel}" id="SecChars">
<uxap:subSections>
<uxap:ObjectPageSubSection >
<uxap:blocks>
<mvc:XMLView width="100%" viewName="ch.mindustrie.ZMM_OBJECTS_CLASSES.view.CharacSelection" id="CharacSelection"/>
</uxap:blocks>
</uxap:ObjectPageSubSection>
</uxap:subSections>
</uxap:ObjectPageSection>
<uxap:ObjectPageSection title="{i18n>charsObject}" id="SecObject">
<uxap:subSections>
<uxap:ObjectPageSubSection >
<uxap:blocks>
<mvc:XMLView width="100%" viewName="ch.mindustrie.ZMM_OBJECTS_CLASSES.view.ObjectTable" id="ObjectTable"/>
</uxap:blocks>
</uxap:ObjectPageSubSection>
</uxap:subSections>
</uxap:ObjectPageSection>
<!-- <uxap:ObjectPageSection title="Sub classes" id="SecSub" visible="false">
<uxap:subSections>
<uxap:ObjectPageSubSection >
<uxap:blocks>
<mvc:XMLView width="100%" viewName="ch.mindustrie.ZMM_OBJECTS_CLASSES.view.ClassTree" id="SubTree"/>
</uxap:blocks>
</uxap:ObjectPageSubSection>
</uxap:subSections>
</uxap:ObjectPageSection>-->
</uxap:sections>
</uxap:ObjectPageLayout>
</content>
<footer>
<Toolbar>
<ToolbarSpacer/>
<Button id="FindObject" text="{i18n>charsObject}" press="onPress" type="Transparent"/>
</Toolbar>
</footer>
</Page>
I wanted to scroll to section SecChars programmatically and I have done as following:
_scrollToObjectSection: function () {
const oObjPage = this.byId("ClassDetail");
oObjPage.scrollToSection("SecObject", 0, 0);
}
But it does not work at all. What am I doing wrong?

Issues
The API scrollToSection awaits a global ID (the suffix "SecObject" alone is not enough). So it should be:
oObjPage.scrollToSection(this.byId("SecObject").getId());
That API, however, can be only successfully performed when the DOM of the ObjectPageLayout is fully ready. I added "fully" because calling scrollToSection within the onAfterRendering event delegate won't do anything either. There must be an additional timeout of about 450 ms. It's nowhere documented though how many milliseconds are actually required, and there is no public event for this case either.
Alternatives
Use setSelectedSection instead, as mentioned in the documentation topic Object Page Scrolling. The ObjectPageLayout will scroll to that section, but currently without any scrolling animation (iDuration = 0). The "selectedSection" is an association, hence, it can be also set within the view definition:
<uxap:ObjectPageLayout selectedSection="mySection">
<uxap:ObjectPageSection id="mySection">
Keep using scrollToSection but leverage the ⚠️ private event "onAfterRenderingDOMReady"(src) which is fired when the DOM is fully ready:
onInit: function() {
// ...
this.scrollTo(this.byId("mySection"), this.byId("myObjectPageLayout"));
},
scrollTo: function(section, opl) {
const id = section.getId();
const ready = !!opl.getScrollingSectionId(); // DOM of opl is fully ready
const fn = () => opl.scrollToSection(id);
return ready ? fn() : opl.attachEventOnce("onAfterRenderingDOMReady", fn);
},
The API getScrollingSectionId() returns a falsy value (currently "") if the DOM is not fully ready.

Related

Data Binding from TableSelectDialog to Form

I'm using TableSelectDialog to view some Carrier details. All I need is: If I select any item (row), then all the values from that row should get automatically populated to the form input fields.
In the attached image, if Carrier Name is selected from TableSelectDialog, then the remaining fields should be populated based on that value.
You can achieve the required functionality using the Binding context that you receive from the TableSelcect Dialog.
But for binding context to work properly, both form and the table select dialog should refer to the same Model.
Below is the working code:
VIEW.XML:
Has a Button to trigger the table select dialog.
Has a form.
<l:VerticalLayout class="sapUiContentPadding" width="100%">
<l:content>
<Button class="sapUiSmallMarginBottom" text="Show Table Select Dialog"
press="handleTableSelectDialogPress">
</Button>
<VBox class="sapUiSmallMargin">
<f:SimpleForm id="SimpleFormDisplay354">
<f:content>
<Label text="Supplier Name" />
<Text id="nameText" text="{SupplierName}" />
<Label text="Description" />
<Text text="{Description}" />
<Label text="ProductId" />
<Text text="{ProductId}" />
<Label text="Quantity" />
<Text id="countryText" text="{Quantity}" />
</f:content>
</f:SimpleForm>
</VBox>
</l:content>
</l:VerticalLayout>
Controller:
onInit: function () {
// set explored app's demo model on this sample
var oModel = new JSONModel(jQuery.sap.getModulePath("sap.ui.demo.mock", "/products.json"));
this.getView().setModel(oModel);
},
handleTableSelectDialogPress: function (oEvent) {
if (!this._oDialog) {
this._oDialog = sap.ui.xmlfragment("sap.m.sample.TableSelectDialog.Dialog", this);
}
this.getView().addDependent(this._oDialog);
// toggle compact style
this._oDialog.open();
},
handleClose: function (oEvent) {
var aContexts = oEvent.getParameter("selectedContexts");
if (aContexts && aContexts.length) {
// MessageToast.show("You have chosen " + aContexts.map(function(oContext) { return oContext.getObject().Name; }).join(", "));
this.byId('SimpleFormDisplay354').setBindingContext(aContexts[0]);
}
oEvent.getSource().getBinding("items").filter([]);
}
Now, we also have a Select dialog and on click of any Item we call method : handleClose
In handleClose, we obtain the clicked Item binding context and then tell the form : hey! refer to this context ( which is present in the model). Binding context has a path which tells the form from where to do the relative binding.
Please feel free to contact for more information.

oData binding to Simple Form

I'm creating a read only form that will be used to display a summary of information. I need to send a parameter to the backend first before getting the information but I don't seem to see that parameter is reaching it.
It does reach the entity set but it does not show the parameter. Am I binding correctly?
This is on the controller:
onInit: function() {
var urlEnding = "1000012233";
var oFilterDist = new sap.ui.model.Filter("ID",
sap.ui.model.FilterOperator.EQ, urlEnding);
var summaryText = this.getView().byId("summaryForm");
summaryText.bindElement({
path: "/SummaryScreenSet",
filters: [oFilterDist]
});
}
This is on the View
<VBox class="sapUiSmallMargin" fitContainer="true"
height="100%" width="100%" justifyContent="End"
displayInline="true" id="leftVBox" items="{/SummaryScreenSet}">
<items>
<f:SimpleForm editable="true" layout="ResponsiveGridLayout" id="summaryForm" columnsL="1" columnsXL="1" labelSpanL="5" title="Account Summary" labelSpanM="5">
<f:content>
<Label text="Status" id="__label6" design="Bold" class="sizeText"/>
<ObjectStatus text="{CONTRACT_STATUS}" id="__status6" state="Success" class="boldText"/>
<Label text="Permit Required" id="__label10" design="Bold" class="sizeText"/>
<Text text="{PERMIT_REQD}" id="__text32" wrapping="false" class="sizeText"/>
<Label text="Bill Date | Due Date" id="__label11" design="Bold" class="sizeText"/>
<Text text="{BILL_DATE} | {DUE_DATE}" id="__text33" wrapping="false" class="sizeText"/>
<Label text="Last Estimated Date | Next MR Date" id="__label17" design="Bold" class="sizeText"/>
<Text text="{LAST_PAYMENT_DATE} | {nextMRDate}" id="__text39" wrapping="false" class="sizeText"/>
</f:content>
</f:SimpleForm>
</items>
</VBox>
Going to assume you want a single, specific entry. In that case, what you're looking for is the Entity, not the EntitySet + filter. Coincidentally, here's one I wrote yesterday that works. I've changed the paths and ID's to reflect yours:
var form = this.getView().byId('summaryForm');
form.bindElement({
path: "/SummaryScreenSet('" + urlEnding + "')",
events: {
change: function() {
//triggers on error too I think
form.setBusy(false);
},
dataRequested: function() {
form.setBusy(true);
}
}
});
In that case you don't need the VBOX either, just the form. Don't forget to implement SUMMARYSCREEN_GET_ENTITY or whatever the method is on your DPC_EXT.
Edit: might want to set editable on the form to false, it shrinks the layout to suit text instead of inputs.

SAPUI5 ColumnListItem, icon need to be displayed on the left hand side

I'm using table and using this property.
<ColumnListItem type="Detail" detailPress="onShowItemEditDialog">
I want the place the icon on the left side.
Because I use responsivePopover.The popover is opening on the right side.
I think I will change the table elements in this popover.
Or is there another way to change the elements of the table?
What can be done for table edit?
Please help.
you can build your own ListItem.
<List headerText="Custom Content" mode="Delete" items="{path: '/ProductCollection'}" >
<CustomListItem>
<HBox>
<core:Icon size="2rem" src="sap-icon://attachment-photo" class="sapUiSmallMarginBegin sapUiSmallMarginTopBottom" />
<VBox class="sapUiSmallMarginBegin sapUiSmallMarginTopBottom" >
<Link text="{Name}" target="{ProductPicUrl}" press="handlePress"/>
<Label text="{ProductId}"/>
</VBox>
</HBox>
</CustomListItem>
</List>
This example is taken from: https://openui5.hana.ondemand.com/#/sample/sap.m.sample.CustomListItem/code
A little tweak worked for me. Use the below code appropriately.
onAfterRendering: function() {
$( "thead .sapMListTblNavCol" ).insertAfter( "thead .sapMListTblHighlightCol" );
$( "tbody .sapMListTblNavCol" ).insertAfter( "tbody .sapMListTblHighlightCell" );
},

UI5 - How to get Marquee Text

I was researching whether UI5 has any in-built functionality to provide marquee text but I cold not find any.
It seems that I may have to use jQuery or pure javascript to implement one. But if anyone already has any solution for this, can you please share it.
My XML View:
<mvc:View xmlns:mvc="sap.ui.core.mvc" xmlns="sap.m"controllerName="marquee.MarqueeDemo">
<Page title="Marquee Demo">
<content>
<FlexBox height="100%" width="100%">
<items>
<FlexBox direction="Column" justifyContent="Start" >
<Label id="idScrollText" design="Bold" text = "Hello World"></Label>
<Text text="How are you???"></Text>
</FlexBox>
</items>
</FlexBox>
</content>
</Page>
</mvc:View>
I would like ot have text of idScrollText to have scrolling effect like Marquee text of HTML.
WHat would be the optimal way to achieve that in Ui5?
Thanks !
I was able to achieve Marquee text using sap.ui.core.HTML
My View:
<FlexBox >
<core:HTML id = "idScrollText" width="100%"></core:HTML>
</FlexBox>
My Controller:
// Scrolling Text
var sPath = "Model/scrolltextdata.json";
$.ajax({
url: sPath,
success: function (result, status, xhr) {
var oDataText = result.Rowsets.Rowset[0].Row;
that.byId("idScrollText").setContent('<marquee style="font-size: 3.0rem;color: white;font-weight: bold">' + oDataText[0].InputText +'</marquee>');
}
});

How I can set the value of element of a fragment?

This is my fragment,
The fragment not have a controller
<core:FragmentDefinition
xmlns="sap.m"
xmlns:core="sap.ui.core">
<Dialog
title="Invio report via mail">
<content>
<FlexBox
alignItems="Start"
justifyContent="Center">
<items>
<TextArea id="idMailReport" value="themail.mail.it" rows="1" cols="50" />
</items>
</FlexBox>
</content>
<beginButton>
<Button text="Ok" press="onDialogOkButton" />
</beginButton>
<endButton>
<Button text="Close" press="onDialogCloseButton" />
</endButton>
</Dialog>
</core:FragmentDefinition>
Ho I can set che value of TextArea element?
I try to set it from a controller where I call the fragment:
var dialogFrafment = sap.ui.xmlfragment(
"dialogFragment",
"appIntra.fragment.dialog",
this // associate controller with the fragment
);
this.getView().addDependent(dialogFrafment);
dialogFrafment.open();
this.byId("idMailReport").setValue("initial.mail.com");
Can you help me?
please try
sap.ui.getCore().byId("idMailReport").setValue("initial.mail.com");
it should work.
Here is the official document.
I solve it!
var dialogFrafment = sap.ui.xmlfragment(
"appIntra.fragment.dialog",
this.getView().getController() // associate controller with the fragment
);
my problem is that i had set a name of a fragment: "dialogFragment"
Whitout it all work! ;)
A bit outdated, but might be useful for others. When you reuse your fragment inside a view, giving it unique id like:
var dialogFrafment = sap.ui.xmlfragment(
"dialogFragment", // this is fragment's ID
"appIntra.fragment.dialog",
...
);
retrieving id of your nested control goes like:
this.byId(sap.ui.getCore().Fragment().createId("dialogFragment", "idMailReport"));
That way, your prepend fragment's id to your control's id.