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"]]
|
||||
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"]]
|
||||
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)})
|
||||
return result
|
||||
|
||||
@@ -691,8 +691,31 @@
|
||||
</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>
|
||||
{% 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' %}
|
||||
<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' %}
|
||||
<div class="control"><input class="input" type="color" name="ctrl_{{ c.key }}" value="{{ c.value or c.default }}"></div>
|
||||
{% elif c.type == 'slider' %}
|
||||
@@ -1389,6 +1412,29 @@ function debouncedSubmitPropsForm() {
|
||||
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() {
|
||||
var form = document.getElementById('propsForm');
|
||||
autosaveIndicator = document.getElementById('autosaveStatus');
|
||||
|
||||
Reference in New Issue
Block a user