remaking relative rank
This commit is contained in:
83
DragDropExample.html
Normal file
83
DragDropExample.html
Normal file
@@ -0,0 +1,83 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en"><head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
||||
<title>Using Drag and Drop API to copy and move elements</title>
|
||||
<!--
|
||||
This example demonstrates using various HTML Drag and Drop interfaces including:
|
||||
* Global "draggable" attribute
|
||||
* Event handlers for dragstart, dragover and drop
|
||||
* Global event handlers for ondragstart, ondragover and ondrop
|
||||
* Using the DataTransfer interface to copy and move elements (<div>)
|
||||
-->
|
||||
<style>
|
||||
div {
|
||||
margin: 0em;
|
||||
padding: 2em;
|
||||
}
|
||||
#src_copy, #src_move {
|
||||
color: blue;
|
||||
border: 5px solid black;
|
||||
max-width: 300px;
|
||||
width: fit-content;
|
||||
height: 50px;
|
||||
}
|
||||
#dest_copy, #dest_move {
|
||||
border: 5px solid blue;
|
||||
width: 300px;
|
||||
min-height: 50px;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
function dragstart_handler(ev) {
|
||||
console.log("dragStart");
|
||||
// Change the source element's background color to signify drag has started
|
||||
ev.currentTarget.style.border = "dashed";
|
||||
// Add the id of the drag source element to the drag data payload so
|
||||
// it is available when the drop event is fired
|
||||
ev.dataTransfer.setData("text", ev.target.id);
|
||||
// Tell the browser both copy and move are possible
|
||||
ev.effectAllowed = "copyMove";
|
||||
}
|
||||
function dragover_handler(ev) {
|
||||
console.log("dragOver");
|
||||
// Change the target element's border to signify a drag over event
|
||||
// has occurred
|
||||
ev.currentTarget.style.background = "lightblue";
|
||||
ev.preventDefault();
|
||||
}
|
||||
function drop_handler(ev) {
|
||||
console.log("Drop");
|
||||
ev.preventDefault();
|
||||
// Get the id of drag source element (that was added to the drag data
|
||||
// payload by the dragstart event handler)
|
||||
var id = ev.dataTransfer.getData("text");
|
||||
// Only Move the element if the source and destination ids are both "move"
|
||||
if (id == "src_move" && ev.target.id == "dest_move")
|
||||
ev.target.appendChild(document.getElementById(id));
|
||||
// Copy the element if the source and destination ids are both "copy"
|
||||
if (id == "src_copy" && ev.target.id == "dest_copy") {
|
||||
var nodeCopy = document.getElementById(id).cloneNode(true);
|
||||
nodeCopy.id = "newId";
|
||||
ev.target.appendChild(nodeCopy);
|
||||
}
|
||||
}
|
||||
function dragend_handler(ev) {
|
||||
console.log("dragEnd");
|
||||
// Restore source's border
|
||||
ev.target.style.border = "solid black";
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Drag and Drop: Copy and Move elements with <code>DataTransfer</code></h1>
|
||||
<div draggable="true" id="src_copy" ondragstart="dragstart_handler(event);" ondragend="dragend_handler(event);">
|
||||
Select this element and drag to the <strong>Copy Drop Zone</strong>.
|
||||
</div>
|
||||
<div id="dest_copy" ondrop="drop_handler(event);" ondragover="dragover_handler(event);"><strong>Copy Drop Zone</strong></div>
|
||||
<div draggable="true" id="src_move" ondragstart="dragstart_handler(event);" ondragend="dragend_handler(event);">
|
||||
Select this element and drag to the <strong>Move Drop Zone</strong>.
|
||||
</div>
|
||||
<div id="dest_move" ondrop="drop_handler(event);" ondragover="dragover_handler(event);"><strong>Move Drop Zone</strong></div>
|
||||
|
||||
|
||||
</body></html>
|
||||
4
app.py
4
app.py
@@ -23,6 +23,10 @@ def home():
|
||||
username = "Test_Username"
|
||||
return render_template('home.html', items=items, testList=testList, username=username)
|
||||
|
||||
@app.route('/relative-rank-ai')
|
||||
def rank_ai():
|
||||
return render_template('relative_rank_ai.html')
|
||||
|
||||
@app.route('/relative-rank')
|
||||
def rank():
|
||||
return render_template('relative_rank.html')
|
||||
|
||||
13
static/css/relative_rank.css
Normal file
13
static/css/relative_rank.css
Normal file
@@ -0,0 +1,13 @@
|
||||
.item {
|
||||
border: 1px solid black;
|
||||
width: fit-content;
|
||||
list-style: none;
|
||||
padding: 5px;
|
||||
margin: 5px 0;
|
||||
}
|
||||
|
||||
.flex-container {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-around;
|
||||
}
|
||||
BIN
static/favicon.ico
Normal file
BIN
static/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.2 MiB |
@@ -1,97 +1,41 @@
|
||||
// Make items draggable
|
||||
const itemsPool = document.getElementById("items-pool");
|
||||
const rankingArea = document.getElementById("ranking-area");
|
||||
const ranksPool = document.getElementById("ranks");
|
||||
const addItemBtn = document.getElementById("add-item-btn");
|
||||
const addRankBtn = document.getElementById("add-rank-btn");
|
||||
// Enable drag-and-drop between the pool and ranking area
|
||||
const sortablePool = new Sortable(itemsPool, {
|
||||
group: {
|
||||
name: "shared", // Group name must match between lists
|
||||
pull: true, // Allow items to be dragged out
|
||||
put: true, // Allow items to be dropped in
|
||||
},
|
||||
animation: 150,
|
||||
});
|
||||
|
||||
const sortableRanking = new Sortable(rankingArea, {
|
||||
group: {
|
||||
name: "shared", // Same group name as itemsPool
|
||||
pull: true, // Allow items to be dragged out
|
||||
put: true, // Allow items to be dropped in
|
||||
},
|
||||
animation: 150,
|
||||
});
|
||||
|
||||
// Add new item functionality
|
||||
addItemBtn.addEventListener("click", () => {
|
||||
const newItemText = prompt("Enter new item name:");
|
||||
if (newItemText) {
|
||||
const li = document.createElement("li");
|
||||
li.className = "list-group-item";
|
||||
li.textContent = newItemText;
|
||||
li.draggable = true;
|
||||
itemsPool.appendChild(li);
|
||||
function dragstart_handler(ev) {
|
||||
console.log("dragStart");
|
||||
// Change the source element's background color to signify drag has started
|
||||
//ev.currentTarget.style.border = "dashed";
|
||||
// Add the id of the drag source element to the drag data payload so
|
||||
// it is available when the drop event is fired
|
||||
ev.dataTransfer.setData("text", ev.target.id);
|
||||
// Tell the browser both copy and move are possible
|
||||
ev.effectAllowed = "copyMove";
|
||||
}
|
||||
function dragover_handler(ev) {
|
||||
//console.log("dragOver");
|
||||
// Change the target element's border to signify a drag over event
|
||||
// has occurred
|
||||
ev.currentTarget.style.background = "lightblue";
|
||||
ev.preventDefault();
|
||||
}
|
||||
function drop_handler(ev) {
|
||||
//console.log("Drop");
|
||||
ev.preventDefault();
|
||||
// Get the id of drag source element (that was added to the drag data
|
||||
// payload by the dragstart event handler)
|
||||
var id = ev.dataTransfer.getData("text");
|
||||
// Only Move the element if the source and destination ids are both "move"
|
||||
if (id == "src_move" && ev.target.id == "drop-target"){
|
||||
ev.target.appendChild(document.getElementById(id));
|
||||
ev.target.style.background = "white";
|
||||
}
|
||||
});
|
||||
|
||||
// Add new item functionality
|
||||
addRankBtn.addEventListener("click", () => {
|
||||
const newItemText = prompt("Enter new rank name:");
|
||||
if (newItemText) {
|
||||
const li = document.createElement("li");
|
||||
li.className = "mb-2";
|
||||
label = document.createElement('label');
|
||||
label.innerHTML = newItemText;
|
||||
input = document.createElement('input');
|
||||
input.setAttribute("type", "number");
|
||||
input.setAttribute("class", "form-control");
|
||||
input.setAttribute("placeholder", "Enter last rank for " + newItemText);
|
||||
li.appendChild(label)
|
||||
li.appendChild(input);
|
||||
//li.draggable = true;
|
||||
ranksPool.appendChild(li);
|
||||
// Copy the element if the source and destination ids are both "copy"
|
||||
if (id == "src_copy" && ev.target.id == "dest_copy") {
|
||||
var nodeCopy = document.getElementById(id).cloneNode(true);
|
||||
nodeCopy.id = "newId";
|
||||
ev.target.appendChild(nodeCopy);
|
||||
}
|
||||
});
|
||||
|
||||
// Save rankings and tier ranges
|
||||
document.getElementById("save-btn").addEventListener("click", () => {
|
||||
// Get ranked items
|
||||
const rankedItems = Array.from(rankingArea.children).map((item) => item.textContent.trim());
|
||||
const sTierEnd = parseInt(document.getElementById("s-tier-end").value || "0");
|
||||
const aTierEnd = parseInt(document.getElementById("a-tier-end").value || "0");
|
||||
|
||||
// Tier categories
|
||||
const tiers = {
|
||||
"S-Tier": rankedItems.slice(0, sTierEnd),
|
||||
"A-Tier": rankedItems.slice(sTierEnd, aTierEnd),
|
||||
"Other": rankedItems.slice(aTierEnd),
|
||||
};
|
||||
|
||||
// Apply colors to items based on tiers
|
||||
Array.from(rankingArea.children).forEach((item, index) => {
|
||||
item.classList.remove("s-tier", "a-tier", "other-tier"); // Remove existing classes
|
||||
if (index < sTierEnd) {
|
||||
item.classList.add("s-tier");
|
||||
} else if (index < aTierEnd) {
|
||||
item.classList.add("a-tier");
|
||||
} else {
|
||||
item.classList.add("other-tier");
|
||||
}
|
||||
});
|
||||
|
||||
// Disable dragging
|
||||
sortableRanking.option("disabled", true); // Disable drag-and-drop for ranking area
|
||||
sortablePool.option("disabled", true); // Optionally disable pool area too
|
||||
|
||||
// Send rankings to the server
|
||||
fetch("/save-rankings", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({ rankedItems, tiers }),
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.catch((error) => console.error("Error:", error));
|
||||
});
|
||||
}
|
||||
function dragend_handler(ev) {
|
||||
//console.log("dragEnd");
|
||||
// Restore source's border
|
||||
//ev.target.style.border = "solid black";
|
||||
ev.target.style.background = "white";
|
||||
}
|
||||
97
static/js/ranking_ai.js
Normal file
97
static/js/ranking_ai.js
Normal file
@@ -0,0 +1,97 @@
|
||||
// Make items draggable
|
||||
const itemsPool = document.getElementById("items-pool");
|
||||
const rankingArea = document.getElementById("ranking-area");
|
||||
const ranksPool = document.getElementById("ranks");
|
||||
const addItemBtn = document.getElementById("add-item-btn");
|
||||
const addRankBtn = document.getElementById("add-rank-btn");
|
||||
// Enable drag-and-drop between the pool and ranking area
|
||||
const sortablePool = new Sortable(itemsPool, {
|
||||
group: {
|
||||
name: "shared", // Group name must match between lists
|
||||
pull: true, // Allow items to be dragged out
|
||||
put: true, // Allow items to be dropped in
|
||||
},
|
||||
animation: 150,
|
||||
});
|
||||
|
||||
const sortableRanking = new Sortable(rankingArea, {
|
||||
group: {
|
||||
name: "shared", // Same group name as itemsPool
|
||||
pull: true, // Allow items to be dragged out
|
||||
put: true, // Allow items to be dropped in
|
||||
},
|
||||
animation: 150,
|
||||
});
|
||||
|
||||
// Add new item functionality
|
||||
addItemBtn.addEventListener("click", () => {
|
||||
const newItemText = prompt("Enter new item name:");
|
||||
if (newItemText) {
|
||||
const li = document.createElement("li");
|
||||
li.className = "list-group-item";
|
||||
li.textContent = newItemText;
|
||||
li.draggable = true;
|
||||
itemsPool.appendChild(li);
|
||||
}
|
||||
});
|
||||
|
||||
// Add new item functionality
|
||||
addRankBtn.addEventListener("click", () => {
|
||||
const newItemText = prompt("Enter new rank name:");
|
||||
if (newItemText) {
|
||||
const li = document.createElement("li");
|
||||
li.className = "mb-2";
|
||||
label = document.createElement('label');
|
||||
label.innerHTML = newItemText;
|
||||
input = document.createElement('input');
|
||||
input.setAttribute("type", "number");
|
||||
input.setAttribute("class", "form-control");
|
||||
input.setAttribute("placeholder", "Enter last rank for " + newItemText);
|
||||
li.appendChild(label)
|
||||
li.appendChild(input);
|
||||
//li.draggable = true;
|
||||
ranksPool.appendChild(li);
|
||||
}
|
||||
});
|
||||
|
||||
// Save rankings and tier ranges
|
||||
document.getElementById("save-btn").addEventListener("click", () => {
|
||||
// Get ranked items
|
||||
const rankedItems = Array.from(rankingArea.children).map((item) => item.textContent.trim());
|
||||
const sTierEnd = parseInt(document.getElementById("s-tier-end").value || "0");
|
||||
const aTierEnd = parseInt(document.getElementById("a-tier-end").value || "0");
|
||||
|
||||
// Tier categories
|
||||
const tiers = {
|
||||
"S-Tier": rankedItems.slice(0, sTierEnd),
|
||||
"A-Tier": rankedItems.slice(sTierEnd, aTierEnd),
|
||||
"Other": rankedItems.slice(aTierEnd),
|
||||
};
|
||||
|
||||
// Apply colors to items based on tiers
|
||||
Array.from(rankingArea.children).forEach((item, index) => {
|
||||
item.classList.remove("s-tier", "a-tier", "other-tier"); // Remove existing classes
|
||||
if (index < sTierEnd) {
|
||||
item.classList.add("s-tier");
|
||||
} else if (index < aTierEnd) {
|
||||
item.classList.add("a-tier");
|
||||
} else {
|
||||
item.classList.add("other-tier");
|
||||
}
|
||||
});
|
||||
|
||||
// Disable dragging
|
||||
sortableRanking.option("disabled", true); // Disable drag-and-drop for ranking area
|
||||
sortablePool.option("disabled", true); // Optionally disable pool area too
|
||||
|
||||
// Send rankings to the server
|
||||
fetch("/save-rankings", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({ rankedItems, tiers }),
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.catch((error) => console.error("Error:", error));
|
||||
});
|
||||
@@ -8,7 +8,7 @@
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/styles.css') }}">
|
||||
<script src="https://cdn.jsdelivr.net/npm/sortablejs@latest/Sortable.min.js"></script>
|
||||
|
||||
<link rel="shortcut icon" href="{{ url_for('static', filename='favicon.ico') }}">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
@@ -19,6 +19,7 @@
|
||||
<li class="nav"><a href="{{ url_for('add_item') }}">Add Item</a></li>
|
||||
<li class="nav"><a href="{{ url_for('get_weather') }}">Weather</a></li>
|
||||
<li class="nav"><a href="{{ url_for('rank') }}">Relative Rank</a></li>
|
||||
<li class="nav"><a href="{{ url_for('rank_ai') }}">Relative Rank AI</a></li>
|
||||
<li class="nav"><a href="{{ url_for('motion') }}">Motion Graphics</a></li>
|
||||
<li class="nav"><a href="{{ url_for('vocabulary') }}">Vocabulary</a></li>
|
||||
<li class="nav"><a href="{{ url_for('short_stories') }}">Short Stories</a></li>
|
||||
|
||||
@@ -1,46 +1,20 @@
|
||||
{%extends "base.html"%}
|
||||
{% extends "base.html" %}
|
||||
|
||||
{%block content%}
|
||||
<h1>Relative Ranking</h1>
|
||||
|
||||
<div class="row">
|
||||
<!-- Items to rank -->
|
||||
<div class="col-md-4">
|
||||
<h4>Items Pool</h4>
|
||||
<ul id="items-pool" class="list-group">
|
||||
<li class="list-group-item" draggable="true">Item A</li>
|
||||
<li class="list-group-item" draggable="true">Item B</li>
|
||||
<li class="list-group-item" draggable="true">Item C</li>
|
||||
{% block content %}
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/relative_rank.css') }}">
|
||||
<div class="flex-container">
|
||||
<div class="unranked-items">
|
||||
Unranked Items
|
||||
<ul>
|
||||
<li draggable="true" id="src_move" class="item" ondragstart="dragstart_handler(event);" ondragend="dragend_handler(event);">Item A</li>
|
||||
<li draggable="true" id="src_move" class="item" ondragstart="dragstart_handler(event);" ondragend="dragend_handler(event);">Item B</li>
|
||||
</ul>
|
||||
<button class="btn btn-primary mt-2" id="add-item-btn">Add Item</button>
|
||||
</div>
|
||||
|
||||
<!-- Ranking area -->
|
||||
<div class="col-md-4">
|
||||
<h4>Ranking Area</h4>
|
||||
<ul id="ranking-area" class="list-group border"></ul>
|
||||
</div>
|
||||
|
||||
<!-- Tier settings -->
|
||||
<div class="col-md-4">
|
||||
<h4>Tier Settings</h4>
|
||||
<div id="tiers">
|
||||
<ul id="ranks">
|
||||
<li class="mb-2">
|
||||
<label>S-Tier Range:</label>
|
||||
<input type="number" id="s-tier-end" class="form-control" placeholder="Enter last rank for S-Tier">
|
||||
</li>
|
||||
<li class="mb-2">
|
||||
<label>A-Tier Range:</label>
|
||||
<input type="number" id="a-tier-end" class="form-control" placeholder="Enter last rank for A-Tier">
|
||||
</li>
|
||||
</ul>
|
||||
<!-- Add more tiers as needed -->
|
||||
</div>
|
||||
<button class="btn btn-success mt-2" id="add-rank-btn">New Ranking</button>
|
||||
<button class="btn btn-success mt-2" id="save-btn">Save Rankings</button>
|
||||
<div id="drop-target" class="ranked-items" ondrop="drop_handler(event);" ondragover="dragover_handler(event);">
|
||||
Ranked Items
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="{{ url_for('static', filename='js/ranking.js') }}"></script>
|
||||
{%endblock%}
|
||||
{% endblock %}
|
||||
46
templates/relative_rank_ai.html
Normal file
46
templates/relative_rank_ai.html
Normal file
@@ -0,0 +1,46 @@
|
||||
{%extends "base.html"%}
|
||||
|
||||
{%block content%}
|
||||
<h1>Relative Ranking</h1>
|
||||
|
||||
<div class="row">
|
||||
<!-- Items to rank -->
|
||||
<div class="col-md-4">
|
||||
<h4>Items Pool</h4>
|
||||
<ul id="items-pool" class="list-group">
|
||||
<li class="list-group-item" draggable="true">Item A</li>
|
||||
<li class="list-group-item" draggable="true">Item B</li>
|
||||
<li class="list-group-item" draggable="true">Item C</li>
|
||||
</ul>
|
||||
<button class="btn btn-primary mt-2" id="add-item-btn">Add Item</button>
|
||||
</div>
|
||||
|
||||
<!-- Ranking area -->
|
||||
<div class="col-md-4">
|
||||
<h4>Ranking Area</h4>
|
||||
<ul id="ranking-area" class="list-group border"></ul>
|
||||
</div>
|
||||
|
||||
<!-- Tier settings -->
|
||||
<div class="col-md-4">
|
||||
<h4>Tier Settings</h4>
|
||||
<div id="tiers">
|
||||
<ul id="ranks">
|
||||
<li class="mb-2">
|
||||
<label>S-Tier Range:</label>
|
||||
<input type="number" id="s-tier-end" class="form-control" placeholder="Enter last rank for S-Tier">
|
||||
</li>
|
||||
<li class="mb-2">
|
||||
<label>A-Tier Range:</label>
|
||||
<input type="number" id="a-tier-end" class="form-control" placeholder="Enter last rank for A-Tier">
|
||||
</li>
|
||||
</ul>
|
||||
<!-- Add more tiers as needed -->
|
||||
</div>
|
||||
<button class="btn btn-success mt-2" id="add-rank-btn">New Ranking</button>
|
||||
<button class="btn btn-success mt-2" id="save-btn">Save Rankings</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="{{ url_for('static', filename='js/ranking.js') }}"></script>
|
||||
{%endblock%}
|
||||
Reference in New Issue
Block a user