How to toggle show hide functionality for multiple fields in formik? - passwords

import React, { Fragment, useState, useEffect } from "react";
import { useSelector, useDispatch, connect } from "react-redux";
import { useNavigate } from "react-router";
import { Field, Form, Formik } from "formik";
import VisibilityIcon from "#material-ui/icons/Visibility";
import VisibilityOffIcon from "#material-ui/icons/VisibilityOff";
import { changePassword } from "../../Redux/Actions/changePasswordAction";
import { passwordErrors, roles } from "../Shared/constants";
import Alert from "../Modal/modal";
import "./ChangePassword.css";
function ChangePassword() {
const [showPassword1, setShowPassword1] = useState(false);
const [showPassword2, setShowPassword2] = useState(false);
const [showPassword3, setShowPassword3] = useState(false);
const alert = useSelector((state) => state.alert);
enter code here
const role_id = localStorage.getItem("role_id");
//Redux Dispatch:
const dispatch = useDispatch();
//Used to navigate
const navigation = useNavigate();
const passwords = {
currentPassword: "",
newPassword: "",
confirmNewPassword: "",
};
// function toggleShowPassword(clickedField) {
// if (clickedField === showPassword1) {
// setShowPassword1(!showPassword1) &&
// setShowPassword2(showPassword2) &&
// setShowPassword3(showPassword3);
// } else if (clickedField === showPassword2) {
// setShowPassword2(!showPassword2) &&
// setShowPassword1(showPassword1) &&
// setShowPassword3(showPassword3);
// } else {
// setShowPassword3(!showPassword3) &&
// setShowPassword1(showPassword1) &&
// setShowPassword2(showPassword2);
// }
// }
function toggleShowPassword1() {
setShowPassword1(!showPassword1);
}
function toggleShowPassword2() {
setShowPassword2(!showPassword2);
}
function toggleShowPassword3() {
setShowPassword3(!showPassword3);
}
//Alert
useEffect(() => {
if (Number(role_id) === roles.TRAINER_ROLE_ID) {
if (alert.type === "success_clear") {
navigation("/trainer-profile");
}
} else {
if (alert.type === "success_clear") {
navigation("/user-profile");
}
}
}, [alert, navigation, role_id]);
function validate(passwords) {
const errors = {};
if (passwords.currentPassword === "") {
errors.currentPassword = passwordErrors.PASSWORD;
}
if (passwords.newPassword === passwords.currentPassword) {
errors.newPassword = passwordErrors.OLD_NEW_SAME;
}
if (passwords.newPassword === "") {
errors.newPassword = passwordErrors.PASSWORD;
} else if (
!/^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!##%&])(?=.{8,})/.test(
passwords.newPassword
)
) {
errors.newPassword = passwordErrors.PASSWORD_INVALID;
}
if (passwords.confirmNewPassword === "") {
errors.confirmNewPassword = passwordErrors.CONFIRM_PASSWORD;
} else if (passwords.confirmNewPassword !== passwords.newPassword) {
errors.confirmNewPassword = passwordErrors.PASSWORDS_UNMATCHED;
}
return errors;
}
function handleChangePassword(passwords) {
const id = localStorage.getItem("user_id");
const passwordsData = {
oldPassword: passwords.currentPassword,
password: passwords.confirmNewPassword,
};
dispatch(changePassword(id, passwordsData));
}
return (
<Fragment>
<div className="row">
<div className="col">
<span className="main-heading mx-4">Change Account Password</span>
<div className="mx-4">
<hr></hr>
</div>
</div>
</div>
{alert.message && <Alert show={true} />}
<div className="passwords">
<Formik
initialValues={passwords}
validate={(values) => validate(values)}
onSubmit={(values) => handleChangePassword(values)}
>
{({ errors, touched }) => (
<Form>
<div className="row">
<div className="col-md">
<div className="form-group mb-4">
<label htmlFor="currentPassword" className="cp-label">
Current Password
</label>
<div className="input-group">
<Field
type={showPassword1 ? "text" : "password"}
id="currentPassword"
name="currentPassword"
placeholder="Enter your Current password"
className={
errors.currentPassword && touched.currentPassword
? "form-control primary-input-field is-invalid pass"
: "form-control primary-input-field pass"
}
/>
<span
className="input-group-text"
id="basic-addon2"
// onClick={() => toggleShowPassword(showPassword1)}
onClick={toggleShowPassword1}
>
{showPassword1 ? (
<VisibilityIcon
fontSize="small"
className="iconColor"
/>
) : (
<VisibilityOffIcon
fontSize="small"
className="iconColor"
/>
)}
</span>
{touched.currentPassword && errors.currentPassword ? (
<div className="invalid-feedback">
{errors.currentPassword}
</div>
) : null}
</div>
</div>
</div>
</div>
<div className="row">
<div className="col-md">
<div className="form-group mb-4">
<label htmlFor="newPassword" className="cp-label">
New Password
</label>
<div className="input-group">
<Field
type={showPassword2 ? "text" : "password"}
id="newPassword"
name="newPassword"
placeholder="Enter your New password"
className={
errors.newPassword && touched.newPassword
? "form-control primary-input-field is-invalid pass"
: "form-control primary-input-field pass"
}
/>
<span
className="input-group-text"
id="basic-addon2"
// onClick={() => toggleShowPassword(showPassword2)}
onClick={toggleShowPassword2}
>
{showPassword2 ? (
<VisibilityIcon
fontSize="small"
className="iconColor"
/>
) : (
<VisibilityOffIcon
fontSize="small"
className="iconColor"
/>
)}
</span>
{touched.newPassword && errors.newPassword ? (
<div className="invalid-feedback">
{errors.newPassword}
</div>
) : null}
</div>
</div>
</div>
</div>
<div className="row">
<div className="col-md">
<div className="form-group mb-4">
<label htmlFor="confirmNewPassword" className="cp-label">
Confirm New Password
</label>
<div className="input-group">
<Field
type={showPassword3 ? "text" : "password"}
id="confirmNewPassword"
name="confirmNewPassword"
placeholder="Confirm your New password"
className={
errors.confirmNewPassword &&
touched.confirmNewPassword
? "form-control primary-input-field is-invalid pass"
: "form-control primary-input-field pass"
}
/>
<span
className="input-group-text"
id="basic-addon2"
// onClick={() => toggleShowPassword(showPassword3)}
onClick={toggleShowPassword3}
>
{showPassword3 ? (
<VisibilityIcon
fontSize="small"
className="iconColor"
/>
) : (
<VisibilityOffIcon
fontSize="small"
className="iconColor"
/>
)}
</span>
{touched.confirmNewPassword &&
errors.confirmNewPassword ? (
<div className="invalid-feedback">
{errors.confirmNewPassword}
</div>
) : null}
</div>
</div>
</div>
</div>
<div className="row mt-4">
<div className="col text-end">
<button className="btn primary-button" type="submit">
Change Password
</button>
</div>
</div>
</Form>
)}
</Formik>
</div>
</Fragment>
);
}
const mapStateToProps = (state) => ({
changePassword: state.changePassword,
});
export default connect(mapStateToProps, {
changePassword,
})(ChangePassword);
Please someone help me to apply only one function that can toggle show and hide for three fields, I have already tried one function but it's not working. I couldn't know what to do ? I need one function there to toggle eye symbol when it is clicked, but with the function I have used it's changing and I am pressing for one field and another field's being shown, please someone explain me

