Add Stimulus
This commit is contained in:
parent
8aa69e13b8
commit
6cdc7f43a3
@ -40,7 +40,7 @@ def send_page(self, page):
|
|||||||
# Hidrate page
|
# Hidrate page
|
||||||
match page:
|
match page:
|
||||||
case "home":
|
case "home":
|
||||||
update_TODO(self)
|
pass
|
||||||
|
|
||||||
|
|
||||||
def action_signup(self, data):
|
def action_signup(self, data):
|
||||||
@ -88,29 +88,10 @@ def action_logout(self):
|
|||||||
send_page(self, "login")
|
send_page(self, "login")
|
||||||
|
|
||||||
|
|
||||||
def add_lap(self):
|
|
||||||
"""Add lap to Home page"""
|
|
||||||
# Send current time to client
|
|
||||||
self.send_html({
|
|
||||||
"selector": "#laps",
|
|
||||||
"html": render_to_string("components/_lap.html", {"time": datetime.now()}),
|
|
||||||
"append": True,
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
def add_task(self, data):
|
def add_task(self, data):
|
||||||
"""Add task from TODO section"""
|
|
||||||
# Add task to list
|
|
||||||
self.scope["session"]["tasks"].append(data["task"])
|
|
||||||
self.scope["session"].save()
|
|
||||||
# Update task list
|
|
||||||
update_TODO(self)
|
|
||||||
|
|
||||||
|
|
||||||
def update_TODO(self):
|
|
||||||
"""Update TODO list"""
|
"""Update TODO list"""
|
||||||
self.send_html({
|
self.send_html({
|
||||||
"selector": "#todo",
|
"selector": "#todo-list",
|
||||||
"html": render_to_string("components/_tasks.html", {"tasks": self.scope["session"]["tasks"]}),
|
"html": render_to_string("components/_task.html", {"task": data["newTask"]}),
|
||||||
"append": False,
|
"append": True,
|
||||||
})
|
})
|
@ -9,11 +9,6 @@ class ExampleConsumer(JsonWebsocketConsumer):
|
|||||||
"""Event when client connects"""
|
"""Event when client connects"""
|
||||||
# Accept the connection
|
# Accept the connection
|
||||||
self.accept()
|
self.accept()
|
||||||
# Make session task list
|
|
||||||
if "tasks" not in self.scope["session"]:
|
|
||||||
self.scope["session"]["tasks"] = []
|
|
||||||
self.scope["session"].save()
|
|
||||||
|
|
||||||
|
|
||||||
def disconnect(self, close_code):
|
def disconnect(self, close_code):
|
||||||
"""Event when client disconnects"""
|
"""Event when client disconnects"""
|
||||||
@ -38,8 +33,6 @@ class ExampleConsumer(JsonWebsocketConsumer):
|
|||||||
actions.action_login(self, data)
|
actions.action_login(self, data)
|
||||||
case "Logout":
|
case "Logout":
|
||||||
actions.action_logout(self)
|
actions.action_logout(self)
|
||||||
case "Add lap":
|
|
||||||
actions.add_lap(self)
|
|
||||||
case "Add task":
|
case "Add task":
|
||||||
actions.add_task(self, data)
|
actions.add_task(self, data)
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
||||||
<title>Example website</title>
|
<title>Example website</title>
|
||||||
<link rel="stylesheet" href="{% static 'css/main.css' %}">
|
<link rel="stylesheet" href="{% static 'css/main.css' %}">
|
||||||
<script defer src="{% static 'js/index.js' %}"></script>
|
<script type="module" src="{% static 'js/main.js' %}"></script>
|
||||||
</head>
|
</head>
|
||||||
<body
|
<body
|
||||||
data-host="{{ request.get_host }}"
|
data-host="{{ request.get_host }}"
|
||||||
@ -14,7 +14,7 @@
|
|||||||
>
|
>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<header>
|
<header>
|
||||||
<nav id="nav" class="nav">{% include 'components/_nav.html' %}</nav>
|
<nav id="nav" class="nav" data-controller="navbar">{% include 'components/_nav.html' %}</nav>
|
||||||
</header>
|
</header>
|
||||||
<main id="main">{% include page %}</main>
|
<main id="main">{% include page %}</main>
|
||||||
<footer class="footer">My footer</footer>
|
<footer class="footer">My footer</footer>
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
<ul class="nav__ul" data-controller="navbar">
|
<ul class="nav__ul">
|
||||||
{# Links always visible #}
|
{# Links always visible #}
|
||||||
<li>
|
<li>
|
||||||
<a
|
<a
|
||||||
href="#"
|
href="#"
|
||||||
class="nav__link nav__link--page{% if active_nav == "home" %} active{% endif %}"
|
class="nav__link nav__link--page{% if active_nav == "home" %} active{% endif %}"
|
||||||
data-target="home"
|
data-page="home"
|
||||||
|
data-action="click->navbar#changePage"
|
||||||
>
|
>
|
||||||
Home
|
Home
|
||||||
</a>
|
</a>
|
||||||
@ -15,7 +16,8 @@
|
|||||||
<a
|
<a
|
||||||
href="#"
|
href="#"
|
||||||
class="nav__link nav__link--page{% if active_nav == "profile" %} active{% endif %}"
|
class="nav__link nav__link--page{% if active_nav == "profile" %} active{% endif %}"
|
||||||
data-target="profile"
|
data-page="profile"
|
||||||
|
data-action="click->navbar#changePage"
|
||||||
>
|
>
|
||||||
Profile
|
Profile
|
||||||
</a>
|
</a>
|
||||||
@ -35,7 +37,8 @@
|
|||||||
<a
|
<a
|
||||||
href="#"
|
href="#"
|
||||||
class="nav__link nav__link--page{% if active_nav == "login" %} active{% endif %}"
|
class="nav__link nav__link--page{% if active_nav == "login" %} active{% endif %}"
|
||||||
data-target="login"
|
data-page="login"
|
||||||
|
data-action="click->navbar#changePage"
|
||||||
>
|
>
|
||||||
Login
|
Login
|
||||||
</a>
|
</a>
|
||||||
@ -44,8 +47,8 @@
|
|||||||
<a
|
<a
|
||||||
href="#"
|
href="#"
|
||||||
class="nav__link nav__link--page{% if active_nav == "signup" %} active{% endif %}"
|
class="nav__link nav__link--page{% if active_nav == "signup" %} active{% endif %}"
|
||||||
data-target="signup"
|
data-page="signup"
|
||||||
data-action="click->message#displayUpdateForm"
|
data-action="click->navbar#changePage"
|
||||||
>
|
>
|
||||||
Signup
|
Signup
|
||||||
</a>
|
</a>
|
||||||
|
1
app/app_template/templates/components/_task.html
Normal file
1
app/app_template/templates/components/_task.html
Normal file
@ -0,0 +1 @@
|
|||||||
|
<li>{{ task }}</li>
|
@ -1,3 +0,0 @@
|
|||||||
{% for task in tasks %}
|
|
||||||
<li>{{ task }}</li>
|
|
||||||
{% endfor %}
|
|
@ -2,16 +2,9 @@
|
|||||||
<h1>Welcome to an example of browsing with WebSockets over the Wire</h1>
|
<h1>Welcome to an example of browsing with WebSockets over the Wire</h1>
|
||||||
<p>You will be able to experience a simple structure with a registration, a login and a private page.</p>
|
<p>You will be able to experience a simple structure with a registration, a login and a private page.</p>
|
||||||
</section>
|
</section>
|
||||||
<section>
|
<section data-controller="todo">
|
||||||
<h2>Laps</h2>
|
|
||||||
<p>
|
|
||||||
<button id="add-lap">Add lap</button>
|
|
||||||
</p>
|
|
||||||
<ul id="laps"></ul>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<h2>TODO</h2>
|
<h2>TODO</h2>
|
||||||
<input type="text" id="task">
|
<input type="text" data-todo-target="task">
|
||||||
<button id="add-task">Add task</button>
|
<button data-action="click->todo#addNewTask">Add task</button>
|
||||||
<ul id="todo"></ul>
|
<ul id="todo-list"></ul>
|
||||||
</section>
|
</section>
|
||||||
|
@ -1,28 +0,0 @@
|
|||||||
import { Controller } from "../vendors/stimulus.js"
|
|
||||||
import { sendData } from "../webSocketsCli.js"
|
|
||||||
|
|
||||||
export default class extends Controller {
|
|
||||||
|
|
||||||
static targets = [ "author", "text" ]
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send new message
|
|
||||||
* @param {Event} event
|
|
||||||
* @return {void}
|
|
||||||
*/
|
|
||||||
add(event) {
|
|
||||||
event.preventDefault();
|
|
||||||
// Prepare the information we will send
|
|
||||||
const newData = {
|
|
||||||
"action": "add message",
|
|
||||||
"data": {
|
|
||||||
"author": this.authorTarget.value,
|
|
||||||
"text": this.textTarget.value
|
|
||||||
}
|
|
||||||
};
|
|
||||||
// Send the data to the server
|
|
||||||
sendData(newData, window.myWebSocket);
|
|
||||||
// Clear message form
|
|
||||||
this.textTarget.value = "";
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,116 +0,0 @@
|
|||||||
import { Controller } from "../vendors/stimulus.js"
|
|
||||||
import { sendData } from "../webSocketsCli.js"
|
|
||||||
|
|
||||||
export default class extends Controller {
|
|
||||||
|
|
||||||
static targets = [ "item", "paginator" ]
|
|
||||||
|
|
||||||
connect() {
|
|
||||||
this.enableInfiniteScroll();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
FUNCTIONS
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Switches to the next page when the last message is displayed.
|
|
||||||
*/
|
|
||||||
enableInfiniteScroll() {
|
|
||||||
const lastMessage = this.itemTargets.at(-1);
|
|
||||||
// Turn the page when the last message is displayed.
|
|
||||||
const observerLastMessage = new IntersectionObserver((entries) => {
|
|
||||||
entries.forEach((entry) => {
|
|
||||||
if (entry.isIntersecting) {
|
|
||||||
if (!this.isLastPage()) this.goToNextPage();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
observerLastMessage.observe(lastMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get current page stored in #paginator as dataset
|
|
||||||
* @returns {number}
|
|
||||||
*/
|
|
||||||
getCurrentPage() {
|
|
||||||
return parseInt(this.paginatorTarget.dataset.page);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if we are on the last page
|
|
||||||
* @returns {boolean}
|
|
||||||
*/
|
|
||||||
isLastPage() {
|
|
||||||
return parseInt(this.paginatorTarget.dataset.totalPages) === this.getCurrentPage();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Switch to the next page
|
|
||||||
* @param {Event} event
|
|
||||||
* @return {void}
|
|
||||||
*/
|
|
||||||
goToNextPage(event) {
|
|
||||||
// Prepare the information we will send
|
|
||||||
const newData = {
|
|
||||||
"action": "list messages",
|
|
||||||
"data": {
|
|
||||||
"page": this.getCurrentPage() + 1,
|
|
||||||
}
|
|
||||||
};
|
|
||||||
// Send the data to the server
|
|
||||||
sendData(newData, myWebSocket);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Displays the update form
|
|
||||||
* @param {Event} event
|
|
||||||
* @return {void}
|
|
||||||
*/
|
|
||||||
displayUpdateForm(event) {
|
|
||||||
const message = {
|
|
||||||
"action": "open edit page",
|
|
||||||
"data": {
|
|
||||||
"id": event.target.dataset.id
|
|
||||||
}
|
|
||||||
};
|
|
||||||
sendData(message, window.myWebSocket);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Update message
|
|
||||||
* @param {Event} event
|
|
||||||
* @return {void}
|
|
||||||
*/
|
|
||||||
updateMessage(event) {
|
|
||||||
event.preventDefault();
|
|
||||||
const message = {
|
|
||||||
"action": "update message",
|
|
||||||
"data": {
|
|
||||||
"id": event.target.dataset.id,
|
|
||||||
"author": event.target.querySelector("#message-form__author--update").value,
|
|
||||||
"text": event.target.querySelector("#message-form__text--update").value
|
|
||||||
}
|
|
||||||
};
|
|
||||||
sendData(message, myWebSocket);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Delete message
|
|
||||||
* @param {Event} event
|
|
||||||
* @return {void}
|
|
||||||
*/
|
|
||||||
deleteMessage(event) {
|
|
||||||
const message = {
|
|
||||||
"action": "delete message",
|
|
||||||
"data": {
|
|
||||||
"id": event.target.dataset.id
|
|
||||||
}
|
|
||||||
};
|
|
||||||
sendData(message, window.myWebSocket);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,28 +0,0 @@
|
|||||||
import { Controller } from "../vendors/stimulus.js"
|
|
||||||
import { sendData } from "../webSocketsCli.js"
|
|
||||||
|
|
||||||
export default class extends Controller {
|
|
||||||
|
|
||||||
static targets = [ "page" ]
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send new message
|
|
||||||
* @param {Event} event
|
|
||||||
* @return {void}
|
|
||||||
*/
|
|
||||||
add(event) {
|
|
||||||
event.preventDefault();
|
|
||||||
// Prepare the information we will send
|
|
||||||
const newData = {
|
|
||||||
"action": "add message",
|
|
||||||
"data": {
|
|
||||||
"author": this.authorTarget.value,
|
|
||||||
"text": this.textTarget.value
|
|
||||||
}
|
|
||||||
};
|
|
||||||
// Send the data to the server
|
|
||||||
sendData(newData, window.myWebSocket);
|
|
||||||
// Clear message form
|
|
||||||
this.textTarget.value = "";
|
|
||||||
}
|
|
||||||
}
|
|
22
static/js/controllers/navbar_controller.js
Normal file
22
static/js/controllers/navbar_controller.js
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
import { Controller } from "../vendors/stimulus.js"
|
||||||
|
import { sendData } from "../webSocketsCli.js"
|
||||||
|
|
||||||
|
export default class extends Controller {
|
||||||
|
|
||||||
|
static targets = [ "page" ]
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send message to update page
|
||||||
|
* @param {Event} event
|
||||||
|
* @return {void}
|
||||||
|
*/
|
||||||
|
changePage(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
sendData({
|
||||||
|
action: 'Change page',
|
||||||
|
data: {
|
||||||
|
page: event.target.dataset.page
|
||||||
|
}
|
||||||
|
}, window.myWebSocket);
|
||||||
|
}
|
||||||
|
}
|
22
static/js/controllers/todo_controller.js
Normal file
22
static/js/controllers/todo_controller.js
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
import { Controller } from "../vendors/stimulus.js"
|
||||||
|
import { sendData } from "../webSocketsCli.js"
|
||||||
|
|
||||||
|
export default class extends Controller {
|
||||||
|
|
||||||
|
static targets = [ "task" ]
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render new task
|
||||||
|
* @return {void}
|
||||||
|
*/
|
||||||
|
addNewTask() {
|
||||||
|
sendData({
|
||||||
|
action: 'Add task',
|
||||||
|
data: {
|
||||||
|
newTask: this.taskTarget.value
|
||||||
|
}
|
||||||
|
}, window.myWebSocket);
|
||||||
|
// Clean input
|
||||||
|
this.taskTarget.value = '';
|
||||||
|
}
|
||||||
|
}
|
@ -1,25 +0,0 @@
|
|||||||
import { Controller } from "../vendors/stimulus.js"
|
|
||||||
import { sendData } from "../webSocketsCli.js"
|
|
||||||
|
|
||||||
export default class extends Controller {
|
|
||||||
|
|
||||||
static targets = [ "author", "text" ]
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Update message
|
|
||||||
* @param {Event} event
|
|
||||||
* @return {void}
|
|
||||||
*/
|
|
||||||
update(event) {
|
|
||||||
event.preventDefault();
|
|
||||||
const message = {
|
|
||||||
"action": "update message",
|
|
||||||
"data": {
|
|
||||||
"id": event.target.dataset.id,
|
|
||||||
"author": this.authorTarget.value,
|
|
||||||
"text": this.textTarget.value
|
|
||||||
}
|
|
||||||
};
|
|
||||||
sendData(message, myWebSocket);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,6 +1,7 @@
|
|||||||
import {connect, startEvents} from './webSocketsCli.js';
|
import {connect, startEvents} from './webSocketsCli.js';
|
||||||
import { Application } from "./vendors/stimulus.js"
|
import { Application } from "./vendors/stimulus.js"
|
||||||
import navbarController from "./controllers/navbar.js"
|
import navbarController from "./controllers/navbar_controller.js"
|
||||||
|
import todoController from "./controllers/todo_controller.js"
|
||||||
/*
|
/*
|
||||||
INITIALIZATION
|
INITIALIZATION
|
||||||
*/
|
*/
|
||||||
@ -13,3 +14,4 @@ startEvents();
|
|||||||
window.Stimulus = Application.start();
|
window.Stimulus = Application.start();
|
||||||
// Register all controllers
|
// Register all controllers
|
||||||
Stimulus.register("navbar", navbarController);
|
Stimulus.register("navbar", navbarController);
|
||||||
|
Stimulus.register("todo", todoController);
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* @param {string} url - WebSockets server url
|
* @param {string} url - WebSockets server url
|
||||||
* @return {WebSocket}
|
* @return {WebSocket}
|
||||||
*/
|
*/
|
||||||
export function connect(url=`${document.body.dataset.scheme === 'http' ? 'ws' : 'wss'}://${ document.body.dataset.host }/ws/social-network/`) {
|
export function connect(url=`${document.body.dataset.scheme === 'http' ? 'ws' : 'wss'}://${ document.body.dataset.host }/ws/example/`) {
|
||||||
window.myWebSocket = new WebSocket(url);
|
window.myWebSocket = new WebSocket(url);
|
||||||
return window.myWebSocket;
|
return window.myWebSocket;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user