Passing type "checkbox" is not being registered with react-final-form - react-final-form

I'm running into an issue with react-final-form where it tells me I'm not passing the type=checkbox so it cannot unpack properly. I'm a little confused because in the example the custom component does get the type passed to it. A live example can be found below:
https://codesandbox.io/s/9o227yp3q4
What I'm seeing is the input starts in an undefined state and is then toggled to either true or false on user input. Starting in an undefined state I think is what is causing the issue but I'm not positive.
The error message I receive is
Warning: You must pass `type="checkbox"` prop to your Field(attendees[0].isHost) component. Without it we don't know how to unpack your `value` prop - "undefined".

I found out that I needed to pass the type on the <Field /> so that react-final-form could unpack the values and apply them correctly.
export const CustomField: React.SFC<Props> = ({
label,
name,
placeholder,
type
}) => (
<Field name={name} type={type}>
{({ input, meta }) => (
<div>
<StyledLabel htmlFor={name}>{label}</StyledLabel>
<StyledInput
{...input}
id={name}
placeholder={placeholder}
type={type}
/>
{meta.error && meta.touched && <span>{meta.error}</span>}
</div>
)}
</Field>
)

Related

playwright-test: test that input is required

I have an input for a login form that is required:
<input
autoComplete="email"
defaultValue={email}
disabled={state === 'submitting'}
id="email"
name="email"
placeholder={t('user-authentication:email-placeholder')}
required // HERE!
type="email"
/>
How can I test that the input is required with Playwright? My native browser warning in Chromium is: "Please fill in this field."
Is there a way to check / assert for this warning in Playwright? Or another way to test that the input is required?
I tried writing nothing in the input with .fill('') and then pressing enter with page.keyboard.press('Enter'), but those did not cause the warning to show up.
If the message is displayed by the browser and not something added to the DOM, you would struggle to test it directly in Playwright.
You could check the the required attribute is present, and trust that the browser is going to display the warning.
await page.locator('input#email[required]')
There's also a Constraint validation you could apply
If the element is required and the element's value is the empty string, then the element is suffering from valueMissing and the element will match the :invalid pseudo class.
await page.locator('input#email[required]:invalid')

Svelte input binding breaks when a reactive value is a reference type?

