Error "Cannot add direct child without default aggregation defined for control ..." - sapui5

I am getting the error "Cannot add direct child without default aggregation defined for control sap.m.Label". Not sure what this means. Here is my fragment:
<core:FragmentDefinition xmlns="sap.m" xmlns:core="sap.ui.core" xmlns:f="sap.f">
<ResponsivePopover id="popover" title="{Name}" class="sapUiPopupWithPadding" placement="Bottom">
<beginButton>
<Button id="submit" text="{i18n>submit}" press="onSubmit" class="sapUiTinyMargin"/>
</beginButton>
<content>
<f:GridContainer>
<f:layout>
<f:GridContainerSettings rowSize="5rem" columnSize="8rem" gap="1rem"/>
</f:layout>
<f:layoutS>
<f:GridContainerSettings rowSize="5rem" columnSize="10rem" gap="0.5rem"/>
</f:layoutS>
<f:layoutXS>
<f:GridContainerSettings rowSize="5rem" columnSize="10rem" gap="0.5rem"/>
</f:layoutXS>
<Label text="{i18n>req}" required="true">
<f:layoutData>
<f:GridContainerItemLayoutData columns="3"/>
</f:layoutData>
</Label>
<Label id="txt" text="{i18n>cat}" required="true">
<f:layoutData>
<f:GridContainerItemLayoutData columns="3"/>
</f:layoutData>
</Label>
<RadioButton id="rbtn1" text="{i18n>grq}">
<f:layoutData>
<f:GridContainerItemLayoutData columns="4"/>
</f:layoutData>
</RadioButton>
<RadioButton id="rbtn2" text="{i18n>frq}">
<f:layoutData>
<f:GridContainerItemLayoutData columns="4"/>
</f:layoutData>
</RadioButton>
<TextArea id="txtarea" value="" placeholder="{i18n>typeq}" growing="true" growingMaxLines="10" width="100%">
<f:layoutData>
<f:GridContainerItemLayoutData columns="7"/>
</f:layoutData>
</TextArea>
<Text text="{i18n>note}">
<f:layoutData>
<f:GridContainerItemLayoutData columns="7"/>
</f:layoutData>
</Text>
</f:GridContainer>
</content>
</ResponsivePopover>
</core:FragmentDefinition>
Expected result is the fragment will load with out errors.

The named aggregation must have the same namespace as the parent tag.
The namespace of the parent control tag and the aggregation tag must be the same. (Source)
In your case, the issue is in <SomeSapMControl><f:layoutData>. Remove the f: in <f:layoutData> so that it matches with the parent's (default) namespace.
sap.ui.require([
"sap/ui/core/Core"
], Core => Core.attachInit(() => sap.ui.require([
"sap/ui/core/Fragment"
], Fragment => Fragment.load({
definition: `<f:GridContainer xmlns:f="sap.f" xmlns="sap.m">
<Label text="Label within GridContainer">
<layoutData>
<f:GridContainerItemLayoutData columns="3"/>
</layoutData>
</Label>
</f:GridContainer>`
}).then(control => control.placeAt("content")))));
<script id="sap-ui-bootstrap" src="https://ui5.sap.com/resources/sap-ui-core.js"
data-sap-ui-libs="sap.m,sap.f,sap.ui.layout"
data-sap-ui-theme="sap_fiori_3"
data-sap-ui-async="true"
data-sap-ui-compatversion="edge"
data-sap-ui-xx-waitfortheme="init"
></script>
<body id="content" class="sapUiBody"></body>
"Cannot add direct child without default aggregation defined for control sap.m.Label". Not sure what this means.
Within control definition, control developers can assign a default aggregation so that application developers can add children without having to put an aggregation name explicitly in the XML view definition. An example of this is sap.f.GridContainer. Its default aggregation is items.src Hence, you won't need to add <f:items> to add children there (See my code snippet above).
If, however, the control has no default aggregation and the child node name matches with none of the named aggregations, the XML processor will throw the above error.

