ranking / layouts /task_layout.html
davidjurgens's picture
Deploy Potato demo: Potato — Ranking
210f44b verified
Raw
History Blame Contribute Delete
7.84 kB
<!-- CONFIG_HASH: 6040918e61da2c3bd676690bf814c65e_23f28b3de898677df10a542c3e7b9a3b -->
<!-- Generated annotation layout file -->
<!-- This file was automatically generated based on the annotation schemes in your config -->
<!-- You can customize this file to modify the layout of your annotation interface -->
<!-- Changes to this file will be preserved across server restarts -->
<div class="annotation_schema">
<form id="response_quality" class="annotation-form ranking shadcn-ranking-container"
data-annotation-id="0"
data-annotation-type="ranking"
data-schema-name="response_quality"
data-grid-columns="1">
<fieldset schema="response_quality">
<legend class="shadcn-ranking-title">Rank the responses from best (1st) to worst (last) based on helpfulness and accuracy</legend>
<p class="schema-help-text">Drag to reorder, or use the arrow buttons</p>
<input type="hidden"
class="annotation-input ranking-order-input"
id="response_quality_rank_order_hidden"
name="response_quality:::rank_order"
schema="response_quality"
label_name="rank_order"
validation=""
value="Response A,Response B,Response C,Response D"
data-modified="true">
<div class="ranking-list" id="ranking-list-response_quality" data-schema="response_quality">
<div class="ranking-item" draggable="true" data-value="Response A" >
<span class="ranking-handle">&#9776;</span>
<span class="ranking-rank">1</span>
<span class="ranking-label">Response A</span>
<div class="ranking-buttons">
<button type="button" class="ranking-up" title="Move up" aria-label="Move up">&#9650;</button>
<button type="button" class="ranking-down" title="Move down" aria-label="Move down">&#9660;</button>
</div>
</div>
<div class="ranking-item" draggable="true" data-value="Response B" >
<span class="ranking-handle">&#9776;</span>
<span class="ranking-rank">2</span>
<span class="ranking-label">Response B</span>
<div class="ranking-buttons">
<button type="button" class="ranking-up" title="Move up" aria-label="Move up">&#9650;</button>
<button type="button" class="ranking-down" title="Move down" aria-label="Move down">&#9660;</button>
</div>
</div>
<div class="ranking-item" draggable="true" data-value="Response C" >
<span class="ranking-handle">&#9776;</span>
<span class="ranking-rank">3</span>
<span class="ranking-label">Response C</span>
<div class="ranking-buttons">
<button type="button" class="ranking-up" title="Move up" aria-label="Move up">&#9650;</button>
<button type="button" class="ranking-down" title="Move down" aria-label="Move down">&#9660;</button>
</div>
</div>
<div class="ranking-item" draggable="true" data-value="Response D" >
<span class="ranking-handle">&#9776;</span>
<span class="ranking-rank">4</span>
<span class="ranking-label">Response D</span>
<div class="ranking-buttons">
<button type="button" class="ranking-up" title="Move up" aria-label="Move up">&#9650;</button>
<button type="button" class="ranking-down" title="Move down" aria-label="Move down">&#9660;</button>
</div>
</div>
</div>
</fieldset>
</form>
<script>
(function() {
const schema = "response_quality";
const list = document.getElementById('ranking-list-' + schema);
const hiddenInput = list.parentElement.querySelector('.ranking-order-input');
function updateOrder() {
const items = list.querySelectorAll('.ranking-item');
const order = [];
items.forEach((item, idx) => {
item.querySelector('.ranking-rank').textContent = idx + 1;
order.push(item.getAttribute('data-value'));
});
hiddenInput.value = order.join(',');
hiddenInput.setAttribute('data-modified', 'true');
hiddenInput.dispatchEvent(new Event('change', { bubbles: true }));
}
// Drag and drop
let draggedItem = null;
list.addEventListener('dragstart', function(e) {
draggedItem = e.target.closest('.ranking-item');
if (draggedItem) {
draggedItem.classList.add('dragging');
e.dataTransfer.effectAllowed = 'move';
}
});
list.addEventListener('dragend', function(e) {
if (draggedItem) {
draggedItem.classList.remove('dragging');
draggedItem = null;
}
list.querySelectorAll('.ranking-item').forEach(item => {
item.classList.remove('drag-over');
});
});
list.addEventListener('dragover', function(e) {
e.preventDefault();
e.dataTransfer.dropEffect = 'move';
const target = e.target.closest('.ranking-item');
if (target && target !== draggedItem) {
const rect = target.getBoundingClientRect();
const midY = rect.top + rect.height / 2;
list.querySelectorAll('.ranking-item').forEach(item => item.classList.remove('drag-over'));
target.classList.add('drag-over');
if (e.clientY < midY) {
list.insertBefore(draggedItem, target);
} else {
list.insertBefore(draggedItem, target.nextSibling);
}
}
});
list.addEventListener('drop', function(e) {
e.preventDefault();
updateOrder();
});
// Button controls
list.addEventListener('click', function(e) {
const btn = e.target.closest('.ranking-up, .ranking-down');
if (!btn) return;
e.preventDefault();
const item = btn.closest('.ranking-item');
if (btn.classList.contains('ranking-up') && item.previousElementSibling) {
list.insertBefore(item, item.previousElementSibling);
updateOrder();
} else if (btn.classList.contains('ranking-down') && item.nextElementSibling) {
list.insertBefore(item.nextElementSibling, item);
updateOrder();
}
});
// Keyboard controls
list.addEventListener('keydown', function(e) {
if (e.key !== 'ArrowUp' && e.key !== 'ArrowDown') return;
const item = document.activeElement.closest('.ranking-item');
if (!item) return;
e.preventDefault();
if (e.key === 'ArrowUp' && item.previousElementSibling) {
list.insertBefore(item, item.previousElementSibling);
updateOrder();
item.focus();
} else if (e.key === 'ArrowDown' && item.nextElementSibling) {
list.insertBefore(item.nextElementSibling, item);
updateOrder();
item.focus();
}
});
updateOrder();
})();
</script>
</div>