aaayumi
aaayumi

Reputation: 1274

Changing height of div element by adding the number of items React.js

I'm making an application using React.js. I have a list of items. A list of item is editable.

I want to add a title element next to a list of items and a height of title element should be changed as the number of item is increased or decreased.

Imageenter image description here

If the number of item is decreased to 3, the height of title element(Advice & FAQ) should be shorten. If it is increased to 5, the height should be widened.

How can I achieve this functionality? I tried to use inline styling but I failed..

<div className="titleElement" style={height: this.state.questionItem.length * 20px }></div>

index.js

export default class List extends React.Component {
constructor(props){
    super(props);
    this.state={
        questionItem
    };
}

createItem(item){
    this.state.questionItem.unshift({
        item : item,
    });
    this.setState({
        questionItem : this.state.questionItem
    });
}

findItem(item) {
    return this.state.questionItem.filter((element) => element.item === item)[0];
}

toggleComplete(item){
    let selectedItem = this.findItem(item);
    selectedItem.completed = !selectedItem.completed;
    this.setState({ questionItem : this.state.questionItem });
}

saveItem(oldItem, newItem) {
    let selectedItem = this.findItem(oldItem);
    selectedItem.item = newItem;
    this.setState({ questionItem : this.state.questionItem });
    console.log(this.state.questionItem)
}

deleteItem(item) {
    let index = this.state.questionItem.map(element => element.item).indexOf(item);
    this.state.questionItem.splice(index, 1);
    this.setState({ questionItem : this.state.questionItem });
}

render() {
    return (
    <div className="list">
    <div className="titleElement" style={height: this.state.questionItem.length * 20px }></div>
    <QuestionList questionItem={this.state.questionItem} deleteItem={this.deleteItem.bind(this)}  saveItem={this.saveItem.bind(this)} toggleComplete={this.toggleComplete.bind(this)} />
    <CreateItem questionItem={this.state.questionItem} createItem={this.createItem.bind(this)} />
    </div>);
}
}

Upvotes: 2

Views: 8600

Answers (2)

user
user

Reputation: 4811

I think you're doing too much work manually. You should look at flexbox and have CSS automatically handle the height resizing for you. The end result would be something like (have not tested this, just giving you a conceptual idea):

render() {
    return (
    <div className="list" style={{"display": "flex";}}>
        <div className="titleElement" style={{"flex": 1}}></div>
        <div style={{"flex": 5; "display": "flex"; "flex-direction": "column"}}>
            <QuestionList questionItem={this.state.questionItem} deleteItem={this.deleteItem.bind(this)}  saveItem={this.saveItem.bind(this)} toggleComplete={this.toggleComplete.bind(this)} />
            <CreateItem questionItem={this.state.questionItem} createItem={this.createItem.bind(this)} />
        </div>
    </div>);
}

The outer div has display: flex set to enable flex box, then you can play with the flex: 1 and flex: 5 settings in the children divs to get the widths correct.

I would then add the wrapping div around QuestionList and CreateItem so that you can make those appear vertically / in columns (with the display: flex and flex-direction: column styles).

Upvotes: 6

melmquist
melmquist

Reputation: 470

I agree with user1370384 that you are doing a lot of work manually, and here is a post that discusses the correct way to do inline styles as objects Reactjs - setting inline styles correctly.

However, if you wanted to do your original approach, perhaps backticks aka ES6 Template Literals may be a solution like below. (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals)

render() {
    return (
    <div className="list">
        <div className="titleElement" style={{'height': `${this.state.questionItem.length * 20}px` }}>

        </div>
        <QuestionList questionItem={this.state.questionItem} deleteItem={this.deleteItem.bind(this)}  saveItem={this.saveItem.bind(this)} toggleComplete={this.toggleComplete.bind(this)} />
        <CreateItem questionItem={this.state.questionItem} createItem={this.createItem.bind(this)} />
    </div>
    );
}

Upvotes: 2

Related Questions