how can i get value from the hidden field inside the div below:
<div class="col-lg-6" th:each="devicedit : ${eachdevicedetails}">
<div class="courses-container">
<div class="course">
<div
class="course-preview"
th:style="${devicedit.color} == 'Green' ? 'background: #03CB61' : 'background: #F22A54'"
>
<input type="hidden" name="hiddenDiviceId" th:value="${devicedit.id}" />
<h6 th:text="${devicedit.area}"></h6>
<h2 th:text="${devicedit.country}"></h2>
<br /><br />
<h6 th:text="${devicedit.state}"></h6>
</div>
<div class="course-info">
<div class="progress-container">
Status :
<span
class="badge badge-pill badge-success"
th:style="${devicedit.color} == 'Green' ? 'background: #03CB61' : 'background: #F22A54'"
th:text="${devicedit.color} == 'Green' ? 'Active' : 'Inactive'"
></span>
</div>
LastUpdate :
<h6 th:text="${devicedit.lastupdatedon}"></h6>
<h2 th:text="${devicedit.device_Name}"></h2>
<br />
<button
onclick="openModal(this)"
id="pickerMaster"
class="btn btn-primary"
>
Detail View
</button>
</div>
</div>
</div>
</div>
and I used the below jquery code to get value, but i can only pick value of 1st div:
$("#pickerMaster").click(function () {
var divid = $(this)
.closest("div.course")
.find("input[name='hiddenDiviceId']")
.val();
console.log(divid);
});
for this you should set class for button and use this for get input value:
<button onclick="openModal(this)" class="btn btn-primary pickerMaster">Detail View</button>
and:
$(".pickerMaster").click(function() {
var divid = $(this).closest("div.course").find("input[name='hiddenDiviceId']").val();
console.log(divid);
});
Related
i'm trying to close the hamburger menu onClick with react, but so far have no results :( Read a lot of similar questions here, but everyone html is different and none of the answers worked for me :( Here's the code, i know it should be done with with useState, but how can i do it ? It's the first condition, the second is just a search input for the start page
return (
<>
{city ?
<nav>
<input id="nav-toggle" type="checkbox" />
<div className="nav-input">
<form method='POST' type="text" className='form' onSubmit={searchLocation}>
<input className="form-input" name='city' placeholder='Enter your location ...' />
<button type="submit" class="search-button">
<img src={search} />
</button>
</form>
</div>
<ul className="links">
<li><NavLink to="/now" style={({ isActive }) =>
isActive ? active : undefined
}>Now</NavLink></li>
<li><NavLink to="/hourly" style={({ isActive }) =>
isActive ? active : undefined
}>Hourly</NavLink></li>
<li><NavLink to="/daily" style={({ isActive }) =>
isActive ? active : undefined
}>Daily</NavLink></li>
</ul>
<label htmlFor="nav-toggle" className="icon-burger">
<div className="line"></div>
<div className="line"></div>
<div className="line"></div>
</label>
{city ?
<div className='city-name'>
<p>weather at: </p>
<h4>{city}</h4>
</div>
: null}
</nav>
:
<>
<div className='nav-start-page'>
<div>
<h3>Get Your Forecast</h3>
</div>
<div>
<Link className='location-link' to="/location">
<img src={location} />
</Link>
</div>
<div>
<form method='POST' type="text" onSubmit={searchLocation}>
<input className="form-input" name='city' placeholder='Enter your location ...' />
<button type="submit" class="search-button">
<img src={search} />
</button>
</form>
</div>
</div>
</>
}
</>
);
};
Add a click event on hamburger menu and set menu list hidden by default from css
i.e; visiblity: hidden. And on menu click function get menu list div by id from js and set their css visiblity: visible
Use useState and a callback function to toggle the hamburger menu onClick.
Try this:
const [isOpen, setIsOpen] = useState(false);
return (
<>
{city ?
<nav>
<input id="nav-toggle" type="checkbox" onClick={() => setIsOpen(!isOpen)} />
<div className="nav-input">
<form method='POST' type="text" className='form' onSubmit={searchLocation}>
<input className="form-input" name='city' placeholder='Enter your location ...' />
<button type="submit" class="search-button">
<img src={search} />
</button>
</form>
</div>
{isOpen && <ul className="links">
<li><NavLink to="/now" style={({ isActive }) =>
isActive ? active : undefined
}>Now</NavLink></li>
<li><NavLink to="/hourly" style={({ isActive }) =>
isActive ? active : undefined
}>Hourly</NavLink></li>
<li><NavLink to="/daily" style={({ isActive }) =>
isActive ? active : undefined
}>Daily</NavLink></li>
</ul>}
<label htmlFor="nav-toggle" className="icon-burger">
<div className="line"></div>
<div className="line"></div>
<div className="line"></div>
</label>
{city ?
<div className='city-name'>
<p>weather at: </p>
<h4>{city}</h4>
</div>
: null}
</nav>
:
<>
<div className='nav-start-page'>
<div>
<h3>Get Your Forecast</h3>
</div>
<div>
<Link className='location-link' to="/location">
<img src={location} />
</Link>
</div>
<div>
<form method='POST' type="text" onSubmit={searchLocation}>
<input className="form-input" name='city' placeholder='Enter your location ...' />
<button type="submit" class="search-button">
<img src={search} />
</button>
</form>
</div>
</div>
</>
}
</>
);
};
This question expands on my problem which got partially solved here. I have two components, ApplicationOverview.js and ApplicationModal.jsx and I want to dynamically add div panels to the ApplicationOverview.js Component from the Modal. In the Modal I have two input fields and I can add an image, which will be displayed on the div after I clicked on the 'Add' button. This is what the Modal looks like and this is what I am trying to achieve with n number of panels. (Note that the first 3 panels are hard coded)
So far, I can add a single div panel to my page, but whenever I try to add another one, it just changes the text of the panel that I just added. I am currently just toggling the visibility of that single div I am adding with a boolean (as you can see on the bottom of ApplicationOverview.js), but I can't figure out how I'd add multiple divs from my Modal to the page. Also, when I close the Modal but type something into the input fields, the text on the added div will still change without clicking on 'Add' beforehand.
ApplicationModal.jsx:
import React from "react";
var name = "";
var comment = "";
var filename = "";
const ApplicationModal = ({
setOpen,
setState,
setStateComment,
setFile,
file,
setBool,
}) => {
React.useEffect(() => {
function handleEscapeKey(event) {
if (event.code === "Escape") {
setOpen(false);
}
}
document.addEventListener("keydown", handleEscapeKey);
return () => document.removeEventListener("keydown", handleEscapeKey);
});
const handleComment = (e) => {
setStateComment(e.target.value);
};
const handleChange = (e) => {
setState(e.target.value);
};
const addNewApplication = () => {
setBool(true);
setOpen(false);
};
function openDialog() {
document.getElementById("inputUpload").click();
}
function loadFile(e) {
console.log(e.target.files);
setFile(URL.createObjectURL(e.target.files[0]));
}
document.addEventListener("click", function (e) {});
return (
<React.Fragment>
<div className="modalDark" style={{ paddingRight: "250px" }}>
<div class="modal-dialog">
<div class="modal-content" style={{ width: "800px" }}>
<div class="modal-close">
<div class="module-button" style={{ left: "750px" }}>
<button
class="btn btn-link "
onClick={() => setOpen(false)}
></button>
<div class="button-animation"></div>
<div class="button-content new">
<i class="icon icon-dc_close"></i>
</div>
</div>
</div>
<div class="modal-header">
<h3>Add new Application</h3>
</div>
<div class="modal-body">
<div
class="module-input form-group has-placeholder"
data-plugin="moduleInput"
style={{ bottom: "60px", width: "350px" }}
>
<label for="demo-default">Customer Name</label>
<div class="input-animation-wrapper">
<input
type="text"
id="demo-default"
class="form-control "
maxLength="42"
placeholder="[Application Name]"
onChange={(e) => handleChange(e)}
/>
<div class="input-animation"></div>
</div>
</div>
<div
class="module-textarea form-group floating-label has-placeholder"
data-plugin="moduleInput"
style={{ bottom: "60px" }}
>
<label for="demo-3">Customer Short text</label>
<div class="input-animation-wrapper" style={{ width: "350px" }}>
<textarea
id="demo-3"
class="form-control"
rows="9"
placeholder="Short description of Customer; max. 280 characters"
maxLength={180}
onChange={(e) => handleComment(e)}
style={{ width: "350px" }}
></textarea>
<div class="label-area"></div>
<div class="input-animation"></div>
</div>
</div>
<img
class="image"
alt="Customer Logo"
id="logo"
src={file}
style={{
left: "420px",
bottom: "280px",
position: "absolute",
height: "250px",
}}
/>
<div
class="module-button"
style={{
left: "500px",
bottom: "200px",
position: "absolute",
zIndex: "1",
}}
>
<button
type="file"
class="btn btn-light"
onClick={() => openDialog()}
id="fileUpload"
>
<input
type="file"
hidden={true}
accept="image/*"
id="inputUpload"
onChange={(e) => loadFile(e)}
></input>
</button>
<div class="button-animation"> </div>
<div class="button-content">
<span class="content-text">Upload Logo</span>
</div>
</div>
<div
class="module-button"
style={{ bottom: "50px", width: "100px", textAlign: "center" }}
>
<button
type="button"
class="btn btn-secondary btn"
onClick={() => addNewApplication()}
id="adding"
></button>
<div class="button-animation"></div>
<div class="button-content">
<span class="content-text">Add</span>
</div>
</div>
</div>
</div>
</div>
</div>
</React.Fragment>
);
};
export default ApplicationModal;
export { name, comment, filename };
ApplicationOverview.js:
import React from "react";
import "../Overview.css";
import ApplicationModal from "../components/ApplicationModal.jsx";
var id = 0;
const ApplicationOverview = () => {
const [open, setOpen] = React.useState(false);
const [state, setState] = React.useState("");
const [stateComment, setStateComment] = React.useState("");
const [file, setFile] = React.useState("https://upload.wikimedia.org/wikipedia/commons/thumb/3/3f/Placeholder_view_vector.svg/681px-Placeholder_view_vector.svg.png");
const [bool, setBool] = React.useState(false);
function addID()
{
id++;
console.log(id)
return id;
}
return (
<div id="wrapper">
{open && <ApplicationModal setOpen={setOpen} setState={setState} file={file} setBool={setBool} setFile={setFile} setStateComment={setStateComment} />}
<div class="component-headline">
<h4 style={{ color: "gray", display: "inline" }}>
Application overview
</h4>
<div
class="module-button"
style={{
backgroundColor: "rgb(18,205,212,255)",
borderRadius: "12px",
marginLeft: "1032px",
}}
onClick={() => setOpen(true)}
>
<button type="button" class="btn btn-secondary"></button>
<div class="button-animation"></div>
<div
class="button-content"
style={{
backgroundColor: "rgb(18,205,212,255)",
borderRadius: "12px",
}}
>
<span class="content-text" style={{ color: "black" }}>
Add Application
</span>
</div>
</div>
</div>
<hr style={{ marginTop: "-20px" }} />
<div class="center-content" id="center">
<div class="overview-box">
<img
class="image"
src="https://st.depositphotos.com/1968353/2535/i/600/depositphotos_25357041-stock-photo-close-up-of-machine-gears.jpg"
alt="car"
/>
<div class="box-content">
<h3 class="overview-h3">Press</h3>
<p class="overview-p">This Application is used for maintenance</p>
<h3 class="overview-h3-second">Connected Products</h3>
<h1 class="overview-h1-second">
?/?
<p class="overview-p-second">Online</p>
</h1>
<div class="module-button" id="configure">
<button type="button" class="btn btn-secondary"></button>
<div class="button-animation"></div>
<div class="button-content">
<span class="content-text">Configure</span>
</div>
</div>
</div>
</div>
<div class="overview-box">
<img
class="image"
src="https://st.depositphotos.com/1968353/2535/i/600/depositphotos_25357041-stock-photo-close-up-of-machine-gears.jpg"
alt="car"
/>
<div class="box-content">
<h3 class="overview-h3">Tooling Machine</h3>
<p class="overview-p">
This Application is used for drilling records
</p>
<h3 class="overview-h3-second">Connected Products</h3>
<h1 class="overview-h1-second">
?/?
<p class="overview-p-second">Online</p>
</h1>
<div class="module-button" id="configure">
<button type="button" class="btn btn-secondary"></button>
<div class="button-animation"></div>
<div class="button-content">
<span class="content-text">Configure</span>
</div>
</div>
</div>
</div>
<div class="overview-box">
<img
class="image"
src="https://st.depositphotos.com/1968353/2535/i/600/depositphotos_25357041-stock-photo-close-up-of-machine-gears.jpg"
alt="car"
/>
<div class="box-content">
<h3 class="overview-h3">Storing Unit</h3>
<p class="overview-p">
This Application is used for store parameters
</p>
<h3 class="overview-h3-second">Connected Products</h3>
<h1 class="overview-h1-second">
?/?
<p class="overview-p-second">Online</p>
</h1>
<div class="module-button" id="configure">
<button type="button" class="btn btn-secondary"></button>
<div class="button-animation"></div>
<div class="button-content">
<span class="content-text">Configure</span>
</div>
</div>
</div>
</div>
{(stateComment || state) && bool && <div class='overview-box' id={addID()}> <img class='image' src={file} alt='car'/> <div class='box-content'><h3 class='overview-h3' id='new-headline'>{state}</h3> <p class='overview-p'>{stateComment}</p><h3 class='overview-h3-second'>Connected Products</h3><h1 class='overview-h1-second'> ?/? <p class='overview-p-second'>Online</p> </h1> <div class='module-button' id='configure'> <button type='button' class='btn btn-secondary'></button> <div class='button-animation'></div> <div class='button-content'> <span class='content-text'>Configure</span> </div> </div> </div> </div> }
</div>
</div>
);
};
export default ApplicationOverview;
So if I understand your problem is that you have a modal and when you fill the modal and send add it will add the text and images to ApplicationOverview. I think you want to be able to do that several times. You want your users to be able to complete the modal again and again so it keep adding at the bottom of the ApplicationOverview.
So you need your ApplicationModal to have its own state.
const [modalState, setModalState] = useState("");
const [modalCommentState, setCommentModalState] = useState("");
const [modalFile, setModalFile] = useState("");
so your handler function should be
const handleComment = (e) => {
setCommentModalState(e.target.value);
};
const handleChange = (e) => {
setModalState(e.target.value);
};
function loadFile(e) {
setModalFile(URL.createObjectURL(e.target.files[0]));
}
Your submit function
const addNewApplication = () => {
setOpen(false);
setStates( oldArray => [...oldArray, {
state:modalState,
stateComment:modalCommentState,
file: modalFile } ]);
};
in the ApplicationOverview.js
const [states, setStates] = useState([]);
in your HTML section you loop through the state with a map
{ states.map((state)=> {
return (
<div class='overview-box' id={addID()}>
<img class='image' src={state.file} alt='car'/>
<div class='box-content'>
<h3 class='overview-h3' id='new-headline'>{state.state}</h3>
<p class='overview-p'>{state.stateComment}</p>
<h3 class='overview-h3-second'>Connected Products</h3>
<h1 class='overview-h1-second'> ?/? <p class='overview-p-second'>Online</p></h1>
<div class='module-button' id='configure'>
<button type='button' class='btn btn-secondary'></button>
<div class='button-animation'></div>
<div class='button-content'>
<span class='content-text'>Configure</span>
</div>
</div>
</div>
</div>
})}
So everytime the user submit the modal it will get added to the array of states and it will be display in the ApplicationOverview
I'm fairly new to using TypeScript, React and Bootstrap modals in general, however I'm pretty confident that I have avoided the most common mistakes like using the same id and data-bs-target in multiple places.
Basically I have a dynamic list of accordions. Each accordion has a body which (in this case) contains a list of restaurants. I have a modal which allows the user to edit this list of restaurants when clicking on the 'Edit' button. As you can see in the code below, the value of the button's data-bs-target has the state constant deckId which changes accordingly when clicking on any of the accordions. Same goes for the id of each modal.
Excuse the bad markup below. Also ignore it if there are is a bracket or a tag too much or too little. I edited out a bunch of broken code so I might've accidentally deleted something unintentionally with that.
The accordions:
const DeckList = (list: any[]) => {
var numberToWords = require('number-to-words');
return (
<div className="accordion" id="accordionPanelsCloseEachother">
{/* <div id="myGroup"> */}
<div className="accordion-group">
{list
.sort((a, b) => a.deckLevel > b.deckLevel ? 1 : -1)
.map((d: DeckModel) => {
return (
<div className="accordion-item" key={d.id}
>
<h2 className="accordion-header" >
<button
onClick={() => setDeckId(d.id)}
className="accordion-button collapsed"
type="button"
data-bs-toggle="collapse"
data-bs-target={"#" + numberToWords.toWords(d.deckLevel)}
aria-expanded="false"
aria-controls={numberToWords.toWords(d.deckLevel)}
>
Level {d.deckLevel}
</button>
</h2>
<div id={numberToWords.toWords(d.deckLevel)} className="accordion-collapse collapse" data-bs-parent="#accordionPanelsCloseEachother">
<div className="accordion-body">
<div className="row">
<div className="col-sm-4">
<div className="card">
<div className="card-body">
<h5 className="card-title">{intl.formatMessage({ id: 'RESTAURANTS' })}</h5>
{restDeckListNEW.filter(f => f.deckId === d.id).map((r: RestaurantDeckModel) => {
return (
<li key={r.restaurantId}>{r.restaurantName}</li>
)
})}
</div>
<div className="position-absolute bottom-0 end-0 p-7">
<EditRestaurantFunction
intl={intl}
shipId={shipId}
list={list}
deckId={deckId}
filteredRestaurants={filteredRestaurants}
GET_DECK_URL={GET_DECK_URL}
GET_RESTAURANTDECK_URL={GET_RESTAURANTDECK_URL}
setStatusCode={setStatusCode}
statusCode={statusCode}
GET_SHIP_URL={GET_SHIP_URL}
setReloadValue={setReloadValue}
restDeckListNEW={restDeckListNEW}
checkedRestaurantIdList={checkedRestaurantIdList}
setCheckedRestaurantIdList={setCheckedRestaurantIdList}
unCheckedRestaurantIdList={unCheckedRestaurantIdList}
setUnCheckedRestaurantIdList={setUnCheckedRestaurantIdList} />
</div>
</div>
</div>
<div className="col-sm-4">
<div className="card">
<div className="card-body">
<h5 className="card-title">{intl.formatMessage({ id: 'FACILITIES' })}</h5>
{facilityListNEW.filter(f => f.deckLevel === d.deckLevel || f.optXtrDeckLevel === d.deckLevel).map((t: FacilitiesModel) =>
<li key={facilityListNEW.filter(f => f.deckLevel === d.deckLevel).indexOf(t)}>{t.name}</li>
)}
</div>
<div className="position-absolute bottom-0 end-0 p-7">
<button
type='button'
className='btn btn-warning'
data-bs-toggle='modal'
data-bs-target='#kt_modal_edit2'
onClick={() => getDeck(d.id)}
>
{intl.formatMessage({ id: 'EDIT' })}
</button>
</div>
</div>
</div>
<div className="col-sm-4">
<div className="card">
<div className="card-body">
<h5 className="card-title">{intl.formatMessage({ id: 'CABIN_CATEGORY' })}</h5>
{cabinDeckListNEW.filter(f => f.deckId === d.id).map((c: CabinDeckModel) => {
return (
<li key={c.cabinToDeckId}>{c.category + ' - ' + c.description + ' - ' + c.cabinType}</li>
)
})}
</div>
<div className="position-absolute bottom-0 end-0 p-7">
<button
type='button'
className='btn btn-warning'
data-bs-toggle='modal'
data-bs-target='#kt_modal_edit3'
onClick={() => getDeck(d.id)}
>
{intl.formatMessage({ id: 'EDIT' })}
</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
)
})}
</div>
</div>
)
}
The modal component w/ button a.k.a. <EditRestaurantFunction />:
<div className="col-md-auto">
<button
type='button'
className='btn btn-warning'
data-bs-toggle='modal'
data-bs-target={'#editRestaurants' + deckId}
onClick={ifHasThenChecked}
>
{intl.formatMessage({ id: 'EDIT' })}
</button>
</div>
<div className="modal fade" tabIndex={-1} id={'editRestaurants' + deckId}>
<div className="modal-dialog modal-dialog-centered mw-900px">
<div className="modal-content">
<div className="modal-header">
<h5 className="modal-title">{intl.formatMessage({ id: 'EDIT_RESTAURANT_TO_DECK' })}</h5>
<button
type="button"
className="btn-close"
data-bs-dismiss="modal"
aria-label="Close"
id='closeButtonEditRestaurantDeck'
>
</button>
</div>
<div className="modal-body py-lg-10 px-lg-10">
<div
ref={stepperRef}
className='stepper stepper-pills stepper-column d-flex flex-column flex-xl-row flex-row-fluid'
id='kt_modal_create_app_stepper'
>
<div className='d-flex justify-content-center justify-content-xl-start flex-row-auto w-100 w-xl-300px'>
<div className='stepper-nav ps-lg-10'>
<div className='stepper-item current' data-kt-stepper-element='nav'>
<div className='stepper-line w-40px'></div>
<div className='stepper-icon w-40px h-40px'>
<i className='stepper-check fas fa-check'></i>
<span className='stepper-number'>1</span>
</div>
<div className='stepper-label'>
<h3 className='stepper-title'>{intl.formatMessage({ id: 'EDIT_RESTAURANT_LIST' })}</h3>
<div className='stepper-desc'>{intl.formatMessage({ id: 'SELECT_RESTAURANTS' })}</div>
</div>
</div>
</div>
</div>
<div className='flex-row-fluid py-lg-5 px-lg-15'>
<Formik
validationSchema={currentSchema}
initialValues={initValues}
onSubmit={submitStep}
>
{({ errors, status, touched }) => (
<Form className='form' noValidate id='kt_modal_create_cabin_benefits_form'>
<div className='current' data-kt-stepper-element='content'>
<div className='w-100'>
<div className='fv-row mb-10'>
<label className='d-flex align-items-center fs-5 fw-bold mb-2'>
<span>{intl.formatMessage({ id: 'RESTAURANTS' })}</span>
<i
className='fas fa-exclamation-circle ms-2 fs-7'
data-bs-toggle='tooltip'
title={intl.formatMessage({ id: 'SELECT_ANY_NUMBER_RESTAURANTS' })}
></i>
</label>
{filteredRestaurants
.map((r: RestaurantDeckModel) => (
<div className="form-check mt-5" key={r.restaurantId} >
<input className="form-check-input" type="checkbox" value="" id={r.restaurantName}
onClick={() => checkRestaurants(r.restaurantId, r.restaurantName)}
/>
<label className="form-check-label" htmlFor="flexCheckDefault">
{r.restaurantName} - {r.restaurantId}
</label>
</div>
))}
</div>
</div>
</div>
<div>
<button
type='submit'
className='btn btn-lg btn-primary me-3'>
<span className='indicator-label'>
{intl.formatMessage({ id: "AUTH.GENERAL.SUBMIT_BUTTON" })}
</span>
</button>
</div>
</Form>
)}
</Formik>
</div>
</div>
</div>
</div>
</div>
</div>
So far I'm able to open the modal for the first accordion, but when I click on any other accordion and then on the 'Edit' button which triggers the modal to appear, it simply doesn't and also doesn't give any error message in the console. What am I doing wrong?
This is my second question ever on stackoverflow, so do let me know if I'm missing anything important in my question!
UPDATE: I figured out via this questions that my modal only shows up if the first accordion is expanded as well besides any other accordion that I might open. If I close the first accordion and open any other accordion, the modal will not appear. In the solution of the referenced question they use jQuery, which is something I'd like to avoid as much as possible.
Any idea how I can fix this issue using my technologies?
I'm working with ReactJS and this success notification thing is not working as expected. When I crop the image and click on Confirm Crop button as shown in image below, I get the Loading loader and after the image is cropped it shows Image Saved! notification below the Confirm Crop button. But I want the Loading and Image Saved on side of the button, someone else worked on this before me and I am unable to solve this. What could fix the problem?
This is the form I'm working on below:
return (
<form className="form-horizontal" ref="form" onSubmit={this.handleForm}>
<fieldset>
<legend>
{this.state.success === true ? (
this.props.history.push(`/${serviceId}`)
) : this.state.success === false ? (
<Alert bsStyle="danger">
<strong>An error occured!</strong>
<ol>
{this.state.errorMessages.map((err, index) => (
<li key={index}>{err.message}</li>
))}
</ol>
</Alert>
) : (
""
)}
</legend>
<div className="row-fluid">
<div className="span5">
<div
className={
this.state.invalid.name === true
? "control-group error"
: "control-group"
}
>
<label className="control-label" htmlFor="name">
Name: <i className="required">*</i>
</label>
<div className="controls">
<input
type="text"
required
id="name"
defaultValue={this.state.form.name}
name="name"
onChange={this.handleState}
/>
<span className="help-inline">Field required</span>
</div>
</div>
<div
className={
this.state.invalid.image === true
? "control-group error"
: "control-group"
}
>
<label className="control-label" htmlFor="image">
Image: <i className="required">*</i>
</label>
<div className="controls">
<input
type="file"
name="image"
defaultValue={this.state.form.image}
onChange={this.handleState}
accept="image/gif, image/png, image/jpeg, image/jpg"
required
/>
<span className="help-inline">File Type: png, gif, jpg</span>
<div>
<ReactCrop
src={
this.state.companyImage === null
? ""
: this.state.companyImage
}
crop={this.state.crop}
onImageLoaded={this.handleImageLoaded.bind(this)}
onComplete={this.handleOnCropComplete.bind(this)}
onChange={this.handleOnCropChange.bind(this)}
keepSelection={true}
/>
</div>
{this.state.croppedImageUrl && (
<img alt="Crop" src={this.state.croppedImageUrl} />
)}
<br />
{this.state.croppedImageUrl ? (
<div>
<button
className="btn btn-primary"
type="button"
onClick={this.handleState}
>
Confirm Crop
</button>
</div>
) : null}
</div>
</div>
{this.state.imageFetching && (
<div className="controls">
<p className="imageWait">Loading...</p>
</div>
)}
{this.state.showImageSuccess && (
<div className="controls">
<p style={{ color: "green" }}>Image Saved! </p>
</div>
)}
<div
className={
this.state.invalid.address
? "control-group error"
: "control-group"
}
>
<label className="control-label" htmlFor="address">
Address <i className="required">*</i>
</label>
<div className="controls">
<textarea
rows="4"
required
cols="20"
id="address"
name="address"
onChange={this.handleState}
defaultValue={this.state.form.address}
/>
<span className="help-inline">Field required</span>
</div>
</div>
<div
className={
this.state.invalid.telephone
? "control-group error"
: "control-group"
}
>
<label className="control-label" htmlFor="telephone">
Telephone: <i className="required">*</i>
</label>
<div className="controls">
<input
type="number"
step="any"
required
name="telephone"
defaultValue={this.state.form.telephone}
onChange={this.handleState}
/>
<span className="help-inline">Field required</span>
</div>
</div>
<div
className={
this.state.invalid.city === true
? "control-group error"
: "control-group"
}
>
<label className="control-label" htmlFor="city">
City: <i className="required">*</i>
</label>
<div className="controls">
<input
type="text"
required
id="city"
defaultValue={this.state.form.city}
name="city"
onChange={this.handleState}
/>
<span className="help-inline">Field required</span>
</div>
</div>
<div
className={
this.state.invalid.country === true
? "control-group error"
: "control-group"
}
>
<label className="control-label" htmlFor="country">
Country: <i className="required">*</i>
</label>
<div className="controls">
<input
type="text"
required
id="country"
defaultValue={this.state.form.country}
name="country"
onChange={this.handleState}
/>
<span className="help-inline">Field required</span>
</div>
</div>
<div className="row-fluid">
<div className="span12">
<button
className={disabledColor}
type="submit"
disabled={this.state.disabled}
ref={button => {
this.submitButton = button;
}}
>
Submit
</button>
</div>
</div>
</div>
</div>
</fieldset>
</form>
);
How it looks right now:
The "Image Saved!" notification also appears in the same place as Loading as evident from code above, I need them on the side of the button.
This link provides the entire file and css associated with it that I'm working: https://gist.github.com/BikalNepal/0fe035e8845a5bb92c477abd9c003a50
CSS: https://gist.github.com/BikalNepal/73a3db6127ebda4b5489be8df3143d43
You need to re-structure you react element and that's all.
{this.state.croppedImageUrl ? (
<div className="flexContainer">
<button
className="btn btn-primary"
type="button"
onClick={this.handleState}
>
Confirm Crop
</button>
{this.state.imageFetching && (
<div className="controls">
<p className="imageWait">Loading...</p>
</div>
)}
{this.state.showImageSuccess && (
<div className="controls">
<p style={{ color: "green" }}>Image Saved! </p>
</div>
)}
</div>
) : null}
NOTE: All what I've done is: wrapped the elements that need to share same horizontal space, in one parent div.
And in the css file introduce a class:
.flexContainer {
display: flex;
justify-content: space-between;
align-items: center;
}
This might lead to lot of spacing between your button and notification. If so, try adding max-width: requiredValue; in the definition of the flexContainer class.
I am trying to disable the save button untill date is not picked. it is disabled but its not able to enbale untill i dont press any key from the keyboard.please tell me what i am doing wrong and thanks in advance.
<div class = "form-group" ng-class="{ 'has-error' : Form.fromTime.$invalid && !Form.fromTime.$pristine }">
<label for = "fromTime"> From Time:
<img src = "images/required.gif" alt = "Required" class = "required-star">
</label>
<div class='input-group date' id='fromTime' >
<input type='text' class="form-control" name="fromTime" ng-model = "fromTime" required />
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
<p ng-show="Form.fromTime.$invalid && !Form.fromTime.$pristine" class="help-block">From Time is required.</p>
</div>
<button type="button" class="col-sm-2 btn btn-primary" ng-click="scheduleCall()" style="margin-left:10px;" ng-disabled="Form.$invalid"> Save </button>
change:
ng-disabled="Form.$invalid"
to:
ng-disabled="Form.fromTime.$invalid"
You have to use like below
ng-disabled="Form.fromTime.$invalid"
Formname: Form;
Input field name : fromTime;
Input field state: $invalid
If i understand your problem correctly, you need to use a date input.
Now save button will be disabled until a valid date is picked.
function Ctrl($scope) {
$scope.fromTime = '';
$scope.scheduleCall = function() {};
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.9/angular.min.js"></script>
<div ng-app>
<div ng-controller="Ctrl">
<form name="Form">
<div class="form-group"
ng-class="{ 'has-error' : Form.fromTime.$invalid && !Form.fromTime.$pristine }">
<label for="fromTime">From Time:</label>
<div class='input-group date' id='fromTime'>
<input type='date' class="form-control" name="fromTime" ng-model="fromTime" required />
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
<p ng-show="Form.fromTime.$invalid && !Form.fromTime.$pristine"
style="font-size: 11px; color: red;">
From Time is required.
</p>
</div>
<button type="button" ng-click="scheduleCall()" ng-disabled="Form.$invalid">Save</button>
</form>
</div>
</div>