Depending fields validation - cxjs

I have two password fields that, among other rules, have to be equal for the form to be valid.
<form onSubmit="resetPassword">
<ValidationGroup valid-bind="$page.formvalid" >
<FlexCol>
<TextField
value-bind="$page.password1"
label="Password 1"
inputType="password"
required
validationRegExp={/(?=.*\d)(?=.*[!##$%^&*]+)(?![.\n])(?=.*[A-Z])(?=.*[a-z]).*$/}
minLength="6"
onValidate="validatePasswordsEqual"
/>
<TextField
value-bind="$page.password2"
label="Password 2"
inputType="password"
required
validationRegExp={/(?=.*\d)(?=.*[!##$%^&*]+)(?![.\n])(?=.*[A-Z])(?=.*[a-z]).*$/}
minLength="6"
onValidate="validatePasswordsEqual"
/>
<Button
submit
disabled-expr="!{$page.formvalid}"
text="Reset Password"
/>
</FlexCol>
</ValidationGroup>
</form>
However, the validatePasswordsEqual runs only for the currently edited field, leaving the other field always unequal. I tried using store.notify() from inside the validatePasswordsEqual, but without success.
How can I cause validation on both fields at the same time?

You can use the validationParams field to trigger the validation if a value in another field changes.
<TextField
value-bind="$page.password1"
label="Password 1"
inputType="password"
validationParams={{ password2: { bind: '$page.password2 }}
required
validationRegExp={/(?=.*\d)(?=.*[!##$%^&*]+)(?![.\n])(?=.*[A-Z])(?=.*[a-z]).*$/}
minLength="6"
onValidate="validatePasswordsEqual"
/>
The third argument provided to the onValidate callback will be the calculated value of validationParams.

Related

ValidationError: 'value' is not a valid binding on <textField> elements Svelte-Native

I've created a new Svelte-native application and I'm trying to bind my value as follows:
<script lang="ts">
let newItem = ''
</script>
<page>
<actionBar title="Svelte Native App" />
<flexboxLayout flexDirection="column">
<textField bind:value={newItem} />
</flexboxLayout>
</page>
The problem is, when I run this application I get the following error:
ValidationError: 'value' is not a valid binding on elements
I'm not sure how to solve this, my IDE (VSCode) also returns a svelte invalid binding error.

AMP autocomplete how get id from autocomplete results and display only text in input

view screen I am using https://amp.dev/documentation/components/amp-autocomplete/ and I am able show in results id and name concated in one string, but I need show only name and store id in hidden input.
code screen
<amp-autocomplete filter="substring" filter-value="name" min-characters="2" src="/ajax/get_active_clinics.php" class="name_autocomplete">
<input type="text" placeholder="Numele clinicii" name="clinic_name" id="clinic_name"
{literal}on="change:AMP.setState({clinic_name_validation: true, form_message_validation:true})"{/literal}>
<span class="hide"
[class]="formResponse.clinic_name && !clinic_name_validation ? 'show input_validation_error' : 'hide'">Clinica este obligatorie</span>
<template type="amp-mustache" id="amp-template-custom">
{literal}
<div class="city-item" data-value="ID - {{id}}, {{name}}">
<div class="autocomplete-results-item-holder">
<div class="autocomplete-results-item-img">
<amp-img src="{{link}}" alt="{{name}}" width="40" height="40"></amp-img>
</div>
<div class="autocomplete-results-item-text">{{name}}</div>
</div>
</div>
{/literal}
</template>
</amp-autocomplete>
You can use the select event on amp-autocomplete to get the event.value which will return the value of the data-value attribute of the selected item.
https://amp.dev/documentation/components/amp-autocomplete/#events
You can then call the split() string method on the result.
You'll need to modify the data-value in your mustache template like so:
<div class="city-item" data-value="{{id}},{{name}}">
Then add the following code to your autocomplete, this will assign the split values to 2 temporary state properties.
<amp-autocomplete
...
on="select: AMP.setState({
clinicName: event.value.split(',')[0],
clinicId: event.value.split(',')[1]
})"
>
Once these values are in state you can then access them using bound values. Note the [value] attribute, this will update the inputs value when state changes. It's worth mentioning that the change in value won't trigger the change event listener on your input here as it's only triggered on user interaction.
<input
type="text"
placeholder="Numele clinicii"
name="clinic_name"
id="clinic_name"
[value]="clinicName"
on="change:AMP.setState({
clinic_name_validation: true,
form_message_validation:true
})"
/>
Last thing you'll need to do is add the hidden input for Clinic ID, again this will need to be bound to the temporary state property clinicId.
<input
type="hidden"
name="clinic_id"
[value]="clinicId"
>

Input assisted doesn't show all suggestions

I have input field i need suggest items from odata model.
<Input
id="productInput"
type="Text"
placeholder="Enter Product ..."
showSuggestion="true"
showValueHelp="true"
valueHelpRequest="handleValueHelp"
suggestionItems="{/ProductCollection}" >
<suggestionItems>
<core:Item text="{Name}" />
</suggestionItems>
</Input>
the problem is there are missing items : not all items are displayed (you can check this link
https://sapui5.hana.ondemand.com/#/sample/sap.m.sample.InputAssisted/preview
it is the same behaviour when you put a for example it shows some items in the search it shows more with a )
What you are trying to do is basically show all items that contains the value in the input. SAPUI5 has a convenient filter for this called sap.ui.model.FilterOperator.Contains.
The problem with the sap.m.Input is that it will only work one way, even if you manually set the Contains filter in the Suggest event, it will show suggestions that will start with the provided letter instead, just like sap.ui.model.FilterOperator.StartsWith filter operator. That's why it is showing you less suggestions.
Using the same products.json model in your question, we can do the following:
XML Input:
<Label text="Product" labelFor="productInput"/>
<Input
id="productInput"
type="Text"
placeholder="Enter Product ..."
showSuggestion="true"
showValueHelp="false"
suggest="handleSuggest"
suggestionItems="{productsModel>/ProductCollection}" >
<suggestionItems>
<core:Item text="{productsModel>Name}" />
</suggestionItems>
</Input>
Controller:
handleSuggest: function (oEvent) {
var aFilters = [];
var sTerm = oEvent.getParameter("suggestValue");
if (sTerm) {
aFilters.push(new sap.ui.model.Filter("Name", sap.ui.model.FilterOperator.Contains, sTerm));
}
oEvent.getSource().getBinding("suggestionItems").filter(aFilters);
//do not filter the provided suggestions before showing them to the user - important
oEvent.getSource().setFilterSuggests(false);
}
It is very important to set the setFilterSuggests() method to false in order not to filter the provided suggestions before showing them to the user, this would go against we just did previously.
Using this approach, the suggested item will show only those values filtered by the specified filter condition which is sap.ui.model.FilterOperator.Contains.
Other SAPUI5 Filter Operators

sap.ui.table.Column Regards Only Last Control and Expression Binding Doesn't Work

I have a column in a sap.ui.table.Table. In this column, I want to display my template control depending on the value. If I have a typeof DateTime, I want to use the DatePicker, typeof DateTime a DateTimePicker, and so on.
Now I want to differ it in my XMLView / Fragment but it only checks my last control (DateTimePicker):
<table:template>
<Input id="masterDataValueInput"
value="{thingDetail>value}"
placeholder="{path:'thingDetail>type', formatter:'.formatter.placeHolderFormatter'}"
visible="{= ! ${path: 'thingDetail>properties'} && ${path: 'thingDetail>type', formatter: '.formatter.inputVisibility'}}"
enabled="{appView>/isCurrentTenant}"
type="{path:'thingDetail>type', formatter:'.formatter.inputTypeFormatter'}"
/>
<DatePicker id="masterDataValueDate"
value="{thingDetail>value}"
displayFormat="short"
visible="{= ! ${path: 'thingDetail>properties'} && ${path: 'thingDetail>type', formatter: '.formatter.dateVisibility'}}"
enabled="{appView>/isCurrentTenant}"
change="handleChange"
/>
<DateTimePicker id="masterDataValueDateTime"
value="{thingDetail>value}"
displayFormat="short"
visible="{= ! ${path: 'thingDetail>properties'} && ${path: 'thingDetail>type', formatter: '.formatter.datetimeVisibility'}}"
enabled="{appView>/isCurrentTenant}"
change="handleChange"
/>
</table:template>
So the <Input> and the <DatePicker> controls are never displayed..
The methods in my formatter are never called either.
The reason why only the last control (DateTimePicker) is taken into account is because the template aggregation of sap.ui.table.Column awaits only a single control (0..1).
In order to make use of all three controls, you'll have to wrap them together in another container / layout control such as HorizontalLayout:
<table:template>
<layout:HorizontalLayout>
<!-- your controls -->
</layout:HorizontalLayout>
<table:template>
About the expression binding..
Try with parts:
visible="{= !${thingDetail>properties} && ${parts: [{path: 'thingDetail>type'}], formatter: '.formatter.inputVisibility'}}"
If that didn't call the formatter, toss that expression binding (as it's become hard to read anyway) and go for the usual property binding with the appropriate formatter:
visible="{
parts: [
'thingDetail>properties',
'thingDetail>type'
],
formatter: '.formatter.myFormatter'
}"

Contact form 7 set minimum field value

I want set a minimum value in "Amount" field. An error message should be lower than the minimum value.
<p>Amount:<br />
[text* amount]</p>
<p>Name :<br />
[text* your-name] </p>
<p>Email :<br />
[email* your-email] </p>
<p>Message :<br />
[textarea your-message] </p>
<p>[submit "SEND"]</p>
Contact Form 7 has a number field. So, in your case, you could do something like:
[number* amount min:10 max:99 step:1 "40"]