Conditionally format value in React-Final-Form based on data in form? - react-final-form

I am displaying a currency value in a react-final-form. I am using a format function on the field.
const formatMoney = (value) => {
if (!value) return value;
const formatter = new Intl.NumberFormat('en-US', {
style: 'currency',
minimumFractionDigits: 2,
currency: 'USD'
});
return formatter.format(value);
};
The problem is the currency is another option in the form. I do not see a clean way to access the rest of the values inside a format function.

After asking the question, I figured out this work around, pass the values into the render function of the form and pass down to the format function like this:
<Field
name="total"
type="text"
readOnly
component={LabeledInput}
placeholder="10"
label="Total"
help="Estimated total including tax"
format={v => formatMoney(v, values.currency)}
/>

Related

My component returns undefined in react hook form controller

I can't figure out how to add an array from a component to my form. When I submit the form I get undefined. You need to use a controller, but it doesn't return anything. Help me to understand. I added an example to the github repository. I will be glad for any help
https://github.com/NikolayMirov/form-step
<Controller
control={control}
name="parameters"
render={({field}) => <Step name={field.name} value={field.value} onChange={field.onChange}/>}
/>
Then in your Step component when value change call props.onChange and pass the array.
const handleMonthChange = (month: string, idx: number) => {
const newStateArr = state.map((item) => {
if (idx !== item.id) return item;
return { ...item, month: Number(month) };
});
setState(newStateArr);
props.onChange({
target: {
name: props.name,
value:newStateArr
}
});
};

how to retrieve form values and labels from react hook form and antd Select

I am using antd Select and react hook form via 'Controller'. I am populating the Select options from a fetched data with structure;
{
{
"id": "232342",
"term": "hello"
}
{
"id": "232342",
"term": "hello"
}
}
the Select component properly displays the term for selection. However, i want to retrieve both the 'id'and 'term' of the selected and use it to populate another json object.
getValues(" ") retrieves the 'id' only. How do i retrieve and access both the 'id' and 'term'.
Here is a portion of code:
import React from 'react'
import { useForm, Controller } from 'react-hook-form'
import { Select } from 'antd'
const { Option } = Select
export default function PatientRegistrationForm({ options }) {
const { register, handleSubmit, getValues, control, formState: { errors } } = useForm({
defaultValues: {
customer: "",
}
})
const children = []
for (const {id, pt: {term}} of options){
children.push(<Option key={id}>{term}</Option>)
}
// Define the retrieved values from the form
const retrievedID = getValues("customer")
// Use the retreived values to populate this object
const customer = {
customerId = retrievedID
customerName = "nothing happens here"
},
return (
<div className="">
<form onSubmit={handleSubmit(onSubmit)} className="">
<section>
<Controller
control={control}
name="customer"
render={({ field }) => (
<Select {...field} defaultValue=""
bordered={true}
filterOption={true}
className="form-control"
>
{ children }
</Select>
)}
/>
</section>
</form>
</div>
);
}
Thanks in advance for your help.
You have to retrieve the option manually using something like:
const retrievedID = getValues("customer")
const retrievedOption = options.find(option => option.id === retrievedID)
const customer = {
customerId: retrievedID,
customerName: retrievedOption.term
}
thank you #sgarcia.dev for your answer. I know its been a while but i want to put it out here incase it helps someone else. It turns out it had little to do with react hook form. Ant design select component has a prop 'labelInValue' which returns an object containing both the label and value.

Form Data not submitting complete string

