mirror of
https://github.com/RunLit/Bambu-Run.git
synced 2026-06-22 14:09:04 +01:00
js and filament form for transparent color
This commit is contained in:
27
bambu_run/migrations/0002_filament_is_transparent.py
Normal file
27
bambu_run/migrations/0002_filament_is_transparent.py
Normal file
@@ -0,0 +1,27 @@
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("bambu_run", "0001_initial"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="filamentcolor",
|
||||
name="is_transparent",
|
||||
field=models.BooleanField(
|
||||
default=False,
|
||||
help_text="True for clear/transparent filaments — display as checkerboard, not solid color",
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="filament",
|
||||
name="is_transparent",
|
||||
field=models.BooleanField(
|
||||
default=False,
|
||||
help_text="True for clear/transparent filaments — display as checkerboard, not solid color",
|
||||
),
|
||||
),
|
||||
]
|
||||
156
bambu_run/static/bambu_run/js/filament_form.js
Normal file
156
bambu_run/static/bambu_run/js/filament_form.js
Normal file
@@ -0,0 +1,156 @@
|
||||
/**
|
||||
* filament_form.js — Filament add/edit form interactions.
|
||||
*
|
||||
* Handles:
|
||||
* - Filament type preset → auto-fill Type / Sub Type / Brand
|
||||
* - Transparent checkbox → toggle color picker vs. checkerboard swatch
|
||||
* - Color picker ↔ hex text sync
|
||||
* - Delete confirmation modal
|
||||
*/
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
|
||||
// ── Filament type preset auto-fill ────────────────────────────────────────
|
||||
|
||||
const dataEl = document.getElementById('filament-type-data');
|
||||
const filamentTypeMap = dataEl ? JSON.parse(dataEl.textContent) : {};
|
||||
|
||||
const filamentTypeSelect = document.getElementById('id_filament_type');
|
||||
const typeField = document.getElementById('id_type');
|
||||
const subTypeField = document.getElementById('id_sub_type');
|
||||
const brandField = document.getElementById('id_brand');
|
||||
|
||||
if (filamentTypeSelect) {
|
||||
filamentTypeSelect.addEventListener('change', function () {
|
||||
const mapping = filamentTypeMap[this.value];
|
||||
if (mapping && typeField && subTypeField && brandField) {
|
||||
typeField.value = mapping.type;
|
||||
subTypeField.value = mapping.sub_type;
|
||||
brandField.value = mapping.brand;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// ── Transparent toggle ────────────────────────────────────────────────────
|
||||
|
||||
const transparentCheckbox = document.getElementById('id_is_transparent');
|
||||
const transparentSwatch = document.getElementById('transparent-swatch');
|
||||
const colorPicker = document.getElementById('id_color_hex_picker');
|
||||
const colorText = document.getElementById('id_color_hex_text');
|
||||
|
||||
/**
|
||||
* Show checkerboard swatch and disable color inputs when transparent,
|
||||
* restore normal color picker when not transparent.
|
||||
* @param {boolean} isTransparent
|
||||
*/
|
||||
function applyTransparentState(isTransparent) {
|
||||
if (!colorPicker) return;
|
||||
if (isTransparent) {
|
||||
transparentSwatch.style.display = 'block';
|
||||
colorPicker.style.display = 'none';
|
||||
colorPicker.disabled = true;
|
||||
if (colorText) { colorText.disabled = true; colorText.value = ''; }
|
||||
} else {
|
||||
transparentSwatch.style.display = 'none';
|
||||
colorPicker.style.display = '';
|
||||
colorPicker.disabled = false;
|
||||
if (colorText) { colorText.disabled = false; }
|
||||
}
|
||||
}
|
||||
|
||||
if (transparentCheckbox) {
|
||||
applyTransparentState(transparentCheckbox.checked);
|
||||
transparentCheckbox.addEventListener('change', function () {
|
||||
applyTransparentState(this.checked);
|
||||
});
|
||||
}
|
||||
|
||||
// ── Color picker ↔ hex text sync ──────────────────────────────────────────
|
||||
|
||||
if (colorPicker && colorText) {
|
||||
colorPicker.addEventListener('input', function () {
|
||||
colorText.value = this.value.toUpperCase();
|
||||
});
|
||||
|
||||
colorText.addEventListener('input', function () {
|
||||
const value = this.value.trim();
|
||||
if (/^#[0-9A-Fa-f]{6}$/.test(value)) {
|
||||
colorPicker.value = value;
|
||||
this.classList.remove('is-invalid');
|
||||
} else if (value.length === 7) {
|
||||
this.classList.add('is-invalid');
|
||||
}
|
||||
});
|
||||
|
||||
if (colorText.value && /^#[0-9A-Fa-f]{6}$/.test(colorText.value)) {
|
||||
colorPicker.value = colorText.value;
|
||||
} else if (colorPicker.value && !colorText.value) {
|
||||
colorText.value = colorPicker.value.toUpperCase();
|
||||
}
|
||||
}
|
||||
|
||||
// ── Delete confirmation modal ─────────────────────────────────────────────
|
||||
|
||||
const deleteConfirmText = document.getElementById('deleteConfirmText');
|
||||
const confirmDeleteBtn = document.getElementById('confirmDeleteBtn');
|
||||
const deleteForm = document.getElementById('deleteForm');
|
||||
const deleteModal = document.getElementById('deleteModal');
|
||||
|
||||
if (deleteConfirmText && confirmDeleteBtn) {
|
||||
deleteConfirmText.addEventListener('input', function () {
|
||||
const value = this.value.trim();
|
||||
if (value === 'DELETE') {
|
||||
confirmDeleteBtn.disabled = false;
|
||||
this.classList.remove('is-invalid');
|
||||
this.classList.add('is-valid');
|
||||
} else {
|
||||
confirmDeleteBtn.disabled = true;
|
||||
this.classList.remove('is-valid');
|
||||
if (value.length > 0) {
|
||||
this.classList.add('is-invalid');
|
||||
} else {
|
||||
this.classList.remove('is-invalid');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (deleteForm) {
|
||||
deleteForm.addEventListener('submit', function (e) {
|
||||
if (confirmDeleteBtn.disabled) {
|
||||
e.preventDefault();
|
||||
alert('Please type DELETE to confirm deletion');
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
if (deleteModal) {
|
||||
deleteModal.addEventListener('hidden.bs.modal', function () {
|
||||
deleteConfirmText.value = '';
|
||||
confirmDeleteBtn.disabled = true;
|
||||
deleteConfirmText.classList.remove('is-valid', 'is-invalid');
|
||||
});
|
||||
|
||||
deleteModal.addEventListener('shown.bs.modal', function () {
|
||||
deleteConfirmText.focus();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// ── Delete button modal opener (backup) ───────────────────────────────────
|
||||
|
||||
const deleteBtn = document.getElementById('deleteBtn');
|
||||
if (deleteBtn && deleteModal) {
|
||||
deleteBtn.addEventListener('click', function () {
|
||||
if (!deleteModal.classList.contains('show')) {
|
||||
if (typeof bootstrap !== 'undefined') {
|
||||
bootstrap.Modal.getOrCreateInstance(deleteModal).show();
|
||||
} else if (typeof coreui !== 'undefined' && coreui.Modal) {
|
||||
coreui.Modal.getOrCreateInstance(deleteModal).show();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
Reference in New Issue
Block a user