How to access TextArea's text and/or change it? - sapui5

XML View
<TextArea id="message"
maxLength="100"
width="100%"
valueLiveUpdate="true"
showExceededText="false"
placeholder="Type here.."
required="true"
/>
Controller
onInit: function() {
// ...
this.getView().byId("message").setText("");
},
Here I tried two commands to clear the text area values. But got error
this.getView().byId("message").setText("");
TypeError: this.getView(...).byId(...).setText is not a function
sap.ui.getCore().byId("message").setText("");
TypeError: sap.ui.getCore(...).byId(...) is undefined.
How to clear TextArea values from JS?

The control sap.m.TextArea doesn't have the text property and thus no such mutator and accessor either. Instead, the text value can be set via the property value since the control extends InputBase.
Therefore, the line should be:
this.byId("message").setValue();

Related

SAP UI5 : Unable to bind a controller variable in xml

Button on click of which the variable is getting changed:
<f:content>
<Button icon="sap-icon://edit" press="editClick" type="Transparent"></Button>
</f:content>
xml code where i need 2-way binding:
<VBox class="sapUiSmallMargin">
<form:SimpleForm id="SimpleFormDisplayColumn_oneGroup">
<form:content>
<Label text="{i18n>contextofusage}"/>
<Text text="{contextofusagetext}" visible="{!isInfoEditable}"/>
<Input type="Text" visible="{isInfoEditable}" value="{contextofusagetext}"></Input>
</form:content>
</form:SimpleForm>
</VBox>
controller:
var isInfoEditable=false;
return Controller.extend("abc.controller.Detail", {
editInfoClick: function(event){
if(isInfoEditable){
isInfoEditable=false;
}
else{
isInfoEditable=true;
}
}
});
It seems like you have tried nothing, but I will try to guide you:
You cannot simply declare a variable in your controller and then use it in your view. That's not how UI5 works. Instead create a model and bind it to your view. I also give my models a name, in this case "view":
onInit: function() {
var oViewModel = new sap.ui.model.json.JSONModel({
isInfoEditable: false
});
this.getView().setModel(oViewModel, "view");
}
Then use it in your view. Make sure that you use the name of your model ("view") in your bindings. If you want to do more than simply use the raw value (e.g. negate it) you have to use expression binding. Also you have to use an absolute path starting with /:
<form:SimpleForm id="SimpleFormDisplayColumn_oneGroup">
<form:content>
<Label text="{i18n>contextofusage}"/>
<Text text="{contextofusagetext}" visible="{= !${view>/isInfoEditable} }"/>
<Input type="Text" visible="{view>/isInfoEditable}" value="{contextofusagetext}"></Input>
</form:content>
</form:SimpleForm>
When you click on the button you have to modify/toggle the value in your model:
editClick: function (oEvent) {
var oViewModel = this.getView().getModel("view");
var bIsEditable = oViewModel.getProperty("/isInfoEditable");
// negate the current value and set it as the new value
oViewModel.setProperty("/isInfoEditable", !bIsEditable);
}
I suggest strongly reading on the basics of UI5. Your approach looks more like Vue.js, but UI5 has its own paradigms.

salesforce lightning this.template.querySelector not working