The sap.m.Label and the other controls cannot be used inside sap.f.Gridcontainer directly. You'll need to place them inside <f:items> first.
From the documentation: https://sapui5.netweaver.ondemand.com/sdk#/api/sap.f.GridContainer%23overview
<f:GridContainer>
<f:layout>
<f:GridContainerSettings rowSize="5rem" columnSize="5rem" gap="1rem" />
</f:layout>
<f:layoutS>
<f:GridContainerSettings rowSize="4rem" columnSize="4rem" gap="0.5rem" />
</f:layoutS>
<f:items>
<GenericTile header="Sales Fulfillment">
<layoutData>
<f:GridContainerItemLayoutData rows="2" columns="2" />
</layoutData>
</GenericTile>
<w:Card manifest="url-to-manifest">
<w:layoutData>
<f:GridContainerItemLayoutData rows="6" columns="3" />
</w:layoutData>
</w:Card>
<Panel>
<layoutData>
<f:GridContainerItemLayoutData columns="4" />
</layoutData>
<Text text="Sales information" />
</Panel>
</f:items>
</f:GridContainer>

Related

How to have multiple dialogs in a single fragment

I have been working on dialog in fragment , for a sample :
test.fragment.xml :
<core:FragmentDefinition
xmlns="sap.m"
xmlns:f="sap.ui.layout.form"
xmlns:core="sap.ui.core">
<Dialog title="P Selection" id='TestDialog1'>
<content>
<f:SimpleForm id="SimpleFormDisplay354"
minWidth="1024"
maxContainerCols="2"
editable="false"
layout="ResponsiveGridLayout"
title=""
labelSpanL="3"
labelSpanM="3"
emptySpanL="4"
emptySpanM="4"
columnsL="1"
columnsM="1">
<f:content>
<Label text="DC" />
<Select id='Test1DCId'
forceSelection="false"
items="{
path: '/P/DC',
sorter: { path: 'Name' }
}">
<core:Item key="{key}" text="{value}" />
</Select>
<Label text="Quantity" />
<Select id='Test1Quantity'
forceSelection="false"
items="{
path: '/P/Quantity',
sorter: { path: 'Name' }
}">
<core:Item key="{key}" text="{value}" />
</Select>
</f:content>
</f:SimpleForm>
</content>
<buttons>
<Button text="OK" press="onTest1OkButtonPress" />
</buttons>
<buttons>
<Button text="Cancel" press="onTest1CancelButtonPress" />
</buttons>
</Dialog>
</core:FragmentDefinition>
In test.view.xml:
The view part when I want to open a dialog is as:
<m:Select id="Gu" items="{/Gu/GList}" change="onTestPress">
<c:Item key="{key}" text="{value}" />
<m:layoutData>
<l:GridData span="L2 M2 S2"/>
</m:layoutData>
</m:Select>
In test.Controller.js:
onTestPress: function () {
this.ADD = 'Yes';
if (!this.byId("TestDialog1")) {
this._oDialog = sap.ui.xmlfragment("test", this);
this.getView().addDependent(this._oDialog);
}
this._oDialog.open();
},
here in similar way may I how can I use multiple dialogs in the same fragment ? Is this possible ?
I have tried as giving another dialog with different ID TestDialog2 ,
And in view some test button and on press , i need to open a Dialog and i tried as:
onTestButtonPress: function () {
this.ADD = 'Yes';
if (!this.byId("TestDialog2")) {
this._oDialog1 = sap.ui.xmlfragment("test1", this);
this.getView().addDependent(this._oDialog1);
}
this._oDialog1.open();
},
But this doesn't work as expected also Throws error Error: Error: adding element with duplicate id.....
I have searched Doc's and many examples but i have been stuck finding an example which shows this use case......
Any help or a sample or a guiding link is much appreciated , TIA

CanĀ“t to bind or show data from ModelData.read to form in SapUi5

