AEM anchor link css class - aem

I managed to display the anchor link option in the RTE for the text component for authoring. Because on our website we have a fixed header, it's offsetting the anchor link.
I could resolve the issue with CSS but supporting that I'd need a CSS class on the anchor links. Could someone advise how to add a 'link-anchor' class to the anchor links in AEM?
<links jcr:primaryType="nt:unstructured" features="[modifylink,unlink,anchor]" />
<uiSettings jcr:primaryType="nt:unstructured">
<cui jcr:primaryType="nt:unstructured">
<inline jcr:primaryType="nt:unstructured" toolbar="[undo#undo,undo#redo,#paraformat,#styles,-,#format,experience-aem#colorPicker,-,#justify,-,#lists,-,subsuperscript#subscript,subsuperscript#superscript,links#modifylink,links#unlink,links#anchor,edit#cut,edit#copy,edit#paste-plaintext,edit#paste-wordhtml,misctools#specialchars,misctools#sourceedit,-,table#table]">
<popovers jcr:primaryType="nt:unstructured">
<format
jcr:primaryType="nt:unstructured"
items="[format#bold,format#italic,format#underline]"
ref="format"/>
<justify
jcr:primaryType="nt:unstructured"
items="[justify#justifyleft,justify#justifycenter,justify#justifyright]"
ref="justify"/>
<lists
jcr:primaryType="nt:unstructured"
items="[lists#unordered,lists#ordered,lists#outdent,lists#indent]"
ref="lists"/>
<styles
jcr:primaryType="nt:unstructured"
items="styles:getStyles:styles-pulldown"
ref="styles"/>
<paraformat
jcr:primaryType="nt:unstructured"
items="paraformat:getFormats:paraformat-pulldown"
ref="paraformat"/>
</popovers>
</inline>
<dialogFullScreen jcr:primaryType="nt:unstructured" toolbar="[undo#undo,undo#redo,#paraformat,-,#format,experience-aem#colorPicker,-,#justify,-,#lists,-,subsuperscript#subscript,subsuperscript#superscript,links#modifylink,links#unlink,links#anchor,edit#cut,edit#copy,edit#paste-plaintext,edit#paste-wordhtml,misctools#specialchars,misctools#sourceedit,-,table#table]">
<popovers jcr:primaryType="nt:unstructured">
<format
jcr:primaryType="nt:unstructured"
items="[format#bold,format#italic,format#underline]"
ref="format"/>
<justify
jcr:primaryType="nt:unstructured"
items="[justify#justifyleft,justify#justifycenter,justify#justifyright]"
ref="justify"/>
<lists
jcr:primaryType="nt:unstructured"
items="[lists#unordered,lists#ordered,lists#outdent,lists#indent]"
ref="lists"/>
<styles
jcr:primaryType="nt:unstructured"
items="styles:getStyles:styles-pulldown"
ref="styles"/>
<paraformat
jcr:primaryType="nt:unstructured"
items="paraformat:getFormats:paraformat-pulldown"
ref="paraformat"/>
</popovers>
</dialogFullScreen>
<tableEditOptions
jcr:primaryType="nt:unstructured"
toolbar="[table#insertcolumn-before,table#insertcolumn-after,table#removecolumn,-,table#insertrow-before,table#insertrow-after,table#removerow,-,table#mergecells-right,table#mergecells-down,table#mergecells,table#splitcell-horizontal,table#splitcell-vertical,-,table#selectrow,table#selectcolumn,-,table#ensureparagraph,-,table#modifytableandcell,table#removetable,-,undo#undo,undo#redo,-,table#exitTableEditing,-]"/>
</cui>
</uiSettings>

