Where to place modals in a simple React application? - reactjs

I am building a simple React application that implements CRUD operations on the client-side and communicates with a backend via Ajax. I have a container component that has a list component that has many items.
So I have a component with a form to create a new item. I can also write a similar form to edit an item in the list. But I wanted to actually make a modal popup instead of just having a form on the same view. Typically, for instance, with Materialize, you have the following:
<!-- Modal Trigger -->
<a class="waves-effect waves-light btn modal-trigger" href="#modal1">Modal</a>
<!-- Modal Structure -->
<div id="modal1" class="modal">
<div class="modal-content">
<h4>Modal Header</h4>
<p>A bunch of text</p>
</div>
<div class="modal-footer">
Agree
</div>
</div>
$(document).ready(function(){
// the "href" attribute of .modal-trigger must
// specify the modal ID that wants to be triggered
$('.modal-trigger').leanModal();
});
So I have an edit button in each list item that would actually be the first part of the code above. Now my question is: where should the second part of the code -- the modal itself -- go in the structure of my React components? If I place it in the ListItem component, then every item is going to have a modal. My idea was to place the modal structure in the container component, right after the List component itself. But it does not seem to be working. So where exactly would you place your modal structure if you are using React? Note: I am not using Flux nor Redux, I am just trying to build a simple application using state and props.
// ContainerComponent:
<List>
<NewItemForm>
// I put the modal code inside the EditForm component,
// but it doesn't seem to be trigger from the ListItem edit button :/
<EditForm>
// My ContainerComponent has the following code in componentDidMount:
$('.modal-trigger').leanModal();

Related

Why is my modal only taking the first prop passed to it? (Using React and Bootstrap)

Hello :) I'm using Bootstrap to make an offcanvas component that can render a modal for each item in an array passed to it. However, when clicking open my modals, they each display omly the first items props. Why? And, how can I fix it? I recreated it here in codesandbox codesandbox recreation
If i can improve my question let me know in a kind way, please.
The way you have done is not the correct way of building Modal in React .
However just to give you clarity about the mistake you have done:
The prop letter is passed correctly. The problem is the way you're calling the modal.
If you see your code in Example.js , you have used data-bs-target="#exampleModal". And id="exampleModal" for the modal to show up.
So all the handlers are pointing to exampleModal id . Hence After you click on the buttons only the first modal shows up.
To solve this , you need to assign the data-bs-target and id dynamically. Something like below :
<button
type="button"
class="btn btn-primary"
data-bs-toggle="modal"
data-bs-target={`#exampleModal${props.letter}`}
>
click to view prop
</button>
and then in Modal set id as :
<div
class="modal fade"
id={`exampleModal${props.letter}`}
tabindex="-1"
aria-labelledby="exampleModalLabel"
aria-hidden="true"
>
It should work as expected.
here is the working example : Demo

Issues using react-loading-overlay

I have a simple react app, and im trying to add a simple loading overlay.
I saw the most common usage is react-loading-overlay.
My main app.js structure looks like that, I have a simple menu and a deck.gl map
<div className="container">
<AppMenu/>
<div className="deckgl_map">
<DeckMap/>
</div>
</div>
If I get it correctly, to use the loading overlay, I need to do something like that (using true for testing):
<LoadingOverlay
active={isActive}
spinner
text='Loading your content...'
>
<div className="container">
<AppMenu/>
<div className="deckgl_map">
<DeckMap/>
</div>
</div>
</LoadingOverlay>
But once I do that, my entire app page, instead of filling the whole screen, just takes the top 20% of the screen (and the rest is empty white).
Why wrapping my component with the LoadOverlay component causes the whole page to look weird?
Do I need to "play" with the CSS for the LoadOverlay component?

Is there a way to create a react popup modal without using a third party package

I tried using the technique below, but the modal does not blur out the rest of the content. At the same time, I would like to make it reusable and avoid manipulating the elements' z-index
return (
<>
<div className='dashboard-main-neworder' onClick={newOrder}>
<img alt='New Order' src={addorder}></img>
<span>New Order</span>
</div>
{selected && (
<div className='neworder'>
<div className='neworder-title'>
<p>ORDER DETAILS</p>
</div>
You may want to check out portals (https://reactjs.org/docs/portals.html).
They provide a way to attach react nodes somewhere else in the dom tree (let's say next to you #app node so that your modal is always on top of your application, and you can then add a blur effect if that's what you want on your app below the modal.

Multiple components scope conflict

I am working on an admin panel application which is based on AngularJS 1.5. It is structured as follows:
There is a main component called app, in which I am using all other components.
app.html
<div class="wrapper">
<message-component></message-component>
<header></header>
<leftbar></leftbar>
<body></body>
</div>
In the body component, I am using ui-view to render my component based on the current route.
At one time, three components are usually present : header, leftbar and body. I am using ng-if directive in my leftbar component in which I am calling a function.
leftbar.html
<li ng-if="leftbar.hasPermission('FOO')">
<a ui-sref="foo">
<span>Demo Page</span>
</a>
</li>
leftbar.controller
class LeftbarController {
constructor() {}
hasPermission(name) {
return user[name];
}
}
It basically shows the <li> if the user has a permission named "FOO".
Now, simultaneously my body component is also visible to the user and there is an input field present inside that, so whenever I write something in that field hasPermission method also gets called which is present in a different component.
So what can be the issue here? Why scopes are behaving like this ?

Rending a Modal in AngularJS

I'm attempting to learn AngularJS (background in BackboneJS). I have a div with some content inside, and I hope to render this div as a modal upon clicking inside of it:
<div class="stickynote"> Content here </div>
My thinking is to add a modal class that I can style in CSS. However, I'm not too sure how to add the modal class upon clicking (and conversely, removing the modal class upon clicking after the modal is rendered). Would I have to use ng-click and somehow set the class property from the JavaScript (myApp.js) file?
If you want to use your own modal styling and if you simply want to achieve adding an extra item to class attribute of your element, you can use a combination of ng-class and ng-click:
<div class="stickynote"
ng-class="{yourModalCSSClass: isModalOpen}"
ng-click="isModalOpen = true">
And somewhere else, you need another ng-click to turn it off:
<button ng-click="isModalOpen = false">Close modal</button>
Beware that both div and button must be in the same scope hierarchy to be able to use the same isModalOpen value. And by the way, I haven't tried this code but this should give you an idea. If you have a controller/directive, you can set isModalOpen from there by introducing functions in the scope:
// controller
$scope.toggleModal = function () {
$scope.isModalOpen = !$scope.isModalOpen;
}
<div ...
ng-click="toggleModal()">
<button ng-click="toggleModal()">...
If you're open to using a third-party solution, ng-dialog is an outstanding solution for modals+Angular.
https://github.com/likeastore/ngDialog

Resources