I am working on a SAPUI5 application. I have an XML view which contains an XML Fragment and a Button to save.
The fragment contains a few controls like drop-down, text field and a table. When I press on the save button, I need to get all the rows in the table and call an OData update service.
The problem is in the onSave
method in view controller. I get an error while accessing the table using its ID. Can anyone help me and advice how can I access controls used in fragments by their ID in the controller?
Here is the code snippet:
View:
<mvc:View xmlns:mvc="sap.ui.core.mvc" xmlns:core="sap.ui.core" xmlns:form="sap.ui.layout.form" xmlns="sap.m"> <Page> ... <form:SimpleForm> <core:Fragment id ="fr1" fragmentName="first" type="XML" /> <Button id="id1" press="onSave" /> </form:SimpleForm> </Page> </mvc:View>
Fragment definition:
<core:FragmentDefinition xmlns="sap.m" xmlns:core="sap.ui.core"> <Table id="tab1" mode="MultiSelect"> ... </Table> </core:FragmentDefinition>
Controller:
sap.ui.controller("view", { onSave: function() { //var tab = this.getView().byId("tab1"); // Not working var tab = sap.ui.getCore().byId("tab1"); // Not working }, // ... });
Fragment is embedded into a view if it is part of the static view declaration. Controls inside this fragment are prefixed with view's ID. This is the same as controls which are directly placed in a view. In this most simple case, you can retrieve controls just as you retrieve controls inside a view.
If you need an id property for your fragment then it is possible to get a control from the fragment by generating the fragment's ID with this. getView(). createId() and the method sap.
Below is the code : onAddMovie: function() { var view = this. getView(); var createDialog = view. byId("CreateDialog"); var oDummyController = { // This is when I clicked the Submit button in dialog submitDialog: function() { var user = sap.
With the help of id, we can easily call the control of the fragment from the view controller file and in below code we try to achieve the same. In the controller. js file first define the Fragment and add the object to the function parameter. Next, add the function onOpenDialog.
Accessing controls inside a fragment depends on how your fragment was created in the first place. Here is a list of cases with respective API to use to get the control reference.
Given:
this
as a reference to the current controller instanceFragment
required from the module sap/ui/core/Fragment
<MyControl id="controlId"/>
in the fragment definitionthis.byId("controlId");
... if the fragment was created with the view ID (either indirectly or directly):
this.loadFragment({ name: "..." }); // id: view ID given by default, API since 1.93
<!-- In the view embedding the fragment declaratively: --> <core:Fragment fragmentName="..." type="XML"/><!-- id = view ID given by default -->
Fragment.load({ // API since 1.58 id: this.getView().getId(), name: "...", controller: this, });
sap.ui.xmlfragment(this.getView().getId(), "...", this); // Deprecated
Resulting global ID: "componentId---viewId--controlId"
*
this.byId(Fragment.createId("fragmentId", "controlId"));
... if a fragment ID was given with the view ID combined:
this.loadFragment({ id: this.createId("fragmentId"), name: "..." });
<core:Fragment id="fragmentId" fragmentName="..." type="XML"/>
Fragment.load({ id: this.createId("fragmentId"), name: "...", controller: this, });
sap.ui.xmlfragment(this.createId("fragmentId"), "...", this); // Deprecated
Resulting global ID: "componentId---viewId--fragmentId--controlId"
*
Fragment.byId("fragmentId", "controlId");
... if only the fragment ID was given without combining with the view ID:
this.loadFragment({ id: "fragmentId", name: "...", autoPrefixId: false, // Explicitly disabled view ID as prefix });
Fragment.load({ id: "fragmentId", name: "...", controller: this, });
sap.ui.xmlfragment("fragmentId", "...", this); // Deprecated
Resulting global ID: "fragmentId--controlId"
*
sap.ui.getCore().byId("controlId");
... if no ID to prefix was given. The below settings are not recommended as all control IDs within the fragment definition will be registered globally without any prefix. The uniqueness of the IDs is not guaranteed!
this.loadFragment({ name: "...", autoPrefixId: false }); // Not recommended if no id
Fragment.load({ name: "...", controller: this }); // Not recommended
sap.ui.xmlfragment("demo.view.MyFragment", this); // Deprecated
Resulting global ID: "controlId"
* Do not rely on the resulting global ID, for example, concatenating ID parts manually in your application. Always use the dedicated APIs mentioned above such as byId
and createId
. See Stable IDs: All You Need to Know.
Instead of accessing the fragment controls directly, consider manipulating the UI via data binding. ⇒ Changes in the model will be reflected in the UI automatically, and, if two-way binding is enabled, user inputs from the UI will be stored in the model directly.
No need to use byId
or createId
.
Looking at the OpenUI5 code at GitHub, it seems that the Fragment delegates the local ID generation to the containing view if the <Fragment/>
itself does not have an explicit ID.
So your code this.getView().byId("tab1")
should work as soon as you remove the id="fr1"
attribute from your <Fragment/>
element.
When using explicit IDs there is a static Fragment.byId
method to retrieve the control. I guess you have to use it like this:
// Fragment required from "sap/ui/core/Fragment" var fragmentId = this.getView().createId("fr1"); var tab = Fragment.byId(fragmentId, "tab1");
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With