"Unable to find drag handle" mistake in react-beautiful-dnd - reactjs

I have a list of cards that want to drag and drop. I want the user could drag and drop by pressing on the specific place (div) on the card (not the whole card). I transfer this div to the child component and add {...provided.dragHandleProps} on this div. Everything works ok, but I get mistakes in console, that Unable to find drag handle. How can I fix this problem?
const posts = (
<DragDropContext onDragEnd={this.dragDrop}>
<Droppable droppableId="dragCards">
{(provided) => (
<div ref={provided.innerRef}>
{cards.map((item, index) => {
return (
<Draggable draggableId={item.key} index={index}>
{(provided) => (
<div
ref={provided.innerRef}
{...provided.draggableProps}
>
<Cards
dragChip={
<div {...provided.dragHandleProps}>
{dragChip}
</div>
} />
</div>
)}
</Draggable>
);
})}
{provided.placeholder}
</div>
)}
</Droppable>
</DragDropContext>
);
And this is div, that I transfer to the child component.
const dragChip = (
<div >
drag me
</div>
);

Looks like your <Draggable> needs a key.
Before
<Draggable draggableId={item.key} index={index}>
After
<Draggable key={item.key} draggableId={item.key} index={index}>
https://github.com/atlassian/react-beautiful-dnd/issues/1673#issuecomment-571293508

You can spread the props in the div inside the drag chip component.
And if you want to conditionally drag and drop, then you can use the isDragDisabled prop of Draggable component

Related

How to stop Animate.css animation after one scroll in Rect.js?

I'm using react-on-screen and Animate.css to create slideInUp animation on scroll. But I want to the animation to show up when the page is loaded and the scroll-down happened. Now in my code, the animation happens every time I scroll up and down. How do I prevent that? Additional to that, if there is any way to do it without using Animate.css or react-on-screen I would love to learn it.
Here is the code that I track scrolling and Animate.css:
<>
<div className={`container mb-5 `}>
<h1 className='text-center my-5 blue-text'>SOME HEADER</h1>
<TrackVisibility partialVisibility>
{({ isVisible }) =>
<div className={`row animated-row my-element ${isVisible ? "animate__animated animate__slideInUp animate__repeat-1 my-element" :""}`} >
<Card />
<Card />
<Card />
<Card />
</div>
}
</TrackVisibility>
</div>
</>
I saw the "Usage with Javascript" codes on the Animate.css main page but I couldn't apply them to my React code.
Thanks.

Fabric UI Using PivotItem in Map Loop

I'm trying to dynamically add PivotItems to a Fabric UI Pivot.
return (
<div>
<PrimaryButton style={{margin:5 }} onClick={addItem}>
Add
</PrimaryButton>
<Pivot aria-label="My Items">
{items.map((item)=>{
return (
<div key={uniqueId}>
<PivotItem headerText="test">
Test
</PivotItem>
</div>)
})}
</Pivot>
</div>
)
but the items are not rendering.
When I remove all the Pivot/item-stuff and just print out some text it works fine...
ok I finally found the issue here.
Inside the map-function I used
<div key...
but this code is inside a <pivot> which allows only <PivotItem> as childs...
so I fixed it like this and it works:
return (
<div>
<PrimaryButton style={{margin:5 }} onClick={addItem}>
Add
</PrimaryButton>
<Pivot aria-label="My Items">
{items.map((item)=>{
return (
<PivotItem headerText="test" key={uniqueId}>
Test
</PivotItem>
)
})}
</Pivot>
</div>
)

Put linebreak between components rendered with .map and boostrap

I´m rendering an array, every element of the array is showed with component "Post", but the elements are in the same line, I tried with
return (
<div style={{ height: 'calc(100vh - 65px)' }} className="d-flex justify-content-center align-items-center">
{posts.map((post) => {
return <Post key={post._id} post={post} />
})}
</div>
);
The component "Post" is the next:
I´m using Boostrap por the css styles
return (
{usuario.nombre}
Special title treatment
{texto}
Go somewhere
2 days ago
);
My result (All the elements are in horizontal position and I need them in vertical position):
The father component is root.
If I delete the css classes of the component "Post", teh problem remains.
Have you tried this.
return (
<div>
{posts.map((post) => {
return <><Post key={post._id} post={post} /><br /></>
})}
</div>
);
I only changed the class of div where I put the .map ;| adn the problem was solved.
className="container" instead className="d-flex justify-content-center align-items-center">

