quill editor
This commit is contained in:
parent
e61907e557
commit
209292a61a
|
|
@ -318,8 +318,11 @@ function addQuoteItem(item = null) {
|
||||||
</div>
|
</div>
|
||||||
<div class="col-span-5">
|
<div class="col-span-5">
|
||||||
<label class="block text-xs font-medium text-gray-700 mb-1">Description</label>
|
<label class="block text-xs font-medium text-gray-700 mb-1">Description</label>
|
||||||
<textarea data-item="${itemId}" data-field="description" rows="2"
|
<div data-item="${itemId}" data-field="description"
|
||||||
class="item-input w-full px-2 py-2 border border-gray-300 rounded-md text-sm focus:ring-blue-500 focus:border-blue-500">${item ? item.description : ''}</textarea>
|
class="item-description-editor border border-gray-300 rounded-md bg-white"
|
||||||
|
style="min-height: 80px;">
|
||||||
|
</div>
|
||||||
|
<input type="hidden" data-item="${itemId}" data-field="description-html" class="item-description-html">
|
||||||
</div>
|
</div>
|
||||||
<div class="col-span-2">
|
<div class="col-span-2">
|
||||||
<label class="block text-xs font-medium text-gray-700 mb-1">Rate</label>
|
<label class="block text-xs font-medium text-gray-700 mb-1">Rate</label>
|
||||||
|
|
@ -349,6 +352,35 @@ function addQuoteItem(item = null) {
|
||||||
|
|
||||||
itemsDiv.appendChild(itemDiv);
|
itemsDiv.appendChild(itemDiv);
|
||||||
|
|
||||||
|
// Initialize Quill editor for description
|
||||||
|
const editorDiv = itemDiv.querySelector('.item-description-editor');
|
||||||
|
const hiddenInput = itemDiv.querySelector('.item-description-html');
|
||||||
|
|
||||||
|
const quill = new Quill(editorDiv, {
|
||||||
|
theme: 'snow',
|
||||||
|
modules: {
|
||||||
|
toolbar: [
|
||||||
|
['bold', 'italic', 'underline'],
|
||||||
|
[{ 'list': 'ordered'}, { 'list': 'bullet' }],
|
||||||
|
['clean']
|
||||||
|
]
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Load existing content if editing
|
||||||
|
if (item && item.description) {
|
||||||
|
quill.root.innerHTML = item.description;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save HTML content on change
|
||||||
|
quill.on('text-change', () => {
|
||||||
|
hiddenInput.value = quill.root.innerHTML;
|
||||||
|
updateTotals();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Store quill instance for later access
|
||||||
|
editorDiv.quillInstance = quill;
|
||||||
|
|
||||||
// Get references to inputs for auto-calculation
|
// Get references to inputs for auto-calculation
|
||||||
const qtyInput = itemDiv.querySelector('[data-field="quantity"]');
|
const qtyInput = itemDiv.querySelector('[data-field="quantity"]');
|
||||||
const rateInput = itemDiv.querySelector('[data-field="rate"]');
|
const rateInput = itemDiv.querySelector('[data-field="rate"]');
|
||||||
|
|
@ -442,9 +474,14 @@ function getQuoteItems() {
|
||||||
const itemDivs = document.querySelectorAll('#quote-items > div');
|
const itemDivs = document.querySelectorAll('#quote-items > div');
|
||||||
|
|
||||||
itemDivs.forEach(div => {
|
itemDivs.forEach(div => {
|
||||||
|
const descEditor = div.querySelector('.item-description-editor');
|
||||||
|
const descriptionHTML = descEditor && descEditor.quillInstance
|
||||||
|
? descEditor.quillInstance.root.innerHTML
|
||||||
|
: '';
|
||||||
|
|
||||||
const item = {
|
const item = {
|
||||||
quantity: div.querySelector('[data-field="quantity"]').value,
|
quantity: div.querySelector('[data-field="quantity"]').value,
|
||||||
description: div.querySelector('[data-field="description"]').value,
|
description: descriptionHTML,
|
||||||
rate: div.querySelector('[data-field="rate"]').value,
|
rate: div.querySelector('[data-field="rate"]').value,
|
||||||
amount: div.querySelector('[data-field="amount"]').value,
|
amount: div.querySelector('[data-field="amount"]').value,
|
||||||
is_tbd: div.querySelector('[data-field="is_tbd"]').checked
|
is_tbd: div.querySelector('[data-field="is_tbd"]').checked
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,8 @@
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>Quote Management System - Bay Area Affiliates</title>
|
<title>Quote Management System - Bay Area Affiliates</title>
|
||||||
<script src="https://cdn.tailwindcss.com"></script>
|
<script src="https://cdn.tailwindcss.com"></script>
|
||||||
|
<link href="https://cdn.quilljs.com/1.3.6/quill.snow.css" rel="stylesheet">
|
||||||
|
<script src="https://cdn.quilljs.com/1.3.6/quill.js"></script>
|
||||||
<style>
|
<style>
|
||||||
.modal {
|
.modal {
|
||||||
display: none;
|
display: none;
|
||||||
|
|
|
||||||
27
server.js
27
server.js
|
|
@ -731,6 +731,33 @@ function generateQuoteHTML(quote) {
|
||||||
text-align: left;
|
text-align: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Quill editor formatting in PDF */
|
||||||
|
.items-table td.description ul,
|
||||||
|
.items-table td.description ol {
|
||||||
|
margin: 5px 0;
|
||||||
|
padding-left: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.items-table td.description li {
|
||||||
|
margin: 2px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.items-table td.description p {
|
||||||
|
margin: 5px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.items-table td.description strong {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.items-table td.description em {
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
.items-table td.description u {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
.items-table td.rate,
|
.items-table td.rate,
|
||||||
.items-table td.amount {
|
.items-table td.amount {
|
||||||
text-align: right;
|
text-align: right;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue