React Bootstrap Custom Component Overflowing Column - javascript

I have a custom toggle dropdown:
import React from 'react';
import 'react-datepicker/dist/react-datepicker.css';
const DateRange = props => (
<div className="dropdown artesianDropdownContanier">
<div className="btn-group width100">
<button type="button" className="btn dropdown-width">{props.selected}</button>
<button type="button" className="btn dropdown-toggle dropdown-toggle-split artesianDropdownToggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<span className="sr-only">Toggle Dropdown</span>
</button>
<div className="dropdown-menu artesianDropdown">
{props.dropDownValues.map(val => (
<span
key={val}
value={val}
className={`dropdown-item ${props.dropdownItemClass}`}
onClick={() => props.onClick(val)}
aria-hidden="true"
>
{val}
</span>
))
}
</div>
</div>
</div>
);
export default DateRange;
Wich looks like this on the page:
When I go to resize the webpage the arrow portion of the component spills out of its bootstrap container:
If I set display on the arrow to "none" you can see that the dropdown button itself with the text is resizing perfectly. It seems to be the dropdown arrow portion which is giving me trouble.
Any ideas on how to keep this guy firmly in his parent container?
Thanks!

Try adding this style to the component containing {props.selected} :
<button
type="button"
className="btn dropdown-width"
style={{
textOverflow: 'ellipsis',
overflow: 'hidden'
}}
>
{props.selected}
</button>
This should replace the end of the {props.selected} text by 3 dots and let the place to the dropdown button. (some adjustments may be needed depending on your dropdown-width class)

Related

click button to toggle show one component and hide another component in reactjs

I have two separate button like grid and list button:
<button
onClick={() => setClassName('jsGridView')}
title="Grid View"
>
<IoGrid className="active" size="25"/>
</button>
<button
onClick={() => setClassName('jsListView')}
title="List View"
>
<BiAlignLeft size="25"/>
</button>
const [cName, setClassName] = useState('jsGridView');
So when i click Grid view button it will show this component:
<GridCard className={cName}/>
and when i click list view button it will show
<ListCard className={cName}/>
with this mentioned className..
class is changed button but show hide component is not working.
You can display different components depending on the value of cName.
<div className="row mt-4 book-div">
<div className={cName}>
{ cName === 'jsGridView' ? <BooksGridCard/> : <BooksListCard/> }
</div>
</div>

onClick in button tag is not working in react component

hi i am a newbie in react i am facing a issue in classbased component
given below is my component which i am calling inside another component of react i just want to call the temp function when onClick gets fired but in my case it is not working please let me know where i am doing wrong?
import react from 'react'
import '../../../css/classBased/editor/textFieldForEditor.css'
import addTextField from './leftTrayIconsForEditor'
class TextField extends react.Component {
temp() {
console.log('hi there')
}
render(){
return (
<div className='textfield_parent_container'>
<div>
<center>
<div>
<button onClick={()=> {this.temp()}}>
<i className="material-icons md-18">article</i>
</button>
<button>
<i className="material-icons md-18">image</i>
</button>
<button>
<i className="material-icons md-18">movie</i>
</button>
</div>
</center>
</div>
<textarea className='text' id={`textfield${this.props.widgetNumber}`}></textarea>
<div className='utilitytrayouter'>
<center>
<div className='temp'>
<button>
<i className="material-icons md-18">article</i>
</button>
<button>
<i className="material-icons md-18">image</i>
</button>
<button>
<i className="material-icons md-18">movie</i>
</button>
</div>
</center>
</div>
</div>
)
}
}
export default TextField;
It actually works and clicking the first article button really calls console.log('hi there'). Proving the error message could be helpful.
But since you are using Class components most likely you are facing the Handling Events "problem" and what you need is to bind your temp method to TextField component. The easiest way (but may require a Babel plugin depending on your setup) is by using the arrow function:
temp = () => {console.log('hi there')}

conditional rendering order of the elements based on props?