(I'm new to Svelte so it is quite likely that I'm doing something wrong here)
UPDATE: I've added a second, slightly different REPL which may demonstrate the problem better. Try this one: https://svelte.dev/repl/ad7a65894f8440ad9081102946472544?version=3.20.1
I've encountered a problem attempting to bind a text input to a reactive value.
I'm struggling to describe the problem in words, so hopefully a reduced demo of the issue in the attached REPL will make more sense.
https://svelte.dev/repl/6c8068ed4cc048919f71d87f9d020696?version=3.20.1
The demo contains two custom <Selector> components on a page.
The first component is passed two string values ("one" and "two"):
<Selector valueOne="one" valueTwo="two"/>
Clicking the buttons next to the input field sets selectedValue to one of these values.
This, in turn, triggers the following reactive declaration to update:
$: value = selectedValue
The input field is bound to this reactive value:
<input type="text" bind:value>
So clicking the "One" button sets the input text to "one", and clicking the "Two" button sets the input field to "two".
Importantly though, you can still type anything into the input field.
The second component is passed two array values:
<Selector valueOne={[1, "one"]} valueTwo={[2, "two"]}/>
Again, clicking the buttons sets selectedValue to one of these.
However this time the reactive declaration depends on an array element:
$: value = selectedValue[1]
Everything works as before, except now you can no longer type into the input field at all.
So the question is - why does <input bind:value> behave differently for these two:
$: value = aString
vs
$: value = anArray[x]
It seems that this is only an issue when using two-way bindings.
By switching to a one-way and an on:input handler, the problem goes away:
i.e. instead of this:
<input type="text" bind:value={valX}/>
use this:
<input type="text" value={valX} on:input={e => valX = e.target.value}/>
I'm pretty sure your reactive declaration is overwriting your bound value as soon as it changes, which is with every key stroke on the input and every button press. Meaning it technically is working, you're just reverting it each time it changes. Check out this version of it that uses a watcher.
Also binding to a reactive declaration means you're never actually changing the variables with the input (which you can see in your JSON result on the first selector when you type in the input the value doesn't update only on button click).
Why not lose the reactive declaration and bind directly to the variable you want. Then use an {#if} block to switch between which version of the input you're showing based on the truthiness of index?
<script>
export let valueOne;
export let valueTwo;
export let index;
let selectedValue = index? [] : '';
let selectValue = (val) => selectedValue = val;
</script>
{#if index}
<input type="text" bind:value={selectedValue[index]} placeholder="Type anything...">
{:else}
<input type="text" bind:value={selectedValue} placeholder="Type anything...">
{/if}
<button on:click={() => selectValue(valueOne)}>One</button>
<button on:click={() => selectValue(valueTwo)}>Two</button>
<p>
<strong>Selected value:</strong> {JSON.stringify(selectedValue)}
</p>
By binding directly to the selectedValue or an index of it you have the added benefit of changing the value with the input. Here's a working example in the REPL

New to React: Why is one array treated differently than the other?

I'm working on a React app that is fed data from a Rails api. I'm currently working on a form that includes a nested association (i.e. in the model_a has many model_b's and you can create them in the same form).
The problem I'm having is that Rails expects nested association with a certain naming convention and the same field that controls how the parameter is named when its sent to rails also controls how React finds the right data when the Rails API responds.
This becomes problematic on the edit page because I want to show the models_a's (Retailers) already existing model_b's (SpendingThresholds in this case) and when I change the 'name' field to suit the rails side, React doesn't know where to look for that data anymore. When I try to pass the data directly it comes in as a different type of array and certain functions fail.
I think its easier to show than tell here so
initially I had this
<FieldArray
name="spending_thresholds"
component={renderSpendingThresholds}
/>
and data was coming through like
Object {_isFieldArray: true, forEach: function, get: function, getAll: function, insert: function…
to my React app from the Rails API, which worked, however that 'name' isn't to Rails liking (Rails wants it to be called 'spending_thresholds_attributes' for accepts_nested_attributes to work) so I changed it to
<FieldArray
name="spending_thresholds_attributes"
fields={this.props.retailer.spending_thresholds}
component={renderSpendingThresholds}
/>
and data start coming through to the renderSpendingThresholds component in this format
[Object]
0:Object
length:1
__proto__:Array(0)
which React doesn't like for some reason.
Anyone know how to fix this/why those two objects, which hold the same information from the Rails side anyway, are being treated differently?
EDITS
renderSpendingThresholds component
The fields attribute in the renderSpendingThresholds component is the object that's coming through differently depending on how I input it
const renderSpendingThresholds = ({ fields }) => (
<ul className="spending-thresholds">
<li>
<Button size="sm" color="secondary" onClick={(e) => {
fields.push({});
e.preventDefault();
}
}>
Add Spending Threshold
</Button>
</li>
{fields.map((spending_threshold, index) => (
<li key={index}>
<h4>Spending Threshold #{index + 1}</h4>
<Button
size="sm"
color="danger"
title="Remove Spending Threshold"
onClick={() => fields.remove(index)}
>
Remove
</Button>
<Field
name={`${spending_threshold}.spend_amount`}
type="number"
component={renderField}
label="Spend Amount"
placeholder="0"
/>
<Field
name={`${spending_threshold}.bonus_credits`}
type="number"
component={renderField}
label="Bonus Credits"
placeholder="0"
/>
</li>
))}
</ul>
);
It looks like you are passing fields through props and then destructuring the fields out of the props in the callback of the renderSpendingThresholds and discarding the rest. According to the docs, a specific redux-form object is passed through to the render callback. You're essentially overwriting this. Try changing {field} to something like member or spending_threshold. Then you can use the specific map function to iterate over the spending_threshold items. Your field prop should still be available under member.fields or something similar.
For the code that you currently show, who exactly handles the submission?
you use the original flow of form submit?
if so, so please handle that by yourself.
** this line of code, looks weird:
onClick={() => fields.remove(index)}
as you interact directly with the state values...
you need to update the state through
this.setState({fields: FIELDS_WITHOUT_ITEM})
and now when you need to handle your own submission, you don't really care of the input names. Because you are using the state as input.
ie:
class FormSpending extends Component {
handleSubmit() {
var fieldsData = this.state.fields.map(field => {
return {
whateverkey: field.dontcare,
otherKey: field.anotherDontCare
};
});
var formData = {
fields: fieldsData
};
ajaxLibrary.post(URL_HERE, formData).....
}
render() {
return (
...
<form onSubmit={()=>this.handleSubmit()}>
...
</form>
...
);
}
}

How to reset input value if a condition fails Primefaces3.5

I have a problem. I am trying to save a information into the database, and before that I check some conditions like if-else like:
if(condition){
//Some Action
}else{
getFacesContext().addMessage(null,MessageFactory.getMessage(ResourceBundle.FACES_BUNDLE.getName(), FacesBundle.LANDLINE_NUMBER_SHOULD_BE_TEN.getName()));
getExternalContext().getFlash().setKeepMessages(true);
return;
}
and When the condition does not match I would like to restore the previous values of the input field.
In that case, it was 22 in place of ss. but the field does not take input except numbers. So the validation fails and shows an message Invalid Input via growl.
How can I also reset the value of the field ss to 22 in java?
Please suggest!
You can use default validator that comes with JSF
<p:inputText id="number" value="" label="Number">
<f:validateDoubleRange minimum="0" maximum="99" />
</p:inputText>
<p:message for="number" />
But if you reset the filed with old value, user may not know what he's entered. However you will not submit until validation success.
Since the input text component implements EditableValueHolder you can call EditableValueHolder.resetValue() on the input component (or call the more convenient RequestContext.getCurrentInstance().reset(inputTextId)) and then re-render it by calling RequestContext.getCurrentInstance().update(inputTextId) if it isn't already being re-rendered through the update attribute of p:ajax.

asp.net mvc checkbox inconsistency

I'm using an checkbox on an ASP.NET MVC form like so:
<%=Html.CheckBox("AgreeToRules", Model.AgreeToRules)%>
The AgreeToRules property on the model is a boolean value. During testing, this all worked fine. However, now that we've gone live with this app, I'm seeing a relatively small but significant number of errors with the following messaging:
System.Web.HttpUnhandledException:
Exception of type
'System.Web.HttpUnhandledException'
was thrown. --->
System.InvalidOperationException: The
parameter conversion from type
'System.String' to type
'System.Boolean' failed. See the inner
exception for more information. --->
System.FormatException: Y is not a
valid value for Boolean. --->
System.FormatException: String was not
recognized as a valid Boolean.
This appears to happen when the view engine tries to render the form after a post, and the value of the checkbox that is returned from the ValueProvider looks like:
Y,false
OR
N,false
The html that is rendered in the original form looks like:
<input id="AgreeToRules" name="AgreeToRules" type="checkbox" value="true" />
<input name="AgreeToRules" type="hidden" value="false" />
During testing, I expected (and showed) the posted value to look like:
true,false
if checked or
false
if not checked. So where is the N and Y coming from?
I added user agent to the list of information returned from the error handler and it appears (so far) that all of the errors are occuring under windows XP with FF 3.0.10, but that's exactly what I have tested with and the problem did not exist during testing.
Any thoughts?
We had this same issue on a project I'm working on (MVC 2). We solved it by replacing the helper with plain html code:
Before:
<%= Html.CheckBox("Credit", false, new {#validate = "required"}) %>
After:
<input type="checkbox" name="Credit" value="true" validate="required" />
<input type="hidden" name="Credit" value="false" />
It's quite possible that your site is being hit by spambots that are submitting this value, and not real users. The more sites I add automated logging and emailing to, the more of these types of "probes" and errors (though not exactly the type you mention, with a "Y" for a checkbox) that I see piling into my inbox. Does your logging also capture the rest of the submitted form contents?
Today I came up with a solution for a similar problem that could be perhaps be adapted to fit your particular need. It will "do the job" for what you are asking, but may not be the most reusable solution.
The idea is that you will walk through the posted form fields and fix the "broken" checkbox values. You can create a ValueProviderDictionary a.k.a. IDictionary<string, ValueProviderResult> and then hand that to your UpdateModel method.
public static IDictionary<string, ValueProviderResult> CreateScrubbedValueProvider(NameValueCollection postedForm, string[] checkboxFieldsToScrub)
{
Dictionary<string, ValueProviderResult> dict = new Dictionary<string, ValueProviderResult>();
foreach (string key in postedForm.AllKeys) {
string[] values = postedForm.GetValues(key);
if (checkboxFieldsToScrub.Contains(key)) {
// Ensure we have a "true" value instead of "Y" or "YES" or whatever...
// Note that with a checkbox, only the first value matters, so we will only
// worry about values[0] and not values[1] (the "unchecked" value, if exists).
if (values[0] == "Y" || values[0] == "YES") {
values[0] = "true";
}
}
string value = String.Join(",", values);
ValueProviderResult vpr = new ValueProviderResult(values, value, null);
dict.Add(key, vpr);
}
return dict;
}
Your controller will need to accept a NameValueCollection (or FormCollection) in its parameters, and you'll need to hand your generated ("scrubbed") value provider dictionary to the UpdateModel method. I haven't tested this exactly, but my version of this is working very similarly for me. Best of luck!
Well I found the problem, and thought I'd post it here in case others encounter it. Certain form fillers will detect the fields using the names I've used and try to "fill them" automatically by setting the value to whatever the user has previously used for similarly named fields. Starting late last night, I'm also receiving "UNSUBSCRIBED" and "SUBSCRIBED" as values for a checkbox named "OptIn".
So, the form filler changes the value of the checkbox to something and the user checks the box, resulting in the unexpected value being transmitted to the server.
Any thoughts on dealing with this would be appreciated.

Resources