José Orellana Jr
José Orellana Jr

Reputation: 11

:focus issues with React

I'm relatively new with ReactJS and I'm trying to implement a small form that contains an input text field and a search button. I'm using the :focus pseudo-selector on the input field so when the user enters information it increases the width to 2000% and when the element loses focus it goes back to width:130%.

The problem I'm having is when I click my search button for the first time the input field shrinks back to the original position but it doesn't do the search until I click it for the second time. If I type something and then click somewhere else to loose focus it works like a charm.

Here's my code:

import React from 'react'
import Header from '../base/header'
import axios from 'axios'
import SearchResults from './searchResults'
import ReactCSSTransitionGroup from 'react-addons-css-transition-group';
import Radium from 'radium';

class Search extends React.Component {

    constructor(props) {

        super(props)

        this.state = {
            searchTerm: "",
            searchResultsList: ""
        }

        this.handleChange = this.handleChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
        this.handleCallback = this.handleCallback.bind(this);

    }

    handleCallback() {

        console.log("calling handleSubmit");
    }


    handleSubmit() {

        var that = this
        event.preventDefault();

        axios.post('http://localhost:3000/users/findusers', {

            searchTerm: this.state.searchTerm

        }).then(function (response) {

            console.log("data sent");
            that.setState({searchResultsList: response.data})

        }).catch(function (error) {
            console.log(error);
        });
    }

    handleChange(e) {

        this.setState({searchTerm: e.target.value}, () => {
            console.log(this.state.searchTerm);

        });
    }


    render() {
        return (
            <div>
                <Header/>
                <form onSubmit={this.handleSubmit}>
                    <div>
                        <ReactCSSTransitionGroup
                            transitionName="search-input"
                            transitionAppear={true}
                            transitionAppearTimeout={500}
                            transitionEnter={false}
                            transitionLeave={false}>
                            <input
                                type="text"
                                style={styles.inputStyle}
                                value={this.state.searchTerm}
                                onChange={this.handleChange}
                                placeholder="Find Friends..."
                            />

                            {/*<img onClick={() => this.handleSubmit()} */}

                            <img src="/icons/svg/magnifying-glass.svg"
                                     alt="Search" className="searchIcon"
                             onClick={() => this.handleCallback()}
                            />
                            </ReactCSSTransitionGroup>
                </div>
                </form>

                <div className="container-fluid">
                    <div className="row">
                        <div className="col-md-3">left</div>
                        {/* Main Area */}
                        <div className="col-md-6">
                            <SearchResults
                             searchResultsList={this.state.searchResultsList}
                            />
                        </div>
                        <div className="col-md-3">right</div>
                    </div>
                </div>
            </div>
        )
    }
}

const styles = {

    inputStyle: {
        marginTop: 5,
        marginLeft: 20,
        width: 130,
        WebkitTransition: 'width 0.4s easeInOut',
        msTransition: 'width 0.4s easeInOut',
        ':focus': {
            width: '2000%'
        }
    }
};

export default Radium(Search)

I originally had the code in a separate CSS file and decided to make it inline to see if there was any difference. I tried creating different functions to see if there was any difference but is still behaving the same.

I would really appreciate any help!

Upvotes: 1

Views: 1782

Answers (1)

Marvin Clerge
Marvin Clerge

Reputation: 11

In regards to the width changing when clicking the magnifying glass. I believe it is because the :focus property is on the input and not the div containing the input and img.

I would recommend using the :focus-within property on the parent div. Here is an example of divs with both properties.

#div1:focus-within > input {
  width: 300px;
}

#div2 > input:focus {
  width: 300px;
}
<div id="div1">
  <input type="text"/>
  <button>Search</button>
</div>

<div id="div2">
  <input type="text"/>
  <button>Search</button>
</div>

This should solve the focusing issue.

Not sure why your magnifying glass image works so strangely. When reading the code it seems that clicking the image calls handleCallback() which is only logging not submitting.

Not sure if this helps but I would recommend using a button or input element for submission. The button would have type="submit" with the magnifying glass image as the child. The input would have type="submit" value="" and set the CSS background-image: to the magnifying glass.

Upvotes: 1

Related Questions