Form Inputs, Styling, and Background Options

vue.js logo

Form inputs

Our form modal currently displays a Hello message. Replace this with form inputs to capture the event data from the user inside the EventForm.vue:

<template>
    <div v-if="show" class="modal-overlay">
        <!-- <p>Hello</p> -->
        <div class="modal">
            <div class="modal-header">
                <h2>Add New Event</h2>
                <button class="close-button">&times;</button>
            </div>
            <form class="modal-form">
                <div class="form-group">
                    <label for="name">Event Name *</label>
                    <input
                        id="name"
                        type="text"
                        required
                        placeholder="Enter event name"
                    />
                </div>

                <div class="form-group">
                    <label for="details">Details</label>
                    <textarea
                        id="details"
                        placeholder="Enter event details"
                        rows="3"
                    ></textarea>
                </div>

                <div class="form-group">
                    <label for="date">Date *</label>
                    <input id="date" type="date" required />
                </div>

                <div class="form-group">
                    <label>Background Color</label>
                    <!-- will complete soon -->
                    <div class="color-options"></div>
                </div>

                <div class="form-actions">
                    <button type="button" class="cancel-button">Cancel</button>
                    <button type="submit" class="submit-button">Add Event</button>
                </div>
            </form>
        </div>
    </div>

Styling the form

So far, this is just regular HTML, and we can style with CSS:

.modal-overlay {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: rgba(0, 0, 0, 0.5);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 1000;
    backdrop-filter: blur(4px);
}

.modal {
    background: white;
    border-radius: 12px;
    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
    width: 90%;
    max-width: 500px;
    max-height: 90vh;
    overflow-y: auto;
    animation: modalSlideIn 0.3s ease;
}

@keyframes modalSlideIn {
    from {
        opacity: 0;
        transform: translateY(-20px) scale(0.95);
    }
    to {
        opacity: 1;
        transform: translateY(0) scale(1);
    }
}

.modal-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 1.5rem;
    border-bottom: 1px solid #e1e5e9;
    padding-bottom: 1rem;
}

.modal-header h2 {
    margin: 0;
    color: #2c3e50;
}

.close-button {
    background: none;
    border: none;
    font-size: 1.5rem;
    color: #6c757d;
    cursor: pointer;
    transition: all 0.2s ease;
}

.close-button:hover {
    background: #f8f9fa;
    color: #495057;
}

.modal-form {
    padding: 1.5rem;
}

.form-group {
    margin-bottom: 1.5rem;
}

.form-group label {
    display: block;
    margin-bottom: 0.75rem;
    color: #2c3e50;
}

.form-group input,
.form-group textarea {
    width: 100%;
    padding: 0.75rem;
    border: 2px solid #e1e5e9;
    border-radius: 5px;
    transition: border-color 0.2s ease;
    box-sizing: border-box;
}

.form-actions {
    display: flex;
    gap: 1rem;
    margin-top: 2rem;
    padding-top: 1rem;
    border-top: 1px solid #e1e5e9;
}

.cancel-button,
.submit-button {
    padding: 0.75rem 1.5rem;
    border-radius: 5px;
    font-size: 1rem;
    cursor: pointer;
    transition: all 0.2s ease;
    border: none;
    flex: 1;
}

.cancel-button {
    background: #f8f9fa;
    color: #6c757d;
    border: 2px solid #e1e5e9;
}

.cancel-button:hover {
    background: #e9ecef;
    color: #495057;
}

.submit-button {
    background: linear-gradient(135deg, #445cf4, #86e6f4);
    color: white;
}

.submit-button:hover {
    transform: translateY(-2px);
    box-shadow: 0 4px 12px rgba(78, 101, 255, 0.3);
}

@media (max-width: 768px) {
    .modal {
        width: 95%;
        margin: 1rem;
    }

    .form-actions {
        flex-direction: column;
    }
}

Looping over color options

You should now have a much nicer looking form modal. The HTML for the background color selector is currently empty:

<div class="form-group">
    <label>Background Color</label>
    <!-- will complete soon -->
    <div class="color-options"></div>
</div>

This section will now be updated to loop over the available background colors, first, we need to define them in an array. Add the following array to the <script> section:

const backgroundOptions = [
    "linear-gradient(135deg, #FF416C, #FF4B2B)",
    "linear-gradient(135deg, #11998e, #38ef7d)",
    "linear-gradient(135deg, #4E65FF, #92EFFD)",
    "linear-gradient(135deg, #FC466B, #3F5EFB)",
    "linear-gradient(135deg, #009FFF, #ec2F4B)",
    "linear-gradient(135deg, #654ea3, #eaafc8)",
    "linear-gradient(135deg, #667eea, #764ba2)",
    "linear-gradient(135deg, #f093fb, #f5576c)",
];

This will create the following background colors to choose from:

💡 Tip: You can update these color options or CSS values to make your app more custom if you prefer!

Now the background color section can loop over these avilable options:

<div class="form-group">
    <label>Background Color</label>
    <div class="color-options">
        <div
            v-for="(bg, index) in backgroundOptions"
            :key="index"
            class="color-option"
            :style="{ background: bg }"
        ></div>
    </div>
</div>
  • v-for - Loops through the backgroundOptions array, storing each value in bg.
  • :key - Provides a unique id for each element in the loop (required).
  • class - The color-option CSS class for styling.
  • :style - Sets the background color using the current bg value from the loop.

You will notice no updates in the browser yet. To show the color options we can update the CSS to display as a grid, and give each <div> a fixed size:

.color-options {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(40px, 1fr));
}

.color-option {
    width: 40px;
    height: 40px;
    border-radius: 5px;
    cursor: pointer;
}

.color-option.active {
    border-color: #2c3e50;
    transform: scale(1.1);
}

.color-option.active::after {
    content: "✓";
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    color: white;
    font-weight: bold;
    font-size: 1.2rem;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
}

You should now see the available colors listed in the modal!