Stuart Gardner Stuart Gardner - 2 months ago 33
React JSX Question

Counting the character in a redux form before submitting

I am trying to add a character counter below an input box. Something similar to how Twitter has on their input box:

enter image description here

I'm using React and Redux with ReduxForm and have tried to follow this guide Overview: We’re Going to Build a “Tweet Box”, however it doesn't use Redux.
I have also tried to use an action and reducer to put it in state, but this seems to mess with the input box, and doesn't allow from anything to be inputted.

The end goal is to add a character count and disable the submit button before anything has been entered.
If anyone has any suggestion on how best to go about this, I would greatly appreciate it.

Here is the component code:



import React, { Component } from 'react';
import { connect } from 'react-redux';
import { Link } from 'react-router';
import {reduxForm} from 'redux-form';

import * as actions from 'Actions';

class PostQuestionLD extends Component {

handleFormSubmit({content}) {
this.props.postQuestionLD({content});
}

render() {
const { handleSubmit, fields: { content }} = this.props;
return (
<div>
<form onSubmit={handleSubmit(this.handleFormSubmit.bind(this))}>
<fieldset className = "form-group" >
<lable >Question: < /lable> <input {...content} className = "form-control" / >
</fieldset>
<button action = "submit" className = "btn btn-primary" > Ask it... </button>
</form>
</div>
);
}
}

function mapStateToProps(state) {
return {
errorMessage: state.questions.error
}
}

export default reduxForm({
form: 'postquestion',
fields: ['content']
}, mapStateToProps, actions)(PostQuestionLD);




Answer

Well, because of the need of a ternary to handle the undefined case, I'd assign the length to a variable, and do something like this:

render() {
  const { handleSubmit, fields: { content } } = this.props
  const length = content.value ? content.value.length : 0
  return (
    <form onSubmit={handleSubmit(this.handleFormSubmit.bind(this))}>
      // fieldset here
      <div className="count">{length}</div>
      <button 
        type="submit" // type, not action
        className="btn ban-primary"
        disabled={length < 1 || length > 140}>Ask it...</button>
    </form>
  )
}

That's the shortest possible path to your goal. Ideally, you'd use redux-form's built-in synchronous validation to show a warning when the character limit was passed, and disable the button with disabled={this.props.invalid}. See how the length of username is controlled in the Synchronous Validation Example.

Comments