Javascript code popup doesn't stay active after onclick event - javascript

JavaScript Noob
On the footer of the site I'm trying to display the contact info with a popup like form
whenever I copied the code to new page or new device the button clicked opens the form
but then the form closes immediately
Is there a way to fix this?
<button class="open-button" onclick="openForm()">
Contact Us</button>
<div class="form-popup">
<form class="form-container" id="myForm">
<h1>info#indiepump.com</h1>
<button type="button" class="btn-cancel" onclick="closeForm()">×</button>
</form>
</div>
<script>
function openForm() {
//openForm().stopPropagation();
document.getElementById("myForm").style.display = "flex";
}
function closeForm() {
document.getElementById("myForm").style.display = "none";
}
</script>
And the CSS part:
.open-button {
background-image: url(/usr/fsociety/indiepump_test/test_4/social_icons/email.png);
background-repeat: no-repeat;
background-color: transparent;
padding: 17px 21px;
border: none;
cursor: pointer;
position: fixed;
justify-content: space-between;
align-items: center;
vertical-align: middle;
text-align: right;
text-decoration: none;
font-size: 0.9rem;
margin-left: 1rem;
height: 27px;
width: 121px;
padding: 3px 3px;
padding-left: 3px;
color: red;
}
.form-popup {
display: none;
position: fixed;
align-items: center;
justify-content: space-between;
vertical-align: middle;
bottom: 2.5rem;
left: 2rem;
border: 1px solid red;
border-radius: 10px;
color: red;
font-size: 0.7rem;
z-index: 10000;
}
.form-container {
display: flex;
max-width: 300px;
width: 300px;
height: 50px;
align-items: center;
justify-content: space-between;
vertical-align: middle;
text-align: center;
padding: 10px;
background-color: #f9e3d5;
z-index: 100000;
}
.btn-cancel {
display: flex;
align-items: center;
margin-bottom: 1rem;
vertical-align: middle;
text-align: center;
width: 25px;
height: 25px;
border: none;
background-color: transparent;
color: red;
font-size: 1.9rem;
cursor: pointer;
}
I've already tried Google search solutions to no avail.
Also different methods from other helpful sites but every time I change something the button doesn't work at all.

After click on button the element with .form-popup class does not show because in your CSS you have set display:none:
.form-popup {
display: none;
....
}
So you need to set display:flex or block for .form-popup too.
Here is working sample:
function openForm() {
document.getElementById("myForm").parentElement.style.display = "flex";
document.getElementById("myForm").style.display = "flex";
}
function closeForm() {
document.getElementById("myForm").style.display = "none";
document.getElementById("myForm").parentElement.style.display = "none";
}
.open-button {
background-image: url(/usr/fsociety/indiepump_test/test_4/social_icons/email.png);
background-repeat: no-repeat;
background-color: transparent;
padding: 17px 21px;
border: none;
cursor: pointer;
position: fixed;
justify-content: space-between;
align-items: center;
vertical-align: middle;
text-align: right;
text-decoration: none;
font-size: 0.9rem;
margin-left: 1rem;
height: 27px;
width: 121px;
padding: 3px 3px;
padding-left: 3px;
color: red;
}
.form-popup {
display: none;
position: fixed;
align-items: center;
justify-content: space-between;
vertical-align: middle;
bottom: 2.5rem;
left: 2rem;
border: 1px solid red;
border-radius: 10px;
color: red;
font-size: 0.7rem;
z-index: 10000;
}
.form-container {
display: flex;
max-width: 300px;
width: 300px;
height: 50px;
align-items: center;
justify-content: space-between;
vertical-align: middle;
text-align: center;
padding: 10px;
background-color: #f9e3d5;
z-index: 100000;
}
.btn-cancel {
display: flex;
align-items: center;
margin-bottom: 1rem;
vertical-align: middle;
text-align: center;
width: 25px;
height: 25px;
border: none;
background-color: transparent;
color: red;
font-size: 1.9rem;
cursor: pointer;
}
<button class="open-button" onclick="openForm()">
Contact Us
</button>
<div class="form-popup">
<form class="form-container" id="myForm">
<h1>info#indiepump.com</h1>
<button type="button" class="btn-cancel" onclick="closeForm()">×</button>
</form>
</div>

#Alireza Ahmadi
Reposting the new code...
function openForm() {
document.getElementById("myForm").parentElement.style.display = "flex";
document.getElementById("myForm").style.display = "flex";
}
function closeForm() {
document.getElementById("myForm").style.display = "none";
document.getElementById("myForm").parentElement.style.display = "none";
}
.open-button {
background-image: url(/usr/fsociety/indiepump_test/test_4/social_icons/email.png);
background-repeat: no-repeat;
background-color: transparent;
padding: 17px 21px;
border: none;
cursor: pointer;
position: fixed;
justify-content: space-between;
align-items: center;
vertical-align: middle;
text-align: right;
text-decoration: none;
font-size: 0.9rem;
margin-left: 1rem;
height: 27px;
width: 121px;
padding: 3px 3px;
padding-left: 3px;
color: red;
}
.form-popup {
display: none;
position: fixed;
align-items: center;
justify-content: space-between;
vertical-align: middle;
bottom: 2.5rem;
left: 2rem;
border: 1px solid red;
border-radius: 10px;
color: red;
font-size: 0.7rem;
z-index: 10000;
}
.div-form {
display: flex;
max-width: 300px;
width: 300px;
height: 50px;
align-items: center;
justify-content: space-between;
vertical-align: middle;
text-align: center;
padding: 10px;
background-color: #f9e3d5;
z-index: 100000;
}
.btn-cancel {
display: flex;
align-items: center;
margin-bottom: 1rem;
vertical-align: middle;
text-align: center;
width: 25px;
height: 25px;
border: none;
background-color: transparent;
color: red;
font-size: 1.9rem;
cursor: pointer;
}
<button class="open-button" onclick="openForm()">
Contact Us</button>
<div class="form-popup">
<div class="div-form" id="myForm">
<form class="form-container">
<h1>info#indiepump.com</h1>
<button type="button" class="btn-cancel" onclick="closeForm()">×</button>
</form>
</div>
</div>
Right now the button doesn't do anything the page only shows that is refreshing

