React beautiful dnd first column of two not working properly - unable to find draggable with id - javascript

I've implemented react beautiful dnd into my app, however I've found that dragging items that are initialised in the first column mostly doesn't work (it sometimes works if you keep refreshing). I tried swapping my columns around and it appears the first one rendered has the problem rather than one column having an issue.
I'm not sure what is causing it, the error I receive in the console from the library is:
Unable to find draggable with id: 6112804b8127dd10b00138d8.
The id however matches the ids in my lists and the HTML viewed in inspect element.
Here's the minimum code, I've not included the functions for filtering search, reordering, move and onDragEnd (isn't being fired as it doesn't find the draggable)
const id2List = {
'available': availableSections,
'selected': selectedSections
};
const getList = id => id2List[id];
return (
<Container>
<Widget title={template.name} paddingStyle="10px" buttonRight={<SaveButton handleSubmit={handleSubmit} loading={loading}/>}>
<DragDropContext onDragEnd={onDragEnd}>
<Row>
<Col >
Available Sections
<Form.Control onChange={(e) => setSearchTextAvailable(e.target.value)} className="mb-3" type="text" placeholder="Search..." />
<Droppable key="available" droppableId="available">
{provided => (
<div ref={provided.innerRef} {...provided.droppableProps}>
{Object.keys(visibleAvailableSections).map((section) => {return <SectionCard key ={visibleAvailableSections[section]._id} section={ visibleAvailableSections[section] } index={parseInt(availableSections.indexOf(visibleAvailableSections[section])) } /> })}
{provided.placeholder}
</div>
)}
</Droppable>
</Col>
<Col>
Selected Sections
<Form.Control onChange={(e) => setSearchTextSelected(e.target.value)} className="mb-3" type="text" placeholder="Search..." />
<Droppable key="selected" droppableId="selected">
{provided => (
<div ref={provided.innerRef} {...provided.droppableProps}>
{Object.keys(visibleSelectedSections).map((section) => {return <SectionCard key ={visibleSelectedSections[section]._id.toString()} section={ visibleSelectedSections[section] } index={parseInt(selectedSections.indexOf(visibleSelectedSections[section])) } /> })}
{provided.placeholder}
</div>
)}
</Droppable>
</Col>
</Row>
</DragDropContext>
</Widget>
</Container>
)
const SectionCard = ({section, index}) => {
return (
<Draggable draggableId={section._id.toString()} key={section._id} index={index}>
{provided => (
<Card key={"card-" + section._id.toString()} style={{ width: '18rem' }}
ref={provided.innerRef}
{...provided.draggableProps}
{...provided.dragHandleProps}
>
<Card.Body>
<Card.Title>{ section.name }</Card.Title>
<Card.Subtitle className="text-muted">{ section.description }</Card.Subtitle>
{ section.tags.map((tag) => {
return <Badge pill bg={"secondary"} key={section._id + tag} >{ tag }</Badge>
})}
</Card.Body>
</Card>
)}
</Draggable>
);
}

Related

how to have multiple cards in each Carousel slide react-bootstrap

