How to properly set state to allow React Bootstrap Modal to work on mapped data? - bootstrap-modal

Trying to build a D.R.Y. list of vocabulary terms with React Bootstrap (v.2.2.3) using Bootstrap 5.1.
I bring in my data:
import vocData from '../data/vocData'
My component:
const VocList = () => {
const [show, setShow] = useState(false)
const handleClose = () => setShow(false)
return (
<ul className="list-inline">
{Object.keys(vocData).map((item, key) => (
<React.Fragment key={key}>
<li className="list-inline-item voc-item">
<Button>
<small>{vocData[item].title}</small>
</Button>
</li>
<Modal
show={show}
onHide={handleClose}
backdrop="static"
keyboard={false}
aria-labelledby={`contained-modal-title-${vocData[item].href}`}
centered
>
<Modal.Header closeButton>
<Modal.Title id={`contained-modal-title-${vocData[item].href}`}>
{vocData[item].title}
</Modal.Title>
</Modal.Header>
<Modal.Body>{vocData[item].content}</Modal.Body>
</Modal>
</React.Fragment>
))}
</ul>
)
}
I can see my list of vocabulary terms is working but my modal is not appearing when I click the button. I've tried to research and read through:
React-Bootstrap Multiple Modal
React-bootstrap Modal component opens/closes all modals when I map through a list
How do I get my react app to display object information in my bootstrap modal when they click on a list item?
How to use React-Bootstrap modals inside a map array method to display AJAX data on button click in React?
how to show react bootstrap modal inside the function
but I'm unable to find an answer.
How can I dynamically setState and be able to render my modal for that vocabulary term in my list?

Try to use Modal only once and not render it many times. You can show only one Modal at time anyway. I have created a subcomponent for clarity.
There are many ways how to play with state. Here the initial state is null and hides the modal. When we click on button we set state with one vocData entry. This also toggles the visibility of Modal.
Finally, when we close its again, we set our state to null. In this way we use one state for two purposes - control vision and rendering of Modal and holding data for it.

Related

Is it possible to have Livewire events in a Datatables render function

I'm trying to open a modal and populate a form field with a model value.
The button to open the modal is embedded in the datatable config js and I'm thinking Livewire is running before the table is built.
The datatable uses ajax to populate and columnDefs to configure rows.
The JS for the config of the datatable is in a #push('scripts') in the component blade file.
The (simplified) render function for the row is:
var datatable = thetable.DataTable({
.....
render: function (data, type, full, meta){
return ('Edit');
},
.....
})
Clicking the button opens the modal but no XHR is made to the components edit function.
If I create an anchor in the same blade file as "normal" html:
<a href="#" wire:click="edit({{ 25 }})">test</button>
The XHR is called as expected.
So, I'm assuming Livewire doesn't know about the button - perhaps it ran before the table was built. Is there a way to force Livewire to wait?
I have tried to emit a Livewire event instead of wire:click = also no XHR.
I have seen the couple Laravel packages for Datatables. They don't suit.
I got this done with emitted events and component listeners.
jQuery's on to bind to the future elements clicks which livewire.emit the events.
protected listeners[] in the component respond to the emitted events.

Button as Link that routes to express semantic-ui react

I have a header in a react app that is using semantic-ui react. I want to route my login button to a backend express route (/auth/login). I tried the composition method by passing in {Link} from react-router-dom, but this is not routing to the express route, rather looking at the React routing.. in hindsight, this is of course how it should work..
This leaves me with the question though, how can I pass in a link to the backend api's for this button component? If I pass in 'a' and a path, this renders as a hyperlink but the path isn't passed in.
What is the prop I need to pass in to make this work as I can't see one that makes sense in the semantic-ui docs on buttons.. Or am I doing this the completely wrong way (this has happened before surprisingly)?
My login component is below..
import React, {Component} from 'react';
import { Button, Icon } from 'semantic-ui-react';
export default class LoginButtonNav extends Component {
render() {
return (
<Button primary animated="vertical" as='a' path='/auth/login'>
<Button.Content visible>Login</Button.Content>
<Button.Content hidden>
<Icon name="cloud" />
</Button.Content>
</Button>
);
}
}
Okay, rubber ducked this one myself, passing in a value for href solved it!
Correct component:
import React, {Component} from 'react';
import { Button, Icon } from 'semantic-ui-react';
export default class LoginButtonNav extends Component {
render() {
return (
<Button primary animated="vertical" as='a' href='/auth/login'>
<Button.Content visible>Login</Button.Content>
<Button.Content hidden>
<Icon name="cloud" />
</Button.Content>
</Button>
);
}
}
Still interested if there's a better way to do this..
I want to share my mistake and thank OP for posting the answer. Below is what I did and you should NOT do it like this:
<Button>
<Link to="/yourURL/">Nav Button</Link>
</Button>
This works technically but creates a unique problem where user MUST click on the text directly ("Nav Button" in this case) because the button itself is not rendered as a hyperlink. So if you click within the button but not the text itself, it won't navigate. It would even create an odd behavior where if you have another button next to it. Say, you have a "Submit" and a "Cancel" button where the Cancel button navigates user to the previous URL, if you click within the Cancel button but not the "Cancel" text, it would trigger the Submit button action instead. Hope this helps someone learning React!