Your usecase is a simplified version of this use case - http://experience-aem.blogspot.com/2017/09/aem-63-touch-ui-extend-rich-text-link-dialog-add-rel-select.html.
Instead of adding drop down and 2 way mapping, you just need to hard code class name during save. This worked for me:
Create a clientlib - /apps/myproj/clientlibs/authoring
Add categories cq.authoring.dialog
Add a new js file as rte-link-class.js. Any name and give same name inside js.txt
Add below code in the rte-link-class.js
(function ($) {
"use strict";
var _ = window._,
Class = window.Class,
CUI = window.CUI,
RTE_LINK_DIALOG = "rtelinkdialog";
if (CUI.rte.ui.cui.CuiDialogHelper.eaemExtended) {
return;
}
var EAEMLinkBaseDialog = new Class({
extend: CUI.rte.ui.cui.CQLinkBaseDialog,
toString: "EAEMLinkBaseDialog",
initialize: function (config) {
this.superClass.initialize.call(this, config);
},
dlgToModel: function () {
this.superClass.dlgToModel.call(this);
this.objToEdit.attributes["class"] = "custom-anchor-link";
},
dlgFromModel: function () {
this.superClass.dlgFromModel.call(this);
},
});
CUI.rte.ui.cui.CuiDialogHelper = new Class({
extend: CUI.rte.ui.cui.CuiDialogHelper,
toString: "EAEMCuiDialogHelper",
instantiateDialog: function (dialogConfig) {
var type = dialogConfig.type;
if (type !== RTE_LINK_DIALOG) {
this.superClass.instantiateDialog.call(this, dialogConfig);
return;
}
var $editable = $(this.editorKernel.getEditContext().root),
$container = CUI.rte.UIUtils.getUIContainer($editable),
dialog = new EAEMLinkBaseDialog();
dialog.attach(dialogConfig, $container, this.editorKernel);
return dialog;
},
});
CUI.rte.ui.cui.CuiDialogHelper.eaemExtended = true;
})(jQuery);
After adding link from RTE, it gets saved in jcr like this

Related

Retrieving values from multifield component in HTL in AEM 6.5

I have a multifield component following this format
<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:nt="http://www.jcp.org/jcr/nt/1.0"
jcr:primaryType="nt:unstructured"
jcr:title="Awards List"
sling:resourceType="cq/gui/components/authoring/dialog">
<content
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/container">
<layout
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/tabs"
type="-nav"/>
<items jcr:primaryType="nt:unstructured">
<awards
jcr:primaryType="nt:unstructured"
jcr:title="Awards Properties"
sling:resourceType="granite/ui/components/foundation/section">
<layout
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/fixedcolumns"/>
<items jcr:primaryType="nt:unstructured">
<column
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/container">
<items jcr:primaryType="nt:unstructured">
<description
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/textarea"
fieldLabel="Description"
name="./description"/>
<awards
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/multifield"
composite="{Boolean}true"
fieldLabel="Awards">
<field
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/container"
name="./awards">
<items jcr:primaryType="nt:unstructured">
<column
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/container">
<items jcr:primaryType="nt:unstructured">
<awardtype
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/select"
fieldDescription="Select Award Type"
fieldLabel="Award Type"
name="./type">
<items jcr:primaryType="nt:unstructured">
<gold
jcr:primaryType="nt:unstructured"
text="gold"
value="gold"/>
<silver
jcr:primaryType="nt:unstructured"
text="silver"
value="silver"/>
<bronze
jcr:primaryType="nt:unstructured"
text="bronze"
value="bronze"/>
<other
jcr:primaryType="nt:unstructured"
text="other"
value="other"/>
</items>
</awardtype>
<award
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/textfield"
fieldDescription="Name of Award"
fieldLabel="Award Name"
name="./award"/>
</items>
</column>
</items>
</field>
</awards>
</items>
</column>
</items>
</awards>
</items>
</content>
</jcr:root>
And I'm trying to just output the contents of the multifield into a list.
And I'm attempting to do so with
<ul data-sly-list="${properties.awards}">
<li>${item.type}</li>
</ul>
But it doesn't render anything. As a test I did
<ul data-sly-list="${[1,2,3,4]}">
<li>${item}</li>
</ul>
Which did work. Looking online I found resources like https://helpx.adobe.com/experience-manager/using/aem65_coral_resourcetypes.html#UseaDataSourceObjecttopopulateaSelectfield
But they seem to be using Java classes to generate the multifield and I'm hoping that's not necessary. I don't need any extra logic all I'm trying to do is display the values of the fields.
Is there something I'm doing wrong? Does using multifields require making a Java class to handle it?
EDIT: I've tried getting the content using a javascript object by having a js file with the contents
"use strict";
use(function () {
var description = granite.resource.properties["description"];
var awards = granite.resource.properties["awards"];
return {
description: description,
};
});
and using
<div data-sly-use.awardsObject="awardslist.js">
<p>
${awardsObject.description}
${awardsObject.awards}
</p>
</div>
But I can't get awards to return anything. I've tried stringifying the awards object to see if I get any data, but I get none.
It is probably because you are using a composite multifield (look at the property composite="{Boolean}true" against the multifield) which generally handles the form content as composite and creates child nodes under the current component to hold the property values.
Quoting from the docs
true to handle the form content value as composite.
Composite multifield supports nesting another multifield (composite or
not). However, non-composite one doesn’t support nesting.
For example, given the name property of field is addresses, and the
descendant fields have following name property values:
street1
street2
postcode
city/name
city/state
city/country/name
gps/lat
gps/long
it would save the following structure in the repository:
+ addresses + item0
- street1
- street2
- postcode
+ city
- name
- state
+ country
- name
+ gps
- lat
- long + item1
- street1
- street2
- postcode
+ city
- name
- state
+ country
- name
+ gps
- lat
- long
Since the properties object only holds the properties of the current resource, ${properties.awards} would be null and hence it doesn't display anything.
It would be easier to create either a Sling Model or Java / Javascript Use API class to get the list and then use it in the HTL file.
Sample JS Use API
"use strict";
use(function () {
var awards = resource.getChild("awards").listChildren();
return {
awards: awards,
};
});
Sample HTL code
<sly data-sly-use.children="children.js">
<ul data-sly-list.award="${children.awards}">
<li>${award.type}</li>
</ul>
<sly>
Kindly note that the properties object, which is an instance of ValueMap only returns the properties of the current resource. Since the multifield values are stored as child resources, you need to access the child resource first before accessing its properties.

