How to create Modal Window using React Native? - javascript

developers!
I have tried to create a simple Modal Window with React.
But my window still not appeared!
So, my code have two parts: JS-part and CSS-part.
I used "Modal" keyword, constructor and render(). All my code was written in CodePen area, so I'm able to see the result. But still something missing. What is it?
It will be mobile application. So, should I use keyword "Native" somewhere?
import "./modal.scss";
class Modal extends React.Component {
constructor(props) {
super(props);
}
shouldComponentUpdate(nextProps) {
return !I.is(this.props.data, nextProps.data);
}
render() {
let isOpen = this.props.data.get("isOpen");
return (
<div className={`flex middle center modal ${isOpen ? "open" : ""}`}>
{isOpen ?
(<div className={`row modal-content ${this.props.size || ""}`}>
<div className="col-12 middle modal-title">{this.props.title}</div>
<div className="col-12 modal-body">
{this.props.body}
</div>
<div className="col-12 middle modal-footer">{this.props.footer}</div>
</div>) : null
}
</div>);
}
}
export default Modal;
.modal {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 10000;
padding: 2rem;
background-color: rgba(0, 0, 0, 0.55);
.modal-content {
background-color: white;
max-height: 80%;
height: 80%;
.modal-title {
padding: 0 2.25rem;
height: 5rem;
max-height: 5rem;
text-transform: uppercase;
font-size: 1.8rem;
}
.modal-body {
height: calc(100% - 16rem);
overflow-y: scroll;
padding: 0 2rem;
}
.modal-footer {
height: 5rem;
max-height: 5rem;
padding: 0 2.25rem;
}
}
}
See also a fragment from CodePen:
enter image description here

import Modal from "react-native-modal";
render () {
return (
<View>
<Modal isVisible={true}>
<View style={{ flex: 1 }}>
<Text>I am the modal content!</Text>
</View>
</Modal>
</View>
)
}
See also https://github.com/react-native-community/react-native-modal

I think what you're trying to do is make a mobile application. The best way to do that would be to use React React Native instead of React
Check this out:
https://github.com/react-community/create-react-native-app
Once you're started showing a modal on a screen is quite simple.
https://facebook.github.io/react-native/docs/modal#docsNav
If this is your first time, it would be best to follow the getting started guide on React Native's website. Its helpful. There are no divs, but inLine styling can still be used.
https://facebook.github.io/react-native/docs/getting-started
Hope this helps

Related

Unable to move the button position to down

I am new to CSS.I am trying to move the position of button down which is overlapping with another button. I tried putting the button in different div, still facing the same issue. Below is my code
<div className="App">
{!showEvents && (<div>
<button onClick= {() => setShowEvents(true)}>Show Events </button>
</div>)}
{showEvents && (<div>
<button onClick = {() => setShowEvents(false)}>Hide Events</button>
</div>)}
<Title title={title} />
{showEvents && < Eventlist events={events} handleClick = {handleClick} />}
{showModal && (
<Modal handleClose={handleClose}>
<h2>Terms and Conditions</h2>
<p>Agree the terms and Conditions</p>
</Modal>
)}
<div>
<button1 onClick={() => setShowModal(true)}> Show </button1>
</div>
</div>
);
}
// Export the App component to consume/ import the component in some other pages.
export default App;
CSS code for two buttons
button{
display: inline-block;
padding: 10px 20px;
background: #f1f6;
border-radius: 8px;
font-weight: normal;
height: 40px;
}
button1{
display: inline-block;
padding: 10px 20px;
background: #f1f6;
border-radius: 8px;
font-weight: normal;
height: 40px;
}
In the above code, I need to move button1 down from button. Can anyone help me to resolve this issue.
The button is likely taking up the full space of the container div. Instead trying applying a margin to the container rather than the button
ie.
.button-div {
margin: 10px 0;
}
The problem is that you are not applying a margin on the button. You are applying padding, which is spacing from the border of the button inside towards the content.
You need to apply margin to it and it will still work. Div is a block element so if you put margin it will just scale up to match the needed height.
Applying margin to the div is also correct though depending on what you are trying to accomplish.

How to customise css for react-bootstrap Dropdown open state?

