Ajoute un sélecteur de champ pour insérer {{champ}} dans le Contenu
Une fois "Lier à un objet de données" réglé (widget Texte/Titre...),
propose maintenant les champs de CET objet en liste déroulante juste sous
le champ "Contenu", avec un bouton "+ Ajouter" qui insère "{{nom_du_champ}}"
à l'emplacement du curseur - plutôt que d'avoir à taper cette syntaxe à
la main sans savoir quels noms de champs existent réellement.
controls_with_values.py pose field_options sur le contrôle "content"
quand _data_definition_id est réglé (réutilise data_binding_options, déjà
calculé pour data_filtre_champ/data_filtre2_champ) ; insertFieldAtCursor()
(screen_edit.html) fait l'insertion via selectionStart/selectionEnd puis
déclenche un événement "input" pour que l'enregistrement automatique se
déclenche normalement, comme une saisie manuelle.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
baa3da1035
commit
7e80ff952a
@@ -67,5 +67,12 @@ def controls_with_values(slug, el):
|
|||||||
control["options"] = [("", "(sélectionner un objet d'abord)")] + [(f["name"], _field_label(f)) for f in jauge_options["fields"]]
|
control["options"] = [("", "(sélectionner un objet d'abord)")] + [(f["name"], _field_label(f)) for f in jauge_options["fields"]]
|
||||||
if control["key"] in ("data_filtre_champ", "data_filtre2_champ"):
|
if control["key"] in ("data_filtre_champ", "data_filtre2_champ"):
|
||||||
control["options"] = [("", "(sélectionner un objet d'abord)")] + [(f["name"], _field_label(f)) for f in data_binding_options["fields"]]
|
control["options"] = [("", "(sélectionner un objet d'abord)")] + [(f["name"], _field_label(f)) for f in data_binding_options["fields"]]
|
||||||
|
if control["key"] == "content" and attributes.get("_data_definition_id"):
|
||||||
|
# Une fois "Lier à un objet de données" réglé (voir
|
||||||
|
# DATA_BINDING_CONTROLS), propose les champs de CET objet en
|
||||||
|
# liste déroulante à côté du texte — plutôt que de devoir taper
|
||||||
|
# "{{nom_du_champ}}" à la main sans savoir quels noms existent
|
||||||
|
# (voir insertFieldAtCursor() dans screen_edit.html).
|
||||||
|
control["field_options"] = [(f["name"], _field_label(f)) for f in data_binding_options["fields"]]
|
||||||
result.append({**control, "value": _control_value(el, control)})
|
result.append({**control, "value": _control_value(el, control)})
|
||||||
return result
|
return result
|
||||||
|
|||||||
@@ -691,8 +691,31 @@
|
|||||||
</div>
|
</div>
|
||||||
<p class="help">Colle une adresse (URL) ci-dessus, ou choisis un fichier sur ton ordinateur — il sera hébergé automatiquement avec ce jeu.</p>
|
<p class="help">Colle une adresse (URL) ci-dessus, ou choisis un fichier sur ton ordinateur — il sera hébergé automatiquement avec ce jeu.</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% if c.field_options %}
|
||||||
|
<div class="control fieldRow" style="margin-top:6px;">
|
||||||
|
<div class="select is-small is-expanded"><select id="fieldPicker-{{ c.key }}">
|
||||||
|
<option value="">— champ de l'objet lié —</option>
|
||||||
|
{% for fname, flabel in c.field_options %}
|
||||||
|
<option value="{{ fname }}">{{ flabel }}</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select></div>
|
||||||
|
<button type="button" class="button is-small" onclick="insertFieldAtCursor('field-{{ c.key }}', 'fieldPicker-{{ c.key }}')">+ Ajouter</button>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
{% elif c.type == 'textarea' %}
|
{% elif c.type == 'textarea' %}
|
||||||
<div class="control"><textarea class="textarea" name="ctrl_{{ c.key }}" rows="4" placeholder="{{ c.placeholder or '' }}">{{ c.value }}</textarea></div>
|
<div class="control"><textarea class="textarea" name="ctrl_{{ c.key }}" id="field-{{ c.key }}" rows="4" placeholder="{{ c.placeholder or '' }}">{{ c.value }}</textarea></div>
|
||||||
|
{% if c.field_options %}
|
||||||
|
<div class="control fieldRow" style="margin-top:6px;">
|
||||||
|
<div class="select is-small is-expanded"><select id="fieldPicker-{{ c.key }}">
|
||||||
|
<option value="">— champ de l'objet lié —</option>
|
||||||
|
{% for fname, flabel in c.field_options %}
|
||||||
|
<option value="{{ fname }}">{{ flabel }}</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select></div>
|
||||||
|
<button type="button" class="button is-small" onclick="insertFieldAtCursor('field-{{ c.key }}', 'fieldPicker-{{ c.key }}')">+ Ajouter</button>
|
||||||
|
</div>
|
||||||
|
<p class="help">Insère "{{champ}}" à l'emplacement du curseur — affichera la valeur de ce champ, sur la ligne trouvée par "Donnée liée" ci-dessous.</p>
|
||||||
|
{% endif %}
|
||||||
{% elif c.type == 'color' %}
|
{% elif c.type == 'color' %}
|
||||||
<div class="control"><input class="input" type="color" name="ctrl_{{ c.key }}" value="{{ c.value or c.default }}"></div>
|
<div class="control"><input class="input" type="color" name="ctrl_{{ c.key }}" value="{{ c.value or c.default }}"></div>
|
||||||
{% elif c.type == 'slider' %}
|
{% elif c.type == 'slider' %}
|
||||||
@@ -1389,6 +1412,29 @@ function debouncedSubmitPropsForm() {
|
|||||||
autosaveTimer = setTimeout(submitPropsForm, 500);
|
autosaveTimer = setTimeout(submitPropsForm, 500);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Insère "{{champ}}" à l'emplacement du curseur dans le champ "Contenu"
|
||||||
|
// (voir controls_with_values.py, control["field_options"] posé une fois
|
||||||
|
// "Lier à un objet de données" réglé) — évite d'avoir à taper la syntaxe
|
||||||
|
// à la main sans savoir quels noms de champs existent. OPEN/CLOSE en deux
|
||||||
|
// morceaux : Jinja interpréterait "{{"/"}}" littéralement adjacents dans
|
||||||
|
// le SOURCE de ce template comme le début d'une expression s'il les
|
||||||
|
// rencontrait tels quels (même à l'intérieur d'un <script>), voir la même
|
||||||
|
// astuce pour _FILTER_REF_OPEN/_FILTER_REF_CLOSE plus bas.
|
||||||
|
function insertFieldAtCursor(fieldId, pickerId) {
|
||||||
|
var field = document.getElementById(fieldId);
|
||||||
|
var picker = document.getElementById(pickerId);
|
||||||
|
if (!field || !picker || !picker.value) return;
|
||||||
|
var open = '{' + '{', close = '}' + '}';
|
||||||
|
var text = open + picker.value + close;
|
||||||
|
var start = field.selectionStart || 0, end = field.selectionEnd || 0;
|
||||||
|
field.value = field.value.substring(0, start) + text + field.value.substring(end);
|
||||||
|
var newPos = start + text.length;
|
||||||
|
field.focus();
|
||||||
|
field.setSelectionRange(newPos, newPos);
|
||||||
|
field.dispatchEvent(new Event('input', { bubbles: true }));
|
||||||
|
picker.value = '';
|
||||||
|
}
|
||||||
|
|
||||||
function bindPropsAutosave() {
|
function bindPropsAutosave() {
|
||||||
var form = document.getElementById('propsForm');
|
var form = document.getElementById('propsForm');
|
||||||
autosaveIndicator = document.getElementById('autosaveStatus');
|
autosaveIndicator = document.getElementById('autosaveStatus');
|
||||||
|
|||||||
Reference in New Issue
Block a user