Why does my searchfield work on one table but not at another one?

i got some wired problems..
<core:FragmentDefinition xmlns="sap.ui.table" xmlns:dnd="sap.ui.core.dnd" xmlns:mvc="sap.ui.core.mvc" xmlns:core="sap.ui.core"
xmlns:m="sap.m">
<m:Dialog id="AuftragDialog" title="Aufträge">
<!-- <m:beginButton>
<m:Button text="Fertig" press=".onSaveAufträge"/>
</m:beginButton> -->
<m:endButton>
<m:Button text="Zurück" press=".onCancelAufträge"/>
</m:endButton>
<m:content>
<m:HBox renderType="Bare">
<Table id="table1" selectionMode="MultiToggle" rows="{ path: 'Hallo>/results' }" visibleRowCount="10">
<extension>
<m:OverflowToolbar>
<m:Title text="Alle Aufträge"/>
<m:ToolbarSpacer/>
<m:SearchField id="allOrder" liveChange="onFilterAllOrder">
<m:layoutData><m:OverflowToolbarLayoutData minWidth="25%" maxWidth="30%" /></m:layoutData>
</m:SearchField>
</m:OverflowToolbar>
</extension>
<columns>
<Column >
<m:Text text="Auftrags Nummer"/>
<template>
<m:Text text="{Hallo>Aufnr}" wrapping="false"/>
</template>
</Column>
<Column filterProperty="Ktext">
<m:Text text="Auftrag"/>
<template>
<m:Text text="{Hallo>Ktext}" wrapping="false"/>
</template>
</Column>
</columns>
<dragDropConfig>
<dnd:DragInfo groupName="moveToTable2" sourceAggregation="rows" dragStart="onDragStart"/>
<dnd:DropInfo groupName="moveToTable1" drop="onDropTable1"/>
</dragDropConfig>
</Table>
<m:VBox justifyContent="Center" class="sapUiTinyMarginBeginEnd">
<m:Button class="sapUiTinyMarginBottom" icon="sap-icon://navigation-right-arrow" tooltip="Move to selected" press="moveToTable2"/>
<m:Button icon="sap-icon://navigation-left-arrow" tooltip="Move to available" press="moveToTable1"/>
</m:VBox>
<Table id="table2" selectionMode="MultiToggle" rows="{/ZAUFK_VARSet}" visibleRowCount="10" noData="Bitte wählen sie Ihre Aufträge aus.">
<extension>
<m:OverflowToolbar>
<m:Title text="Selektierte Aufträge"/>
<m:ToolbarSpacer/>
<m:SearchField id="selectedOrder" liveChange="onFilterSelectedOrder">
<m:layoutData><m:OverflowToolbarLayoutData minWidth="25%" maxWidth="30%" /></m:layoutData>
</m:SearchField>
</m:OverflowToolbar>
</extension>
<columns>
<Column>
<m:Text text="Auftrags Nummer"/>
<template>
<m:Text text="{Aufnr}" wrapping="false" />
</template>
</Column>
<Column filterProperty="Ktext">
<m:Text text="Auftrag"/>
<template>
<m:Text text="{Ktext}" wrapping="false" />
</template>
</Column>
</columns>
<dragDropConfig>
<dnd:DragInfo groupName="moveToTable1" sourceAggregation="rows" dragStart="onDragStart"/>
<dnd:DropInfo groupName="moveToTable2" targetAggregation="rows" dropPosition="Between" drop="onDropTable2"/>
<dnd:DragDropInfo sourceAggregation="rows" targetAggregation="rows" dropPosition="Between" dragStart="onDragStart" drop="onDropTable2"/>
</dragDropConfig>
</Table>
</m:HBox>
</m:content>
</m:Dialog>
thats my fragment.. on table1 there is a Searchfield and it works.. like it should.
on my second table on table2 this does not work..
and i dont really know why.. the one is a json model the other not.. maybe thats why?
controller
onFilterAllOrder: function (oEvent) {
var oTable = this.byId("table1");
var searchText = oEvent.getParameters().newValue;
var filters = [];
if (searchText.trim() != '') {
var filter1 = new sap.ui.model.Filter({
path: "Ktext",
operator: sap.ui.model.FilterOperator.Contains,
value1: searchText
});
filters = [filter1];
var finalFilter = new sap.ui.model.Filter({
filters: filters,
and: false
});
oTable.getBinding("rows").filter(finalFilter, sap.ui.model.FilterType.Application);
} else {
oTable.getBinding("rows").filter([], sap.ui.model.FilterType.Application);
}
},
onFilterSelectedOrder: function (oEvent) {
var oTable = this.byId("table2");
var searchText = oEvent.getParameters().newValue;
var filters = [];
if (searchText.trim() != '') {
var filter1 = new sap.ui.model.Filter({
path: "Ktext",
operator: sap.ui.model.FilterOperator.Contains,
value1: searchText
});
filters = [filter1];
var finalFilter = new sap.ui.model.Filter({
filters: filters,
and: false
});
oTable.getBinding("rows").filter(finalFilter, sap.ui.model.FilterType.Application);
} else {
oTable.getBinding("rows").filter([], sap.ui.model.FilterType.Application);
}
}
so maybe i dont see something? or make some mistakes? so i try everything.. but nothing work.. i mean it should be the same as the one before but somehow it dont work...
If the latter is a OData model, the filtering would be done against the service if you have not set the operation mode to client. In this case, a request against the backend is made and if that service does ignore $filter, you'll see no change.
Check the network tab and look if a request is made.

