Private
Public Access
1
0

demo of drag/drop and JS to capture the new order

This commit is contained in:
Sander Roosendaal
2022-04-05 12:07:42 +02:00
parent 61884d9a00
commit 5ba43564f8
6 changed files with 153 additions and 2 deletions

View File

@@ -2425,7 +2425,7 @@ class PlannedSessionStep(models.Model):
intensity = models.TextField(default='',max_length=200, blank=True, null=True,
choices=intensitytypes)
notes = models.TextField(default='',max_length=200, blank=True, null=True)
color = models.TextField(default='gray',max_length=200)
color = models.TextField(default='#ddd',max_length=200)
class PlannedSession(models.Model):

View File

@@ -0,0 +1,95 @@
{% extends "newbase.html" %}
{% load static %}
{% load rowerfilters %}
{% block title %}Rowsandall Training Plans{% endblock %}
{% block main %}
<h2>Plan Training Steps</h2>
<div class="stepcontainer" id="list">
{% for step in steps %}
<div draggable="true" class="trainingstep" style="background-color: {{ step.color }}">
<div id="{{ forloop.counter }}" class="stepcontent">
{{ step.name }}
</div>
</div>
{% endfor %}
</div>
{% endblock %}
{% block scripts %}
<script type='text/javascript'
src='https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js'>
</script>
<script>
document.addEventListener('DOMContentLoaded', (event) => {
var list = document.getElementById('list')
function handleDragStart(e) {
this.style.opacity = '0.4';
dragSrcEl = this;
e.dataTransfer.effectAllowed = 'move';
e.dataTransfer.setData('text/html', this.innerHTML);
}
function handleDragEnd(e) {
this.style.opacity = '1';
items.forEach(function (item) {
item.classList.remove('over');
});
}
function handleDragOver(e) {
if (e.preventDefault) {
e.preventDefault();
}
return false;
}
function handleDragEnter(e) {
this.classList.add('over');
}
function handleDragLeave(e) {
this.classList.remove('over');
}
function handleDrop(e) {
e.stopPropagation();
if (dragSrcEl !== this) {
dragSrcEl.innerHTML = this.innerHTML;
this.innerHTML = e.dataTransfer.getData('text/html');
var steps = []
var nl = document.querySelectorAll(".stepcontainer .trainingstep .stepcontent");
nl.forEach((s) => {
console.log(s.id);
steps.push(s.id)
})
console.log(steps);
}
return false;
}
let items = document.querySelectorAll('.stepcontainer .trainingstep');
items.forEach(function(item) {
item.addEventListener('dragstart', handleDragStart);
item.addEventListener('dragover', handleDragOver);
item.addEventListener('dragenter', handleDragEnter);
item.addEventListener('dragleave', handleDragLeave);
item.addEventListener('dragend', handleDragEnd);
item.addEventListener('drop', handleDrop);
});
});
</script>
{% endblock %}
{% block sidebar %}
{% include 'menu_plan.html' %}
{% endblock %}

View File

@@ -875,6 +875,8 @@ urlpatterns = [
views.rower_create_trainingplan, name='rower_create_trainingplan'),
re_path(r'^plans/$', views.rower_select_instantplan,
name='rower_select_instantplan'),
re_path(r'^plans/stepeditor/$',
views.stepeditor, name='stepeditor'),
re_path(r'^plans/(?P<id>[0-9a-fA-F]{8}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{12})/$',
views.rower_view_instantplan, name='rower_view_instantplan'),
re_path(r'^buyplan/(?P<id>\d+)/$', views.buy_trainingplan_view,

View File

@@ -2959,6 +2959,40 @@ def rower_create_trainingplan(request, id=0):
'old_targets': old_targets,
})
@user_passes_test(can_plan, login_url="/rowers/paidplans",
message="This functionality requires a Coach or Self-Coach plan",
redirect_field_name=None)
def stepeditor(request, id=0):
step1 = PlannedSessionStep(
manager = request.user,
name = "Warming Up",
intensity = "Warmup",
durationtype = "Time",
durationvalue = 60000,
)
step2 = PlannedSessionStep(
manager = request.user,
name = "Steady",
intensity = "Active",
durationtype = "Time",
durationvalue = 180000,
)
step3 = PlannedSessionStep(
manager = request.user,
name = "Cooling Down",
intensity = "Cooldown",
durationtype = "Time",
durationvalue = 60000,
)
steps = [step1,step2,step3]
return render(request, 'stepeditor.html',
{
'steps':steps,
})
@user_passes_test(can_plan, login_url="/rowers/paidplans",
message="This functionality requires a Coach or Self-Coach plan",

View File

@@ -151,7 +151,8 @@ from rowers.models import (
PlannedSessionComment, CoachRequest, CoachOffer,
VideoAnalysis, ShareKey,
StandardCollection, CourseStandard,
VirtualRaceFollower, TombStone, InstantPlan
VirtualRaceFollower, TombStone, InstantPlan,
PlannedSessionStep,
)
from rowers.models import (
RowerPowerForm, RowerHRZonesForm, RowerForm, RowerCPForm, GraphImage, AdvancedWorkoutForm,

View File

@@ -322,6 +322,25 @@ th.rotate > div > span {
margin: 2px;
}
.stepcontainer {
display: grid;
grid-template-columns: repeat(5, 1fr);
gap: 10px;
}
.trainingstep {
border: 3px solid #666;
background-color: #ddd;
border-radius: .5em;
padding: 10px;
cursor: move;
}
.trainingstep.over {
border: 3px dotted #666;
}
.divlines {
display: block;
overflow-x: hidden;