diff --git a/index.html b/index.html index 86ad942..0ec8628 100644 --- a/index.html +++ b/index.html @@ -1,4 +1,4 @@ -!DOCTYPE html> + @@ -9,9 +9,25 @@

VCard Viewer

-
- -
+ +

Contact Details

+ + + + + + + + + + + + +
NamePhoneEmailOrganization
+ + + + diff --git a/script.js b/script.js index b49df3a..3ebdeb7 100644 --- a/script.js +++ b/script.js @@ -3,12 +3,82 @@ document.getElementById('vcardFile').addEventListener('change', function(event) if (file) { const reader = new FileReader(); reader.onload = function(e) { - const content = e.target.result; - const vcardContentDiv = document.getElementById('vcardContent'); - // For now, just display the raw content. - // We can implement more sophisticated parsing later. - vcardContentDiv.textContent = content; + const rawContent = e.target.result; + const contacts = parseVCard(rawContent); + displayContactsInTable(contacts); + // For debugging, also show raw content + // const vcardContentDiv = document.getElementById('vcardRawContent'); + // vcardContentDiv.textContent = rawContent; }; reader.readAsText(file); } }); + +function parseVCard(rawContent) { + const contacts = []; + const lines = rawContent.split(/\r\n|\r|\n/); + let currentContact = null; + + lines.forEach(line => { + if (line.toUpperCase() === 'BEGIN:VCARD') { + currentContact = {}; + } else if (line.toUpperCase() === 'END:VCARD') { + if (currentContact) { + contacts.push(currentContact); + currentContact = null; + } + } else if (currentContact) { + const parts = line.split(':'); + if (parts.length >= 2) { + const keyPart = parts[0]; + const value = parts.slice(1).join(':'); + + // Basic parsing for common fields + // FN (Formatted Name) + if (keyPart.startsWith('FN')) { + currentContact.fn = value; + } + // TEL (Telephone) + else if (keyPart.startsWith('TEL')) { + // Simplistic approach: take the first TEL found + if (!currentContact.tel) currentContact.tel = value; + } + // EMAIL + else if (keyPart.startsWith('EMAIL')) { + // Simplistic approach: take the first EMAIL found + if (!currentContact.email) currentContact.email = value; + } + // ORG (Organization) + else if (keyPart.startsWith('ORG')) { + currentContact.org = value; + } + } + } + }); + return contacts; +} + +function displayContactsInTable(contacts) { + const tableBody = document.getElementById('contactsTableBody'); + if (!tableBody) { + console.error('Table body not found!'); + return; + } + tableBody.innerHTML = ''; // Clear previous entries + + if (contacts.length === 0) { + const row = tableBody.insertRow(); + const cell = row.insertCell(); + cell.colSpan = 4; // Number of columns + cell.textContent = 'No contacts found in the VCard file.'; + return; + } + + contacts.forEach(contact => { + const row = tableBody.insertRow(); + row.insertCell().textContent = contact.fn || 'N/A'; + row.insertCell().textContent = contact.tel || 'N/A'; + row.insertCell().textContent = contact.email || 'N/A'; + row.insertCell().textContent = contact.org || 'N/A'; + }); +} diff --git a/style.css b/style.css index 3580336..2dde92a 100644 --- a/style.css +++ b/style.css @@ -13,11 +13,33 @@ input[type="file"] { margin-bottom: 20px; } -#vcardContent { - background-color: #fff; - border: 1px solid #ddd; - padding: 15px; - min-height: 100px; - white-space: pre-wrap; /* Preserve line breaks and spaces */ - word-wrap: break-word; /* Break long lines */ +/* #vcardRawContent { + background-color: #eee; + border: 1px solid #ccc; + padding: 10px; + margin-top: 20px; + min-height: 50px; + white-space: pre-wrap; + word-wrap: break-word; +} */ + +#contactsTable { + width: 100%; + border-collapse: collapse; + margin-top: 20px; +} + +#contactsTable th, #contactsTable td { + border: 1px solid #ddd; + padding: 8px; + text-align: left; +} + +#contactsTable th { + background-color: #e9e9e9; + color: #333; +} + +#contactsTable tr:nth-child(even) { + background-color: #f9f9f9; }