I'm using react-bootstrap v0.28.5 and trying to customise the background colour of the Dropdown.Toggle when the Dropdown component is open (see the toggle button with grey background in the 1st pic).
Any idea how I can achieve this?
I've been able to customise the Dropdown style as shown in the code below, but it seems that bootstrap has its own "open" class (see element tree in 2nd pic), which I can't figure out how to access using react className. I've looked in the source code for react-bootstrap/lib/Dropdown.js for some clues but no luck.
react component
<Dropdown className={styles.container}>
<Dropdown.Toggle className={styles.toggle} noCaret>
<div className={styles.title}>Title</div>
<div className={styles.placeholder}>Selection</div>
</Dropdown.Toggle>
<Dropdown.Menu>
<MenuItem eventKey="1" onSelect={(key, e) => onSelect(key, e)}>
Action
</MenuItem>
<MenuItem eventKey="2">Another action</MenuItem>
<MenuItem eventKey="3">Active Item</MenuItem>
</Dropdown.Menu>
</Dropdown>
styles.scss
.container {
display: block;
width: 100%;
height: 100%;
.toggle {
border: none;
text-align: start;
width: 100%;
padding: 0;
.title {
font-size: 13px;
font-weight: 700;
margin-bottom: 2px;
}
.placeholder {
font-size: 16px;
}
&:hover {
background: #e4e5e9;
}
}
I've tried looking at the source code but I don't see how to customise the "open" class.
Pic 1: Dropdown component
Pic 2: Page elements
Any help will be appreciated! Thanks a lot.
You may want to overwrite the styles for the toggle class by using the !important tag like this :
&:hover {
background: #e4e5e9 !important;
}

Closing a modal window in react

I'm doing an app, and i have a modal window, and i want to close the modal window when i click on the black background, and the way i did it works, the problem, is that i have white container in the center of the modal window, and i need to click stuff there, and when i do it, it closes the whole window, even though the onClick event is on the ModalHero that is the container that has the black background.
Just let me show you the code...
import React from "react";
import { ModalHero, ContainSettings } from "./ModalSettingsStyled";
const Modal = ({ setProfile }) => {
return (
<ModalHero onClick={() => setProfile(false)}>
<ContainSettings></ContainSettings>
</ModalHero>
);
};
export default Modal;
When i click on ContainSettings it closes the window, but i don't want that to happen.
Let me show you the css ( i'm using styled components )
import styles from "styled-components";
export const ModalHero = styles.section`
width: 100%;
height: 100vh;
background: rgba(0,0,0, .5);
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
display: flex;
align-items: center;
justify-content: center;
`;
export const ContainSettings = styles.div`
width: 45%;
height: 40vh;
border-radius: .5rem;
background: white;
`;
This is how it looks
What can i do so when i click the black background it will close the window, but when i click on the white container it won't
Thanks for your time !
You can put an Event.stopPropagation() onClick={(e) => e.stopPropagation()} on your ContainSettings
<ContainSettings onClick={(e) => e.stopPropagation()}>
Here a live example:
https://codesandbox.io/s/so-67143988-jmc0k?file=/src/Modal.js

adding onclick to an array of items

I have this problem where if I click on an item, all the items in that column gets affected by the click. I want only that very item where I clicked to have the class. but in my code, all the other items of that column are getting the class when I click on a certain single item. I want to make a div go fullscreen when I click on that particular div. kinda like modal pop up, here I want that the div slowly animates to fullscreen
export default class App extends React.Component {
constructor(props) {
super(props);
this.addActiveClass = this.addActiveClass.bind(this);
this.state = {
activeIndex: -1
};
}
addActiveClass(activeIndex) {
this.setState(prev => ({
activeIndex: prev.activeIndex === activeIndex ? -1 : activeIndex
}));
}
render() {
return (
<div className="container">
{Array.from({ length: 30 }).map((item, index) => {
return (
<div
key={index}
style={{
background: randomColor(colors),
height: randomHeight(100, 200)
}}
className={this.state.activeIndex === index ? "full" : ""}
onClick={() => this.addActiveClass(index)}
/>
);
})}
</div>
);
}
}
* {
box-sizing: border-box;
}
body {
margin: 40px;
background-color: #fff;
color: #444;
font: 2em Sansita, sans-serif;
}
.container {
display: flex;
flex-direction: column;
flex-wrap: wrap;
max-height: 100vh;
}
.container > * {
border: 2px solid orange;
border-radius: 5px;
margin: 10px;
padding: 10px 20px;
background-color: red;
color: #fff;
}
.full{
width: 100%;
height: 100%;
transition: 2s;
}
sandbox demonstrating the problem
I don't know exactly what kind of effect you would like to achieve with the selected item but items in the column are affected because of the default value of flexbox align-items which is stretch. The other items are stretching to match the selected element. Try to add align-items: flex-start to your .container class.
You'll have to make sure you're adding the class to the event target. Your onClick function needs to take the event as one of it's arguments, and you need to use event.target in the function body to make sure you're only affecting the element that is clicked. Hope that makes sense!
https://developer.mozilla.org/en-US/docs/Web/API/Event/target
The class adding logic works ok. You can observe this by checking the elements on developer tools. The problem is you are adding an inline style to your elements.
style={{
background: randomColor(colors),
height: randomHeight(100, 200)
}}
So, after each new render, this overrides the full class and give new height and new color.
The other problem is your full class. You are using 100% for height and width and probably this causes problems for your flex.
Just remove the inline style part and instead of using a percentage give custom width and height to full class, then you can see adding the class logic works well.
Pass down an event (e) from your onClick, then access that specific item through e.target.className. This way only the clicked item is updated, even if dynamically rendered from an array:
handleClick = e => { e.target.classNamme = 'class' }
<div className='' onClick={e => handleClick(e)}></div>
Alternatively, if you're keeping your classes in the state, you can just replace the string value with your variable and control in inside the function, as you've done in the example you've provided.
Adding !important overrides the inline-style height.
Height is set to 100vh to expand the div into full screen.
.full{
width: 100%;
height: 100vh !important;
transition: 2s;
}

Reactjs Not able to make a button functional

I am designing a sidebar for my react project and I have the sidebar which is functioning correctly as expected. As you will see that I have also created a button that will basically open the sidebar from left to right and close it from right to left. But I was not able to make the button functional. Help would be appreciated. Thanks in advance.
[This is what I am getting in the output][1]
[1]: https://i.stack.imgur.com/qnOHz.png
This is the file in which I have the sidebar
import React, { Component } from 'react';
import {NavLink} from 'react-router-dom'
import './TableStyle.css'
class HomePage extends Component {
constructor(props){
super(props);
this.state = {
visible: false
}
}
toggleSidebar(){
this.setState.visible = !this.state.visible
}
render() {
return (
<div id = "sidebar">
<div class = "toggle-btn" onClick = {this.toggleSidebar()}>
<span></span>
<span></span>
<span></span>
<ul>
<NavLink to = "/" style={{color: "white"}}>Home</NavLink>
<p></p>
<NavLink to = "/data" style={{color: "white"}}>Show all entries</NavLink>
</ul>
</div>
</div>
This is TableStyle.css
* {
margin: 0px;
padding: 0px;
font-family: sans-serif;
}
#sidebar {
position: fixed;
width: 200px;
height: 100%;
background: rgb(58, 68, 77);
}
/* #sidebar.active{
left: 0px;
} */
#sidebar ul{
color: rgb(240, 243, 245);
list-style: none;
padding: 15px 10px;
border-bottom: 1px solid rgba(100,100,100,0.3);
transition: all 500ms linear;
}
#sidebar.active{
left: 0px;
}
#sidebar.toggle-btn {
position: absolute;
left: 230px;
top: 30px;
}
#sidebar .toggle-btn span {
display: block;
width: 30px;
height: 3px;
background: white;
margin: 5px 0px;
}
Try using the React Hook useState instead, you don't need an internal state in this case, here is what I would've done:
import React, { Component, useState } from 'react';
import { NavLink } from 'react-router-dom'
import './TableStyle.css'
class HomePage extends Component {
const [visible, setIsVisible] = useState(false);
render() {
return (
<div id="sidebar">
<div class="toggle-btn" onClick={setIsVisible(!visible)}>
<span></span>
<span></span>
<span></span>
<ul>
<NavLink to = "/" style={{color: "white"}}>Home</NavLink>
<p></p>
<NavLink to = "/data" style={{color: "white"}}>Show all entries</NavLink>
</ul>
</div>
</div>
In this way, the button will toggle the visible value from false to true and viceversa. This happens on
<div class="toggle-btn" onClick={setIsVisible(!visible)}>
Where onClick toggles the visible value.
And then use the visible value for example in the following:
<div id="sidebar" class={visible ? "open-sidebar-class" : "close-sidebar-class"}>
The "open-sidebar-class" : "close-sidebar-class" is where you would put the class you want to trigger in the sidebar when the menu opens or closes.
Try then doing this example in TableStyle.css to see if it works, if it does, then just type in the css attributes you want instead to trigger in the sidebar whenever you click the button.
...
.open-sidebar-class {
background-color:green;
}
.close-sidebar-class {
background-color:red;
}
...
Your problem is re-rendering HomePage each time you click on the button, so it resets visibility to false as it executes the component script again. I can't tell why you are re-rendering from the snippet (and please reformat to usual indentation and I couldn't get it to run in a sandbox bc unclosed brackets), but you can work around by passing the sidebar visibility as a prop to the HomePage component.

Categories

Resources