I'm trying to display PhoneInput value in a data preview (React) using an event handler handleOnChangePhoneInput. How do I make it work?
Here is the source code.
I want to display the "phone number" value entered by a user in the "data preview" sheet right below the "Submit" button in the demo. For example, when one enters a "first name" value and click on "Submit", the first name is displayed in the data preview but I could not make it work for "phone number" and "data of birth".
Demo
Component
<PhoneInput
name="phoneNumber"
type="text"
country={"us"}
enableAreaCodes={true}
onlyCountries={["us"]}
areaCodes={{ us: ["000"] }}
inputProps={{
name: "phone",
country: "us",
required: true,
autoFocus: true
}}
value={this.state.phone}
onChange={this.handleOnChangePhoneInput}
inputStyle={{
width: "230px",
height: "45px"
}}
/>
Event
handleOnChangePhoneInput = value => {
this.setState({ phone: value }, () => {
return this.state.phone;
});
};
[Thanks! I'm new to React.]
So this is how you would do it , First of all you need to maintain the state of your inputs so you would have to modify the state a bit
state = {
firstName: "",
lastName: "",
phone: "",
emailAddress: "",
eligibleAge: false,
max: new Date(
new Date().getFullYear() - 21,
new Date().getMonth(),
new Date().getDate()
),
min: new Date(
new Date().getFullYear() - 120,
new Date().getMonth(),
new Date().getDate()
),
selectedDate: ""
};
the next thing you want to do is create three additional event listeners one for all the text inputs and one for the checkbox and one for the calender, this could be merged into one but for simplicity let's keep it separate
// Text Inputs
onChange = e => {
console.log(e);
this.setState(
{
...this.state,
[e.fieldProps.name]: e.fieldProps.value
},
() => {
console.log(this.state);
}
);
};
// CheckBox
onCheckBoxChange = e => {
this.setState(
{
...this.state,
eligibleAge: !this.state.eligibleAge
},
() => {
console.log(this.state);
}
);
};
// Calender
onSelect = e => {
var SelectedDate =
e.getDate() + "-" + (e.getMonth() + 1) + "-" + e.getFullYear();
this.setState(
{
...this.state,
selectedDate: SelectedDate
},
() => {
console.log(this.state);
}
);
};
the next thing you want to do is pass the arguments to the function.(since in the demo that you provided if a filed is empty it does not show.so i decided to mimic that by checking if that field is empty)
<Form
onSubmitStart={() =>
this.props.onSubmitStart({
...(this.state.firstName !== "" && {
firstName: this.state.firstName
}),
...(this.state.lastName !== "" && {
lastName: this.state.lastName
}),
...(this.state.emailAddress !== "" && {
emailAddress: this.state.emailAddress
}),
...(this.state.phone !== "" && { phone: this.state.phone }),
selectedDate: this.state.selectedDate,
eligibleAge: this.state.eligibleAge
})
}
>
and in the parent component(index.js) you would just change
handleSubmitStart = ({serialized}) => {
to this:
handleSubmitStart = serialized => {
CodeSandbox : here
your handle function must be something like:
const handleOnChangePhoneInput = value => {
this.setState({ phone: value });
};
and then, if you want to show the value make an onClick function inside the submit button
like:
const handleOnSubmit=()=>{
this.setState({visibleTelephone:true})
}
and in your component you need to add where is going to show the value:
<div>
{this.state.visibleTelephone?this.state.phone:null}
</div>
Related
I tried to only show the relevant objects only and strip as much as possible non-relevant things.
allComponentsFiltered returns a combination of 3 things,
search input
component_group_id
selectedComponent .status
// Desired objective:
I've created a tab with a value of inactive, which does not match a component status status.inactive
The idea is to return in the filter function the components that do not have status.active as true.
const state = {
componentStatusTabs: [
{ name: "All", value: "all", icon: "mdi-all-inclusive" },
{ name: "Starred", value: "starred", icon: "mdi-star" },
{ name: "Modular", value: "modular", icon: "mdi-view-module" },
{ name: "Active", value: "active", icon: "mdi-lightbulb-on" },
{ name: "Inactive", value: "inactive", icon: "mdi-lightbulb-off" }
],
};
// How the component statuses object looks.
selectedComponent = {
component_group_id: 81,
status: {
active: true,
modular: false,
starred: false,
}
}
// Returns the name of the tab name selected within the form field editor
activeComponentEditFormFieldsStatusTabName: state => {
return state.componentStatusTabs[state.activeStatusTab].value;
},
// Returns components that either belong to the selected group, matches the search string or has the corresponding status.
allComponentsFiltered: (state, getters, rootState) => {
if (!getters.hasSelectedSomeGroups) return [];
const search = rootState.application.search.toLowerCase();
return state.allComponents.filter(component => {
return (
(search === "" || component.config.general_config.title.toLowerCase().match(search)) &&
(getters.activeComponentEditFormFieldsStatusTabName === "all" || component.status[getters.activeComponentEditFormFieldsStatusTabName]) &&
state.selectedComponentGroups.some(group => group.id === component.component_group_id)
);
});
}
Answering to my self after I found the solution:
allComponentsFiltered: (state, getters, rootState) => {
if (!getters.hasSelectedSomeGroups) return [];
const search = rootState.application.search.toLowerCase();
return state.allComponents.filter(component => {
return (
(search === "" || component.config.general_config.title.toLowerCase().match(search)) &&
(getters.activeComponentEditFormFieldsStatusTabName === "all" ||
(getters.activeComponentEditFormFieldsStatusTabName === "inactive" && !component.status.active) ||
component.status[getters.activeComponentEditFormFieldsStatusTabName]) &&
state.selectedComponentGroups.some(group => group.id === component.component_group_id)
);
});
},
I added
|| (getters.activeComponentEditFormFieldsStatusTabName === "inactive" && !component.status.active)
I am trying to get my "submit" button to be enabled or disabled based on the validity of the email that is passed. However, the RegExp expression I am using is not reading the string properly. I've tried testing my isWorking() function with just email.length > 0 to make sure that whatever is being passed to isWorking() is indeed a string, and we are good there but RegExp is always returning false regardless of the input it receives. I'm using React without JSX in this app. Any help at all would be deeply appreciated. Thank you so much!
const validEmailRegex = RegExp(/^(([^<>()\[\]\\.,;:\s#"]+(\.[^<>()\[\]\\.,;:\s#"]+)*)|(".+"))#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/);
class Signup extends React.Component {
constructor() {
super();
this.state = {
email: ""
};
this.handleSubmit = this.handleSubmit.bind(this);
}
isWorking () {
const email = event.target;
//if (email.length > 0) {
// return false;
// }
// return true;
if (validEmailRegex.test(email) === true) {
return false;
}
return true;
}
handleSubmit(event) {
event.preventDefault();
if (!event.target.checkValidity()) {
this.setState({
invalid: true,
displayErrors: true,
});
return;
}
const form = event.target;
const data = new FormData(form);
for (let name of data.keys()) {
const input = form.elements[name];
const parserName = input.dataset.parse;
console.log('parser name is', parserName);
if (parserName) {
const parsedValue = inputParsers[parserName](data.get(name));
data.set(name, parsedValue);
}
}
this.setState({
res: stringifyFormData(data),
invalid: false,
displayErrors: false,
});
}
render() {
const { res, invalid, displayErrors } = this.state;
//pass data to the button for disabling or not
const isEnabled = this.isWorking();
return (
React.createElement("div", { className: "container" },
React.createElement("div", { className: "row" },
React.createElement("form", { onSubmit: this.handleSubmit, noValidate: true, className: displayErrors ? 'displayErrors' : '' },
React.createElement("input", { className: "form-control", name: "formEmail", id: "formEmail", type: "email", placeholder: "email"}),
),
React.createElement("span", { className: "span"},
React.createElement("fieldset", { className: "form-group" },
React.createElement(Link, { className: "nav-link", activeClassName: "nav-link-active", to: "/contact" },
React.createElement("button", { className: "button1", disabled: isEnabled, type: "button"}, "next")
),
)
),
),
)
);
}
}
Your isWorking() does not receive event from anywhere. Also, event.target will be an HTML element and definitely not an input value. For a form, you do event.target.elements["<name_of_input>"] (here, name of input if formEmail) to get input value.
I have input field to type numbers
<input type="text" class="form-control" id="validationTooltip01" v-model="verse.number" required>
I'd like to increment this number after store it in database.
Example
I enter 1 and save my form, next time i open my form the number be 2 instead of i be needed to type it every time.
Code
data() {
return {
verse: {
number: '',
heading: '',
body: '',
book_id: '',
chapter_id: '',
}
}
},
submit: function(e) {
axios.post('/my_url', this.verse)
.then(res => {
this.isLoading = false;
$('#exampleModal').modal('toggle');
this.getVerses.push( res.data.verse );
this.verse = {
number: this.verse.number, // here
heading: '',
body: '',
book_id: this.verse.book_id,
chapter_id: this.verse.chapter_id,
};
})
.catch(error => {
// handle authentication and validation errors here
this.errors = error.response.data.errors
this.isLoading = false
})
}
I have already tried these but none worked as i wanted,
this.verse = {
number: this.verse.number +=1,
...
and
this.verse = {
number: this.verse.number +1,
...
any idea?
Your this.verse.number type is String, so
this.verse.number + 1 // ''+ 1 = '1'
You should set your default value of verse.number( in data() {} ) to 0 insteed ''. Just change number: '', to number: 0, And it will be
this.verse.number + 1 // 0 + 1 = 1
And next increment will 1 + 1 = 2 etc
In my React app, I'm getting this error during onChange event with my email input field:
Warning: A component is changing a controlled input of
type text to be uncontrolled. Input elements should not switch from
controlled to uncontrolled (or vice versa).
Here's the onChange block that's causing this warning; The error goes away if I remove the first if block but of course I need it there for email validation.
validateEmail(email) {
const re = /^(([^<>()\[\]\\.,;:\s#"]+(\.[^<>()\[\]\\.,;:\s#"]+)*)|(".+"))#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
return re.test(email);
}
handleOnChange = e => {
const { name, value } = e.target;
const emailInput = e.target.value;
const emailValid = this.validateEmail(emailInput);
if (name === 'email') {
this.setState({
inputs: {
email: emailInput,
},
errors: {
email: !emailValid,
},
});
} else {
this.setState({
inputs: {
...this.state.inputs,
[name]: value,
},
errors: {
...this.state.errors,
[name]: false,
},
});
}
};
State:
constructor() {
super();
this.state = {
inputs: {
name: '',
email: '',
message: '',
},
phone: '',
show: true,
errors: {
name: false,
email: false,
message: false,
},
};
}
How do I keep my current code and address the warning?
You need to spread the existing/previous state in the if-block. You likely have other input tags that were initially connected to the input-state object which looks like:
inputs: {
name: "",
email: "",
message: ""
}
<input value={this.state.input.name} name="name"/>
<input value={this.state.input.email} name="email"/>
<input value={this.state.input.message} name="message"/>
but when you used this.setState() in your posted code, the connection is lost. You are setting the inputs state to an object with a single property of email:
inputs: {
email: "valueFromEventTarget"
}
What you need to do is spread the existing state so you don't lose the other key/value pairs in the input object: Update your handleChange() function to this:
handleOnChange = e => {
const { name, value } = e.target;
const emailInput = e.target.value;
const emailValid = this.validateEmail(emailInput);
if (name === 'email') {
this.setState({
inputs: {
...this.state.inputs,
email: emailInput,
},
errors: {
...this.state.errors,
email: !emailValid,
},
});
} else {
this.setState({
inputs: {
...this.state.inputs,
[name]: value,
},
errors: {
...this.state.errors,
[name]: false,
},
});
}
};
I have this form in my component :
this.state.customFieldsArray.length > 0 &&
(
<Form
ref="customForm"
type={this.customForm}
options={this.customFormOptions}
/>
)}
I want to add more options to the form (so it render more fields) when i click on a button.
This is the methode that handle the click on the button:
addCustomField = () => {
let newFieldName = this.state.customFieldLabel;
let newField = { newFieldName: "" };
this.customFormOptions.fields[newFieldName] = {
label: newFieldName
};
tempCustomFieldsArray.push(newField);
this.setState({
customFieldsArray: tempCustomFieldsArray
});
};
i have tried this but it didn't work.
this code works for me, create struct form model that call function, and user your condition there
formModel: t.struct({
customFields: this.getCustomFields(),
}),
then you create customFields function like,
getCustomFields = () => {
const customFields = {}
//write your condition here
return t.enums(customFields)
}