You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

181 lines
8.1 KiB

{% load i18n %}
<div class="space-y-3 max-w-2xl" data-multilang-json data-field-name="{{ widget.field_name }}">
<div class="relative">
<div class="w-full max-w-2xl overflow-x-auto scrollbar-hover pr-2">
<div class="inline-flex flex-nowrap items-center gap-1 whitespace-nowrap py-1 min-w-max" data-lang-bar>
{% for code in widget.languages %}
<button type="button"
class="lang-btn px-3 py-1.5 rounded-md border transition-all duration-150 text-xs font-medium
border-base-200 text-font-default-light
dark:border-base-700 dark:text-font-default-dark{% if widget.has_value_codes and code in widget.has_value_codes %} has-value{% endif %}"
data-lang-code="{{ code }}">
{{ code|upper }}
</button>
{% endfor %}
</div>
</div>
</div>
<div class="space-y-3" data-inputs>
{% for input in widget.inputs %}
<div class="hidden" data-input-wrapper data-lang-code="{{ input.code }}">
<div class="flex items-center gap-2 mb-1">
<span class="text-xs font-medium text-font-subtle-light dark:text-font-subtle-dark">
{{ input.code|upper }}
</span>
</div>
{{ input.html|safe }}
</div>
{% endfor %}
<input type="hidden" name="{{ widget.field_name }}" value='{{ widget.serialized|escapejs }}'>
</div>
<div class="text-xs text-font-subtle-light dark:text-font-subtle-dark">
{% trans "Click a language code to add or edit its title." %}
</div>
</div>
<style>
.scrollbar-hover {
--scrollbar-track: rgb(var(--color-base-100));
--scrollbar-thumb: rgb(var(--color-base-300));
scrollbar-color: var(--scrollbar-thumb) var(--scrollbar-track);
scrollbar-width: none;
}
.scrollbar-hover:hover { scrollbar-width: thin; }
.dark .scrollbar-hover { --scrollbar-track: rgb(var(--color-base-800)); --scrollbar-thumb: rgb(var(--color-base-600)); }
.scrollbar-hover::-webkit-scrollbar { height: 0; }
.scrollbar-hover:hover::-webkit-scrollbar { height: 6px; }
.scrollbar-hover::-webkit-scrollbar-track { background: var(--scrollbar-track); border-radius: 3px; }
.scrollbar-hover::-webkit-scrollbar-thumb { background: var(--scrollbar-thumb); border-radius: 3px; }
.scrollbar-hover::-webkit-scrollbar-corner { background: var(--scrollbar-track); }
.scrollbar-hover:hover::-webkit-scrollbar-thumb:hover { background: rgb(var(--color-base-400)); }
.dark .scrollbar-hover:hover::-webkit-scrollbar-thumb:hover { background: rgb(var(--color-base-500)); }
.lang-btn { background: transparent; }
.lang-btn:hover { background: rgb(var(--color-base-50)); border-color: rgb(var(--color-base-300)); }
.dark .lang-btn:hover { background: rgb(var(--color-base-800)); border-color: rgb(var(--color-base-600)); }
.lang-btn.is-active { border-color: rgb(var(--color-primary-500)); background: rgb(var(--color-primary-50)); color: rgb(var(--color-primary-700)); box-shadow: 0 0 0 1px rgb(var(--color-primary-200)); }
.dark .lang-btn.is-active { border-color: rgb(var(--color-primary-600)); background: rgb(var(--color-primary-900)); color: rgb(var(--color-primary-300)); box-shadow: 0 0 0 1px rgb(var(--color-primary-700)); }
.lang-btn.has-value { border-color: rgb(var(--color-primary-400)); color: rgb(var(--color-primary-600)); }
.dark .lang-btn.has-value { border-color: rgb(var(--color-primary-600)); color: rgb(var(--color-primary-300)); }
.lang-btn.is-active:hover { background: rgb(var(--color-primary-50)); border-color: rgb(var(--color-primary-500)); }
.dark .lang-btn.is-active:hover { background: rgb(var(--color-primary-900)); border-color: rgb(var(--color-primary-600)); }
</style>
<script>
(function () {
function init(root) {
var fieldName = root.getAttribute("data-field-name");
if (!fieldName) return;
var buttons = root.querySelectorAll(".lang-btn[data-lang-code]");
var inputsRoot = root.querySelector("[data-inputs]");
if (!inputsRoot) return;
var hasActiveLanguage = false;
var withValue = [];
var withoutValue = [];
buttons.forEach(function (btn) {
var code = btn.getAttribute("data-lang-code");
var wrapper = inputsRoot.querySelector('[data-input-wrapper][data-lang-code="' + code + '"]');
var hasValue = false;
if (wrapper) {
var input = wrapper.querySelector('input[name="' + fieldName + '__' + code + '"], textarea[name="' + fieldName + '__' + code + '"], input[id*="' + fieldName + '__' + code + '"]');
hasValue = !!(input && input.value && input.value.trim() !== "");
}
if (hasValue) {
btn.classList.add("has-value");
withValue.push(btn);
if (!hasActiveLanguage && wrapper) {
btn.classList.add("is-active");
wrapper.classList.remove("hidden");
hasActiveLanguage = true;
}
} else {
withoutValue.push(btn);
}
});
if (!hasActiveLanguage && buttons.length) {
var firstBtn = (withValue[0] || buttons[0]);
var firstCode = firstBtn.getAttribute("data-lang-code");
var firstWrapper = inputsRoot.querySelector('[data-input-wrapper][data-lang-code="' + firstCode + '"]');
if (firstWrapper) {
firstBtn.classList.add("is-active");
firstWrapper.classList.remove("hidden");
}
}
var bar = root.querySelector('[data-lang-bar]');
if (bar) {
withValue.concat(withoutValue).forEach(function (btn) {
bar.appendChild(btn);
});
}
buttons.forEach(function (btn) {
btn.addEventListener("click", function () {
var code = btn.getAttribute("data-lang-code");
var wrapper = inputsRoot.querySelector('[data-input-wrapper][data-lang-code="' + code + '"]');
if (!wrapper) return;
var isActive = btn.classList.contains("is-active");
buttons.forEach(function (b) { b.classList.remove("is-active"); });
inputsRoot.querySelectorAll('[data-input-wrapper]').forEach(function (w) { w.classList.add("hidden"); });
if (!isActive) {
btn.classList.add("is-active");
wrapper.classList.remove("hidden");
var input = wrapper.querySelector('input, textarea');
if (input) { setTimeout(function(){ input.focus(); }, 50); }
var hidden = root.querySelector('input[type="hidden"][name="' + fieldName + '"]');
if (hidden) {
var result = [];
inputsRoot.querySelectorAll('[data-input-wrapper]').forEach(function (w) {
var c = w.getAttribute('data-lang-code');
var inp = w.querySelector('input, textarea');
if (inp && inp.value && inp.value.trim() !== '') { result.push({ language_code: c, title: inp.value }); }
});
try { hidden.value = JSON.stringify(result); } catch (e) {}
}
}
});
});
var hidden = root.querySelector('input[type="hidden"][name="' + fieldName + '"]');
if (hidden) {
inputsRoot.querySelectorAll('input, textarea').forEach(function (inp) {
inp.addEventListener('input', function () {
var result = [];
inputsRoot.querySelectorAll('[data-input-wrapper]').forEach(function (w) {
var c = w.getAttribute('data-lang-code');
var i = w.querySelector('input, textarea');
if (i && i.value && i.value.trim() !== '') {
result.push({ language_code: c, title: i.value });
var btn = root.querySelector('.lang-btn[data-lang-code="' + c + '"]');
if (btn) btn.classList.add('has-value');
} else {
var btn2 = root.querySelector('.lang-btn[data-lang-code="' + c + '"]');
if (btn2) btn2.classList.remove('has-value');
}
});
try { hidden.value = JSON.stringify(result); } catch (e) {}
});
});
}
}
document.addEventListener("DOMContentLoaded", function () {
document.querySelectorAll('[data-multilang-json]').forEach(init);
});
document.addEventListener("formset:added", function (event) {
var newFormset = event.detail.formsetRow;
if (newFormset) {
newFormset.querySelectorAll('[data-multilang-json]').forEach(init);
}
});
})();
</script>