I'm working with react-bootstrap and I have my data coming from an API and saved in recipes as an array.
I'm trying to have Carousel with react-bootstrap but right now it shows each item on a separate slide, how can I show 3 items on each slide?
this is my code
<div>
<Wrapper>
<h3>Breakfast Recipes</h3>
<Carousel>
{recipes.map((item,index) => (
<Carousel.Item key={index}>
<Card style={{ width: '18rem' }}>
<Card.Img variant="top" src={item.photo_location} />
<Card.Body>
<Card.Title>{item.name}</Card.Title>
<Button variant="primary">Go somewhere</Button>
</Card.Body>
</Card>
</Carousel.Item>
))}
</Carousel>
</Wrapper>
</div>
I know that to do so I should have 3 <Carousel.Item> tags but I can't figure out how to do it with map
Assuming that the goal is to have 3 cards on each slide, it seems that instead of having 3 <Carousel.Item>, the desired output should probably be to have each <Carousel.Item> containing 3 <Card>.
Perhaps try use reduce on recipes to make an array that groups every 3 recipes to map a <Carousel.Item> for each group, and then nest another map inside to output 3 <Card>.
The below example also added a <div> to wrap the <Card> and place them horizontally. It used bootstrap syntax with assumption that the project also uses bootstrap classes.
But if inline styling is preferred, perhaps change <div className="d-flex justify-content-center"> to <div style={{display:"flex", justifyContent: "center"}}>.
Live demo of the example: stackblitz
A very basic example could be:
// Helper function to group every 3 recipe to a new array
const reduceRecipes = (acc, cur, index) => {
const groupIndex = Math.floor(index / 3);
if (!acc[groupIndex]) acc[groupIndex] = [];
acc[groupIndex].push(cur);
console.log(acc);
return acc;
};
return (
<div>
<Wrapper>
<h3>Breakfast Recipes</h3>
<Carousel>
{recipes.reduce(reduceRecipes, []).map((item, index) => (
<Carousel.Item key={index}>
<div className="d-flex justify-content-center">
{item.map((item, index) => {
return (
<Card key={index} style={{ width: "18rem" }}>
<Card.Img variant="top" src={item.photo_location} />
<Card.Body>
<Card.Title>{item.name}</Card.Title>
<Button variant="primary">Go somewhere</Button>
</Card.Body>
</Card>
);
})}
</div>
</Carousel.Item>
))}
</Carousel>
</Wrapper>
</div>
);
Some further custom styles should probably be added to make this work better, but hope that this still helps.

React DnD, could not find "store" in the context of Connect(Droppable)

Hello I am trying to make a drag and drop in my application but I have got a huge error. I have no idea if property is missing because in IDE it is an error free code.
Uncaught Error: Could not find "store" in the context of "Connect(Droppable)". Either wrap the root component in a <Provider>, or pass a custom React context provider to <Provider> and the corresponding React context consumer to Connect(Droppable) in connect options.
Down here are my components
3 Columns ( I want drag and drop across one column each, not between them)
const DetailColumns: React.FC<funcProps> = (props) => {
const onDragEnd = () => {};
return (
<Box
h="80vh"
borderWidth="0.5rem"
borderColor="orange.300"
borderRadius="1rem"
w="80%"
marginTop="2rem"
>
<Grid w="100%" h="100%" templateColumns="60% 20% 20%">
<Box border="0.5rem" borderColor="orange.300">
<RecipeDescriptionBox recipe={props.recipe} />
</Box>
<Box borderLeftWidth="0.5rem" borderColor="orange.300">
<RecipeStepsBox recipe={props.recipe} />
</Box>
<DragDropContext onDragEnd={onDragEnd}>
<Box borderLeftWidth="0.5rem" borderColor="orange.300">
<RecipeIngredientsBox recipe={props.recipe} />
</Box>
</DragDropContext>
</Grid>
</Box>
);
};
List of Items
<Box>
<ColumnHeader title="Steps" />
<Droppable droppableId="unique">
{(provided) => (
<Box {...provided.droppableProps} innerRef={provided.innerRef}>
{steps.map((step, index) => (
<DetailListItem
key={step}
itemName={step}
indexOfItem={index}
id={Math.random().toString()}
/>
))}
{provided.placeholder}
</Box>
)}
</Droppable>
</Box>
Item element
<Draggable draggableId={props.id} index={props.indexOfItem}>
{(provided) => (
<Box
{...provided.draggableProps}
{...provided.dragHandleProps}
innerRef={provided.innerRef}
>
<Flex margin="1rem">
<Box
bgGradient="linear(to-r, orange.200, orange.400)"
height="6vh"
width="6vh"
boxShadow="md"
rounded="md"
>
<Grid w="100%" h="100%" placeItems="center">
<Text color="white" fontWeight="700" fontSize="140%">
{props.amount && props.amount + props.unit}
{!props.amount && props.indexOfItem}
</Text>
</Grid>
</Box>
<Grid placeItems="center">
<Text marginLeft="1rem" fontWeight="500" fontSize="1.8rem">
{props.itemName}
</Text>
</Grid>
</Flex>
</Box>
)}
</Draggable>
If you want I can put this code to some sandbox to make it easier to debug.