How to handle a CSS property of clicked object in Ember?

Tell me please, how to handle onclick action by ID. For example, i’ve something in hbs template:
<button id="myButton" {{action "myAction"}} >OK</button>
it has CSS:
button {color: "red";}
How to do two things by onclick action:
1. Set property to clicked object (only to clicked), eg to set CSS colour “green”,
2. Get some property of clicked (eg CSS colour), and console log or alert.
Thanks in advance!
You can connect the action to the "onclick" event of the button like this
<button id="myButton" onclick={{action "myAction"}} >OK</button>
And then the first argument of the action will be the click event, from which you can take the target DOM element.
Check out this example twiddle:
https://ember-twiddle.com/1d14560e0e979dbbdddbfee57c84601c?openFiles=templates.application.hbs%2C

Render sidebar based on model in EmberJS

I started with learning EmberJS and maybe the answer is trivial, but after some researching, I still can't find a solution.
In my model template, I have some buttons(each for the different object) which after click should expand sidebar with its details.
What do I want to reach is something like this:
Could someone provide me with some simple twiddle?
There are two ways to achieve this effect.
Using controller's variable
{{#foreach model as |obj|}}
<button onclick={{action (mut activeModel) obj}}>{{obj.name}}</button>
{{/foreach}}
<!--Somewhere later in template-->
{{#if activeModel}}
<!--Code of overlay and sidebar, close button sets activeModel to undefined-->
{{/if}}
Using child (nested) route
Parent template:
{{#foreach model as |obj|}}
{{#link-to 'parentRoute.childRoute' obj tagName="button"}}
{{obj.name}}
{{/link-to}}
{{/foreach}}
<!--Somewhere later in template-->
{{outlet}}
Child template should contain code of overlay and sidebar, close button redirects back to parent route
well, one of the options is that you can create components and pass the modified model(modify the model using onclick function) as the data to that component.
for example,
let us just say that this is your main template
<button onclick="changeSideBar()">click</button>
<div style="display:none; //render it in the left-half(using bootstrap models)">
{{sidebar-component model=model.modified}}
</div>
in the javascript code (component.js),
function changeSideBar()
{
var modified= ;//set as per your convienince by iterating actual models or by any means
this.set('model.modified',modified);
//make display of sidebar div "block"
}
sidebar-component is your component. make the component as per your wish.
hope it helps.
I can't help much without your templates or codes. It would be great if you provide some of your works.

Return values from ionic2 modal to parent page

I am opening a Modal in ionic2, to search the values from a list. After search, I want to get the selected values back in my parent screen.
searchRooms(){
let modal = this.modalCtrl.create(RoomSearch);
modal.present();
}
This opens my search Modal and there I have list of available rooms. If user click on any room then I want to return back the value to parent page. I am not sure how to do this.
From documentation I feel NavConroller.pop can be used to pass back the values but I don't know how to use that.
Thanks in advance.
You can use onDidDismiss method explained in the Modal Controller.
In the page that opens your modal you can do :
let modal = this.modalCtrl.create(RoomSearch);
modal.onDidDismiss(data => {
// Do things with data coming from modal, for instance :
console.log(data);
});
modal.present();
And this in your modal controller, to close the modal :
this.viewCtrl.dismiss({"foo" : "bar"});