I'm trying somehow to create a popup modal for an editing function. However I'm having difficulties to add a simple title "Edit vote" and the headers of each fields to be edited. The functionality is working but I'm facing issues with "cosmetic" as I am beginner with js and css.
Here is the code I'm using to build popup modal classes:
{editVote && (
<div className="edit-modal">
<div className="modal-content">
<h3>Edit Vote</h3>
<div className="form-fields">
{columns.map((column, index) => (
<div key={index}>
<label>{column}:</label>
<span>{editVote[columnMappings[column]] || 'N/A'}</span>
</div>
))}
</div>
<div className="input-fields">
<label>First Name:</label>
<input
type="text"
value={editedFields.first_name}
onChange={(e) => handleFieldChange('first_name', e.target.value)}
/>
<label>Last Name:</label>
<input
type="text"
value={editedFields.last_name}
onChange={(e) => handleFieldChange('last_name', e.target.value)}
/>
<label>Gender:</label>
<input
type="text"
value={editedFields.gender}
onChange={(e) => handleFieldChange('gender', e.target.value)}
/>
<label>Size:</label>
<input
type="number"
value={editedFields.size}
onChange={(e) => handleFieldChange('size', e.target.value)}
/>
<label>Weight:</label>
<input
type="number"
value={editedFields.weight}
onChange={(e) => handleFieldChange('weight', e.target.value)}
/>
<label>Birthday:</label>
<input
type="datetime-local"
value={`${editedFields.birthday}T${editedFields.birthtime}`}
onChange={(e) => handleFieldChange('birthday', e.target.value)}
/>
</div>
<div className="button-container">
<button onClick={handleUpdateClick}>Update</button>
<button onClick={() => setEditVote(null)}>Cancel</button>
</div>
</div>
</div>
)}
For info, I have also put the colorMapping declaration to handle headers of the field:
const columnMappings: {
Prénom: string;
'Nom de famille': string;
Sexe: string;
'Taille(cm)': string;
'Poids (kg)': string;
Birthday: string;
}
Finally this is the different CSS I have created for each classes :
.edit-modal {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5); /* Semi-transparent background */
display: flex;
justify-content: center;
align-items: center;
}
.modal-content {
background-color: white;
padding: 20px;
border-radius: 5px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
}
.modal-content h3 {
margin-top: 0;
}
.form-fields {
/* Style for the form fields section */
margin-bottom: 20px;
}
.form-fields label {
/* Style for field labels */
display: block;
font-weight: bold;
margin-bottom: 5px;
}
.form-fields input {
/* Style for input fields */
width: 100%;
padding: 8px;
margin-bottom: 10px;
border: 1px solid #ccc;
border-radius: 4px;
}
.input-fields {
width: 100%;
padding: 8px;
margin-bottom: 10px;
border: 1px solid #ccc;
border-radius: 4px;
}
.button-container {
/* Style for the button container section */
text-align: center;
}
.button-container button {
/* Style for buttons */
margin-right: 10px;
padding: 8px 16px;
background-color: #007bff;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
.button-container button:hover {
/* Style for button hover state */
background-color: #0056b3;
}
In advance, many thanks !
I know that you already did the dialog and just needed a suggestion for the styling, but I couldn't help trying out the dialog element.
That aside, I will suggest using flexbox to control the form fields and the labels. It is quite ... flexible and a nice way to align elements.
window.addEventListener('click', e => {
let href = e.target.attributes['href'];
if(href && document.getElementById(href.value)){
e.preventDefault();
document.getElementById(href.value).showModal();
}
});
document.forms.editvote.addEventListener('submit', e => {
e.preventDefault();
let submitter = e.submitter;
// close the dialog parsing the name of the button clicked
document.getElementById(e.target.name).close(submitter.name);
});
document.getElementById('editvote').addEventListener('close', e => {
let form = document.forms[e.target.id];
switch(e.target.returnValue) {
case 'cancel':
// clear the form
form.reset();
break;
case 'update':
// do something with the data
let data = new FormData(form);
console.log([...data]);
break;
}
});
body {
font-family: sans-serif;
}
#editvote {
border: gray solid thin;
border-radius: 5px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
}
#editvote::backdrop {
background-color: AntiqueWhite;
opacity: .8;
}
#editvote fieldset {
border: none;
padding: 0;
margin: 0;
display: flex;
flex-direction: column;
gap: .4em;
}
#editvote fieldset legend {
margin-bottom: .5em;
font-weight: bold;
font-size: 110%;
}
#editvote fieldset label {
display: flex;
justify-content: space-between;
gap: .4em;
}
#editvote fieldset label input {
width: 300px;
}
<p><a href="editvote">Edit</a></p>
<dialog id="editvote">
<form name="editvote" method="dialog">
<fieldset>
<legend>Edit Vote</legend>
<label>First Name:<input type="text" name="firstname" value="" /></label>
<label>Last Name:<input type="text" name="lastname" value="" /></label>
<label>Gender:<input type="text" name="gender" value="" /></label>
<label>Size:<input type="number" name="size" value="" /></label>
<label>Weight:<input type="number" name="weight" value="" /></label>
<label>Birthday:<input type="datetime-local" name="birthday" value="" /></label>
<div class="button-container">
<button name="update">Update</button>
<button name="cancel">Cancel</button>
</div>
</fieldset>
</form>
</dialog>