mirror of
https://github.com/Findus23/acronomy.git
synced 2024-09-19 15:33:45 +02:00
support showing acronym letters
This commit is contained in:
parent
a8224289c1
commit
45937a65a8
12 changed files with 177 additions and 41 deletions
|
@ -51,6 +51,12 @@ class EditForm(ModelForm):
|
||||||
fields = ['name', 'full_name', "description_md", "stub", "tags"]
|
fields = ['name', 'full_name', "description_md", "stub", "tags"]
|
||||||
|
|
||||||
|
|
||||||
|
class EditLetterForm(ModelForm):
|
||||||
|
class Meta:
|
||||||
|
model = Acronym
|
||||||
|
fields = ["acro_letters"]
|
||||||
|
|
||||||
|
|
||||||
class AddForm(ModelForm):
|
class AddForm(ModelForm):
|
||||||
tags = TagField()
|
tags = TagField()
|
||||||
|
|
||||||
|
|
24
acros/migrations/0045_auto_20200719_1838.py
Normal file
24
acros/migrations/0045_auto_20200719_1838.py
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
# Generated by Django 3.0.8 on 2020-07-19 18:38
|
||||||
|
|
||||||
|
import django.contrib.postgres.fields
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('acros', '0044_auto_20200718_2030'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='acronym',
|
||||||
|
name='acro_letters',
|
||||||
|
field=django.contrib.postgres.fields.ArrayField(base_field=models.SmallIntegerField(), null=True, size=None),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='historicalacronym',
|
||||||
|
name='acro_letters',
|
||||||
|
field=django.contrib.postgres.fields.ArrayField(base_field=models.SmallIntegerField(), null=True, size=None),
|
||||||
|
),
|
||||||
|
]
|
|
@ -1,3 +1,4 @@
|
||||||
|
from django.contrib.postgres.fields import ArrayField
|
||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
|
@ -17,6 +18,10 @@ class Acronym(models.Model):
|
||||||
name = models.CharField(max_length=100, validators=[valid_acronym])
|
name = models.CharField(max_length=100, validators=[valid_acronym])
|
||||||
full_name = models.CharField(max_length=1000)
|
full_name = models.CharField(max_length=1000)
|
||||||
slug = models.SlugField(null=False, unique=True)
|
slug = models.SlugField(null=False, unique=True)
|
||||||
|
acro_letters = ArrayField(
|
||||||
|
models.SmallIntegerField(),
|
||||||
|
null=True
|
||||||
|
)
|
||||||
description_md = models.TextField(blank=True)
|
description_md = models.TextField(blank=True)
|
||||||
description_html = models.TextField(editable=False)
|
description_html = models.TextField(editable=False)
|
||||||
history = HistoricalRecords(excluded_fields=["created_date"])
|
history = HistoricalRecords(excluded_fields=["created_date"])
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
{% bootstrap_form form %}
|
{% bootstrap_form form %}
|
||||||
{% buttons %}
|
{% buttons %}
|
||||||
<input type="submit" value="Update">
|
<input type="submit" class="btn btn-primary" value="Update">
|
||||||
{% endbuttons %}
|
{% endbuttons %}
|
||||||
</form>
|
</form>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<form method="post">
|
<form method="post">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
{% bootstrap_form form %}
|
{% bootstrap_form form %}
|
||||||
{% buttons %}
|
{% buttons %}
|
||||||
<input type="submit" value="Add">
|
<input type="submit" class="btn btn-primary" value="Add">
|
||||||
{% endbuttons %}
|
{% endbuttons %}
|
||||||
</form>
|
</form>
|
||||||
|
|
|
@ -12,12 +12,15 @@
|
||||||
|
|
||||||
{% block heading %}
|
{% block heading %}
|
||||||
<h1 class="acronym">{{ acro.name }}</h1>
|
<h1 class="acronym">{{ acro.name }}</h1>
|
||||||
<p class="fullName">{{ acro.full_name }}</p>
|
<p class="fullName">
|
||||||
|
{% for letter in acro.full_name %}<span {% if forloop.counter0 in acro.acro_letters %}class="al"{% endif %}>{{ letter }}</span>{% endfor %}
|
||||||
|
</p>
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block admin_navbar %}
|
{% block admin_navbar %}
|
||||||
<a class="nav-item nav-link" href="{% url 'edit' acro.slug %}">Edit</a>
|
<a class="nav-item nav-link" href="{% url 'edit' acro.slug %}">Edit</a>
|
||||||
|
<a class="nav-item nav-link" href="{% url 'edit_letter' acro.slug %}">Letters</a>
|
||||||
{% if user.is_staff %}
|
{% if user.is_staff %}
|
||||||
<a class="nav-item nav-link" href="{% url 'admin:acros_acronym_change' acro.id %}">Admin-Edit</a>
|
<a class="nav-item nav-link" href="{% url 'admin:acros_acronym_change' acro.id %}">Admin-Edit</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
{% load bootstrap4 %}
|
{% load bootstrap4 %}
|
||||||
|
|
||||||
{% block heading %}
|
{% block heading %}
|
||||||
<h1>Edit "{{ form.name.value }}"</h1>
|
<h1>Edit "{{ acro.full_name }}"</h1>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
{% bootstrap_form form %}
|
{% bootstrap_form form %}
|
||||||
{% buttons %}
|
{% buttons %}
|
||||||
<input type="submit" value="Update">
|
<input type="submit" class="btn btn-primary" value="Update">
|
||||||
{% endbuttons %}
|
{% endbuttons %}
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|
23
acros/templates/acros/edit_letter.html
Normal file
23
acros/templates/acros/edit_letter.html
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
{% extends 'base.html' %}
|
||||||
|
{% load static %}
|
||||||
|
|
||||||
|
{% block heading %}
|
||||||
|
<h1>Edit "{{ acro.full_name }}"</h1>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<h1 id="letterselect">
|
||||||
|
{% for letter in acro.full_name %}<span {% if forloop.counter0 in acro.acro_letters %}class="als"{% endif %}>{{ letter }}</span>{% endfor %}
|
||||||
|
</h1>
|
||||||
|
<form method="post" id="letterform">
|
||||||
|
{% csrf_token %}
|
||||||
|
{{ form.acro_letters }}
|
||||||
|
<button class="btn btn-outline-primary" type="button" id="initials">Initials</button>
|
||||||
|
<input type="submit" class="btn btn-primary" value="Update">
|
||||||
|
</form>
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block extra_head %}
|
||||||
|
{% endblock %}
|
|
@ -26,6 +26,7 @@ urlpatterns = [
|
||||||
path('acronym/add', views.AddView.as_view(), name="add"),
|
path('acronym/add', views.AddView.as_view(), name="add"),
|
||||||
path('acronym/<str:slug>', views.DetailView.as_view(), name='detail'),
|
path('acronym/<str:slug>', views.DetailView.as_view(), name='detail'),
|
||||||
path('acronym/<str:slug>/edit', views.EditView.as_view(), name='edit'),
|
path('acronym/<str:slug>/edit', views.EditView.as_view(), name='edit'),
|
||||||
|
path('acronym/<str:slug>/edit-letters', views.EditLetterView.as_view(), name='edit_letter'),
|
||||||
path('acronym/<str:slug>/add/wikipedia', views.AddWikipediaView.as_view(), name='add_wikipedia'),
|
path('acronym/<str:slug>/add/wikipedia', views.AddWikipediaView.as_view(), name='add_wikipedia'),
|
||||||
path('acronym/<str:slug>/add/paper', views.AddPaperView.as_view(), name='add_paper'),
|
path('acronym/<str:slug>/add/paper', views.AddPaperView.as_view(), name='add_paper'),
|
||||||
path('acronym/<str:slug>/add/weblink', views.AddWeblinkView.as_view(), name='add_weblink'),
|
path('acronym/<str:slug>/add/weblink', views.AddWeblinkView.as_view(), name='add_weblink'),
|
||||||
|
|
|
@ -7,7 +7,7 @@ from django.urls import reverse
|
||||||
from django.views import generic
|
from django.views import generic
|
||||||
from rest_framework import viewsets, filters
|
from rest_framework import viewsets, filters
|
||||||
|
|
||||||
from acros.forms import EditForm, AddForm, WikipediaForm, PaperForm, WeblinkForm
|
from acros.forms import EditForm, AddForm, WikipediaForm, PaperForm, WeblinkForm, EditLetterForm
|
||||||
from acros.models import Acronym, Tag, AcroOfTheDay, WikipediaLink, PaperReference, Weblink
|
from acros.models import Acronym, Tag, AcroOfTheDay, WikipediaLink, PaperReference, Weblink
|
||||||
from acros.serializers import AcronymSerializer, AcronymListSerializer, TagSerializer
|
from acros.serializers import AcronymSerializer, AcronymListSerializer, TagSerializer
|
||||||
from acros.utils.assets import get_css
|
from acros.utils.assets import get_css
|
||||||
|
@ -52,6 +52,14 @@ class EditView(LoginRequiredMixin, SuccessMessageMixin, generic.UpdateView):
|
||||||
success_message = 'Acronym "%(name)s" was edited successfully'
|
success_message = 'Acronym "%(name)s" was edited successfully'
|
||||||
|
|
||||||
|
|
||||||
|
class EditLetterView(LoginRequiredMixin, SuccessMessageMixin, generic.UpdateView):
|
||||||
|
template_name = 'acros/edit_letter.html'
|
||||||
|
context_object_name = 'acro'
|
||||||
|
model = Acronym
|
||||||
|
form_class = EditLetterForm
|
||||||
|
success_message = 'Letters were edited successfully'
|
||||||
|
|
||||||
|
|
||||||
class AddView(LoginRequiredMixin, SuccessMessageMixin, generic.CreateView):
|
class AddView(LoginRequiredMixin, SuccessMessageMixin, generic.CreateView):
|
||||||
template_name = "acros/add.html"
|
template_name = "acros/add.html"
|
||||||
form_class = AddForm
|
form_class = AddForm
|
||||||
|
|
104
static/app.js
104
static/app.js
|
@ -33,42 +33,78 @@ $(function () {
|
||||||
autoSelect: true,
|
autoSelect: true,
|
||||||
})
|
})
|
||||||
const input = document.querySelector('input[name="tags"]')
|
const input = document.querySelector('input[name="tags"]')
|
||||||
input.classList.remove("form-control")
|
if (input) {
|
||||||
|
input.classList.remove("form-control")
|
||||||
|
|
||||||
document.querySelector("form").addEventListener("submit", function () {
|
document.querySelector("form").addEventListener("submit", function () {
|
||||||
const list = JSON.parse(input.value).map(function (item) {
|
const list = JSON.parse(input.value).map(function (item) {
|
||||||
return item['value'];
|
return item['value'];
|
||||||
})
|
|
||||||
input.value = list.join(",")
|
|
||||||
console.log(input.value)
|
|
||||||
return false;
|
|
||||||
})
|
|
||||||
const tagify = new Tagify(input, {
|
|
||||||
whitelist: [],
|
|
||||||
maxTags: 10,
|
|
||||||
dropdown: {
|
|
||||||
maxItems: 20,
|
|
||||||
enabled: 0
|
|
||||||
}
|
|
||||||
})
|
|
||||||
fetch("/api/tag/")
|
|
||||||
.then(response => response.json())
|
|
||||||
.then(data =>
|
|
||||||
data.map(function (item) {
|
|
||||||
return item['name'];
|
|
||||||
})
|
})
|
||||||
)
|
input.value = list.join(",")
|
||||||
.then(data => {
|
console.log(input.value)
|
||||||
|
return false;
|
||||||
tagify.settings.whitelist = data
|
|
||||||
|
|
||||||
})
|
})
|
||||||
|
const tagify = new Tagify(input, {
|
||||||
|
whitelist: [],
|
||||||
|
maxTags: 10,
|
||||||
|
dropdown: {
|
||||||
|
maxItems: 20,
|
||||||
|
enabled: 0
|
||||||
|
}
|
||||||
|
})
|
||||||
|
fetch("/api/tag/")
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data =>
|
||||||
|
data.map(function (item) {
|
||||||
|
return item['name'];
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.then(data => {
|
||||||
|
|
||||||
const myCodeMirror = CodeMirror.fromTextArea(
|
tagify.settings.whitelist = data
|
||||||
document.getElementById("id_description_md"),
|
|
||||||
{
|
})
|
||||||
lineWrapping: true,
|
}
|
||||||
lineNumbers: true,
|
if (typeof CodeMirror !== "undefined") {
|
||||||
}
|
const myCodeMirror = CodeMirror.fromTextArea(
|
||||||
);
|
document.getElementById("id_description_md"),
|
||||||
|
{
|
||||||
|
lineWrapping: true,
|
||||||
|
lineNumbers: true,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
const letterform = document.getElementById("letterform");
|
||||||
|
if (letterform) {
|
||||||
|
console.log("found form")
|
||||||
|
const letters = document.querySelectorAll("#letterselect span")
|
||||||
|
letters.forEach(function (letter) {
|
||||||
|
letter.addEventListener("click", function (e) {
|
||||||
|
letter.classList.toggle("als")
|
||||||
|
})
|
||||||
|
})
|
||||||
|
letterform.addEventListener("submit", function (e) {
|
||||||
|
const result = [];
|
||||||
|
for (let i = 0; i < letters.length; i++) {
|
||||||
|
const el = letters[i];
|
||||||
|
if (el.classList.contains("als") && el.innerText !== " ") {
|
||||||
|
result.push(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const inputForm = document.getElementById("id_acro_letters");
|
||||||
|
inputForm.value = result.join(",");
|
||||||
|
});
|
||||||
|
const inButton = document.getElementById("initials");
|
||||||
|
inButton.addEventListener("click", function () {
|
||||||
|
letters.forEach(function (el) {
|
||||||
|
const content = el.innerText
|
||||||
|
if (content !== content.toLowerCase()) {
|
||||||
|
el.classList.add("als")
|
||||||
|
} else {
|
||||||
|
el.classList.remove("als")
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -65,6 +65,36 @@ h1.acronym {
|
||||||
.fullName {
|
.fullName {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-size: 2rem;
|
font-size: 2rem;
|
||||||
|
|
||||||
|
.al {
|
||||||
|
transition: color .2s, text-decoration-color .2s;
|
||||||
|
text-decoration-line: underline;
|
||||||
|
text-decoration-color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
.al {
|
||||||
|
color: green;
|
||||||
|
text-decoration-color: green;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#letterselect {
|
||||||
|
span {
|
||||||
|
cursor: pointer;
|
||||||
|
user-select: none;
|
||||||
|
|
||||||
|
&.als {
|
||||||
|
color: green;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#letterform {
|
||||||
|
input[type=text] {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*.linkwrapper {*/
|
/*.linkwrapper {*/
|
||||||
|
|
Loading…
Reference in a new issue