How to Save Position of react-draggable objects in react

I am using react-draggable to drag and drop elements. How should I save the elements positions after dragging?
I was trying to save the position to the local storage by using onStop and initializing an eventLogger but it's not saving the position.
Here is my code example, i am happy to get some help, as i am pretty new in this topic.
Thank you very much.
return (
<DragDropContext onDragEnd={this.onDragEnd} defaultPosition={{ x: 0, y: 0 }} onStop={eventLogger}>
<Droppable droppableId="droppable" type="droppableItem">
{(provided, snapshot) => (
<div
ref={provided.innerRef}
style={getListStyle(snapshot.isDraggingOver)}
>
{this.state.items.map((item, index) => (
<Draggable
key={item.id} draggableId={item.id} index={index}>
{(provided, snapshot) => (
<div>
<div
ref={provided.innerRef}
{...provided.draggableProps}
style={getItemStyle(
snapshot.isDragging,
provided.draggableProps.style
)}
>
{item.content}
<span
{...provided.dragHandleProps}
>
Drag
</span>
<ServiceCommandUnit
subItems={item.subItems}
type={item.id}
/>
</div>
{provided.placeholder}
</div>
)}
</Draggable>
))}
{provided.placeholder}
</div>
)}
</Droppable>
</DragDropContext>
)

React - I'm using the onclick option which requires a variable from a component that dynamically renders a series of elements, but it doesn't work

dropdownClick =(value ) => {
this.setState({searchGroup: value.name, elementSelected: value})
}
( I tried inserting the setState block inside the onClick and it do not worck too )
<InputGroup className="mb-2">
<Input value={this.state.searchGroup} onChange={(e) => this.filtergroups(e.target.value)} />
<InputGroupButtonDropdown addonType="append" isOpen={this.state.drop} toggle={this.AbrirCerrarDropdown} >
<DropdownToggle caret className="red button">Grupos</DropdownToggle>
<DropdownMenu>{this.state.skillGroupsFiltered.map((element, index) => (
<DropdownItem key={index} onClick={() => this.dropdownClick(element)}>{element.name}</DropdownItem>
))}
</DropdownMenu>
</InputGroup>

Why doesn't Next.js Json.map work properly?

I want to build a simple component where the data comes from a JSON list. On the website I can see the console.log(dat.CardId) so it works for just console.log(). I can't see the cards from the .map function. The Style is bootstrap. I really don't think that something is wrong at the code.
import { Card,Button,Container,Row,Col } from 'react-bootstrap'
const data = [{'CardTitle':'Simple Website','CardText':"Some quick example text to build on the card title and make up the bulk of the card's content.", "CardId":"Simple-Website"},{'CardTitle':'Simple Website','CardText':"Some quick example text to build on the card title and make up the bulk of the card's content.", "CardId":"Simple-Website"} ]
export default function Cards() {
return (
<>
<div>
<Container fluid>
Cards
{data.map(dat => {
{console.log(dat.CardId)}
<Row>
<Col>
<Card style={{ width: '18rem' }}>
<Card.Img variant="top" src="pexels-tima-miroshnichenko-6612358 (2).jpg/100px180" />
<Card.Body>
<Card.Title>{dat.CardTitle}</Card.Title>
<Card.Text>
{dat.CardText}
</Card.Text>
<Button variant="primary">Go somewhere</Button>
</Card.Body>
</Card>
</Col>
</Row>
})}
</Container>
</div>
</>
)
}
Use return ( ... ) in a .map to render an element. https://stackoverflow.com/a/39999745/15257712
Example:
array.map((entry, index) => {
return (
<div key={index}>
...
</div>
)
})

Categories