AEM 6.3 HTL variable usage

I've really new to AEM, and I'm struggling getting with a button component. It has a drop down asking for open type, so either new window or modal. Ideal the gets target="_blank" or data-modal as part of the render.
Here's my dialog:
<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:nt="http://www.jcp.org/jcr/nt/1.0"
jcr:primaryType="nt:unstructured"
jcr:title="Button"
sling:resourceType="cq/gui/components/authoring/dialog">
<content
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/fixedcolumns"
margin="{Boolean}false">
<items jcr:primaryType="nt:unstructured">
<column
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/container">
<items jcr:primaryType="nt:unstructured">
<label
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/textfield"
fieldLabel="Button label"
name="./label"/>
<linkTo
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/pathfield"
fieldLabel="Link to"
name="./linkTo"
rootPath="/content"
suffix=".html"/>
<cssClass
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/textfield"
fieldLabel="Css class(es)"
name="./cssClass"/>
<open
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/select"
fieldLabel="Open options"
fieldDescription="A new tab/window, or a modal"
name="./open">
<items jcr:primaryType="nt:unstructured">
<def
jcr:primaryType="nt:unstructured"
text="(default)"
value=""/>
<tab
jcr:primaryType="nt:unstructured"
text="New Tab/Window"
value="target='_blank'"/>
<modal
jcr:primaryType="nt:unstructured"
text="Modal Window"
value="data-xxx"/>
</items>
</open>
<secondary
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/checkbox"
checked="${not empty cqDesign.useSecondary ? cqDesign.useSecondary : false}"
fieldDescription="Use the secondary style for the button."
name="./useSecondary"
text="Use secondary style"
uncheckedValue="false"
value="{Boolean}true"/>
</items>
</column>
</items>
</content>
</jcr:root>
and here is my button.java
package apps.bbcom_aem_project.components.content.button;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.commons.lang3.StringUtils;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ValueMap;
import com.adobe.cq.sightly.WCMUsePojo;
public class Button extends WCMUsePojo {
public static final Logger log = LoggerFactory.getLogger(Button.class);
public static final String PROP_LINK_TO = "linkTo";
public static final String PROP_LABEL = "label";
public static final String CSS_CLASS = "cssClass";
public static final String OPEN = "open";
private String linkTo;
private String label;
private String cssClass;
private String open;
#Override
public void activate() throws Exception {
Resource resource = getResource();
ValueMap properties = getProperties();
linkTo = properties.get(PROP_LINK_TO, "#");
label = properties.get(PROP_LABEL, "");
cssClass = properties.get(CSS_CLASS, "");
open = properties.get(OPEN, "");
if (StringUtils.isNotEmpty(linkTo) && !"#".equals(linkTo)) {
// is linkTO does not starts with http
if( !linkTo.startsWith("http") ) {
linkTo = linkTo + ".html";
}
}
log.debug("resource: {}", resource.getPath());
log.debug("linkTo: {}", linkTo);
log.debug("label: {}", label);
}
public String getLinkTo() {
return linkTo;
}
public String getLabel() {
return label;
}
public String getCssClass() {
return cssClass;
}
public String getOpen() {
return open;
}
}
At this point I have no errors, and a maven clean install gives no errors.
Here's my current button.html
<div data-sly-test="${wcmmode.edit || wcmmode.design}"><small class="text-muted"><em>Button Component - Configure</em></small></div>
<a data-sly-use.button="Button" data-sly-test="${button.label != ''}" class="btn ${properties.useSecondary ? 'btn-secondary' : 'btn-primary'} ${button.cssClass}" href="${button.linkTo}" role="button" data-opentype="${button.open}" ${button.open} >${button.label} ${button.open}</a>
and when I inspect the element, I see this:
<a class="btn btn-secondary " href="#" role="button" data-opentype="data-xxx" ${button.open}="">Workspaces data-xxx</a>
The data-xxx matches what I selected in the component options, but I can't get that to render in the opening tag.
HTL (previously known as Sightly) uses HTML5 data attributes to define statements over blocks of markup.
This markup is missing the data attribute, so is not HTML5 compliant
<a ... ${button.open}></a>
You can use the data-sly-attribute statement to set the attribute but you required to pass a key-value pairs map object
<a ... data-sly-attribute="${button.open}"></a>
This will output
<a .... target="_blank"></a>
Also you should consider moving from WCMUsePojo to Sling Models as is recommended by Adobe
The syntax <a ${button.open}=""></a> would not work as it is not part of the HTL spec. If you want to render an attribute name AND value you must use:
<a data-sly-attribute="${button.open}"></a>
Please note that button.open must be an object, preferably a map, for example
{"data-xxx":""}
This will render:
<a data-xxx=""></a>
please refer to the data-sly-attribute spec
Here's my solution:
<div data-sly-test="${wcmmode.edit || wcmmode.design}"><small class="text-muted"><em>Button Component - Configure</em></small></div>
<sly data-sly-test="${properties.open == 'tab'}">
<a data-sly-use.button="Button" data-sly-test="${button.label != ''}" class="btn ${properties.useSecondary ? 'btn-secondary' : 'btn-primary'} ${button.cssClass} tab" href="${button.linkTo}" role="button" target="_blank" > ${button.label} ${button.open} </a>
</sly>
<sly data-sly-test="${properties.open == 'modal'}">
<a data-sly-use.button="Button" data-sly-test="${button.label != ''}" class="btn ${properties.useSecondary ? 'btn-secondary' : 'btn-primary'} ${button.cssClass} modal" href="${button.linkTo}" role="button" data-lity > ${button.label} ${button.open} </a>
</sly>
<sly data-sly-test="${!properties.open}">
<a data-sly-use.button="Button" data-sly-test="${button.label != ''}" class="btn ${properties.useSecondary ? 'btn-secondary' : 'btn-primary'} ${button.cssClass}" href="${button.linkTo}" role="button" > ${button.label} ${properties.open} </a>
</sly>
It's not the cleanest, but as I only have two options, it seems to work.