Related

How to encapsulate javascript with repetitive functions into reusable components?

I'm a javascript novice, and I have a problem that bothers me~
I often need to write a function to click a button to pop up a modal. The interaction logic of this function is repeated, but sometimes the UI or copywriting needs to be adjusted~
So I want to know How can such a repetitive function be packaged into a component, and other pages need to use modal-like functions in the future, which can be directly referenced and only need to change the copy without rewriting CSS / HTML / JavaScript?
// 匯出 excel 彈窗 JS
$("*[data-modal]").on("click", Modeal);
function Modeal() {
$(".excel_popup").css("display", "flex");
$("body").css("overflow", "hidden");
// 關閉彈窗
$(document).on("click", function(e) {
if (
e.target.className == "close" ||
e.target.className == "excel_popup" ||
e.target.className == "btn_confirm" ||
e.target.className == "btn_consider"
) {
$("#js-job_excel_popup").css("display", "none");
$("body").css("overflow", "auto");
}
});
}
.excel_popup {
position: fixed;
z-index: 999999999;
width: 100%;
height: 100vh;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
background-color: rgba(0, 0, 0, 0.3);
justify-content: center;
align-items: center;
display: none;
}
.excel_popup .excel_close_wrap {
width: 360px;
background-color: #fff;
padding: 16px 24px;
border-radius: 8px;
margin: 0 8px;
}
.excel_popup .excel_close_wrap header {
position: relative;
width: 100%;
display: flex;
justify-content: center;
align-items: center;
border-bottom: 1px solid #222;
padding-bottom: 16px;
}
.excel_popup .excel_close_wrap header h2 {
font-size: 18px;
line-height: 1.5;
font-weight: 500;
text-align: center;
}
.excel_popup .excel_close_wrap header .close {
position: absolute;
right: 0;
display: inline-block;
width: 20px;
height: 20px;
background-repeat: no-repeat;
background-size: contain;
cursor: pointer;
}
.excel_popup .excel_close_wrap .txt {
font-size: 16px;
font-weight: 400;
line-height: 1.5;
text-align: center;
padding: 32px 0px;
color: #222;
}
.excel_popup .excel_close_wrap .btn_group {
display: flex;
justify-content: space-between;
font-size: 14px;
line-height: 1.5;
letter-spacing: 0.15px;
}
.excel_popup .excel_close_wrap .btn_group .btn_consider {
width: 132px;
text-align: center;
padding: 8px;
border-radius: 4px;
border: 1px solid #222;
margin-right: 4px;
cursor: pointer;
}
.excel_popup .excel_close_wrap .btn_group .btn_consider:hover {
border: 1px solid #222;
}
.excel_popup .excel_close_wrap .btn_group .btn_confirm {
width: 132px;
text-align: center;
padding: 8px;
border-radius: 4px;
border: 1px solid #222;
background-color: #222;
margin-left: 4px;
cursor: pointer;
color: #fff;
}
.excel_popup .excel_close_wrap .btn_group .btn_confirm:hover {
background-color: yellow;
border: 1px solid #222;
color: #222;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<a class="excel_export" id="js-excel_export" href="javascript:;" data-modal="js-job_excel_popup">
<figure></figure>
<p>Click the popup</p>
</a>
<div class="excel_popup" id="js-job_excel_popup">
<div class="excel_close_wrap">
<header>
<h2>TITLE</h2>
<div class="close" id="js-close"></div>
</header>
<p class="txt">Hello World!!!</p>
<div class="btn_group">
<a class="btn_consider">Cancel</a>
<a class="btn_confirm">Send</a>
</div>
</div>
</div>

How can I horizontally center these 3 buttons

At first there were 4 buttons I only wanted 3 so I removed the 4th one and that's why I want to make the remaining 3 look horizontally centered, it looks weird because of the 4th button's blank space. I tried a few things but they didn't work out.
var tabButtons = document.querySelectorAll(".tabContainer .buttonContainer button");
var tabPanels = document.querySelectorAll(".tabContainer .tabPanel");
function showPanel(panelIndex, colorCode) {
tabButtons.forEach(function(node) {
node.style.backgroundColor = "";
node.style.color = "";
});
tabButtons[panelIndex].style.backgroundColor = colorCode;
tabButtons[panelIndex].style.color = "white";
tabPanels.forEach(function(node) {
node.style.display = "none";
});
tabPanels[panelIndex].style.display = "block";
tabPanels[panelIndex].style.backgroundColor = colorCode;
}
showPanel(0, '#f44336');
.title {
color: #dc2d5e;
text-align: center;
}
.tabContainer {
width: 100%;
height: 350px;
}
.tabContainer .buttonContainer {
height: 15%;
align-items: center;
align-content: center;
justify-content: center;
text-align: center;
}
.tabContainer .buttonContainer button {
width: 25%;
height: 100%;
float: left;
border: none;
outline: none;
cursor: pointer;
padding: 10px;
font-family: sans-serif;
font-size: 18px;
background-color: #eee;
}
.tabContainer .buttonContainer button:hover {
background-color: #d7d4d4;
}
.tabContainer .tabPanel {
height: 85%;
background-color: gray;
color: white;
text-align: center;
padding-top: 105px;
box-sizing: border-box;
font-family: sans-serif;
font-size: 22px;
display: none;
}
<h1 class="title">Recieved Data</h1>
<div class="tabContainer">
<div class="buttonContainer">
<button onclick="showPanel(0,'#f44336')">Feedbacks</button>
<button onclick="showPanel(1,'#4caf50')">Suggestions</button>
<button onclick="showPanel(2,'#2196f3')">Messages</button>
</div>
<div class="tabPanel">Tab 1:Content</div>
<div class="tabPanel">Tab 2:Content</div>
<div class="tabPanel">Tab 3:Content</div>
</div>
You are really close, adding these two flex properties can obtain the desired solution:
.tabContainer .buttonContainer{
display: flex;
justify-content: space-between;
}
.title{
color: #dc2d5e;
text-align: center;
}
.tabContainer{
width: 100%;
height: 350px;
}
.tabContainer .buttonContainer{
display: flex;
height: 15%;
align-items: center;
align-content: center;
justify-content: space-between;
text-align: center;
}
.tabContainer .buttonContainer button{
width: 25%;
height: 100%;
float: left;
border: none;
outline:none;
cursor: pointer;
padding: 10px;
font-family: sans-serif;
font-size: 18px;
background-color: #eee;
}
.tabContainer .buttonContainer button:hover{
background-color: #d7d4d4;
}
.tabContainer .tabPanel{
height: 85%;
background-color: gray;
color: white;
text-align: center;
padding-top: 105px;
box-sizing: border-box;
font-family: sans-serif;
font-size: 22px;
display: none;
}
<h1 class="title">Recieved Data</h1>
<div class="tabContainer">
<div class="buttonContainer">
<button onclick="showPanel(0,'#f44336')">Feedbacks</button>
<button onclick="showPanel(1,'#4caf50')">Suggestions</button>
<button onclick="showPanel(2,'#2196f3')">Messages</button>
</div>
<div class="tabPanel">Tab 1:Content</div>
<div class="tabPanel">Tab 2:Content</div>
<div class="tabPanel">Tab 3:Content</div>
</div>
This flexbox guide is my go-to any time I run into this type of issue!
You just need to add this to your css !
.buttonContainer{
display: flex;
}
Since there are only 3 buttons now, I would just make each one's width a third.
You can accomplish this by doing:
.tabContainer .buttonContainer button{
width: calc(100% / 3);
}
EDIT: So it would look like this:
var tabButtons = document.querySelectorAll(".tabContainer .buttonContainer button");
var tabPanels = document.querySelectorAll(".tabContainer .tabPanel");
function showPanel(panelIndex, colorCode) {
tabButtons.forEach(function(node) {
node.style.backgroundColor = "";
node.style.color = "";
});
tabButtons[panelIndex].style.backgroundColor = colorCode;
tabButtons[panelIndex].style.color = "white";
tabPanels.forEach(function(node) {
node.style.display = "none";
});
tabPanels[panelIndex].style.display = "block";
tabPanels[panelIndex].style.backgroundColor = colorCode;
}
showPanel(0, '#f44336');
.title {
color: #dc2d5e;
text-align: center;
}
.tabContainer {
width: 100%;
height: 350px;
}
.tabContainer .buttonContainer {
height: 15%;
align-items: center;
align-content: center;
justify-content: center;
text-align: center;
}
.tabContainer .buttonContainer button {
width: calc(100% / 3);
height: 100%;
float: left;
border: none;
outline: none;
cursor: pointer;
padding: 10px;
font-family: sans-serif;
font-size: 18px;
background-color: #eee;
}
.tabContainer .buttonContainer button:hover {
background-color: #d7d4d4;
}
.tabContainer .tabPanel {
height: 85%;
background-color: gray;
color: white;
text-align: center;
padding-top: 105px;
box-sizing: border-box;
font-family: sans-serif;
font-size: 22px;
display: none;
}
<h1 class="title">Recieved Data</h1>
<div class="tabContainer">
<div class="buttonContainer">
<button onclick="showPanel(0,'#f44336')">Feedbacks</button>
<button onclick="showPanel(1,'#4caf50')">Suggestions</button>
<button onclick="showPanel(2,'#2196f3')">Messages</button>
</div>
<div class="tabPanel">Tab 1:Content</div>
<div class="tabPanel">Tab 2:Content</div>
<div class="tabPanel">Tab 3:Content</div>
</div>
calc() is widely supported on modern browsers.

Warning: Failed prop type: Invalid prop `open` of type `function` supplied to `ForwardRef(Dialog)`, expected `boolean`. at Dialog

The idea is to show a District Overview in a dialog box and then display a table once the dialog box is closed. However, I cannot seem to get rid of the box when I click on close. The Dialog Box comes up when the By District Option is clicked(marked in Yellow) which then brings up a dropdown(marked in Red). Once a value in the dropdown is selected the Dialog Box comes up. Although the dialog box shows up, I cannot seem to close it somehow. The console gives the error I gave in the title. The screenshots and the code are below:
Here's the code:
import React, { useState } from "react";
import './advance_filter.css';
import DistrictFilter from "../../widgets/filter_dropdowns/district_filter/district_filter";
import Dialog from "#material-ui/core/Dialog";
import { DialogActions, DialogContent, DialogTitle } from "#material-ui/core";
const AdvanceFilterScreen = () => {
const [byDistrictFilter, setByDistrictFilter] = useState(false); //This is the hook that selects the By District option
const [district, setDistrict] = useState(''); //This selects the value from the Dropdown
const [districtDialogOpen, setDistrictDialogOpen] = useState(false); //This was meant for opening and closing the dialog box
const districtFilter = () => {
setByDistrictFilter(prev => !prev);
setFilterButtonValue('');
setDistrict('')
}
const openDialog = () => {
setDistrictDialogOpen(prev => !prev)
}
const closeDialog = () => {
setDistrictDialogOpen(prev => !prev);
}
return (
<div className="advanceFilterScreen">
<div className="navBarFilter">
<NavBar></NavBar>
</div>
<div className="chooseFilters">
<div className="chooseColumn">
<div className="caption">Choose Filters (Upto 5 filters at a time)</div>
<div className="filterOptions">
<div onClick={districtFilter}>
<div className={byDistrictFilter ? "districtSelectedFilter" : "byDistrictFilter"}>By District</div>
</div>
</div>
</div>
</div>
<div className={byDistrictFilter ? "filterDropdowns" : "noFilter"}>
<div className="filterClass">
{byDistrictFilter ? <div style={{ marginRight: "15px" }}>
{/* This shows the District Dropdown */}
<DistrictFilter setDistrict={setDistrict}></DistrictFilter>
</div> : null}
</div>
<div>
{district ? <Dialog open={openDialog} onClose={closeDialog}>
<DialogTitle className="districtOverview">{"District Overview"}</DialogTitle>
<DialogContent>
<div className="overAll">
{/* This component shows the overview on the Dialog Box */}
<DistrictTable district={district} setFilterButtonValue={setFilterButtonValue} ></DistrictTable>
</div>
</DialogContent>
<DialogActions>
<div className="closeButton" onClick={closeDialog}>Close</div>
</DialogActions>
</Dialog>
: <FilterSearchButton district={district}></FilterSearchButton>}
</div>
</div>
<div style={{ marginTop: "50px" }}>
<Table buttonValue={buttonValue}></Table>
</div>
</div>
);
};
export default AdvanceFilterScreen;
In case someone needs the CSS file for testing:
.advanceFilterScreen {
display: flex;
flex-direction: column;
}
.navBarFilter {
background-color: rgb(52, 171, 245);
}
.chooseFilters {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 80px;
background-color: rgb(52, 171, 245);
}
.chooseColumn {
display: flex;
justify-content: flex-start;
align-items: flex-start;
flex-direction: column;
width: 75%;
height: 100%;
}
.caption {
font-weight: bold;
margin-top: 10px;
padding-left: 10px;
color: white;
font-weight: bold;
}
.filterOptions {
display: flex;
width: 100%;
height: 100%;
padding: 0 5px;
}
.byNameFilter {
display: flex;
justify-content: center;
align-items: center;
flex: 1;
height: 30px;
margin-right: 5px;
margin-top: 10px;
border-radius: 10px;
box-shadow: 1px 2px 4px 1px gray;
background-color: white;
cursor: pointer;
padding: 0 10px;
}
.nameSelectedFilter {
display: flex;
justify-content: center;
align-items: center;
flex: 1;
height: 30px;
margin-right: 5px;
margin-top: 10px;
border-radius: 10px;
background-color: gray;
cursor: pointer;
padding: 0 10px;
}
.byDateFilter {
display: flex;
justify-content: center;
align-items: center;
flex: 1;
height: 30px;
margin-right: 5px;
margin-top: 10px;
border-radius: 10px;
box-shadow: 1px 2px 4px 1px gray;
background-color: white;
cursor: pointer;
padding: 0 10px;
}
.dateSelectedFilter {
display: flex;
justify-content: center;
align-items: center;
flex: 1;
height: 30px;
margin-right: 5px;
margin-top: 10px;
border-radius: 10px;
background-color: gray;
cursor: pointer;
padding: 0 10px;
}
.byCategoryFilter {
display: flex;
justify-content: center;
align-items: center;
flex: 1;
height: 30px;
margin-right: 5px;
margin-top: 10px;
border-radius: 10px;
box-shadow: 1px 2px 4px 1px gray;
background-color: white;
cursor: pointer;
padding: 0 10px;
}
.categorySelectedFilter {
display: flex;
justify-content: center;
align-items: center;
flex: 1;
height: 30px;
margin-right: 5px;
margin-top: 10px;
border-radius: 10px;
background-color: gray;
cursor: pointer;
padding: 0 10px;
}
.byDistrictFilter {
display: flex;
justify-content: center;
align-items: center;
flex: 1;
height: 30px;
margin-right: 5px;
margin-top: 10px;
border-radius: 10px;
box-shadow: 1px 2px 4px 1px gray;
background-color: white;
cursor: pointer;
padding: 0 10px;
}
.districtSelectedFilter {
display: flex;
justify-content: center;
align-items: center;
flex: 1;
height: 30px;
margin-right: 5px;
margin-top: 10px;
border-radius: 10px;
background-color: gray;
cursor: pointer;
padding: 0 10px;
}
.byStatesFilter {
display: flex;
justify-content: center;
align-items: center;
flex: 1;
height: 30px;
margin-right: 5px;
margin-top: 10px;
border-radius: 10px;
box-shadow: 1px 2px 4px 1px gray;
background-color: white;
cursor: pointer;
padding: 0 10px;
}
.stateSelectedFilter {
display: flex;
justify-content: center;
align-items: center;
flex: 1;
height: 30px;
margin-right: 5px;
margin-top: 10px;
border-radius: 10px;
background-color: gray;
cursor: pointer;
padding: 0 10px;
}
.bySerialNumberFilter {
display: flex;
justify-content: center;
align-items: center;
flex: 1;
height: 30px;
margin-right: 5px;
margin-top: 10px;
border-radius: 10px;
box-shadow: 1px 2px 4px 1px gray;
background-color: white;
cursor: pointer;
padding: 0 10px;
}
.serialNumberSelectedFilter {
display: flex;
justify-content: center;
align-items: center;
flex: 1;
height: 30px;
margin-right: 5px;
margin-top: 10px;
border-radius: 10px;
background-color: gray;
cursor: pointer;
padding: 0 10px;
}
.byIssueFilter {
display: flex;
justify-content: center;
align-items: center;
flex: 1;
height: 30px;
margin-right: 5px;
margin-top: 10px;
border-radius: 10px;
box-shadow: 1px 2px 4px 1px gray;
background-color: white;
cursor: pointer;
padding: 0 10px;
}
.issueSelectedFilter {
display: flex;
justify-content: center;
align-items: center;
flex: 1;
height: 30px;
margin-right: 5px;
margin-top: 10px;
border-radius: 10px;
background-color: gray;
background-color: white;
cursor: pointer;
padding: 0 10px;
}
.filterDropdowns {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
width: 100%;
height: 200px;
background-color: rgb(52, 171, 245);
/* margin-top: 10px; */
}
.noFilter {
display: none;
}
.filterClass {
display: flex;
justify-content: space-evenly;
align-items: center;
/* flex-direction: row; */
/* width: 100%;
height: 50px; */
/* background-color: yellow; */
}
.districtOverview {
display: flex;
justify-content: center;
align-items: center;
}
.overAll {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
padding-left: 15px;
padding-top: 5px;
/* background-color: red; */
}
.closeButton {
display: flex;
justify-content: flex-end;
padding-right: 30px;
align-items: center;
width: 200px;
height: 50px;
color: rgb(52, 171, 245);
/* font-weight: bold; */
cursor: pointer;
font-size: 20px;
}
/* .searchFilterButton {
display: flex;
justify-content: center;
align-items: center;
width: 150px;
height: 30px;
margin-top: 50px;
background-color: rgb(52, 171, 245);
box-shadow: 1px 2px 4px 1px gray;
border-radius: 5px;
cursor: pointer;
background-color: green;
color: white;
font-weight: bold;
} */
The open prop passed to dialog isn't meant to be a function. It should be a boolean. The trigger of the District Overview dialog should be the state of district, when district has a truthy value. So it's either you render using a tenary operator district ? /* dialog */ : /* filter button */ and have
the oepn prop set to true on initial render or you render the dialog immediately with the other nodes and set its open prop to open={Boolean(district)}
const districtFilter = () => {
setByDistrictFilter(prev => !prev);
setFilterButtonValue('');
}
const closeDialog = () => {
setDistrict('')
}
<div>
{district ? (
<Dialog open onClose={closeDialog}>
{/* ... */}
</Dialog>
) : (
<FilterSearchButton district={district}></FilterSearchButton>
)}
</div>
or
<div>
<Dialog open={Boolean(district)} onClose={closeDialog}>
{/* ... */}
</Dialog>
{district && <FilterSearchButton district={district}></FilterSearchButton>}
</div>

How to expand textarea upwards and its parent divs along with it

I'm creating a chat application(React). I'm having this textbox which I need to expand vertically upwards as user types. I tried doing it with position absolute but it takes it out of the normal flow. And this does not allow the parent div to move upwards. Is there a way that this can be done? If anyone could point me in the right direction that would be great. Thanks.
Here is the codepen link.
https://codepen.io/ghewadesumit/pen/zYzRjyY
<div class='chat-inputbox-container'>
<div class='chat-inputbox-wrapper'>
<div class='chat-microphone-container'>
<div class='chat-microphone'></div>
</div>
<div class='inputbox-container'>
<div class='inputbox-wrapper'>
<textarea type='text' class='chat-input-box'></textarea>
<div class='input-box-btn'></div>
</div>
<div class='input-character-container'>
<span class='input-character'>
250 out of 250 characters left
</span>
</div>
</div>
</div>
</div>
css
.chat-inputbox-container {
/* border: 1px solid red; */
width: 100%;
height: 113px;
align-self: flex-end;
display: flex;
justify-content: center;
}
.chat-inputbox-wrapper {
width: 736px;
height: 92px;
display: flex;
flex-direction: row;
justify-content: space-between;
}
.chat-microphone-container {
width: 32px;
height: 92px;
/* border: 1px solid orange; */
display: flex;
align-items: center;
justify-content: center;
margin-right: 10px;
}
.chat-microphone {
width: 32px;
height: 32px;
background: orangered;
}
.inputbox-wrapper {
width: 694px;
height: 52px;
/* border: 1px solid blue; */
display: flex;
align-self: flex-end;
align-items: center;
margin-top: 16px;
background: gray;
border: 1px solid red;
box-sizing: border-box;
border-radius: 4px;
}
.chat-input-box {
width: 632px;
height: 20px;
font-size: 14px;
line-height: 20px;
border: hidden;
background: #f7f7f7;
outline: none;
color: #0d1c3d;
margin: 16px 10px;
}
.input-box-btn {
/* Auto Layout */
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
padding: 0px;
position: static;
width: 32px;
height: 32px;
margin-right: 10px;
background: #0078b3;
border-radius: 4px;
flex: none;
order: 0;
flex-grow: 0;
margin: 0px 0px;
}
.input-character-container {
}
.input-character {
font-size: 12px;
line-height: 16px;
color: #677083;
}
We can use a Javascript ResizeObserver to tell us when the height of the input text has changed. Then we can scroll the window in such a way that the bottom of the input stays in the same position on the viewport - so the elements seem to grow upwards.
Note this snippet uses contenteditable on a div rather than a textarea as the growing/shrinking and text wrapping then happen automatically.
<style>
body {
height: 300vh;
}
.parent {
margin-top: 20vh; /* so we can see it growing not just disappearing */
background: pink;
}
.child {
background: #eeeeee;
}
</style>
<body>
<div class="parent">
Some stuff in the parent<br> here
<div class="child" contenteditable></div>
</div>
<script>
let prevH = 0;
const textArea = document.querySelector('.child');
const resizeObserver = new ResizeObserver(entries => {
for (let entry of entries) {
let h = entry.contentRect.height;
let diff = h - prevH;
if (diff != 0) {
prevH = h;
window.scroll(0, prevH);
}
}
});
resizeObserver.observe(textArea);
</script>
</body>
Don't hard code the height of class .inputbox-wrapper instead remove height property from there or put height: auto(which is default value) so that container expand when the the text-area is expanded
.chat-inputbox-container {
/* border: 1px solid red; */
width: 100%;
height: 113px;
align-self: flex-end;
display: flex;
justify-content: center;
}
.chat-inputbox-wrapper {
width: 736px;
height: 92px;
display: flex;
flex-direction: row;
justify-content: space-between;
}
.chat-microphone-container {
width: 32px;
height: 92px;
/* border: 1px solid orange; */
display: flex;
align-items: center;
justify-content: center;
margin-right: 10px;
}
.chat-microphone {
width: 32px;
height: 32px;
background: orangered;
}
.inputbox-wrapper {
width: 694px;
height: auto;/*Change here*/
/* border: 1px solid blue; */
display: flex;
align-self: flex-end;
align-items: center;
margin-top: 16px;
background: gray;
border: 1px solid red;
box-sizing: border-box;
border-radius: 4px;
}
.chat-input-box {
width: 632px;
height: 20px;
font-size: 14px;
line-height: 20px;
border: hidden;
background: #f7f7f7;
outline: none;
color: #0d1c3d;
margin: 16px 10px;
}
.input-box-btn {
/* Auto Layout */
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
padding: 0px;
position: static;
width: 32px;
height: 32px;
margin-right: 10px;
background: #0078b3;
border-radius: 4px;
flex: none;
order: 0;
flex-grow: 0;
margin: 0px 0px;
}
.input-character-container {
}
.input-character {
font-size: 12px;
line-height: 16px;
color: #677083;
}
<div class='chat-inputbox-container'>
<div class='chat-inputbox-wrapper'>
<div class='chat-microphone-container'>
<div class='chat-microphone'></div>
</div>
<div class='inputbox-container'>
<div class='inputbox-wrapper'>
<textarea type='text' class='chat-input-box'></textarea>
<div class='input-box-btn'></div>
</div>
<div class='input-character-container'>
<span class='input-character'>
250 out of 250 characters left
</span>
</div>
</div>
</div>
</div>
The .inputbox-wrapper should have a min-height not a height if you set only a height, the container will not resize with the textbox.
On another note, if you want the textarea to expand vertically only, you can add resize: vertical; to .chat-input-box {
Textboxes can't expand their height automatically like this by default - you'll need to use a bit of Javascript.
One approach is to dynamically calculate the height of the textfield based on the number of line breaks inside it.
This example from CSS-Tricks has more details on the approach. I've implemented it on your code below.
You also need to change height to min-height on your inputbox-wrapper to allow it to expand as the textfield changes height.
let textarea = document.querySelector(".chat-input-box");
textarea.addEventListener("keyup", () => {
textarea.style.height = calcHeight(textarea.value) + "px";
});
function calcHeight(value) {
let numberOfLineBreaks = (value.match(/\n/g) || []).length;
// min-height + lines x line-height + padding + border
let newHeight = 20 + numberOfLineBreaks * 20 + 0 + 0;
// padding and border are both 0 here but have left in for reference
return newHeight;
}
.chat-inputbox-container {
/* border: 1px solid red; */
width: 100%;
height: 113px;
align-self: flex-end;
display: flex;
justify-content: center;
}
.chat-inputbox-wrapper {
width: 736px;
height: 92px;
display: flex;
flex-direction: row;
justify-content: space-between;
}
.chat-microphone-container {
width: 32px;
height: 92px;
/* border: 1px solid orange; */
display: flex;
align-items: center;
justify-content: center;
margin-right: 10px;
}
.chat-microphone {
width: 32px;
height: 32px;
background: orangered;
}
.inputbox-wrapper {
width: 694px;
min-height: 52px;
/* border: 1px solid blue; */
display: flex;
align-self: flex-end;
align-items: center;
margin-top: 16px;
background: gray;
border: 1px solid red;
box-sizing: border-box;
border-radius: 4px;
}
.chat-input-box {
width: 632px;
height: 20px;
font-size: 14px;
line-height: 20px;
border: hidden;
background: #f7f7f7;
outline: none;
color: #0d1c3d;
margin: 16px 10px;
}
.input-box-btn {
/* Auto Layout */
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
padding: 0px;
position: static;
width: 32px;
height: 32px;
margin-right: 10px;
background: #0078b3;
border-radius: 4px;
flex: none;
order: 0;
flex-grow: 0;
margin: 0px 0px;
}
.input-character-container {
}
.input-character {
font-size: 12px;
line-height: 16px;
color: #677083;
}
<div class='chat-inputbox-container'>
<div class='chat-inputbox-wrapper'>
<div class='chat-microphone-container'>
<div class='chat-microphone'></div>
</div>
<div class='inputbox-container'>
<div class='inputbox-wrapper'>
<textarea type='text' class='chat-input-box'></textarea>
<div class='input-box-btn'></div>
</div>
<div class='input-character-container'>
<span class='input-character'>
250 out of 250 characters left
</span>
</div>
</div>
</div>
</div>

Font Awesome icons don't align

Hey I have a problem with aligning my FA icons to buttons. I don't know why this happens I've been roughly following a tutorial and doing some stuff that I'm capable of figuring out on my own but I can't seem to find a solution for my problem.
This is what it does
Here is my HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.13.0/css/all.min.css" integrity="sha256-h20CPZ0QyXlBuAw7A+KluUYx/3pK+c7lYEpqLTlxjYQ=" crossorigin="anonymous" />
<link href="./style.css" rel="stylesheet"/>
<link href="https://fonts.googleapis.com/css2?family=Bree+Serif&display=swap" rel="stylesheet">
<title>To Do List</title>
</head>
<body>
<head>
<h1>To Do List</h1>
</head>
<form>
<input type="text" class="todo-input">
<button class="todo-button">
<i class="fas fa-plus-square"></i>
</button>
</form>
<div class="todo-container">
<ul class="todo-list"></ul>
</div>
<script src="./app.js"></script>
</body>
</html>
CSS
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
body{
/*background-image: linear-gradient(120deg, #f6d365, #fda08f);*/
background-color: #5cdb95;
color: #0b0c0b;
font-family: "Bree Serif";
min-height: 100vh;
}
h1{
font-size: 2rem;
display: flex;
justify-content: center;
align-content: center;
}
form{
padding-top: 2rem;
display: flex;
justify-content: center;
align-content: center;
}
form input, form button{
padding: 0.5rem;
font-size: 2rem;
border: none;
background: #edf5e1;
}
form button{
color: #5cdb95;
background: #edf5e1;
cursor: pointer;
transition: all 0.3s ease;
}
form button :hover{
color: #46a771;
}
.todo-container {
display: flex;
justify-content: center;
align-items: center;
}
.todo-list {
min-width: 50%;
list-style: none;
}
.todo {
margin: 0.5rem;
background: #379683;
border-radius: 10px;
text-align: left;
padding-left: 10px;
font-size: 1.5rem;
display: flex;
justify-content: space-between;
align-items: center;
}
.todo li{
flex: 10%;
}
.trash-btn, .complete-btn {
background: #5cdb95;
color: #edf5e1;
font-size: 1rem;
padding: 20px;
margin: 4px 2px;
height: 8px;
width: 8px;
border-radius: 50%;
border: none;
cursor: pointer;
}
.trash-btn{
color: rgb(233, 47, 78);
font-size: 2rem;
}
.trash-btn i{
vertical-align: middle;
display: inline-block;
margin-right: 15px;
}
.complete-btn{
color: steelblue;
font-size: 2rem;
}
/*
.trash-btn, .complete-btn {
background-color: #4CAF50;
border: none;
color: white;
padding: 20px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
margin: 4px 2px;
border-radius: 50%;
}
.trash-btn, .complete-btn :hover{
cursor: pointer;
}
.fas fa-fa-check :hover{
cursor: pointer;
}
*/
And JS
//selectors
const todoInput = document.querySelector(".todo-input");
const todoButton = document.querySelector(".todo-button");
const todoList = document.querySelector(".todo-list");
//event listeners
todoButton.addEventListener('click', addTodo);
//functions
function addTodo(event){
//prevent form from submitting
event.preventDefault();
//todo div
const todoDiv = document.createElement("div");
todoDiv.classList.add("todo");
//create li
const newTodo = document.createElement("li");
newTodo.innerText = "hey";
newTodo.classList.add("todo-item");
todoDiv.appendChild(newTodo);
//completed button
const completedButton = document.createElement("button");
completedButton.innerHTML = '<i class="fa fa-check"></i>';
completedButton.classList.add("complete-btn");
todoDiv.appendChild(completedButton);
//trash button
const trashButton = document.createElement("button");
trashButton.innerHTML = '<i class="fa fa-minus-circle"></i>';
trashButton.classList.add("trash-btn");
todoDiv.appendChild(trashButton);
//append to list
todoList.appendChild(todoDiv);
}
It's not finished but I can't stand the way it displays the buttons.
You can you pattern position relative/absolute by
.fa-check, .fa-minus-circle{
position: absolute;
top: 5px;
left: 5px;
}
.trash-btn, .complete-btn {
background: #5cdb95;
color: #edf5e1;
font-size: 1rem;
padding: 20px;
margin: 4px 2px;
height: 8px;
width: 8px;
border-radius: 50%;
border: none;
cursor: pointer;
position: relative;
}
JSFiddle https://jsfiddle.net/viethien/zp5bv0sn/16/
Try this CSS:
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
body{
/*background-image: linear-gradient(120deg, #f6d365, #fda08f);*/
background-color: #5cdb95;
color: #0b0c0b;
font-family: "Bree Serif";
min-height: 100vh;
}
.fa {
margin-left: -16px;
margin-top: -16px;
position: absolute;
}
h1{
font-size: 2rem;
display: flex;
justify-content: center;
align-content: center;
}
form{
padding-top: 2rem;
display: flex;
justify-content: center;
align-content: center;
}
form input, form button{
padding: 0.5rem;
font-size: 2rem;
border: none;
background: #edf5e1;
}
form button{
color: #5cdb95;
background: #edf5e1;
cursor: pointer;
transition: all 0.3s ease;
}
form button :hover{
color: #46a771;
}
.todo-container {
display: flex;
justify-content: center;
align-items: center;
}
.todo-list {
min-width: 50%;
list-style: none;
}
.todo {
margin: 0.5rem;
background: #379683;
border-radius: 10px;
text-align: left;
padding-left: 10px;
font-size: 1.5rem;
display: flex;
justify-content: space-between;
align-items: center;
}
.todo li{
flex: 10%;
}
.trash-btn, .complete-btn {
background: #5cdb95;
color: #edf5e1;
font-size: 1rem;
padding: 20px;
margin: 4px 2px;
height: 8px;
width: 8px;
border-radius: 50%;
border: none;
cursor: pointer;
}
.trash-btn{
color: rgb(233, 47, 78);
font-size: 2rem;
}
.trash-btn i{
vertical-align: middle;
display: inline-block;
margin-right: 15px;
}
.complete-btn{
color: steelblue;
font-size: 2rem;
}
/*
.trash-btn, .complete-btn {
background-color: #4CAF50;
border: none;
color: white;
padding: 20px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
margin: 4px 2px;
border-radius: 50%;
}
.trash-btn, .complete-btn :hover{
cursor: pointer;
}
.fas fa-fa-check :hover{
cursor: pointer;
}
*/
The problem is with your style
.trash-btn i
And the style you added to the buttons. Find the refactored style below
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
/*background-image: linear-gradient(120deg, #f6d365, #fda08f);*/
background-color: #5cdb95;
color: #0b0c0b;
font-family: "Bree Serif";
min-height: 100vh;
}
h1 {
font-size: 2rem;
display: flex;
justify-content: center;
align-content: center;
}
form {
padding-top: 2rem;
display: flex;
justify-content: center;
align-content: center;
}
form input,
form button {
padding: 0.5rem;
font-size: 2rem;
border: none;
background: #edf5e1;
}
form button {
color: #5cdb95;
background: #edf5e1;
cursor: pointer;
transition: all 0.3s ease;
}
form button :hover {
color: #46a771;
}
.todo-container {
display: flex;
justify-content: center;
align-items: center;
}
.todo-list {
min-width: 50%;
list-style: none;
}
.todo {
margin: 0.5rem;
background: #379683;
border-radius: 10px;
text-align: left;
padding-left: 10px;
font-size: 1.5rem;
display: flex;
justify-content: space-between;
align-items: center;
}
.todo li {
flex: 10%;
}
.trash-btn,
.complete-btn {
background: #5cdb95;
color: #edf5e1;
font-size: 1rem;
margin: 4px 2px;
height: 40px;
width: 40px;
border-radius: 50%;
border: none;
cursor: pointer;
}
.trash-btn {
color: rgb(233, 47, 78);
font-size: 2rem;
}
.complete-btn {
color: steelblue;
font-size: 2rem;
}
/*
.trash-btn, .complete-btn {
background-color: #4CAF50;
border: none;
color: white;
padding: 20px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
margin: 4px 2px;
border-radius: 50%;
}
.trash-btn, .complete-btn :hover{
cursor: pointer;
}
.fas fa-fa-check :hover{
cursor: pointer;
}
*/

Categories