Getting all inputs with custom attribute in a view - sapui5

I need to go through all inputs (of different types) which contain a custom attribute in common, like below:
<m:Input value="{building>/shortName}" custom:required="true"/>
...
<m:Input value="{building>/longName}" custom:required="true"/>
So I can do a validation on each one of them.
Some of you can imagine why I'm doing that (sap.m.Input hasn't a required property itself as sap.ui.commons.TextField has).
By pure jQuery, I could get it, but it's definitely my last option to try.
Does anyone know how to get such filtered list of controls?
Another better solution for the same issue is also welcome.

I think adding minLength constraint with String type and listening validation error would be a better approach.
<Input value="{
path : 'building>/shortName',
type : 'sap.ui.model.type.String',
constraints : {
minLength: 1
}
}" />
sap.ui.getCore().attachValidationError(function (oEvent) {
oEvent.getParameter("element").setValueState("Error");
});
Also you can have a look at this sample
https://openui5.hana.ondemand.com/explored.html#/sample/sap.m.sample.InputChecked/preview

Related

TypeError: date.clone is not a function After Added the "name" property to Form.Item (ant design)

I am currently building an application with DatePicker from Ant Design and I am wrapping with Form.item.
<Form.Item
name={key}
label={label}
>
<DatePicker
disabledDate={(current) => disableDaysAfterToday(current)}
onChange={(current) => handleChangeDate(current)}
/>
</Form.Item>
However, when the "name" property is added to the Form.Item component I end up getting the following error: TypeError: date.clone is not a function. And, if I remove this property or change to some other string, that is, remove "name" from the Form.Item everything works normally. Can anybody help me?
The "name" property is used to select the correct attribute in the "initialValues" provided in your <Form/> component. If you don't inform it, it doesn't break because the attribute is not being selected, your input must have been empty.
For me, it worked when I treated the attribute in question before passing it to "initialValues".
this.object.date = moment(this.object.date);

Is using [(ngModel)] in reactive forms bad practice?

I'm starting to use model based forms in my angular App. So far I have been suing template based forms and I bind my data using [(ngModel)].
I noticed that using [(ngModel)] in reactive forms is possible, but I've been reading on stack that it's a bad practice, but I can't find (or missed) anything about this in the docs.
Is it true that you should avoid using when you are working with reactive forms? If so, what would be the correct way to bind data to an input?
Right now I do something like this:
My component:
this.assignForm = this.fb.group({
"balance": [null, Validators.required]
});
My Template
<input type="text" formControlName="balance" [(ngModel)]="myData.Balance" />
Every HTML input element is wrapped by an angular class called FormControl. FormBuilder creates the FormControls explicitly. Putting NgModel on a element will also create a FormControl.
In your example, you have two FormControl objects for the same element.
Assuming they don't fail due to name clash (like <input name="myname" formControlName="myname" [(ngModel)]="model.prop" /> would register myname with the FormGroup twice), then you might get different answers on valid/invalid/touched/dirty depending on which one was queried.
Your question title and question completely mix up model based and reactive, where your code uses them both combined. Using both combined results in absolutely no guarantee that the value you see and the value your form controller contains are equal. Just do not do it.
The correct way would be:
this.assignForm = this.fb.group({
"balance": [myData.Balance, Validators.required]
});

How to get id of invisible element in fragment?

I have a Dialog in fragment:
<core:FragmentDefinition
xmlns="sap.m"
xmlns:f="sap.ui.layout.form"
xmlns:core="sap.ui.core">
<Dialog title="{i18n>AddNewItem}" resizable="true" draggable="true">
<content>
<MessageStrip
id="failMsg"
visible="false"
text="{i18n>SensorTypesCreateFail}"
type="Error"
showIcon="true"/>
</Dialog>
</core:FragmentDefinition>
As in UI5 doc:
Retrieving a control instance when the fragment is not part of a view:
When no fragment ID was given: myControl = sap.ui.getCore().byId("myControl")
When a fragment ID myFrag was given: myControl = sap.ui.core.Fragment.byId("myFrag", "myControl")
If there is no visible="false", I can get this MessageStrip by sap.ui.getCore().byId("failMsg").
But I found that with visible="false", id of MessageStrip is sap-ui-invisible-failMsg, I failed to found proper API to get it.
Of course I can use sap.ui.getCore().byId("sap-ui-invisible-failMsg"), but I am not sure whether this ID will change after I deploy it to FLP, and as #schnoedel said in another question:
Beware that the prefixes like -- and --- used by the framework may change in the future. Thats why it's recommended to use the public api functions the framework supplies like byId() and createId().
So, is there any better way to get it?
Update:
Change my code from:
this[dialogName] = sap.ui.xmlfragment("namespace." + dialogName, this);
this.getView().addDependent(this[dialogName]);
To
this[dialogName] = sap.ui.xmlfragment(dialogName, "namespace." + dialogName, this);
this.getView().addDependent(this[dialogName]);
And now my id is sap-ui-invisible-dialogName--failMsg...
It depends on what you want to achieve after getting the ID. If you just want to change a property you could do it without any ID via a Model.
For that you can assign a Model field (i.e. baseModel>/visable) to the visable property and once it should be changed you change the model and via two way binding it updates the control.
code to change a model:
this.getView().getModel("nameOfUrModel").setProperty("property", "value")
for more information about this just check the walkthrough tutorial on
https://sapui5.hana.ondemand.com/
And if you for whatever reason really need the ID:
https://sapui5.hana.ondemand.com/#docs/api/symbols/sap.ui.core.Fragment.html
here you find the command:
sap.ui.core.Fragment.byId(sFragmentId, sId)
It should be able to return the Control your using
Hope that helps
Eric
You were very close to the solution. After adding dialogName for the fragment ID in its creation, you just have to call the API ...:
sap.ui.require(["sap/ui/core/Fragment"], Fragment => Fragment.byId(dialogName, "failMsg"));
... to get the control instance as mentioned here.
However, regardless whether you provided a fragment ID or not, you can easily ignore the render prefix "sap-ui-invisible-" at any time - Meaning that you could've also been able to get the control instance via sap.ui.getCore().byId("failMsg") instead of sap.ui.getCore().byId("sap-ui-invisible-failMsg") even if the control is invisible.

