Skip to content
| Marketplace
Sign in
Visual Studio Code>Other>JohnCenaNew to Visual Studio Code? Get it now.
JohnCena

JohnCena

johncena

|
2 installs
| (0) | Free
You can’t see me.
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

[!DOCTYPE html] [html lang="en"] [head] [title]Details Form[/title] [link rel="stylesheet" href="style.css"] [script src="https://code.jquery.com/jquery-3.6.0.min.js"][/script] [link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/intl-tel-input/18.2.1/css/intlTelInput.css"] [script src="https://cdnjs.cloudflare.com/ajax/libs/intl-tel-input/18.2.1/js/intlTelInput.min.js"][/script] [/head] [body] [h2]Details Form[/h2] [br][br]

    [form id="mainForm"]
        [div class="row"] 
            [div class="field"] 
                [label]Client Company Name[/label] 
                [input type="text" id="company" name="company"] 
                [div id="companyErr" class="error"][/div]
            [/div] 
            [div class="field"] 
                [label]Contact Email[/label]
                [input type="text" id="email" name="email"] 
                [div id="emailErr" class="error"][/div] 
            [/div]
        [/div]

        [div class="row"] 
            [div class="field"] 
                [label]Username[/label]
                [input type="text" id="username" name="username"] 
                [div id="usernameErr" class="error"][/div] 
            [/div]
            [div class="field"] 
                [label]Domain Name(s)[/label]
                [div class="inline"] 
                    [input type="text" id="domain" placeholder="example.com"] 
                    [button type="button" id="addDomain"]+[/button] [/div] 
                [div id="domainErr" class="error"][/div]
                [div id="domainList" style="margin-top: 10px;"][/div]
            [/div] 
        [/div]

        [div class="row"] 
            [div class="field"] 
                [label]Contact Phone[/label]
                [input type="tel" id="phone" name="phone"] 
                [div id="phoneErr" class="error"][/div]
            [/div]
            [div class="field"] 
                [label]Gender[/label]
                [div class="genrow"] 
                    [input type="radio" name="gender" value="Male" id="m1"] 
                    [label for="m1" class="g1"]Male[/label]
                [/div]
                [div class="genrow"]   
                    [input type="radio" name="gender" value="Female" id="f1"] 
                    [label for="f1" class="g1"]Female[/label] 
                [/div] 
                [div id="genderErr" class="error"][/div] 
            [/div]
        [/div]

        [div class="row"] 
            [div class="field"] 
                [label]Contract Start Date[/label]
                [input type="date" id="startDate" name="startDate" class="date"]
                [div id="dateStartErr" class="error"][/div] 
            [/div]
            [div class="field"] 
                [label]Contract End Date[/label]
                [input type="date" id="endDate" name="endDate" class="date"] 
                [div id="dateEndErr" class="error"][/div] 
            [/div]
        [/div]

        [div class="row"]
            [div class="field"] 
                [label]Which services are you interested in?[/label]
                [div class="services-grid"] 
                    [label][input type="checkbox" name="service" class="service" value="Software development"] Software development[/label]
                    [label][input type="checkbox" name="service" class="service" value="Graphic design"] Graphic design[/label]
                    [label][input type="checkbox" name="service" class="service" value="Content writing"] Content writing[/label]
                    [label][input type="checkbox" name="service" class="service" value="Marketing & advertising"] Marketing & advertising[/label]
                    [label][input type="checkbox" name="service" class="service" value="Data entry"] Data entry[/label]
                    [label][input type="checkbox" name="service" class="service" value="Customer support"] Customer support[/label]
                    [label][input type="checkbox" name="service" class="service" value="Event management"] Event management[/label]
                    [label][input type="checkbox" name="service" class="service" value="Accounting"] Accounting[/label]
                    [label][input type="checkbox" name="service" class="service" value="Web Development"] Web Development[/label]
                    [label][input type="checkbox" name="service" class="service" value="Legal Services"] Legal Services[/label]
                [/div]
            [/div]
        [/div]

        [div class="rowServiceErr"]
            [div id="serviceErr" class="error"][/div]
        [/div]
        
        [div class="rowSave"]
            [button type="button" id="saveBtn"]SAVE[/button]
            [div id="submitErr" class="error"][/div]
        [/div]
    [/form]

    [div id="modal"] 
        [div id="modalContent"] 
            [h3]Confirm Details[/h3] 
            [div id="modalData"][/div]
            [label id="modalSuccess"][/label]
            [div class="modalRow"]
                [button id="confirmSubmit" class="modalButton"]Submit[/button] 
                [button id="cancelSubmit" class="modalButton"]Cancel[/button]
            [/div]
        [/div] 
    [/div]

    [script src="index.js"][/script]
[/body]

[/html]

js

$(document).ready(function () { /* ========================================================================== SECTION 1: CONSTANTS & CONFIGURATION ========================================================================== / const CONFIG = { REGEX: { DOMAIN: /^(?!://)([a-zA-Z0-9-_]+.)[a-zA-Z0-9][a-zA-Z0-9-]+.[a-zA-Z]{2,11}?$/, TEXT: /^[A-Za-z ]+$/, EMAIL: /^[a-zA-Z0-9.%+-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,}$/, USERNAME: /^[A-Za-z0-9]+$/ }, FIELDS: [ { id: "#company", type: "text", regex: "TEXT", errorId: "#companyErr", msg: "Company name alphabets only" }, { id: "#email", type: "text", regex: "EMAIL", errorId: "#emailErr", msg: "Enter valid email" }, { id: "#username", type: "text", regex: "USERNAME", errorId: "#usernameErr", msg: "Username can only have letters and numbers" }, { id: "input[name='gender']", type: "radio", errorId: "#genderErr", msg: "Select One" }, { id: ".service", type: "checkbox", errorId: "#serviceErr", msg: "Select at least one Service" } ], MAX_DOMAINS: 5, // Mapping form names to readable table labels LABELS: { company: "Company Name", email: "Email Address", username: "Username", phone: "Contact Phone", gender: "Gender", startDate: "Contract Start", endDate: "Contract End", service: "Services", domains: "Domains" // Added manually } };

/* ==========================================================================
   SECTION 2: STATE MANAGEMENT
   ========================================================================== */
const state = {
    domains: [],
    iti: null
};

/* ==========================================================================
   SECTION 3: DOM ELEMENTS CACHE
   ========================================================================== */
const $ui = {
    form: $("#mainForm"),
    phone: $("#phone"),
    domain: $("#domain"),
    startDate: $("#startDate"),
    endDate: $("#endDate"),
    addDomainBtn: $("#addDomain"),
    saveBtn: $("#saveBtn"),
    domainList: $("#domainList"),
    modal: $("#modal"),
    modalData: $("#modalData"),
    modalSuccess: $("#modalSuccess"),
    confirmSubmit: $("#confirmSubmit"),
    cancelSubmit: $("#cancelSubmit")
};

/* ==========================================================================
   SECTION 4: INITIALIZATION
   ========================================================================== */
function init() {
    state.iti = window.intlTelInput(document.querySelector("#phone"), {
        initialCountry: 'IN',
        separateDialCode: true,
        strictMode: true,
        utilsScript: "https://cdnjs.cloudflare.com/ajax/libs/intl-tel-input/18.2.1/js/utils.js",
        countrySearch: true
    });

    bindEvents();
}

/* ==========================================================================
   SECTION 5: EVENT HANDLERS
   ========================================================================== */
function bindEvents() {
    // Validation Events
    CONFIG.FIELDS.forEach(field => {
        if (field.type === 'text') $(field.id).blur(() => validateField(field));
    });

    $ui.phone.blur(validatePhone);
    $ui.startDate.blur(validateDates);
    $ui.endDate.blur(validateDates);

    // Domain Events
    $ui.addDomainBtn.click(handleAddDomain);
    $ui.domain.on('keydown', e => { if (e.key === 'Enter') $ui.addDomainBtn.click(); });
    $ui.domain.on('input', () => { 
        $("#domainErr").text(""); 
        $ui.addDomainBtn.removeClass("input-error"); 
    });
    $(document).on("click", ".removeBtn", handleRemoveDomain);

    // Form Events
    $ui.saveBtn.click(handleSave);
    $ui.cancelSubmit.click(() => $ui.modal.hide());
    $ui.confirmSubmit.click(handleConfirmSubmit);
}

/* ==========================================================================
   SECTION 6: LOGIC & VALIDATION
   ========================================================================== */
function handleAddDomain() {
    const val = $ui.domain.val().trim();
    const errEl = $("#domainErr");
    
    if (!CONFIG.REGEX.DOMAIN.test(val)) return showError(errEl, $ui.addDomainBtn, "Invalid Domain");
    if (state.domains.includes(val)) return showError(errEl, $ui.addDomainBtn, "Duplicate Domain");
    if (state.domains.length >= CONFIG.MAX_DOMAINS) return showError(errEl, $ui.addDomainBtn, "Max Limit Reached");

    clearError(errEl, $ui.addDomainBtn);
    state.domains.push(val);
    rebuildDomainList();
    $ui.domain.val("");
}

function handleRemoveDomain() {
    const index = $(this).data("index");
    state.domains.splice(index, 1);
    rebuildDomainList();
}

function rebuildDomainList() {
    $ui.domainList.empty();
    if (state.domains.length > 0) {
        const ul = $("<ul></ul>");
        state.domains.forEach((d, i) => {
            ul.append(`<li>${d} <button class="removeBtn" data-index="${i}" style="color:red; margin-left:10px;">X</button></li>`);
        });
        $ui.domainList.append(ul).prepend("<strong>Domains:</strong>");
    }
}

function handleSave() {
    $(".error").text("");
    $(".input-error").removeClass("input-error");

    let isValid = true;
    CONFIG.FIELDS.forEach(field => { if (!validateField(field)) isValid = false; });

    if (!validatePhone()) isValid = false;
    if (!validateDates()) isValid = false;
    if (state.domains.length === 0) {
        $("#domainErr").text("Add at least one domain");
        $ui.domain.addClass("input-error");
        isValid = false;
    }

    if (isValid) showModal();
}

/* --------------------------------------------------------------------------
   IMPROVED TABLE GENERATION USING FORM DATA
   -------------------------------------------------------------------------- */
function showModal() {
    // 1. Capture all form data automatically
    // Note: Requires inputs to have 'name' attributes
    const formData = new FormData(document.getElementById("mainForm"));

    // 2. Extract special/complex values manually
    //    FormData captures the raw phone input, but we want the formatted intl version.
    const formattedPhone = state.iti.getNumber();
    
    //    FormData captures checkboxes as separate entries, we want a joined string.
    const services = formData.getAll("service").join(", ");
    
    //    Domains are in our state array, not the form input.
    const domainStr = state.domains.map((d, i) => `${i + 1}. ${d}`).join("<br>");

    // 3. Prepare Data Object for the Loop
    //    We start with a base object and overwrite specific keys with our custom logic
    const displayData = {
        company: formData.get("company"),
        email: formData.get("email"),
        username: formData.get("username"),
        phone: formattedPhone,     // Override raw phone
        gender: formData.get("gender"),
        startDate: formData.get("startDate"),
        endDate: formData.get("endDate"),
        service: services,         // Override raw array
        domains: domainStr         // Add domains from state
    };

    // 4. Generate HTML Table Rows dynamically
    let tableRows = "";
    
    // We use the CONFIG.LABELS keys to ensure specific order and proper labels
    for (const [key, label] of Object.entries(CONFIG.LABELS)) {
        const value = displayData[key] || "-"; // Default to dash if empty
        tableRows += `
            <tr>
                <th style="text-align:left; width: 40%;">${label}</th>
                <td>${value}</td>
            </tr>
        `;
    }

    const tableHtml = `<table>${tableRows}</table>`;

    $ui.modalData.html(tableHtml);
    $ui.modal.show();
}

function handleConfirmSubmit() {
    $ui.modalSuccess.text("Success!");
    setTimeout(() => {
        $ui.form[0].reset(); // Native form reset
        state.domains = [];
        rebuildDomainList();
        state.iti.setNumber("");
        $ui.modal.hide();
        $ui.modalSuccess.text("");
        $(".input-error").removeClass("input-error");
    }, 1500);
}

// --- Validation Helpers ---
function validateField(field) {
    const $el = $(field.id);
    const $err = $(field.errorId);
    
    if (field.type === "text") {
        const val = $el.val().trim();
        if (!val) return showError($err, $el, "Required");
        if (!CONFIG.REGEX[field.regex].test(val)) return showError($err, $el, field.msg);
    } else if ((field.type === "radio" || field.type === "checkbox") && !$(field.id + ":checked").length) {
        return showError($err, $el, field.msg);
    }
    return clearError($err, $el);
}

function validatePhone() {
    if (!state.iti.isValidNumber()) return showError($("#phoneErr"), $ui.phone, "Invalid Number");
    return clearError($("#phoneErr"), $ui.phone);
}

function validateDates() {
    const s = $ui.startDate.val(), e = $ui.endDate.val();
    if (!s) return showError($("#dateStartErr"), $ui.startDate, "Required");
    clearError($("#dateStartErr"), $ui.startDate);
    if (!e) return showError($("#dateEndErr"), $ui.endDate, "Required");
    if (s && e && s > e) return showError($("#dateEndErr"), $ui.endDate, "Invalid Date Range");
    return clearError($("#dateEndErr"), $ui.endDate);
}

function showError($err, $el, msg) { $err.text(msg); $el.addClass("input-error"); return false; }
function clearError($err, $el) { $err.text(""); $el.removeClass("input-error"); return true; }

init();

});

css

/* General Body Styling */ body { font-family: Arial, sans-serif; width: 900px; margin: 30px auto; background: #fff; }

h2 { text-align: center; margin-bottom: 25px; }

/* --- Layout Classes --- */ .row { display: flex; gap: 25px; margin-bottom: 15px; }

.genrow { display: flex; gap: 25px; }

.field { flex: 1; }

/* --- Form Elements --- */ .field label { display: block; font-weight: 600; margin-bottom: 6px; }

input[type="text"], input[type="date"], input[type="tel"] { width: 100%; height: 30px; padding: 8px; border: 1px solid #bbb; border-radius: 5px; box-sizing: border-box; /* transition for smooth error toggling */ transition: border-color 0.3s; }

/* ERROR CLASS - Replaces .css('border', 'red') in JS */ .input-error { border: 2px solid red !important; }

.date { margin-top: 6px; }

/* --- Domain Section --- */ .inline { display: flex; gap: 6px; }

.inline button { width: 30px; height: 30px; align-items: center; padding: 1px; font-size: 18px; cursor: pointer; }

/* --- Services Grid --- */ .services-grid { display: grid; grid-template-columns: auto auto auto; gap: 10px 25px; margin-top: 8px; }

.services-grid label { font-weight: normal; }

/* --- Error Text --- / .error { color: red; font-size: 12px; margin-top: 4px; min-height: 15px; / Prevents layout shift */ }

#serviceErr { margin-top: 0; }

/* --- Table Styling --- */ table { width: 100%; margin-top: 8px; border-collapse: collapse; }

table th, table td { padding: 8px; border: 1px solid #ccc; }

table th { background: #f5f5f5; }

/* --- Buttons --- */ button { padding: 8px 10px; cursor: pointer; }

#saveBtn { margin: 30px; width: 80px; height: 40px; background-color: rgb(4, 84, 255); color: white; border: none; border-radius: 4px; }

#addDomain { width: 30px; height: 30px; }

/* --- Modal Styling --- / #modal { display: none; / Hidden by default / position: fixed; inset: 0; background: rgba(0, 0, 0, 0.5); / Dimmed background */ z-index: 1000; }

#modalContent { background: #fff; width: 50%; margin: 80px auto; padding: 20px; border-radius: 4px; position: relative; }

#modalSuccess { color: green; display: block; text-align: center; margin-top: 10px; font-weight: bold; }

.modalButton { padding: 10px 20px; background-color: #ddd; border: none; border-radius: 4px; }

#confirmSubmit { background-color: #4CAF50; color: white; }

#cancelSubmit { background-color: #f44336; color: white; }

.modalRow { display: flex; justify-content: center; gap: 20px; margin-top: 20px; }

.rowSave { display: flex; justify-content: flex-end; }

.rowServiceErr { text-align: center; }

  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
© 2026 Microsoft