i have a big trouble that's freaking me out, check it out:
This is my xml for a View, program is divided in two differents Views, first of them, a table with navigation and second one is the details, involved in a form.
<mvc:View xmlns:core="sap.ui.core" xmlns:mvc="sap.ui.core.mvc" xmlns="sap.m" controllerName="Hello_World.Hello_World.controller.View2"
xmlns:html="http://www.w3.org/1999/xhtml" xmlns:form="sap.ui.layout.form">
<App>
<pages>
<Page title="Detalles" showHeader="true">
<Button type="Back" press="patras" tooltip="test"/>
<VBox>
</VBox>
<form:SimpleForm id="formPruebas" maxContainerCols="2" layout="ResponsiveGridLayout" labelSpanL="5" labelSpanM="4" labelSpanS="6" title="Formulario">
<Label text="CustomerID"/>
<Text text="{jsonmodel>CustomerID}"/>
<Label text="CompanyName"/>
<Text text="{CompanyName}"/>
<Label text="ContactTitle" />
<Text text="{ContactTitle}"/>
<Label text="Adress"/>
<Text text="{Adress}"/>
<Label text="City"/>
<Text text="{City}"/>
<Label text="PostalCode"/>
<Text text="{PostalCode}"/>
<Label text="Country" />
<Text text="{i18n>Country}"/>
<Button text="Aceptar" type="Accept">
<layoutData>
<FlexItemData growFactor="1" />
</layoutData>
</Button>
<Button text="Editar" width="100px">
<layoutData>
<FlexItemData growFactor="1" />
</layoutData>
</Button>
</form:SimpleForm>
</Page>
</pages>
</App>
Alright so this is my controller:
onInit: function() {
var oRouter = sap.ui.core.UIComponent.getRouterFor(this);
oRouter.getRoute("View2").attachMatched(this._onRouteMatched, this);
},
_onRouteMatched: function(oEvent) {
var idDevuelto = oEvent.getParameter("arguments").data;
var idCompleto = "/Customers('" + idDevuelto + "')";
//var oForm = this.getView().byId("formPruebas");
var oForm = this.getView().byId("formPruebas");
var serviceUrl = "myurl";
var oModelData = new sap.ui.model.odata.ODataModel(serviceUrl,{
JSON:true,
useBatch: false
});
oModelData.read(idCompleto, {
success: function (oData) {
sap.m.MessageToast.show(oData.CustomerID);
var oModel = new JSONModel(oData.results);
oForm.setModel(oModel.results);
},
error: function (oError) {
sap.m.MessageToast.show("No funca");
}
});
},
However the result is not showing on my view when i run the program, any idea?
PD: I'm pretty noob on sapui5
Finally i found the solution of the problem, if you check the XML code at the beginning of the question , you realize there is not path in Form element.
In mi first view i have a table with id and a PATH which i don't have in the Form so the fastest way i solve it is to put in the XML a slash, an example:
<form:SimpleForm id="formPruebas" maxContainerCols="2" layout="ResponsiveGridLayout" labelSpanL="5" labelSpanM="4" labelSpanS="6" title="Formulario">
<Label text="CustomerID"/>
<Text text="{/CustomerID}"/> // the slash i mean
With that fix, i only do oForm.setModel(oModel) so everything is connected and works
fine, i want to share this information if more people deal with the same error as i did.
Thanks all ideas.

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 Googlemaps library : multiple directions via list

enter image description here
<openui5.googlemaps:Waypoint id = "waypoint" location="{location}"/>
<!--<openui5.googlemaps:Waypoint location="Talod"/>-->
</openui5.googlemaps:waypoints>
</openui5.googlemaps:Directions>
</openui5.googlemaps:directions>
</openui5.googlemaps:Map>
<Input id="start" value="{start}" width="180px" placeholder="Start Address">
<layoutData>
<FlexItemData growFactor="2"/>
</layoutData>
</Input>
<Input id="end" value="{end}" width="180px" placeholder="End Address">
<layoutData>
<FlexItemData growFactor="2"/>
</layoutData>
</Input>
<Button text="Find distance" type="Emphasized" width="170px" press="go"></Button>
</content>
</Page>
</pages>
</App>
Above code is of the view.I am adding code of controller but could not able to add it.I am having desired result for one start and end address but I could not able to have multiple lines for start and end address on same map.I need multiple lines with pin points as shown in image.

ZK framework getting value of a component on zul page

I am trying to get the value of a textbox on a zul page by using some kind of getValue method. I should handle this on the zul page, not on a controller. I need to assign a listbox cell (which is the first cell of the list box below) with a value coming from the textbox.
<listcell>
<label value="" />
</listcell>
<listcell>
<toolbarbutton visible="true"
image="/resources/images/icons/1616/page_text.gif" />
</listcell>
<listcell>
<label value="#{file.name}" />
</listcell>
<listcell>
<toolbarbutton forward="onClick=onRemoveMultipleFiles"
visible="true" id="newFileAndCommentRemove" image="/resources/images/icons/1616/delete.png" />
</listcell>
</listitem>
If what you want is that after the textbox is filled then the first cell will fill with its value you can do it like this:
put an id into the label in the cell
put an onChange operation in the textbox so when the textbox change you can put its value into the cell
like this:
<textbox id="textbox" onChange="label.setValue(self.getValue())"/>
<listbox id="newFileAndComment">
<listhead>
<listheader label="1" width="30px" />
</listhead>
<listitem self="#{each=file}">
<listcell>
<label id="label"/>
</listcell>
</listitem>