Access model defined in manifest

Using single model definition in manifest.json
"models": {
"i18n": {
"type": "sap.ui.model.resource.ResourceModel",
"settings": {
"bundleName": "....i18n.i18n"
}
},
"": {
"dataSource": "mainService"
}
}
i can bind to model from XML and it's work
<List items="{path: '/myOneSet'}"> ... </List>
<List items="{path: '/myTwoSet'}"> ... </List>
but i can not access to it from code
this.getView().getModel().getProperty('/myOneSet')
or
this.getView().getModel().getProperty('/myOneSet/>param')
not work. How it accessible?
If mainService is an OData service, then your model is an ODataModel. You can access data via methods described in the API, e.g.: read()
this.getView().getModel().read('/myOneSet', {
success: function(oData, response) {
// do sg. with oData
}
});
Most of its data access methods has a second parameter-object with a success function callback. This function will be called asynchronously with the data on the given path upon successful data retrieval from the datasource. Most of the ODataModel API methods works with callbacks. You can read more about callbacks here.
If you defined model in the manifest.json file then you can access it via Component. If you created your project via template then you have a BaseController.js file which is the ancestor of your other controllers and there is a function getComponentModel. So, I would suggest you to try this code in your controller:
this.getComponentModel().getProperty('/myOneSet')
Because of the property name that you try to access I assume you are using an ODataModel. Is that correct?
If that's true you have to consider a few things... ODataModel.getProperty() does not trigger requests. Instead it will return whats already available. If you want to trigger a request you should execute an ODataModel.read(). If you want to get the loaded data from the ODataModel then you should also know when the data has been loaded. This you can achieve by attaching a change event handler when you do the binding.
Instead of describing how to access the data of an ODataModel I wrote s little jsbin example for you (or see below). Just check the change event handler. There are multiple ways to access the data.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>SAPUI5 single file template | nabisoft</title>
<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"
data-sap-ui-bindingSyntax="complex"
data-sap-ui-compatVersion="edge"
data-sap-ui-preload="async"></script>
<!-- use "sync" or change the code below if you have issues -->
<!-- XMLView -->
<script id="myXmlView" type="ui5/xmlview">
<mvc:View
controllerName="MyController"
xmlns="sap.m"
xmlns:core="sap.ui.core"
xmlns:mvc="sap.ui.core.mvc">
<Table
id="myTable"
growing="true"
growingThreshold="10"
growingScrollToLoad="true"
busyIndicatorDelay="0">
<headerToolbar>
<Toolbar>
<Title text="Orders of ALFKI"/>
<ToolbarSpacer/>
</Toolbar>
</headerToolbar>
<columns>
<Column>
<Text text="OrderID"/>
</Column>
<Column>
<Text text="Order Date"/>
</Column>
<Column>
<Text text="To Name"/>
</Column>
<Column>
<Text text="Ship City"/>
</Column>
</columns>
<items>
<!-- filled via bindItems() in controller -->
</items>
</Table>
</mvc:View>
</script>
<!-- XML Fragment -->
<script id="myXMLFragment" type="ui5/fragment">
<core:FragmentDefinition
xmlns="sap.m"
xmlns:core="sap.ui.core">
<ColumnListItem type="Active">
<cells>
<ObjectIdentifier title="{OrderID}"/>
<Text
text="{
path:'OrderDate',
type:'sap.ui.model.type.Date',
formatOptions: { style: 'medium', strictParsing: true}
}"/>
<Text text="{ShipName}"/>
<Text text="{ShipCity}"/>
</cells>
</ColumnListItem>
</core:FragmentDefinition>
</script>
<script>
sap.ui.getCore().attachInit(function () {
"use strict";
//### Controller ###
sap.ui.define([
"sap/ui/core/mvc/Controller",
"sap/ui/model/odata/v2/ODataModel"
], function (Controller, ODataModel) {
"use strict";
return Controller.extend("MyController", {
onInit : function () {
this.getView().setModel(
new ODataModel("https://cors-anywhere.herokuapp.com/services.odata.org/V2/Northwind/Northwind.svc/", {
json : true,
useBatch : false
})
);
var sPath = "/Customers('ALFKI')/Orders";
var oTable = this.byId("myTable");
var oTemplate = sap.ui.xmlfragment({
fragmentContent : jQuery("#myXMLFragment").html()
});
oTable.bindItems({
path : sPath,
template : oTemplate,
templateShareable : false,
sorter : null,
filters : null,
events : {
change : function (oEvent) {
var oModel, oListBnd, aContexts, i, oObj;
console.log("1. Example: ODataModel.getProperty() does not trigger a request (but here we have the data already)!");
oModel = this.getView().getModel();
console.dir( oModel.getProperty("/Orders(10643)")); //OK
console.dir( oModel.getProperty("/Orders") ); //Not OK
console.dir( oModel.getData("/") ); //DANGER: Could contain different entities!!!!!
console.log("2. Example: Accessing the Data via ListBinding");
oListBnd = oTable.getBinding("items"); // get the ListBinding
//oListBnd = oEvent.getSource(); // this works here inside the change handler
aContexts = oListBnd.getCurrentContexts(); // the the contexts
for(i=0; i<aContexts.length; i++){
oObj = aContexts[i].getObject(); // access the items/objects
console.dir( oObj );
}
}.bind(this)
}
});
}
});
});
//### THE APP: place the XMLView somewhere into DOM ###
sap.ui.xmlview({
viewContent : jQuery("#myXmlView").html()
}).placeAt("content");
});
</script>
</head>
<body class="sapUiBody">
<div id="content"></div>
</body>
</html>
Hi Just declare this is manifest
"models": {
"createMod": {
"preload": true,
"dataSource": "CreateService",
"settings": {
}
}
and Try to Access by Controller using.
var oModelCheck = that.getOwnerComponent().getModel("createMod");

How to create multi image component with image preview In adobe cq5?

I want to build a component in which user can drag & drop two images from content finder. For this i created another tab in my dialog but when i am authoring the component its showing the 1st tab image in both div's. Can you please tell me where i'm wrong here is my code.
dialog.xml
<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
jcr:primaryType="cq:Dialog"
activeTab="{Long}0"
helpPath="en/cq/current/wcm/default_components.html#Image"
xtype="tabpanel">
<items jcr:primaryType="cq:WidgetCollection">
<image
jcr:primaryType="cq:Widget"
cropParameter="./imageCrop"
ddGroups="[media]"
fileNameParameter="./fileName"
fileReferenceParameter="./fileReference"
mapParameter="./imageMap"
name="./file"
requestSuffix=".img.png"
rotateParameter="./imageRotate"
title="Image"
xtype="html5smartimage"/>
<advanced
jcr:primaryType="cq:Widget"
title="Advanced"
xtype="panel">
<items jcr:primaryType="cq:WidgetCollection">
<title
jcr:primaryType="cq:Widget"
fieldLabel="Title"
name="./jcr:title"
xtype="textfield"/>
<alt
jcr:primaryType="cq:Widget"
fieldDescription="(leave empty to use the title defined above)"
fieldLabel="Alt Text"
name="./alt"
xtype="textfield"/>
<linkURL
jcr:primaryType="cq:Widget"
fieldDescription="Drop files or pages from the Content Finder"
fieldLabel="Link to"
name="./linkURL"
xtype="pathfield"/>
<description
jcr:primaryType="cq:Widget"
fieldLabel="Description"
name="./jcr:description"
xtype="textarea"/>
<size
jcr:primaryType="cq:Widget"
fieldLabel="Size"
heightParameter="./height"
widthParameter="./width"
xtype="sizefield"/>
</items>
</advanced>
<image4
jcr:primaryType="cq:Widget"
cropParameter="./image4Crop"
ddGroups="[media]"
fileNameParameter="./image4/fileName"
fileReferenceParameter="./image4/fileReference"
mapParameter="./imageMap"
name="./image4/file"
requestSuffix=".img.png"
rotateParameter="./image4/imageRotate"
title="Image"
xtype="html5smartimage"/>
</items>
</jcr:root>
image.jsp is
<%# page import="com.day.cq.commons.Doctype,
com.day.cq.wcm.api.components.DropTarget,
com.day.cq.wcm.foundation.Image" %><%
%><%#include file="/libs/foundation/global.jsp"%><%
Image image = new Image(resource);
//drop target css class = dd prefix + name of the drop target in the edit config
image.addCssClass(DropTarget.CSS_CLASS_PREFIX + "image");
image.loadStyleData(currentStyle);
image.setSelector(".img"); // use image script
image.setDoctype(Doctype.fromRequest(request));
Image image4 = new Image(resource);
//drop target css class = dd prefix + name of the drop target in the edit config
image4.addCssClass(DropTarget.CSS_CLASS_PREFIX + "image4");
image4.loadStyleData(currentStyle);
image4.setSelector(".img"); // use image script
image4.setDoctype(Doctype.fromRequest(request));
// add design information if not default (i.e. for reference paras)
if (!currentDesign.equals(resourceDesign)) {
image.setSuffix(currentDesign.getId());
}
String divId = "cq-image-jsp-" + resource.getPath();
%><div id="<%= divId %>"><% image.draw(out); %></div><%
%><cq:text property="jcr:description" placeholder="" tagName="small" escapeXml="true"/>
<div id="<%= divId %>"><% image4.draw(out); %></div>
<%#include file="/libs/foundation/components/image/tracking-js.jsp"%>
I ran into a problem like this using with multiple images within the dialog. You might check the resourceType after you save the images in CRXDE to make sure they both have a resourceType property set. If either images are missing this property you can add the property using a hidden widget. Reference https://forums.adobe.com/message/4623838 for more
<resType1
jcr:primaryType="cq:Widget"
ignoreData="{Boolean}true"
name="./file/sling:resourceType"
value="foundation/components/image"
xtype="hidden"/>
<resType2
jcr:primaryType="cq:Widget"
ignoreData="{Boolean}true"
name="./image4/sling:resourceType"
value="foundation/components/image"
xtype="hidden"/>