Could someone tell me what my form data's string ends at the comma? I'm sending a form with react with a string with foo, bar but only foo is sent in the form data. This has nothing to do with the database as in the chrome dev tools, under network, I see only one value of the string. Here's a image of my actual views:
Only Wordpress, gets submitted. Noticed the ,?
Some code, in React (I'm using react-select):
<form action="/" method="post">
<Select ref="stateSelect" options={skillsOptions} simpleValue multi={this.state.multi} value={this.state.skillsSelectValue} name="skills" onChange={this.skillsUpdateValue} valueKey="value" labelKey="name" loadOptions={this.getContributors} />
</form>
skillsUpdateValue: function(newValueCnd) {
// var str = newValueCnd.split(',');
this.setState({
skillsSelectValue: newValueCnd
});
this.setState({
skills: newValueCnd
});
},
Am I missing something from the form? Using just Rails, all words great.
Edit:
Input options:
var skillsOptions = [
{ value: 'one', name: 'One' },
{ value: 'two', name: 'Two' }
];

Jqgrid dynamic dropdownlist based on value in some other column

I have a JQGrid with 3 columns. The third column, I want it as a dropdownlist based on some value in the second column. Is this Possible?
Also in the JQGrid demo, do add a dropdown we need to set the edittype to "select" and pass the values in JSON.
edittype:"select",editoptions:{value:"FE:FedEx;IN:InTime;TN:TNT;AR:ARAMEX"}},
My next question is how to pass values to this column from a model object in the format it is expecting.
You can use dataUrl or postData property of editoption defined as function. See the answer or here and here. If you need to send standard URL parameters like /mySetectUrl?status=StatusValue then you can use
name: "Field5", edittype: "select",
editoptions: {
// it produces URL like /mySetectUrl?status=StatusValue
dataUrl: "/mySetectUrl",
postData: function (rowid, value, name) {
return { status: $(this).jqGrid("getCell", rowid, "Status") };
}
}
If you need to construct some another URL like /mySetectUrl/StatusValue you can use dataUrl defined as function:
name: "Field5", edittype: "select",
editoptions: {
// it produces URL like /mySetectUrl/StatusValue
dataUrl: function (rowid, value, name) {
return "/mySetectUrl/" +
encodeURIComponent($(this).jqGrid("getCell", rowid, "Status"));
}
}

Setting error message in html with knockout validation

I would like to use knockout-validation by only adding validation rules in HTML5, which works great:
http://jsfiddle.net/gt228dgm/1/
I would then like to change the default error messages generated by the browser (like "This field is required." or "Invalid"). This is pretty easily done in javascript code, But I believe this kind of texts should go into the HTML. Is that possible and how? I guess I'm looking for something like:
<input data-bind='value: firstName, validate: { message: "Please enter first name" }' required pattern="^[A-Za-z]{1,255}$"/></label>
I have implemented a custom knockout binding that solves my issue:
ko.bindingHandlers.validate = {
init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
var valueBinding = allBindings().value;
var value = valueAccessor();
if (value) {
valueBinding.extend(value);
}
}
};
The binding then looks like this
<input data-bind='value: firstName, validate: { required: { message: 'Full name is missing' }, pattern: { message: 'Full name should be max. 255 alphanumeric characters' } }' required pattern="^[A-Za-z]{1,255}$"/>
Any other suggestions?
I've been playing these days with knockout validation. For your need, you could use validationMessage binding. Here is an example of your code modified, to use this binding: http://jsfiddle.net/elbecita/gt228dgm/4/
Basically, you'd end up having something like:
<span data-bind="validationMessage: firstName, text: 'Your error.'"></span>
<input data-bind='value: firstName, valueUpdate: "input"' required pattern="^[A-Za-z]{1,255}$" />
I've added the valueUpdate binding just to have the validation message shown immediately. And then, in your javascript code, when you define the validation configuration, be sure to turn to false the insertMessages option. If not, you'll see the default message too.
But... I think is easier and cleaner to do this with the knockout extenders in javascript code, having all custom messages centralized in some sort of constants file, instead of having them scattered through the html.
Anyway, dig into the knockout validation bindings, they may help you with your needs. :)
Proper way to handle custom validation message in KO is to create a custom validation not binding.
Here is an example of simple number validation
ko.validation.rules['integerFormat'] = {
validator: function (value, options) {
if (!value) return true;
var regex = /^\d+$/;
var matches = regex.test(value);
if(matches){
value = parseInt(value,10);
return typeof value== "number" && isFinite(value) && value%1===0;
}else{
return false
}
},
message: app.MyCustomIntegerNotValidMSG
}
app.MyCustomIntegerNotValidMSG is just a variable holding your MSG
You would use this in your ViewModel like this
self.myIntegerToValidate = ko.observable().extend({
integerFormat:{}
});;

Resources