<template>
<div class="container-wrapper">
<div if:false={loggedIn} class="slds-m-around_medium">
<span>Login to Salesforce App</span>
<lightning-input name='username' label="Username"></lightning-input>
<lightning-input type="password" name='password' label="Password"></lightning-input>
<br/>
<lightning-button variant="brand" label="Login" title="Login" onclick={login}></lightning-button>
</div>
</div>
</template>
login() {
console.log('login attempt');
console.log(this.template);
var Username =this.template.querySelector('input[name="username"]').value;
var Password =this.template.querySelector('input[name="password"]').value;
console.log(Password);
console.log(Username );
}
values are not getting fetch in username, password variables.
this.template.querySelector('input[name="username"]').value is not working.
I have also tried onchange event approach on lightning-input elements , in that case event.target was undefined ? I am stuck not able to read user input.
app screenshot
There is no property 'name' on lightning-input like on standard HTML input. You should use 'data-id' instead.
HTML:
<lightning-input data-id='username' label="Username"></lightning-input>
JS:
let username = this.template.querySelector('lightning-input[data-id=username]');
The <template> element is not a common element. It holds its (inactive) DOM content inside a Document Fragment that you can access through the content property.
Therefore you should try:
var Username = this.template.content.querySelector('input[name="username"]').value;
var Password = this.template.content.querySelector('input[name="password"]').value;
In Salesforce when you are accessing a lightning input using the query selector first you have to search for lightning-input tag not the input tag.
Secondly when you add a name attribute to the lightning-input that attribute is transfered to the input tag which is created when the lightning component is rendered. But you can not access the input tag (my assumption is that it's in the Shadow DOM). Therefore to search for the lighting-input you must use a class name to identify the lightning component.
<lightning-input type="number" class="optionEditQuantityVal" value={Quantity} variant="label-hidden" step="1" max-length="1"></lightning-input>
let input = this.template.querySelectorAll('lightning-input.optionEditQuantityVal')

Attach browser event to a control using XML-View

My REST service send me a lot of data. Every property contains the value and a help-attribute that contains a long description of the field property.
Ok, I have data (a list of property with value and help) in a JSONModel and I use data-binding XML https://openui5.hana.ondemand.com/#docs/guide/91f0f3cd6f4d1014b6dd926db0e91070.html to map data value in forms and tables.
Now I want show somehow help message for each property.
My idea is show a message dialog when the user double-click on the Label or on the Text of the column header in a table
Both Label and Text have attachBrowserEvent method but I don't know how use the function to attach the event wrinting only in the XML-views
I would like something like this:
In XML-View:
<Label text="Language"
attachBrowserEvent:"function("click",showMessageHelp({model>/language/help}))">
<Input value="{model>/language/value}"/>
In the controller:
showMessageHelp:function(sMessage){
//show message dialog with sMessage
...........
}
You can achieve this using onAfterRendering method.
Have CustomData in the XML:
<Label id="label" text="Language">
<customData>
<core:CustomData key="type" value="{/language/help}" />
</customData>
</Label>
Then in controller use this customData:
onAfterRendering: function () {
var showValueHelp = function () {
var text = this.getCustomData()[0].getValue();
sap.m.MessageToast.show(text);
event.preventDefault();
event.stopPropagation();
return false;
};
this.byId("label").attachBrowserEvent("click", showValueHelp);
}
JS fiddle is here
PS:I am not sure this is viable solution for you.
This is the best I could come up with, currently.
Attach a browser event for each label is possible but I can't find a way to do it without repeat each label id.
I have found an alternative solution: my data are shown in forms and tables.
I have added on the right of each form couple of label: value a Text element with the help info:
<Label text="Field duck"/>
<Text text="{model>/elements/mainFields1/duck/value}"/>
<Text text="{model>/elements/mainFields1/duck/ATTR/help/description}" visible="{ui>/bShowHelp}" />
In tables I have divided each column title in two group: header and footer; in the footer I have placed the help info:
<Column>
<header>
<Text text="Name"/>
</header>
<footer>
<Text text="{model>/elements/airports/templateNewRow/name/ATTR/help/description}" visible="{ui>/bShowHelp}"/>
</footer>
</Column>
I change the value of bShowHelp showing and hiding all help infos

Why does reset() function does not work properly with jsviews

I am using jsviews for data binding:
My template
<script id = "ProfileTemplate" type="text/x-jsrender">
<input data-link="userVO.first_name" type="text">
<input type="reset" value="Reset" onclick="this.form.reset();">
</script>
My Form
<form name="profile-form" id="profile-form" action="profile.html">
<div id="flightEditDetail"></div>`enter code here`
</form>
<script>
var template = $.templates("#ProfileTemplate");
template.link("#flightEditDetail", profileJSON);
</script>
The template binds the value correctly. I changed the value in the text field and clicked on reset button. The text field becomes empty but I want the value that was rendered on page load.
Why does reset() function not work properly with jsviews data-link
reset() will revert the the intial/default value set in the value property: <input value="initialValue" />
For your case you could set the 'statically defined' value to the initial data value:
<input data-link="userVO.first_name" type="text" value="{{:userVO.first_name}}"/>
or better - attribute encode the initial value to avoid injection attacks:
<input data-link="userVO.first_name" type="text" value="{{attr:userVO.first_name}}"/>
The result is that the user will see the original value. However the reset action will only change the UI value, not the value in your underlying data that you are linking to. (See http://bugs.jquery.com/ticket/11043 for a related issue/concern in jQuery). So you would probably be better off not using reset() but instead cloning your initial data, and using $.observable(userVO).setProperty(originalUserVO) to revert.

Persisting JSF2 Composite Component value

I have a datatable which loops through a List and has a value column which renders as such:
<h:dataTable var="assessmentFieldValue" value="#{assessmentBean.assessmentFieldValues}">
...
<ui:fragment rendered="#{assessmentFieldValue.field.type eq 'TEXT'}">
<h:inputText value="#{assessmentFieldValue.value}" />
</ui:fragment>
<ui:fragment rendered="#{assessmentFieldValue.field.type eq 'SLIDER'}">
<component:slider value="#{assessmentFieldValue.value}" />
</ui:fragment>
...
</h:dataTable>
So sometimes I get a standard inputText, sometimes I get my composite slider component:
<composite:interface>
<composite:attribute name="value" />
</composite:interface>
<composite:implementation>
<script type="text/ecmascript">
function updateValue(value) {
$('##{cc.id} span').each(function() {
$(this).text(value);
});
}
</script>
<div id="#{cc.id}">
<input id="sliderComponent" type="range" min="1" max="10"
value="#{cc.attrs.value}"
style="float: left"
onchange="javascript:updateValue(this.value);" />
<h:outputText id="fieldValue" value="#{cc.attrs.value}"
style="min-width: 20px; display: block; float: left" />
</div>
</composite:implementation>
This all renders as I would like it too (deployed on JBoss-AS7), but when I hit the save button associated with the datatable the assessmentBean.assessmentFieldValue List doesn't reflect any value changes on the slider component yet it does for the standard inputText.
Can anyone suggest why changes to the slider aren't making it back to the backing bean? Thanks!
That's because you used a plain HTML <input> element instead of a fullworthy JSF input component like <h:inputText>. This way the value is in no way bound to the JSF context. It's only treated as plain vanilla template output value, not as input value. A composite component isn't going to solve this. You really need to create a fullworthy UIComponent for this (or to look for a 3rd party component library which has already done the nasty job for you, such as PrimeFaces with its <p:slider>).
See also:
When to use <ui:include>, tag files, composite components and/or custom components?