React Warning: Unknown prop `valueAsNumber` on <input> tag

I have a component that wraps an <input type=number>.
Here is my JSX:
function InputNumber(props) {
return (<input
type="number"
valueAsNumber={props.value}
onChange={e => props.onChange(e.target.valueAsNumber)}
step={props.step}
/>);
}
This compiles to the following JS:
function InputNumber(props) {
return (React.createElement("input", {type: "number", valueAsNumber: props.value, onChange: function (e) { return props.onChange(e.target.valueAsNumber); }, step: props.step}));
}
React is giving me the following warning:
Warning: Unknown prop valueAsNumber on tag. Remove this prop from the element.
It seems to work fine if I read and write from element.valueAsNumber in the DOM, so why doesn't React know about this property?
To use non-standard attributes on React components without having them stripped, you must follow HTML 5 standard and prefix them with "data-" and don't use camel case. So yours would be:
data-value-as-number={props.value}
As Jeff McCloud said, you are going to use non standard html attributes. Your function may be rewritten like this:
function InputNumber(props) {
return (<input
type="number"
data-valueAsNumber={props.value}
onChange={e => props.onChange(e.target.dataset.valueAsNumber)}
step={props.step}
/>);
}
According to the DOM Elements Doc, valueAsNumber is not a valid attribute. This article also confirms that unsupported attributes are stripped.
React does not yet recognize the attribute you specified. This will likely be fixed in a future version of React. However, React currently strips all unknown attributes, so specifying them in your React app will not cause them to be rendered.
You might want to check out this repo instead:
react-numeric-input
Number input component that can replace the native number input which is not yet very well supported and where it is, it does not have the same appearance across the browsers. Additionally this component offers more flexible options and can be used for any values (differently formatted representations of the internal numeric value).

Set class or ID on <h:inputHidden> in JSF

I'm trying to set a class or id parameter on a <h:inputHidden> in JSF. The code looks like this:
<h:inputHidden value="#{getData.name}" class="targ" />
But in the browser, the class isn't set:
<input type="hidden" name="j_idt6" value="j_idt6">
I need to set a class to this parameter, because I have a JavaScript autocomplete function for a <h:inputText> that sets a value in the hidden input, which needs to be passed in the next page.
Any ideas? Thanks!
I know it's a little bit late, but it can help someone in the future.
As inputHidden shows nothing in the browser there's no sense to allow it to have a class.
You can use the Id but as the Id could change as you change the component parents using it would bring some headache.
I'd suggest as a workaround, you can give it a parent so you can manipulate it by javascript.
Exemple:
JSF
<h:panelGroup styleClass="someCssClass">
<h:inputHidden id="someId" value="someValue" />
</h:panelGroup>
Javascript (using jQuery, you could use pure javascript also)
$('.someCssClass input[type=hidden]').val('yourNewValue');
None of these answers here satisfied my needs (need the PrimeFaces component, need class not ID, wrapping is too much work), so here's what I came up with:
Use pass-through attributes: https://www.primefaces.org/jsf-2-2-pass-through-attributes
Use pass:hidden-class="blah" (in my case, it's xmlns:pass up top)
Use [attribute=value] selector:
https://www.w3schools.com/cssref/sel_attribute_value.asp
document.querySelector multiple data-attributes in one element
That basically boils down to using something like this (because h:inputHidden becomes a regular input): document.querySelector("input[hidden-class=" + blah + "]")
Please, see similar question - How can I know the id of a JSF component so I can use in Javascript
You can sed "id" property, but in final html code it can be not the same, but composite: for example, if your input with id="myhidden" is inside form with id="myform", final input will have id="myform:myhidden".
In the end, I used a standard HTML <input type="hidden"> tag, as I had no advantages for using the JSF one. If you're trying to set a value in a hidden input with JavaScript, I recommend using this workaround.