Made presets cards full height, improved screen reader navigation, added input focus on add attribute and add preset

This commit is contained in:
2025-11-24 15:40:52 +01:00
parent ff3baf37db
commit 72f0116cab

View File

@@ -92,28 +92,39 @@
@foreach (var preset in Model.Presets) @foreach (var preset in Model.Presets)
{ {
<div class="col-md-6"> <div class="col-md-6">
<div class="border rounded p-3 mb-3" data-preset-id="@(preset.Key)"> <div class="border rounded p-3 mb-3 h-100" data-preset-id="@(preset.Key)">
<label class="form-label" for="Presets.@(preset.Key).Key">@T["Preset name"]</label> <label class="form-label" for="Presets.@(preset.Key).Key">@T["Preset name"]</label>
<input class="form-control mb-3" id="Presets.@(preset.Key).Key" name="Presets.@(preset.Key).Key" value="@preset.Key"/> <input class="form-control mb-3" id="Presets.@(preset.Key).Key" name="Presets.@(preset.Key).Key" value="@preset.Key"/>
<label class="form-label">@T["Attributes"]</label> <label class="form-label">@T["Attributes"]</label>
@foreach (var attr in preset.Value.Attribute) <table class="attributes mb-2">
{ <thead>
<div class="row mb-2" data-type="attribute"> <tr>
<div class="col-md-3 mt-2"> <th class="p-1">@T["Name"]</th>
<input class="form-control" <th class="p-1">@T["Value"]</th>
name="Presets.@(preset.Key).Attribute.@(attr.Key).Key" <th class="p-1">@T["Delete attribute"]</th>
value="@attr.Key" placeholder="@T["Name"]" aria-label="@T["Name"]" /> </tr>
</div> </thead>
<div class="col-md-5 mt-2"> <tbody class="attributes">
<input class="form-control" @foreach (var attr in preset.Value.Attribute)
name="Presets.@(preset.Key).Attribute.@(attr.Key).Value" {
value="@attr.Value" placeholder="@T["Value"]" aria-label="@T["Value"]" /> <tr data-type="attribute">
</div> <td class="col-md-3 p-1">
<div class="col-md-4 mt-2"> <input class="form-control"
<button type="button" class="btn btn-danger" data-type="deleteAttribute">@T["Delete attribute"]</button> name="Presets.@(preset.Key).Attribute.@(attr.Key).Key"
</div> value="@attr.Key" placeholder="@T["Name"]" aria-label="@T["Name"]" />
</div> </td>
} <td class="col-md-5 p-1">
<input class="form-control"
name="Presets.@(preset.Key).Attribute.@(attr.Key).Value"
value="@attr.Value" placeholder="@T["Value"]" aria-label="@T["Value"]" />
</td>
<td class="col-md-4 p-1">
<button type="button" class="btn btn-danger" data-type="deleteAttribute">@T["Delete attribute"]</button>
</td>
</tr>
}
</tbody>
</table>
<div class="attributes"></div> <div class="attributes"></div>
<div class="row mb-2"> <div class="row mb-2">
<div class="col-md-8 mt-2"> <div class="col-md-8 mt-2">
@@ -240,25 +251,25 @@
function addAttribute(presetContainer, presetKey) { function addAttribute(presetContainer, presetKey) {
const attributeId = crypto.randomUUID(); const attributeId = crypto.randomUUID();
const row = document.createElement('div'); const row = document.createElement('tr');
row.classList.add('row', 'mb-2'); row.classList.add('row', 'mb-2');
row.innerHTML = ` row.innerHTML = `
<div class="col-md-3"> <td class="col-md-3 p-1">
<input class="form-control" <input class="form-control"
name="Presets.${presetKey}.Attribute.${attributeId}.Key" name="Presets.${presetKey}.Attribute.${attributeId}.Key"
value="" /> value="" />
</div> </td>
<div class="col-md-5"> <td class="col-md-5 p-1">
<input class="form-control" <input class="form-control"
name="Presets.${presetKey}.Attribute.${attributeId}.Value" name="Presets.${presetKey}.Attribute.${attributeId}.Value"
value="" /> value="" />
</div> </td>
<div class="col-md-4"> <td class="col-md-4 p-1">
<button type="button" class="btn btn-danger btn-delete-attr"> <button type="button" class="btn btn-danger btn-delete-attr">
${presetContainer.dataset.deleteAttributeText} ${presetContainer.dataset.deleteAttributeText}
</button> </button>
</div> </td>
`; `;
presetContainer.querySelector('.attributes').appendChild(row); presetContainer.querySelector('.attributes').appendChild(row);
@@ -335,29 +346,32 @@
const attributeId = crypto.randomUUID(); const attributeId = crypto.randomUUID();
const row = document.createElement('div'); const row = document.createElement('tr');
row.classList.add('row', 'mb-2'); row.classList.add('mb-2');
row.setAttribute('data-type', 'attribute'); row.setAttribute('data-type', 'attribute');
row.innerHTML = ` row.innerHTML = `
<div class="col-md-3"> <td class="col-md-3 p-1">
<input class="form-control" <input class="form-control"
name="Presets.${presetKey}.Attribute.${attributeId}.Key" name="Presets.${presetKey}.Attribute.${attributeId}.Key"
value="" /> value="" />
</div> </td>
<div class="col-md-5"> <td class="col-md-5 p-1">
<input class="form-control" <input class="form-control"
name="Presets.${presetKey}.Attribute.${attributeId}.Value" name="Presets.${presetKey}.Attribute.${attributeId}.Value"
value="" /> value="" />
</div> </td>
<div class="col-md-4"> <td class="col-md-4 p-1">
<button type="button" class="btn btn-danger" data-type="deleteAttribute"> <button type="button" class="btn btn-danger" data-type="deleteAttribute">
${presetContainer.dataset.deleteAttributeText || 'Delete attribute'} ${presetContainer.dataset.deleteAttributeText || 'Delete attribute'}
</button> </button>
</div> </td>
`; `;
attributesContainer.appendChild(row); attributesContainer.appendChild(row);
requestAnimationFrame(() => {
row.querySelector(".col-md-3 input").focus();
});
// Delete-Button Eventlistener aktivieren // Delete-Button Eventlistener aktivieren
const deleteButton = row.querySelector('button[data-type="deleteAttribute"]'); const deleteButton = row.querySelector('button[data-type="deleteAttribute"]');
@@ -392,11 +406,20 @@
const presetDiv = document.createElement('div'); const presetDiv = document.createElement('div');
presetDiv.classList.add('col-md-6'); presetDiv.classList.add('col-md-6');
presetDiv.innerHTML = ` presetDiv.innerHTML = `
<div class="border rounded p-3 mb-3" data-preset-id="${presetId}"> <div class="border rounded p-3 mb-3 h-100" data-preset-id="${presetId}">
<label class="form-label" for="Presets.${presetId}.Key">@T["Preset name"]</label> <label class="form-label" for="Presets.${presetId}.Key">@T["Preset name"]</label>
<input class="form-control mb-3" id="Presets.${presetId}.Key" name="Presets.${presetId}.Key" value=""/> <input class="form-control mb-3" id="Presets.${presetId}.Key" name="Presets.${presetId}.Key" value=""/>
<label class="form-label">@T["Attributes"]</label> <label class="form-label">@T["Attributes"]</label>
<div class="attributes"></div> <table class="mb-2">
<thead>
<tr>
<th class="p-1">@T["Name"]</th>
<th class="p-1">@T["Value"]</th>
<th class="p-1">@T["Delete attribute"]</th>
</tr>
</thead>
<tbody class="attributes"></tbody>
</table>
<div class="row mb-4"> <div class="row mb-4">
<div class="col-md-4"> <div class="col-md-4">
<button type="button" class="btn btn-danger" data-type="deletePreset">@T["Delete preset"]</button> <button type="button" class="btn btn-danger" data-type="deletePreset">@T["Delete preset"]</button>
@@ -410,7 +433,9 @@
// Einfach ans Ende der Container-Liste hängen // Einfach ans Ende der Container-Liste hängen
presetsButton.parentElement.parentElement.insertBefore(presetDiv, presetsButton.parentElement); presetsButton.parentElement.parentElement.insertBefore(presetDiv, presetsButton.parentElement);
requestAnimationFrame(() => {
presetDiv.querySelector(".form-control.mb-3").focus();
});
// Eventlistener für den neuen Preset-Block aktivieren // Eventlistener für den neuen Preset-Block aktivieren
const addAttrBtn = presetDiv.querySelector('button[data-type="addAttribute"]'); const addAttrBtn = presetDiv.querySelector('button[data-type="addAttribute"]');
const deletePresetBtn = presetDiv.querySelector('button[data-type="deletePreset"]'); const deletePresetBtn = presetDiv.querySelector('button[data-type="deletePreset"]');