1

I am creating a react app i have to add an input toggle inside my header component. I tried to add but JavaScript is not working. if

this is the header component file. inside this component I have included my input toggle condition. i have placed JavaScript code right below the imports.

anyone knows please check thanks..

import React, { Component } from 'react'; import PropTypes from 'prop-types'; import { Nav, Navbar, Collapse, DropdownMenu, DropdownItem, NavbarToggler, DropdownToggle, UncontrolledDropdown, } from 'reactstrap'; import { Link, withRouter } from 'react-router-dom'; import Config from '../../../constants/config'; import { SidebarNavItems } from '../Sidebar'; import logoImages from '../../../images/logo.png'; require('./styles.scss'); var allInputs = document.querySelectorAll('.myInput'); allInputs.forEach(function(node) { node.addEventListener("click", function(){ var allHiddenInputs = document.querySelectorAll('.hidden'); if(allHiddenInputs.length === 0) { allInputs.forEach(function(input) { input.classList.add("hidden"); input.classList.add("second"); input.classList.remove("first"); }); node.classList.remove("hidden"); node.classList.remove("second"); node.classList.add("first"); } else { allHiddenInputs.forEach(function(input) { input.classList.remove("hidden"); }); } }); }); class Search extends Component { constructor(props) { super(props); } render() { return ( <div className=""> <div className="input-container"> <input type="password" placeholder="Input 1" className="myInput first" /> <input type="password" placeholder="Input 2" className="myInput second hidden" /> </div> </div> ); } } export default withRouter(Search); 

this is my css file which linked to this component.

.input-container { display: flex; flex-direction: column; } .myInput { margin: 10px; padding: 5px } .first { order: 1; } .second { order: 2; } .hidden { display: none; } 

enter image description here

5
  • when you import this file the JS code will run. you probably dont want to use all of these dom selectors unless you have to. It looks like the js code at the top is trying to make changes to the html rendered in your component? So you should instead change classes on the component inside the component. And probably use state to handle the toggle Commented Aug 9, 2018 at 4:04
  • @JohnRuddell thanks for the reply.I'll try that way thanks again. if possible can you please provide a solution as an answer ? Commented Aug 9, 2018 at 4:11
  • yes i'd be happy to. before i do though can you clarify what your JS code is supposed to be doing? it looks like when you click on an input you then hide that input and show a different one? what is the purpose of that behavior? Commented Aug 9, 2018 at 4:13
  • thanks again for reply .actually its a search bar , there are 2 types of search so 1 input is for type 1 and second input is for other type of search. so when you click each search it will toggle between each codepen.io/feizel/pen/OwBQPy it wil be like this in website Commented Aug 9, 2018 at 4:18
  • just wrote up an answer real quick that does what you want :) let me know if you have any questions Commented Aug 9, 2018 at 5:03

4 Answers 4

2

What I would do to simulate the same thing as you are trying to do would be to use local state to update the view. You can conditionally render items as well as class names for each render cycle.

class App extends React.Component { constructor() { super() this.inputNames = ['input1', 'input2'] this.state = { hiddenInputs: { input1: { hidden: false, first: true }, input2: { hidden: true, first: false } }, expanded: false } } handleClick(name) { const hI = Object.assign({}, this.state.hiddenInputs) let expanded = this.state.expanded if (expanded && hI[name].first === true) { // clicked on the first element, we hide the other expanded = false } else if (expanded) { // clicked on non first item, change order this.inputNames.forEach(input => { const isSame = input === name hI[input].first = isSame hI[input].hidden = !isSame }) } else { // its not open yet, show the other expanded = true } this.setState({expanded, hiddenInputs: hI}) } render() { const { input1, input2 } = this.state.hiddenInputs const {expanded} = this.state const clsName1 = `myInput${input1.hidden && !expanded ? ' hidden' : ''}${input1.first ? ' first' : ' second'}`; const clsName2 = `myInput${input2.hidden && !expanded ? ' hidden' : ''}${input2.first ? ' first' : ' second'}`; return ( <div className=""> <div className="input-container flex"> <input type="password" placeholder="Input 1" onClick={this.handleClick.bind(this, 'input1')} className={clsName1} /> <input type="password" placeholder="Input 2" onClick={this.handleClick.bind(this, 'input2')} className={clsName2} /> </div> </div> ); } } ReactDOM.render( <App />, document.getElementById('container') ); 

CSS:

.flex { display: flex; } .first { order: 0; } .second { order: 1; } .hidden { display: none; } 

Fiddle to see it in action

Sign up to request clarification or add additional context in comments.

7 Comments

this is what I was expecting thanks , and small thing now when we click the right side input it switch with left side input is it possible when we click right side input hide the left side toggle instead of switching
thanks, not sure what you mean. what does click right side input? like a part of the input or just the input? like input1.. are you asking if clicking the right side of input1 we do something or clicking on input1 when its the second input?
It works exactly how it did in that codepen you showed me
sorry my mistake i send the wrong codepen link, at first , im really sorry when you click the down 1 in code pen it hides top 1 but here it only switches the inputs its not hiding the top1
ok thats a different codepen than this one codepen.io/feizel/pen/OwBQPy .. but sure just look at the code. theres a state for expanded. you just need to toggle it when you switch the items. do you need me to do that for you? or can you figure it out
|
1

Try to put your code to component lifecycle (like a componentDidMount), then it would work. But in react it is not good solution to work with DOM nodes directly. Better way would be to make like that:

class Search extends Component { constructor(props) { super(props); this.state = {allInputsHidden: true}; // You can change it later } render() { return ( <div className=""> <div className="input-container"> <input type="password" placeholder="Input 1" className="myInput first" /> <input type="password" placeholder="Input 2" className={this.state.allInputsHidden ? "myInput second hidden" : "myInput second"} /> </div> </div> ); } } 

Also, you can use package classnames to make it look more pretty

Comments

1

You may use state to decide which element to be displayed ...

 class Search extends Component { constructor(props) { super(props); this.state = { toggleInput1:true, } render() { return ( <div className=""> <div className="input-container"> {this.state.toggleInput1? <input type="password" placeholder="Input 1" className="myInput first" />: <input type="password" placeholder="Input 2" className="myInput second hidden" /> } </div> </div> ); } } export default withRouter(Search); 

And On EventListener change the state of toogleInput

handleClick = event => { this.setState({toggleInput1:!this.state.toggleInput1 }); }; 

3 Comments

you mean I have to add this in a separate component and call it inside main component ?
It would be going in same component ... on the event which the toggle need to achieved ... onClick={event => this.handleClick(event)}.. you may keep on both input tag and check
Im expecting somthing like this bro, the click event also would be for input only please check this codepen link codepen.io/feizel/pen/OwBQPy
1

Use conditional rendering to achieve this task. You can refer this page. Create your input group as a component and add a boolean prop to use with if condition. This is much better than adding classes.

function Inputs(props) { const isFirst = props.isFirst; if (isFirst) { return <input type="password" placeholder="Input 1" className="myInput first" />; } return <input type="password" placeholder="Input 2" className="myInput second" />; } ReactDOM.render( <Inputs isFirst={true} />, document.getElementById('root') ); 

And add a click event to toggle the value of isFirst variable.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.