Cannot programmatically add content to simple HTML DIV Element in XML view - sapui5

I have a simple XML view (fragment) like this:
<html:div id="holder"></html:div>
I want to add content programmatically like this:
var holder = this.byId("holder");
var label = new sap.m.Label({
text: "Label"
});
holder.addContent(label);
Effect is nothing, no error, no added content.
Why does it not work?

This is because content is not an aggregation (an easy mistake to make, since content usually is an aggregation).
sap.ui.core.HTML's content metadata object is a property of type string. From the jsdoc:
HTML content to be displayed, defined as a string.
You will need to use a different container for your label, such as sap.ui.layout.VerticalLayout, or you could just use raw HTML to stick in your holder object, rather than that sap.m.Label type.
Here is a jsbin that takes the XML view part of this question out of the equation.
Note: See #hirse's comment below for an important distinction when using html:div in XML views

The HTML element and the UI5 Controls are not directly compatible. UI5 Controls are JavaScript objects that have a render function. The render function creates a html fragment on demand. That html fragment ist then inserted into the page.
I have never tried it, but a solution could be to use the placeAt() method of your label:
label.placeAt("holder");
If you are using an XML View, the holder id will be prefixed. Then you should use something like this:
label.placeAt(this.getView().createId("holder"));

You can get DOM element of UI5 control by using getDomRef of sap.ui.core.Element class.
Then add your content to this DOM element by using placeAt()
Here is working example.

Related

TYPO3 custom content IRRE (inline content)

Is there a solution to get inline elemnts in a custom content element? I only know thd solution to set the page with the data records in the content element where the inline elements are stored.
But i woult like to create a new content element and then put some inline elements directly in it.
Yes, you can add IRRE items on your content element. You need to create the relation between the content element and the table where the IRRE items are saved and get them via the DatabaseQueryProcessor.
Here you can get inspired on how you can achieve this:
How to create custom content elements on TYPO3
If you have any questions, feel free to ask.

How to get html of a SAP UI5 control

Normally when using SAP UI5, we use the following code
this.appContent.placeAt('content');
This will render the content element.
But I just want the html of appContent UI5 control without rendering it. How to do that?
The reason I want to do it is because I want to use sap.ui.template to build a carousel and I want to add get raw HTML of UI5 control and add it as a string to a template instead of rendering it directly.
Assuming this.appContent is a control, then after the contol has been rendered just call
var $domRef = this.appContent.$():
or getDomRef() (visibility is protected!)
var domRef = this.appContent.getDomRef():
Be aware when to call this after the control has been rendered, i.e. like this:
this.appContent.addEventDelegate({
onAfterRendering : function(oEvent){
var $domRef = oEvent.srcControl.$();
// now do something
}
});
this.appContent.placeAt('content');
However, I would try to avoid using placeAt.

Trying to use EJS to dynamically render an edit form

The problem seems to be with EJS. I might be trying to do something EJS wasn't designed for.
I'm working on a web app that uses forms with a variable number of fields. If a Mongo document I'm editing has only one field, I don't want to display input boxes for any additional fields.
I'm able to dynamically control how many fields are displayed when documents are edited but I'm not able to dynamically display the current value of the fields.
If I use the value tag like this: value=<%= document.field1 %>, it works fine. This, however, would have to be manually repeated for each field, including fields that won't be present.
What I want to do is something like this: value=<%= 'document.field' + (i+1) %>. This would ideally produce the same rendered HTML the code above does. However, what I see is 'document.field1' rather than the data I want to retrieve from the database.
EJS is just a thin wrapper around JavaScript code. Anything you can write in JavaScript you can write in EJS, it'll be included in the compiled template without modification.
So to reference a field with a dynamic name you'd use [] just like you would in any other JavaScript code. Based on the code you provided it would be something like this:
value="<%= document['field' + (i + 1)] %>"

Aurelia - Accessing ViewModel functions/binding from within Generated DOM elements

I have a section of my view (html) that is generated programmatically by a viewmodel/class. This uses the Aurelia DOM (Aurelia Docs - pal :: Dom) functionality to generate and add the raw HTML elements to the view.
However, I am unable to get events within the generated html to call back to the viewmodel. An example:
let deleteButton = this.dom.createElement("button");
deleteButton.setAttribute("onclick", "cancelCreditNote(`${ row.creditNoteId }`)");
A click on the generated button won't call back to the viewmodel, which does have a cancelCreditNote function. Various other things like deleteButton.setAttribute("click.delegate", "cancelCreditNote('${ row.creditNoteId }')"); do not work either.
Does anyone know how to access a viewmodel class from essentiall 'raw' html in aurelia?
Unfortunately in this instance I cannot use the standard aurelia templating to generate the HTML.
The DOM property on PAL is just an abstraction for the browser's DOM object, create element is likely just calling document.createElement which doesn't afford any Aurelia binding to the created element.
You could try using aurelia.enhance(context, element) which takes an existing DOM element and runs it through the templating engine.
With this method you can also pass a binding context to apply to the element.
In my HTML I use this:
<div id="collapsesidebar" click.delegate="toggleSidebar()">
In my view-model I have this method:
toggleSidebar(){
alert('hi');
}
You could also do this from your view-model with JQuery like this:
attached() {
$('main').on('click', ()=> alert('hi'));
}
The last option is ONLY available áfter the attached() method is triggered: before that the binding needs to do its job and only after that the elements are located inside of the dom.
In other words: this will not work:
activate(){
$('main').on('click', ()=> alert('hi'));
}
because the constructor and the activate method both get fired before the attached method.

Need to find the tags under a tag in an XML using jQuery

I have this xml as part of the responseXml of an Ajax call:
<banner-ad>
<title><span style="color:#ffff00;"><strong>Title</strong></span></title>
</banner-ad>
When I used this jQuery(responseXml).find("title").text(); the result is "Title".
I also tried jQuery(responseXml).find("title:first-child") but the result is [object Object].
I want to get the result:
<span style="color:#ffff00;"><strong>Title</strong></span>
Please let me know how to do this in jQuery.
Thanks in advance for any help.
Regards,
Racs
Your problem is that you cannot simply append nodes from one document (the XML response) to another (your HTML page). The issue is two-fold:
You can use jQuery to append nodes from the XML document to the HTML page. This works; the nodes appear in the HTML DOM, but they stay XML nodes and therefore the browser ignores the style attribute, for example. Consequently the text will not be yellow (#ffff00).
As far as I can see, jQuery offers no built-in way to get the XML string (i.e. a serialized node) from an XML node. jQuery can handle XML documents quite well, but there is no equivalent to what .html() does in HTML documents.
So to make this work we need to extract the XML string from the XML document. Some browsers support the .xml property on XML nodes (namely, IE), the others come with an XMLSerializer object:
// find the proper XML node
var $title = $(doc).find("title");
// either use .xml or, when unavailable, an XMLSerializer
var html = $title[0].xml || (new XMLSerializer()).serializeToString($title[0]);
// result:
// '<title><span style="color:#ffff00;"><strong>Title</strong></span></title>'
Then we have to feed this HTML string to jQuery so new, real HTML elements can be created from it:
$("#target").append(html);
There is a fiddle to show this in action: http://jsfiddle.net/Tomalak/QWHj8/. This example also gets rid of the superfluous <title> element.
Anyway. If you have a chance to influence the XML itself, it would make sense to change it:
<banner-ad>
<title><span style="color:#ffff00;"><strong>Title</strong></span></title>
</banner-ad>
Just XML-encode the payload of <title> and you can do this in jQuery:
$("#target").append( $(doc).find("title").text() );
This would probably work:
$(responseXml).find("title").html();