Related

Having problems calling an API id

Hi I am having some problems figuring out how to access an id. I am making a twitter cloner and I have an Icon I would like to click and see what people are commenting on it. But I have hit a wall and cant figure out how to access the Id when the chatbubble is clicked.
Any help would be greatly appreciated. The API works perfectly and I can call an id through postman.
const GetData = (id) => {
axios.get('https://localhost:44368/api/users/{id}').then((response) => {
console.log(response.data, "list of heroes ");
});
};
return (
<div className="post">
<div className="ppictur">
<Avatar src={avatar} />
</div>
<div className="post_body">
<div className="post_header">
<div className="post_headerText">
<h3>
{displayName}
<span className="post_headerSpecial">
<VerifiedIcon className="post_badge" />
#{username}
</span>
</h3>
</div>
<div className="post_headerDesription">
<p>{text}</p>
</div>
</div>
<img src={image} alt="" />
<div className="post_footer">
<ChatBubbleOutlineIcon onClick={GetData()} />
<RepeatIcon fontSize="small" />
<FavoriteBorderIcon fontSize="small" />
<PublishOutlinedIcon fontSize="small" />
</div>
</div>
</div>
);
}
export default Post;
const [posts, setPosts] = useState([]);
useEffect(() => {
axios.get('https://localhost:44368/api/users').then((response) => {
console.log(response.data, "list of heroes ");
setPosts(response.data);
});
}, []);
const icon = document.getElementById("Dark");
function DarkM() {
document.body.classList.toggle("dark-theme");
}
return (
<div className="commentbox">
<div className="header">
<h2>Home</h2>
<DarkModeOutlinedIcon id="Dark" onClick={() => DarkM(icon)} />
</div>
<Opinion />
{posts.map(post => (
<Post
avatar={post.profilePicture}
displayName={post.name}
username={post.userName}
text={post.post}
image={post.image}
bull
/>
)).reverse()}
</div>
);
}
export default Feed; ```
Use template literal ES6 with backticks.
const GetData = (id) => {
axios.get(`https://localhost:44368/api/users/${id}`).then((response) => {
console.log(response.data, "list of heroes ");
});
};
Also when you call it, make sure to pass arguments.
<ChatBubbleOutlineIcon onClick={GetData(9)} />
In my other component i wasnt pushing all the data through. that is my props didnt know what i was trying to call
const objectToPass = {
postId, avatar, displayName, username, text, image
}
const showSingleData = (value) => {
navigate(`/tweet/${value.postId}`)
console.log(value)
}```
it was a problem with my other component

Custom Gutenberg Block with Slider

I'm creating a Gutenberg block for a slider using Boostrap. I can't figure out how I can go about inserting the "active" class only on the first post inside the loop, any suggestions would be appreciated, thanks.
This is my Edit file:
import { Component, RawHTML } from "#wordpress/element";
import { RichText, BlockControls, InspectorControls, AlignmentToolbar} from "#wordpress/editor";
import { __ } from "#wordpress/i18n";
import { withSelect } from "#wordpress/data";
import { decodeEntities } from "#wordpress/html-entities";
import { Toolbar, PanelBody, BaseControl, ColorPicker, FontSizePicker, RangeControl, TextControl, SelectControl } from "#wordpress/components";
import { dateI18n, format, __experimentalGetSettings } from '#wordpress/date';
class SliderEdit extends Component {
onChangeCategories = (categories) => {
this.props.setAttributes({postCategories: categories.join(',')})
}
onChangeNumberOfPosts = (numberOfPosts) => {
this.props.setAttributes({numberOfPosts})
}
render() {
const { className, attributes, setAttributes, categories, posts} = this.props;
const {
postCategories,
numberOfPosts,
} = attributes;
const dateFormat = __experimentalGetSettings().formats.date;
return(
<>
<InspectorControls>
<PanelBody
title={__('Loop Settings', 'df-slider-b')}
>
<div class="df-cat-multiple">
<SelectControl
multiple
label={__("Categories","df-blocks")}
help={__('You can select multiple categories!','df-blocks')}
onChange={this.onChangeCategories}
options={categories && categories.map(category => ({value: category.id, label: category.name}))}
value={postCategories && postCategories.split(',')}
/>
</div>
<RangeControl
label={__("Number of Posts","df-blocks")}
help={__('Set -1 to get all posts','df-blocks')}
value={ numberOfPosts }
onChange={ this.onChangeNumberOfPosts }
min={-1}
max={10}
/>
</PanelBody>
</InspectorControls>
{(posts && posts.length > 0) ?
<div id="carouselDFControls" class="df_height_carousel_block carousel slide" data-ride="carousel">
<div class="carousel-inner">
{posts.map( post=> (
<>
{post && post._embedded && post._embedded['wp:featuredmedia'] &&
<div class="carousel-item active">
<img src={ post._embedded['wp:featuredmedia'][0].source_url } />
</div>
}
</>
))}
<a class="carousel-control-prev df-carousel-control-prev" href="#carouselDFControls" role="button" data-slide="prev">
<i class="icon-arrow-left"></i>
</a>
<a class="carousel-control-next df-carousel-control-next" href="#carouselDFControls" role="button" data-slide="next">
<i class="icon-arrow-right"></i>
</a>
</div>
</div>
: <div>{posts ? __("No posts found","df-blocks") : __("Loading...","df-blocks")}</div>
}
</>
)
}
}
export default withSelect(
(select, props) => {
const { attributes } = props;
const { numberOfPosts, postCategories } = attributes;
let query = { per_page: numberOfPosts}
if(postCategories) {
query['categories'] = postCategories;
}
return {
posts: select('core').getEntityRecords('postType', 'post',{_embed: true} ),
posts: select('core').getEntityRecords('postType', 'post', query ),
categories: select('core').getEntityRecords('taxonomy','category', {per_page: -1})
}
}
)(SliderEdit);
If I don't add the "active" class in the first post the carousel doesn't work.
Regards
Denis
You can use the index param in your map function. If the index is 0 it is the first item in the loop.
{ posts.map( ( post, index ) => (
<div className={ `carousel-item${ index === 0 ? ' active' : '' }` }>
...
</div>
) }
Also, you want to use className instead of class in React.

How to call components with function/method in pages?

My partner create a login page with several components like "email", "password", "phone number", "login button" and "forgot password". But then ask me to move all the components into new vue under '/components' folder. I only know to move the components but I cannot make it functional since the method is not callable. Please help.
original login page:
<template>
<div class="q-pa-md" style="width: 400px">
<q-form
#submit="onSubmit"
#reset="onReset"
class="q-gutter-md"
>
<!-- <q-input
filled
v-model="email"
label="Your email *"
lazy-rules
:rules="[val => !!val || 'Email is missing', isValidEmail]"
/>
<q-input
filled
type="password"
v-model="password"
label="Password *"
hint="Password should be 8 characters"
lazy-rules
:rules="[
val => val !== null && val !== '' || 'Please enter your password',
val => val.length === 8 || 'Please enter a valid password'
]"
/>
<q-input
filled
type="number"
v-model="phone"
label="Your phone number *"
lazy-rules
:rules="[
val => val !== null && val !== '' || 'Please enter your phone number',
val => val.length > 8 && val.length < 12 || 'Please enter a valid number'
]"
/>
<div>
<q-btn label="Login" type="submit" color="primary"/>
<q-btn flat to="/user/requestpassword" label="Forgot Password?" type="submit"/>
</div> -->
</q-form>
</div>
</template>
<script>
export default {
data () {
return {
email: null,
password: null,
phone: null,
accept: false
}
},
methods: {
isValidEmail (val) {
const emailPattern = /^(?=[a-zA-Z0-9#._%+-]{6,254}$)[a-zA-Z0-9._%+-]{1,64}#(?:[a-zA-Z0-9-]{1,63}\.){1,8}[a-zA-Z]{2,63}$/
return emailPattern.test(val) || 'Invalid email'
},
onSubmit () {
if (this.accept !== true) {
this.$q.notify({
color: 'red-5',
textColor: 'white',
icon: 'warning'
})
} else {
this.$q.notify({
color: 'green-4',
textColor: 'white',
icon: 'cloud_done',
message: 'Submitted'
})
}
this.onReset()
},
onReset () {
this.email = null
this.password = null
this.phone = null
this.accept = false
}
}
}
</script>
new component vue:
<template>
<q-input
filled
v-model="email"
label="Your email *"
lazy-rules
:rules="[val => !!val || 'Email is missing', isValidEmail]"
/>
<q-input
filled
type="password"
v-model="password"
label="Password *"
hint="Password should be 8 characters"
lazy-rules
:rules="[
val => val !== null && val !== '' || 'Please enter your password',
val => val.length === 8 || 'Please enter a valid password'
]"
/>
<q-input
filled
type="number"
v-model="phone"
label="Your phone number *"
lazy-rules
:rules="[
val => val !== null && val !== '' || 'Please enter your phone number',
val => val.length > 8 && val.length < 12 || 'Please enter a valid number'
]"
/>
<div>
<q-btn label="Login" type="submit" color="primary"/>
<q-btn flat to="/user/requestpassword" label="Forgot Password?" type="submit"/>
</div>
</template>
<script>
export default {
}
</script>
<div id="parent">
<child :delegate="delegateMethod" ref="child" />
</div>
<script>
import { ref } from "vue";
export default({
setup() {
const child = ref()
const callChildMethod = () => {
child.method();
};
const delegateMethod = () => {
console.log("call from child");
};
return { delegateMethod };
}
});
</script>
<div id="child">
<p>child component</p>
<button #click="responseToParent()">
</div>
<script>
export default({
props: {
delegate: {
type: Function,
default: () => {}
}
},
setup(props) {
const method = () => {
console.log("call from parent");
};
const responseToParent = () => {
props.delegate();
};
return { responseToParent };
}
});
</script>
This is a very simple example. It works like this between parent and child components in Vue.

react native multistep wizard formik yup

Hi I am new to react native.
I have react native project in which I have implement multistep form wizard with formik yup validation. Currently I have implemented multistep form wizard with formik yup validation in react.
How can I implement or convert it to react native.
Below is the code which implement in react.
import React, { useState } from 'react';
import { ErrorMessage, Field, Form, Formik } from "formik";
import * as Yup from "yup";
const Wizard = ({ children, initialValues, onSubmit }) => {
const [stepNumber, setStepNumber] = useState(0);
const steps = React.Children.toArray(children);
const [snapshot, setSnapshot] = useState(initialValues);
const step = steps[stepNumber];
const totalSteps = steps.length;
const isLastStep = stepNumber === totalSteps - 1;
const next = values => {
setSnapshot(values);
setStepNumber(Math.min(stepNumber + 1, totalSteps - 1));
};
const previous = values => {
setSnapshot(values);
setStepNumber(Math.max(stepNumber - 1, 0));
};
const handleSubmit = async (values, formikBag) => {
if (isLastStep) {
return onSubmit(values, formikBag);
} else {
next(values);
}
};
return (
<Formik
initialValues={snapshot}
onSubmit={handleSubmit}
validationSchema={step.props.validationSchema}
>
{formik => (
<Form>
<p>
Step {stepNumber + 1} of {totalSteps}
</p>
{step}
<div style={{ display: "flex" }}>
{stepNumber > 0 && (
<button onClick={() => previous(formik.values)} type="button">
Back
</button>
)}
<div>
<button disabled={formik.isSubmitting} type="submit">
{isLastStep ? "Submit" : "Next"}
</button>
</div>
</div>
</Form>
)}
</Formik>
);
};
const WizardStep = ({ children }) => children;
const Demo = () => {
const submitform=(values)=>{
alert('First name:'+values.firstName+' Last name:'+values.lastName+' Mobile:'+values.mobile+' Email:'+values.email);
}
return(
<>
<Wizard
initialValues={{
email: "",
firstName: "",
lastName: "",
mobile:''
}}
onSubmit={values => submitform(values)}
>
<WizardStep
validationSchema={Yup.object({
firstName: Yup.string().required("required"),
lastName: Yup.string().required("required")
})}
>
<div>
<label htmlFor="firstName">First Name</label>
<Field
autoComplete="given-name"
component="input"
id="firstName"
name="firstName"
placeholder="First Name"
type="text"
/>
<ErrorMessage className="error" component="div" name="firstName" />
</div>
<div>
<label htmlFor="lastName">Last Name</label>
<Field
autoComplete="family-name"
component="input"
id="lastName"
name="lastName"
placeholder="Last Name"
type="text"
/>
<ErrorMessage className="error" component="div" name="lastName" />
</div>
</WizardStep>
<WizardStep
validationSchema={Yup.object({
mobile: Yup.number('Invalid mobile').min(10,"Invalid mobile").required("required")
})}
>
<div>
<label htmlFor="mobile">Mobile</label>
<Field
autoComplete="mobile"
component="input"
id="mobile"
name="mobile"
placeholder="Mobile"
type="text"
/>
<ErrorMessage className="error" component="div" name="mobile" />
</div>
</WizardStep>
<WizardStep
validationSchema={Yup.object({
email: Yup.string()
.email("Invalid email address")
.required("required")
})}
>
<div>
<label htmlFor="email">Email</label>
<Field
autoComplete="email"
component="input"
id="email"
name="email"
placeholder="Email"
type="text"
/>
<ErrorMessage className="error" component="div" name="email" />
</div>
</WizardStep>
</Wizard>
</>
)
}
function App() {
return (
<div className="App">
<Demo />
</div>
);
}
export default App;

React Router: login post

I'm a beginner with React & Router and I'm trying to set up a very simple login form & redirection.
I don't really understand where i have to put my 'logic code' (an ajax call and a redirection).
This is what I get when I try to login..
GET security/login?callback=jQuery33102958950754760552_1525660032193&format=json&_=1525660032194 40 5()
It should be "POST" not "GET"
Here is what I've write.
import React from "react";
import { Link } from "react-router-dom";
import $ from "jquery";
class Login extends React.Component {
constructor(props) {
super(props);
this.state = {
userid: "",
password: "",
submitted: false
}
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({value: event.target.value});
}
handleSubmit(e) {
e.preventDefault();
var root = 'security/login';
//var userid = $("#userid").val();
// var password = $("#password").val();
var formData = {
"userId" : $('input[name=userid]').val(),//$('input[name=userid]').val()
"password" : $('input[name=password]').val()//$('input[name=password]').val()
};
var jsondata = JSON.stringify(formData);
console.log(jsondata);
alert("test" +jsondata);
$.ajax({
url: root,
method: 'POST',
data: {
format: 'json'
},
contentType : "application/json; charset=utf-8",
error: function() {
$('#info').html('<p>An error has occurred</p>');
},
headers: {
'Content-Type': 'application/json', /*or whatever type is relevant */
'Accept': 'application/json' /* ditto */
},
dataType: 'jsonp',
encode : true,
success: function(data, response) {
alert(+data.status.message);
var $title = $('<h1>').text(data.talks[0].talk_title);
var $description = $('<p>').text(data.talks[0].talk_description);
$('#info')
.append($title)
.append($description);
}
});
//done(Login.function(data)
// {
// this.setState({});
// console.log(this.state.data);
// }
}
render() {
// const { loggingIn } = this.props;
// const { userid, password, submitted } = this.state;
return (
<div className="container">
<div className="col-md-5 col-md-offset-13 login-form text-center">
<div className="form-top">
<div className="form-top-left">
<h3>LOGIN PAGE</h3>
<p>Please enter your userID and password</p>
</div>
</div>
<form onSubmit={this.handleSubmit}>
<div className="input-group col-lg-10 col-md-offset-1">
<span className="input-group-addon">
<i className="glyphicon glyphicon-user" />
</span>
<input
className="form-control"
placeholder="UserID"
name="userid"
id="userid"
type="text"
required
/>
</div>
<div className="input-group col-lg-10 col-md-offset-1">
<span className="input-group-addon">
<i className="glyphicon glyphicon-lock" />
</span>
<input
type="password"
name="password"
id="password"
className="form-control"
placeholder="Password"
required
/>
</div>
<button type="submit"
className="btn btn-danger btn-block col-xs-6 col-lg-11"
id="login">
>
LOGIN
</button>
</form>
<div className="form-footer">
<div className="row">
<div className="col-xs-7 blink">
<i className="fa fa-unlock-alt" />
</div>
</div>
</div>
</div>
</div>
);
}
}
export default Login;
Hope you all can help me... Thanks in advance