Grid system breakpoint override?

I need some help. I use material-ui Grid system, and my full page is responsive like a charm, but i need at grid components overflowX with fixed header, so only the Grid container should be a horizontal scrollbar, but i tried a lot of things but nothing works.
I have this gird system. So i would like horizontal scrolling when im generated more grid item.
This is my code-snippet for this part.
<DragDropContext onDragEnd={onDragEnd}>
<Droppable droppableId="droppable" direction={windowInnerWidth > 1280 ? 'horizontal' : 'vertical'} type="droppableItem">
{(provided, snapshot) => (
<div>
{windowInnerWidth > 1280 ? (
<Grid container spacing={6} ref={provided.innerRef} {...provided.droppableProps} >
{mergedData &&
mergedData.map((section, index) => (
<Grid item xs={12} xl="auto" lg="auto" key={section.uid} >
<Draggable
key={section.id}
draggableId={section.id}
index={index}
// isDragDisabled={false}
>
{(provided, snapshot) => (
<Card ref={provided.innerRef} {...provided.draggableProps} style={provided.draggableProps.style}>
<CardContent key={section.uid} index={props.index}>
<MyWorkoutSectionListItem
type={section.id} // type
key={section.id}
section={section}
provided={provided}
index={index}
workouts={section.workouts.filter((workout) => {
return workout.title.toLowerCase().includes(props.search.toLowerCase());
})} // subItems
workoutSections={props.workoutSections}
sectionName={props.sectionName}
defaultSectionId={defaultSectionId}
deleteSection={props.deleteSection}
handleWorkoutChange={props.handleWorkoutChange}
handleSectionChange={props.handleSectionChange}
changeMergeData={props.changeMergeData}
/>
{provided.placeholder}
</CardContent>
</Card>
)}
</Draggable>
</Grid>
))}
{provided.placeholder}
It would be great if somebody has idea for this problem.
You need to Use wrap={"nowrap"} prop on container Grid component and also need to provide the overflowX="auto".
Something like this
....
<Grid container spacing={2} wrap={"nowrap"} style={{ overflowX: "auto" }}>
<Grid item>Hello</Grid>
<Grid item>Hello</Grid>
</Grid>
...
I have created this Code sandbox project with the exact implementations

how do i open only one panel when I use mapping in react for panels

I have created a panel to map through my users and display their songs below their name.
The problem im having is that when I click on the {username} it opens all of the accordion panels. I'd like it to only open the accordion for the panel being clicked.
<PanelGroup accordion id="accordion-example">
{this.state.allUsersList.map((user, index) => (
<Panel>
<Panel.Heading>
<Panel.Title toggle >
<Button key={index} className="btn-uvideo">{user.Username}</Button>
</Panel.Title>
</Panel.Heading>
<Panel.Body collapsible>
<ListGroup>
{user.songs.map((song, index) => (
<ListGroupItem key={index}>
<Button className="btn-video" onClick={() => this.handleSongChange(song)}>
<p>{song.SongName}</p>
</Button>
</ListGroupItem>
))}
</ListGroup>
</Panel.Body>
</Panel>
))}
</PanelGroup>
I'm assuming you're using React-Bootstrap. Looks like you're missing eventKey:
A unique identifier for the Component, the eventKey makes it distinguishable from others in a set. Similar to React's key prop, in that it only needs to be unique amoungst the Components siblings, not globally.
https://react-bootstrap.github.io/components/panel/#panels-accordion
<PanelGroup accordion id="accordion-example">
<Panel eventKey="1">
...
</Panel>
<Panel eventKey="2">
...
</Panel>
<Panel eventKey="3">
...
</Panel>
</PanelGroup>
Assuming your usernames are unique you can use that value for your eventKey:
<PanelGroup accordion id="accordion-example">
{this.state.allUsersList.map((user, index) => (
<Panel eventKey={user.Username}>
...

Resources