Search code examples
javascriptreactjsreact-componentreact-starter-kittypescript

REACT -- adding input toggle in react


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


Solution

  • 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