I created a search input component and this input has an icon which I need to change the icon's align (on the left side or right side) based on different situations (it's a bootstrap input-group) so all I need to do is change the order of elements inside my div and I need a clean way to do this. I know I can use a ternary operation to conditional render my elements but this would cause to repeat the code. I'm looking for much cleaner way so any suggestions?
const SearchInput = ({onClose, onChangeValue, ...restProps}) => {
return (
<div className='input-group'>
<button className='btn' type='button'> //right now its on left side...
<i className='bi bi-search'></i>
</button>
<Input placeholder='Search here...' onChangeValue={onChangeValue} {...restProps} />
{onClose && <i className='bi bi-x' onClick={onClose}></i>}
</div>
);
};
My proposal
import clsx from 'clsx';
const SearchInput = ({onClose, onChangeValue, conditionProp, ...restProps}) => {
return (
<div className={clsx('input-group', conditionProp && 'my-order)}>
<button className='btn' type='button'> //right now its on left side...
<i className='bi bi-search'></i>
</button>
<Input placeholder='Search here...' onChangeValue={onChangeValue} {...restProps} />
{onClose && <i className='bi bi-x' onClick={onClose}></i>}
</div>
);
};
In CSS
.my-order {
flex-direction: row-reverse;
}
I like cslsx for conditional classnames, but of course I can do without it - conditionProp ? 'input-group my-order' : 'input-group'

what is the difference between looping the div and making it as separate component and looping?

I need to know what's the difference between this code
{this.state.products &&
this.state.products.map((product, index) => (
<div key={index}>
<Subd
name={product.name}
price={product.price}
info={product.info}
image={product.image}
handleShow={this.showProduct}
handleTotal={this.calculateTotal}
/>
</div>
))}
and looping the div inside <Sudb/> component like
this.state.products &&
this.state.products.map((product, index) => (
<div className="row form-group">
<div className="col-sm-2">
<img
className="card-img-right flex-auto d-none d-lg-block"
alt="Thumbnail+{index}"
src={product.image}
/>
</div>
<div className="col-sm-6">
<h4>
{product.name}: ${product.price}
</h4>
<button className="btn btn-outline-primary" onClick={this.showInfo}>
show info
</button>
</div>
<div className="col-sm-4 text-right">
qty: {this.state.qty}
<br />
<button className="btn btn-outline-primary" onClick={this.add}>
{" "}
+1{" "}
</button>
<button
className="btn btn-outline-primary"
onClick={this.subtract}
disabled={this.state.qty < 1}
>
{" "}
-1{" "}
</button>
</div>
</div>`
in the above case if I update the quantity its affecting all the three objects but in the first case it's working fine. Can anyone explain what's the exact difference between both? Sandbox link Sandbox
In the second code I have made <Subd/> component code directly
The problem from what i can see in the code sample provided with the second sample provided is the following.
You are using the same piece of state for all products. so when you update this.state.qty for one row it updates all of them simultaneously.
The reason it does work when you separate it is because then each row has its own state that you can store individual quantities in.
If you did feel the need to not seperate out that code you could create an array on state for each of the qty's. and change up the subtract method to accept an index that it can use to access a certain rows qty state on the qty state array.
To pass in parameters to onclick you have to wrap it in a arrow function so it does not run automatically when the page mounts like so
onClick={() => {someFunction(param)}

How to fix 'button' interactive role must be focusable

I have list of dropdown options which user can select.
optinos in dropdown are made with tag: < a href>:
<a onClick={() => handleSelect(filter)} role="button">
{filter.name}
</a>
Problem is cus I must add tabIndex="0" or -1, to fix error from Eslint.
But When I add tabIndex=0, my button does not work anymore.
Is there are any other way to fix this error?
This is how looks dropdown component:
<ul name="filters" className="dropdown">
{filterOptions.map((filter) => (
<li
key={filter.id}
defaultChecked={filter.name}
name={filter.name}
className={`option option-${filter.selected ? 'selected' : 'unselected'}`}
>
<span className={`option-${filter.selected ? 'checked-box' : 'unchecked-box'} `} />
<a onClick={() => handleSelect(filter)} role="button">
{filter.name}
</a>
</li>
))}
</ul>
Buttons are interactive controls and thus focusable. If the button
role is added to an element that is not focusable by itself (such as
<span>, <div> or <p>) then, the tabindex attribute has to be used to
make the button focusable.
https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/button_role#Accessibility_concerns
The HTML attribute tabindex corresponds to the attribute tabIndex in
React.
https://reactjs.org/docs/dom-elements.html
So I think #S.. answer is correct:
<a
onClick={() => handleSelect(filter)}
role="button"
tabIndex={0}
>
{filter.name}
</a>
Add a tabindex:
<a onClick={() => handleSelect(filter)} role="button" tabIndex={i}>
{filter.name}
</a>
after first adding an iterator to your map: (filter, i)

Categories