简体   繁体   中英

How to make Show more / Show less toggle button for API dynamic data in paragraph or simple text in REACT?

My requirement is that, I have multiple tabs on web page and in each tab data come from API. The data is dynamic and daily changing. I have a div say a rectangular box of fixed height and below it, there is button "Read more / Read less". If data contained in that rectangular box exceeds the height of that box, "Read more" button will be shown, otherwise if the data size is small, button is invisible. I have done most of these things and have two problems with my code is that,

  1. Sometimes data shown as partial data ie when data size is big, part of the data is hidden back of toggle button and at the same time bottom text line is partially hidden behind box or button.
  2. after clicking read more I can scroll the data up & down. But if I click "Read less" button on scrolled down condition, that div locks over there and scrolling stops. I want that, I may be anywhere on the scrolling page and if I click "Read less", the page should automatically scrolled to top and scrolling should stop.

I am attaching my sample code. I have removed some of the classNames for security issue, please help for above two points..

<div id="tab_number" >
<div className="">
    <div    className=''>
            <div ref={`showTheScrolling`} className={`${Theme} parent`} style={{overflow:"hidden"}}>
                <h3>Tab Heading</h3>
                        {
                            <div className="content" style={{height:"475px"}} dangerouslySetInnerHTML={{ __html: this.state.thisData.tabData }}></div>
                        }
        </div>
    {this.state.thisData.tabData.length > 1500 ?
    <div>
    <div ref={`buttonShowMore`} className="">
        <a id="ClickForShowMore" onClick={() => { this.toggleShow_more() }}><b>Show More</b></a>
    </div>
    <div ref={`buttonShowLess`} className=" showButton_hide">
        <a id="ClickForShowMore" onClick={() => { this.toggleShow_less() }}><b>Show Less</b></a>
    </div>
    </div> : ""
    }
</div>
</div>

and two functions above render() section

toggleShow_more = () => {
    console.log(this.refs)
    this.refs[`showTheScrolling`].classList.add('filterscroller');
    this.refs[`buttonShowMore`].classList.add('showButton_hide');
    this.refs[`buttonShowLess`].classList.remove('showButton_hide');
}


toggleShow_less = () => {
    console.log(this.refs)
    this.refs[`showTheScrolling`].classList.remove('filterscroller');
    this.refs[`buttonShowMore`].classList.remove('showButton_hide');
    this.refs[`buttonShowLess`].classList.add('showButton_hide');
    this.refs[`showTheScrolling_${id}`].scrollTo({top: 0, behavior: 'smooth'});
}

For above first problem, we can use splitString(). Here we count up to 300 characters, if count is more, then we check first 50 words and show them in small window followed by toggle button will be provided for complete view. If character count is less than 300, no toggle.

So, here the toggle window size is dynamic. It depends on characters or words count and it is changing along font size. The problem of partial viewing text behind some other div, box or button can be easily solved here.

{
// if tabData character length > 300 then
this.state.thisData.tabData.length > 300 ?
    <div>
    {this.state.readMore ?
        <div className="your-classname" style={{ margin: "20px" }}
        dangerouslySetInnerHTML={{ __html: this.state.thisData.tabData }}>
        </div>
    :
    <div className="your-classname" style={{ margin: "20px" }}
    dangerouslySetInnerHTML={{ __html: this.splitString(this.state.thisData.tabData, " ", 50) }}>
    </div>
    }
    <div>

    <a className="your-classname2" style={{ }}
        onClick={() => this.toggleReadMore()}>
        {this.state.addRead ?
            // if you are working with mobile view also, the for css adjustment select appropriate class
                <div className={this.props.isMobileView ? "selectclass-if-isMobileViewTrue":"selectclass-if-isMobileViewFalse"}
                >READ MORE
                </div>
            </React.Fragment>
            :
            <React.Fragment>
                <div className={this.props.isMobileView ? "selectclass-if-isMobileViewTrue":"selectclass-if-isMobileViewFalse"}
                >READ LESS
                </div>
            </React.Fragment>}
    </a>
    </div>
    </div>
:
    // if tabData character length < 300 then 
    <div className="your-classname" style={{ margin: "20px" }}
        dangerouslySetInnerHTML={{ __html: this.state.thisData.tabData }}>
    </div>}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM