I am trying to add checkboxes to a login page using code that I found at react-bootstrap.github.io
The problem I'm having is the checkbox is overlapping the label.
My code (register.js) is below
import React, { useState } from 'react'
import { Link } from 'react-router-dom';
import { request } from './services/Request';
import { Button, FormGroup, FormControl, FormLabel, FormCheck } from 'react-bootstrap';
//import { FormRow } from 'react-bootstrap/Form';
import "./Styles/register.css"
export const Register = () => {
return (
<div style={{display: "flex", justifyContent: "center"}}>
<h1> Register </h1>
<div className="Register">
<form onSubmit={handleSubmit}>
</FormGroup>
<FormGroup controlId="email" bsSize="large">
<FormLabel>Email</FormLabel>
<FormControl
required
autoFocus
type="email"
//value={email}
onChange={ onChangeHandlerFn }
/>
</FormGroup>
<FormGroup controlId="password" bsSize="large">
<FormLabel>Password</FormLabel>
<FormControl
required
autoFocus
type="password"
//value={password}
onChange={ onChangeHandlerFn }
/>
</FormGroup>
<FormGroup controlId="password" bsSize="large">
{['checkbox'].map((type) => (
<div key={`default-${type}`} className="mb-3">
<FormCheck
type={type}
id={`default-${type}`}
label={`I am an individual`}
/>
</div>
))}
<Button variant="primary" type="submit" block>Register</Button>
<span>
Have an account?
Sign in
</span>
<ul>
<li><Link to="/privacy">Privacy & Terms</Link></li>
</ul>
</form>
</div>
</div>
);
};
The problem is the checkboxes are overlapping their labels:
Here is my css:
#media all and (min-width: 480px) {
.Register {
padding: 60px 0;
}
.Register form {
margin: 0 auto;
max-width: 320px;
}
}
ul {
list-style-type: none !important;
margin: 0;
padding: 0;
overflow: hidden;
}
Everything works, for the sake of length, I've done post all of the code.
Any help would be greatly appreciated.
What about adding to the left padding of the label so it clears the checkbox?
label {
padding-left:15px;
}
Related
I am working on a site, and i have a modal which basically looks like this:
import React,{useState} from "react";
import './AddItem.css';
import { Form, Button,Modal } from "react-bootstrap";
function AddItem({open, setOpen})
{
const [show, setShow] = useState(false);
const handleClose = () => setShow(false);
const handleShow = () => setShow(true);
return(
<>
<Button className="add" onClick={handleShow}>
ADD
</Button>
<Modal show={show} onHide={handleClose}>
<Modal.Header closeButton>
<Modal.Title>Modal heading</Modal.Title>
</Modal.Header>
<Modal.Body>
<Form>
<Form.Group className="mb-3" controlId="exampleForm.ControlInput1">
<Form.Label>Email address</Form.Label>
<Form.Control
type="email"
placeholder="name#example.com"
autoFocus
/>
</Form.Group>
<Form.Group
className="mb-3"
controlId="exampleForm.ControlTextarea1"
>
<Form.Label>Example textarea</Form.Label>
<Form.Control as="textarea" rows={3} />
</Form.Group>
</Form>
</Modal.Body>
<Modal.Footer>
<Button variant="secondary" onClick={handleClose}>
Close
</Button>
<Button variant="primary" onClick={handleClose}>
Save Changes
</Button>
</Modal.Footer>
</Modal>
</>
);
}
export default AddItem;
When i click on save changes, or close the modal in any way, the add button in the picture,(which i clicked to open the modal) turns un undesirable color-
The color only reverts back to normal when i click anywhere else on the screen.
How do i prevent this from occuring? My Additem.css file:
.add{
position: absolute;
top: 21.35%;
left: 61%;
height: 6%;
width: 10%;
color: white;
background-color: #283d4a;
border-left: 1.5px solid #15aef1;
border-right: 1.5px solid #15aef1;
border-top: 2.7px solid #15aef1;
border-bottom: 2.7px solid #15aef1;
border-top-left-radius: 5px !important;
border-bottom-left-radius: 5px !important;
}
.add:hover{
background-color:#15aef1 ;
}
The color problem lies with bootstrap button. It has a property of rolling back to a color. Using a regular button like:
#React Button
<button className="add" onClick={handleShow}>
ADD
</button>
instead of
#Bootstrap button
<Button className="add" onClick={handleShow}>
ADD
</Button>
is effective in solving this.
I've 2 controllable text input with validation:
required={true}
minLength={5}
maxLength={10}
Both are share the same state, so their text are always in sync.
value={text}
onChange={(e) => setText(e.target.value)}
The initial value of them are 'ab':
const [text, setText] = useState("ab");
Then I added a css for visualizing the validation state:
input[type="text"]:valid {
background-color: lightgreen !important;
}
input[type="text"]:invalid {
background-color: pink !important;
}
The problem:
At the first load, both color are green.
The value are 'ab' it doesn't satisfy the validation.
Why not colored red?
When i added one character of the first textbox => abc
The color is red, that's to be expected.
But the second one still colored green. That's not expected.
Anyone can fix the problem? I want the text & validation are in sync.
Sandbox: enter link description here
code:
import "./styles.css";
import { useState } from "react";
import "./App.css";
export default function App() {
const [text, setText] = useState("ab");
return (
<div className="App">
<input
type="text"
required={true}
minLength={5}
maxLength={10}
value={text}
onChange={(e) => setText(e.target.value)}
/>
<br />
<input
type="text"
required={true}
minLength={5}
maxLength={10}
value={text}
onChange={(e) => setText(e.target.value)}
/>
</div>
);
}
css:
input[type="text"]:valid {
background-color: lightgreen !important;
}
input[type="text"]:invalid {
background-color: pink !important;
}
To be completely honest, I don't know why React is behaving this way, but an alternative would be to add a 'valid' or 'invalid' class to the input depending on the 'text' value:
<input
className={text.length >= 5 && text.length <= 10 ? 'valid' : 'invalid'}
type="text"
required={true}
value={text}
onChange={(e) => setText(e.target.value)}
/>
.valid {
background-color: lightgreen !important;
}
.invalid {
background-color: pink !important;
}
I want to show a spinner until the results load from the HTTP request on autocomplete field. Below is the snippet of the code written.
HTML
<label class="col-2 col-form-label text-right font-weight-bold">City *</label>
<div class="col-2">
<div>
<input id="typeahead-prevent-manual-entry" type="text" class="form-control"
[(ngModel)]="myActivity.city"
[ngbTypeahead]="search"
[inputFormatter]="formatter"
[resultFormatter]="formatter"
name="citySelected"
#citySelected="ngModel"/>
</div>
<div>
Typescript
formatter = (city: City) => city.name;
search = (text$: Observable<string>) => text$.pipe(
debounceTime(10),
distinctUntilChanged(),
filter(criterion => criterion.length >= 2),
map(criterion => criterion.length < 3 ? [] : this.searchLocalities(criterion).filter(city => new
RegExp(criterion, 'mi').test(city.name)).slice(0, 20))
);
searchLocalities(criterion: string): City[] {
this.isLoadingResult = true;
this.activityService.getLocalities(this.prvCodId, criterion).subscribe(
data => {
data.map(item => {
if (this.localities.find((city) => city.name === item.name) === undefined) {
this.localities.push(item);
}});
this.isLoadingResult = false;
});
return this.localities;
}
are you using material angular in your project? if yes you can easily use mat-proggress-spinner.
first of all import the module into your appModule:
import {MatProgressSpinnerModule} from '#angular/material/progress-spinner';
add it to your imports:
//
imports: [MatProgressSpinnerModule]
//
then in your template, you can use it as bellow:
<div class="col-2">
<mat-spinner *ngIf="isLoadingResult" diameter="30"></mat-spinner>
<div *ngIf="!isLoadingResult">
<input id="typeahead-prevent-manual-entry" type="text" class="form-control"
[(ngModel)]="myActivity.city"
[ngbTypeahead]="search"
[inputFormatter]="formatter"
[resultFormatter]="formatter"
name="citySelected"
#citySelected="ngModel"/>
</div>
<div>
but if you are not using material angular and you don't want to, you can just use a tag gif instead of mat-spinner.
put the gif in your assets and:
<img *ngIf="isLoadingResult" src="assets/images/loading.gif" />
in your html:
<div class="input-container">
<img class="loading-img" src="your loading img location">
<input type="text">
</div>
in your css:
.input-container {
display: flex;
position: relative;
width: 200px
}
.loading-img {
position: absolute;
right: 0;
top: 3px;
height: 20px;
width: 20px;
}
input {
width: 100%;
padding-right: 25px;
}
this will put the IMG in the right corner of the input.
You can use the mat-progress-bar library, see the example below.
//declaration
isApiCalling = false;
//use case
this.isApiCalling = true;
this._apiCall.get(this.url)
.subscribe(
data => {
this.isApiCalling = false;
},
err => {
this.isApiCalling = false;
}
);
<!-- actual term is isApiCalling -->
<mat-progress-bar mode="indeterminate" *ngIf="isApiCalling"></mat-progress-bar>
When the error message appears it changes the login form width.
The short message makes it shorter and long - longer. How to fix it without adding a fixed with?
I use FormHelperText element to display an error message.
Moving FormHelperText inside FormControl doesn`t fix the problem.
// some code ....
render () {
const { email, password, error } = this.state;
const isInvalid = password === '' || email === '';
return (
<Paper className={styles.paper}>
<Avatar className={styles.avatar}>
<LockOutlinedIcon />
</Avatar>
<Typography component='h1' variant='h5'>
Login
</Typography>
<form onSubmit={this.onSubmit} className={styles.form}>
<FormControl margin='normal' required fullWidth>
<InputLabel htmlFor='email'>Email Address</InputLabel>
<Input
id='email'
name='email'
autoComplete='off'
autoFocus value={email}
onChange={this.onChange}
/>
</FormControl>
<FormControl margin='normal' required fullWidth>
<InputLabel htmlFor='password'>Password</InputLabel>
<Input
name='password'
type='password'
id='password'
autoComplete='off'
value={password}
onChange={this.onChange}
/>
</FormControl>
{error &&
<FormHelperText className={styles.error} error>{error.message}</FormHelperText>
}
<Button
type='submit'
fullWidth
variant='contained'
color='primary'
disabled={isInvalid}
className={styles.formSubmitBtn}
>
Login
</Button>
</form>
</Paper>
);
}
.paper {
display: flex;
flex-direction: column;
align-items: center;
}
.avatar {
margin-top: 20px;
}
.error {
}
.form {
margin: 30px 30px;
&__submit-btn {
margin-top: 20px !important;
}
}
short error message
default
There are the max-width and min-width properties in CSS that you can specify. They will ensure that the width stays between the specified sizes. If the content exceeds max-width, it affects the height of the box.
I'm trying to simply display a checkbox in a bootstrap drop down but its just displays as blank. It's a generic dropdown. Below I've shown my code and a few screenshots. I feel like this is kinda bizarre and not sure if this is an angular thing or not.
stackblitz url:
https://stackblitz.com/edit/angular-45uk59
Code:
<div class="form-group">
<label *ngIf='label!=null' for={{id}}>{{label}}}</label>
<select class="form-control" id="{{id}}">
<option value="-1"></option>
<option *ngFor="let item of content; let i = index" value="{{item.value}}">
<span *ngIf='hasCheckbox === true'>
<!-- <input type="checkbox" id="{{id}}_i" />   -->
<input type="checkbox" name="item.text[{{i}}]" value="{{item.value}}" />
</span>
{{item.text}}
</option>
</select>
</div>
Component:
import { Component, OnInit, Input } from '#angular/core';
#Component({
selector: 'dropdown',
templateUrl: './dropdown.component.html',
styleUrls: ['./dropdown.component.scss']
})
export class DropdownComponent implements OnInit {
content: DropDownContent[] = new Array<DropDownContent>();
#Input() hasCheckbox:boolean = false;
#Input() label:string = null;
#Input() id:string = 'defaultId'
#Input() selectedId:number = -1;
#Input() size: 'lg' | 'md' | 'sm' = 'lg';
#Input() set contentInput(contentInput: DropDownContent[]) {
if (contentInput) {
this.content = contentInput.map(data => {
return <DropDownContent>(data);
});
console.log(this.content);
} else {
//?
}
}
constructor() { }
ngOnInit() {
console.log(this.id)
}
}
export class DropDownContent {
value: number;
text: string;
}
Screenshot:
Code:
You could wrap divs in a form like sort of hack thing. not exactly what you want but it works:
HTML
<form>
<div class="selectthingy">
<div class="Box" onclick="showMeTheBoxes()">
<select>
<option>Select an option</option>
</select>
<div class="checkboxselect"></div>
</div>
<div id="boxes_wrapper">
<label for="one">
<input type="checkbox" id="1" />SALSA</label>
<label for="two">
<input type="checkbox" id="2" />MUMBA</label>
<label for="three">
<input type="checkbox" id="3" />CHICKEN DANCE</label>
</div>
</div>
</form>
CSS
.selectthingy{
width: 300px;
}
.Box {
position: relative;
}
.Box select {
width: 100%;
}
.checkboxselect {
position: absolute;
right: 0;
left: 0;
bottom: 0;
top: 0;
}
#boxes_wrapper {
display: none;
border: 1px green solid;
}
#boxes_wrapper label {
display: block;
}
#boxes_wrapper label:hover {
background-color: blue;
}
JS
var boxthingy= false;
function showMeTheBoxes() {
var boxes = document.getElementById("boxes_wrapper");
if (!boxthingy) {
boxes.style.display = "block";
boxthingy= true;
} else {
boxes.style.display = "none";
boxthingy= false;
}
}
https://codepen.io/Archtects/pen/LmpLZr
Instead of the checkbox, I suggest to use a plain text with emoji. It will be show and hidden with an ngIf with the help of hasCheckbox property combined with a new property to keep the track of selected elements:
export class DropDownContent {
value: number;
text: string;
selected: boolean
}
...
this.contentInput = [{
"value": 0,
"text": "Users",
"selected": true
},
{...
So the template could be:
<select id="{{id}}" multiple>
<option (dblclick)="item.selected=!item.selected" *ngFor="let item of content; let i = index" value="{{item.value}}">
<span *ngIf="item.selected && hasCheckbox">✓</span>
{{item.text}}
</option>
</select>
Demo