preparing event save
Signed-off-by: Stephan Richter <s.richter@srsoftware.de>
This commit is contained in:
@@ -13,10 +13,11 @@ public class IndexHandler extends PathHandler {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean doGet(String path, HttpExchange ex) throws IOException {
|
public boolean doGet(String path, HttpExchange ex) throws IOException {
|
||||||
switch (path) {
|
return switch (path) {
|
||||||
case "/":
|
case "/" -> staticPages.doGet("/index", ex);
|
||||||
return staticPages.doGet("/index", ex);
|
case "/favicon.ico" -> staticPages.doGet("/images/%s".formatted(path), ex);
|
||||||
}
|
default -> super.doGet(path, ex);
|
||||||
return super.doGet(path, ex);
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<h1>Create new event</h1>
|
<h1>Create new event</h1>
|
||||||
|
<button id="save" disabled>save</button>
|
||||||
<div class="form">
|
<div class="form">
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>basic data</legend>
|
<legend>basic data</legend>
|
||||||
@@ -17,14 +18,14 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<th>Event title</th>
|
<th>Event title</th>
|
||||||
<td>
|
<td>
|
||||||
<input type="text" name="title" class="required" placeholder="Name of the Event" />
|
<input type="text" name="title" class="required" placeholder="Name of the Event" id="title" />
|
||||||
</td>
|
</td>
|
||||||
<th>Description</th>
|
<th>Description</th>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Location</th>
|
<th>Location</th>
|
||||||
<td>
|
<td>
|
||||||
<input type="text" name="location" class="required" placeholder="Address"/>
|
<input type="text" name="location" class="required" placeholder="Address" id="location" />
|
||||||
</td>
|
</td>
|
||||||
<th rowspan="4">
|
<th rowspan="4">
|
||||||
<textarea name="description" id="description" placeholder="Describe the event"></textarea>
|
<textarea name="description" id="description" placeholder="Describe the event"></textarea>
|
||||||
@@ -33,26 +34,26 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<th>Start</th>
|
<th>Start</th>
|
||||||
<td>
|
<td>
|
||||||
<input type="datetime-local" name="start" class="required" />
|
<input type="datetime-local" name="start" class="required" id="start" />
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>End</th>
|
<th>End</th>
|
||||||
<td>
|
<td>
|
||||||
<input type="datetime-local" name="start"/>
|
<input type="datetime-local" name="start" id="end" />
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Keywords</th>
|
<th>Keywords</th>
|
||||||
<td>
|
<td>
|
||||||
<input type="text" name="tags-input" id="tags-input" placeholder="Press Enter to add" onkeyup="tagKeyPress(event)" />
|
<input type="text" name="tags-input" id="tags-input" placeholder="Press Enter to add" onkeyup="tagKeyPress(event)" class="required" />
|
||||||
<select id="proposals" multiple="multiple">
|
<select id="proposals" multiple="multiple">
|
||||||
|
|
||||||
</select>
|
</select>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="2" id="taglist"></td>
|
<td colspan="3" id="taglist">Your must assign at least one keyword before you may save your event!</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
@@ -72,10 +73,10 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<th>Links</th>
|
<th>Links</th>
|
||||||
<td>
|
<td>
|
||||||
<input type="url" name="link-url" placeholder="http://example.com/info" />
|
<input type="url" name="link-url" placeholder="http://example.com/info" id="link-url" />
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<button>add</button>
|
<button onclick="addLink(event)">add</button>
|
||||||
</td>
|
</td>
|
||||||
<td rowspan="4" style="width: 100%">
|
<td rowspan="4" style="width: 100%">
|
||||||
<div id="map" style="width: 100%; height: 500px;"></div>
|
<div id="map" style="width: 100%; height: 500px;"></div>
|
||||||
@@ -97,14 +98,14 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<th>Attachments/Images</th>
|
<th>Attachments/Images</th>
|
||||||
<td>
|
<td>
|
||||||
<input type="url" name="image-url" placeholder="http://example.com/ad.jpg"/>
|
<input type="url" name="image-url" placeholder="http://example.com/ad.jpg" id="image-url"/>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<button>add</button>
|
<button onclick="addImage(event)">add</button>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="2" id="attachment-list">
|
<td colspan="3" id="attachment-list">
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 1.5 KiB |
BIN
de.srsoftware.cal.web/src/main/resources/images/favicon.ico
Normal file
BIN
de.srsoftware.cal.web/src/main/resources/images/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
@@ -1,3 +1,6 @@
|
|||||||
|
body {
|
||||||
|
font-family: sans;
|
||||||
|
}
|
||||||
.index tr:hover td,
|
.index tr:hover td,
|
||||||
.index tr:hover th{
|
.index tr:hover th{
|
||||||
background-color: khaki;
|
background-color: khaki;
|
||||||
@@ -98,3 +101,38 @@ table#eventlist{
|
|||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#attachment-list img {
|
||||||
|
max-width: 175px;
|
||||||
|
max-height: 175px;
|
||||||
|
padding: 1px;
|
||||||
|
}
|
||||||
|
#attachment-list span {
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
#attachment-list a {
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
z-index: 100;
|
||||||
|
background: white;
|
||||||
|
border: 1px solid blue;
|
||||||
|
border-radius: 4px;
|
||||||
|
height: 20px;
|
||||||
|
width: 20px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#proposals{
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#save {
|
||||||
|
min-width: 100px;
|
||||||
|
min-height: 50px;
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: bold;
|
||||||
|
position: fixed;
|
||||||
|
top: 15px;
|
||||||
|
left: 50%;
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
function element(id){
|
||||||
|
return document.getElementById(id);
|
||||||
|
}
|
||||||
@@ -1,11 +1,36 @@
|
|||||||
var keyTimer = null;
|
var keyTimer = null;
|
||||||
var selectedTags = new Set();
|
var selectedTags = new Set();
|
||||||
var marker = NULL;
|
var marker = null;
|
||||||
|
|
||||||
function fetchTags(text){
|
function fetchTags(text){
|
||||||
if (text) fetch('/api/tags?infix='+text).then(handleTags);
|
if (text) fetch('/api/tags?infix='+text).then(handleTags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function removeParent(target){
|
||||||
|
var p = target.parentNode;
|
||||||
|
p.parentNode.removeChild(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
function addLink(evt){
|
||||||
|
var input = element('link-url');
|
||||||
|
var url = input.value;
|
||||||
|
var name = prompt('Description for '+url,'Homepage');
|
||||||
|
var span = document.createElement('span');
|
||||||
|
span.innerHTML = `<a href="${url}">${name}</a><a onclick="removeParent(this)">❌</a> `;
|
||||||
|
element('link-list').appendChild(span);
|
||||||
|
input.value = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
function addImage(evt){
|
||||||
|
var input = element('image-url');
|
||||||
|
var url = input.value;
|
||||||
|
var span = document.createElement('span');
|
||||||
|
span.innerHTML = `<img src="${url}" /><a onclick="removeParent(this)">❌</a> `;
|
||||||
|
element('attachment-list').appendChild(span);
|
||||||
|
input.value = '';
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
async function handleTags(response){
|
async function handleTags(response){
|
||||||
if (response.ok){
|
if (response.ok){
|
||||||
var tags = await response.json();
|
var tags = await response.json();
|
||||||
@@ -13,8 +38,8 @@ async function handleTags(response){
|
|||||||
console.log("no proposals!");
|
console.log("no proposals!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var select = document.getElementById('proposals');
|
var select = element('proposals');
|
||||||
var input = document.getElementById('tags-input');
|
var input = element('tags-input');
|
||||||
if (!select) return;
|
if (!select) return;
|
||||||
select.innerHTML = '';
|
select.innerHTML = '';
|
||||||
tags.forEach(tag => {
|
tags.forEach(tag => {
|
||||||
@@ -35,7 +60,7 @@ async function handleTags(response){
|
|||||||
}
|
}
|
||||||
|
|
||||||
function onMapClick(e) {
|
function onMapClick(e) {
|
||||||
document.getElementById('coords').value = `${e.latlng.lat}, ${e.latlng.lng}`;
|
element('coords').value = `${e.latlng.lat}, ${e.latlng.lng}`;
|
||||||
if (marker) marker.setLatLng(e.latlng);
|
if (marker) marker.setLatLng(e.latlng);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -43,15 +68,66 @@ function onMapClick(e) {
|
|||||||
function tagKeyPress(e){
|
function tagKeyPress(e){
|
||||||
var input = e.target;
|
var input = e.target;
|
||||||
if (e.keyCode == 13){
|
if (e.keyCode == 13){
|
||||||
selectedTags.add(input.value);
|
var tag = input.value;
|
||||||
var list = document.getElementById('taglist');
|
if (!tag) return;
|
||||||
var btn = document.createElement('button');
|
var list = element('taglist');
|
||||||
btn.innerHTML = input.value;
|
if (selectedTags.size<1) list.innerHTML = '';
|
||||||
list.appendChild(btn);
|
list.innerHTML += `<span><button onclick="this.parentNode.parentNode.removeChild(this.parentNode);" title="click to remove">${input.value}</button> </span>`;
|
||||||
list.appendChild(document.createTextNode(' '));
|
selectedTags.add(tag);
|
||||||
input.value = '';
|
input.value = '';
|
||||||
|
var btn = element('save');
|
||||||
|
btn.removeAttribute("disabled");
|
||||||
|
btn.onclick= function(){ saveEvent(); };
|
||||||
|
console.log(btn);
|
||||||
} else {
|
} else {
|
||||||
if (keyTimer != null) clearTimeout(keyTimer);
|
if (keyTimer != null) clearTimeout(keyTimer);
|
||||||
setTimeout(() => fetchTags(input.value),500);
|
setTimeout(() => fetchTags(input.value),500);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getTags(){
|
||||||
|
var list = element('taglist');
|
||||||
|
var buttons = list.getElementsByTagName('button');
|
||||||
|
var tags = [];
|
||||||
|
for(let i = 0;i < buttons.length; i++){
|
||||||
|
tags.push(buttons[i].innerHTML);
|
||||||
|
}
|
||||||
|
return tags;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getLinks(){
|
||||||
|
var list = element('link-list');
|
||||||
|
var anchors = list.getElementsByTagName('a');
|
||||||
|
var links = [];
|
||||||
|
for(let i = 0;i < anchors.length; i++){
|
||||||
|
var anchor = anchors[i];
|
||||||
|
if (anchor.href) links.push({description:anchor.innerHTML,url:anchor.href});
|
||||||
|
}
|
||||||
|
return links;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getAttachments(){
|
||||||
|
var list = element('attachment-list');
|
||||||
|
var images = list.getElementsByTagName('img');
|
||||||
|
var urls = [];
|
||||||
|
for(let i = 0;i < images.length; i++){
|
||||||
|
var img = images[i];
|
||||||
|
if (img.src) urls.push(img.src);
|
||||||
|
}
|
||||||
|
return urls;
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveEvent(){
|
||||||
|
var event = {
|
||||||
|
title : element('title').value,
|
||||||
|
description : element('description').value,
|
||||||
|
location : element('location').value,
|
||||||
|
start : element('start').value,
|
||||||
|
end : element('end').value,
|
||||||
|
tags: getTags(),
|
||||||
|
links: getLinks(),
|
||||||
|
coords: element('coords').value,
|
||||||
|
attachments: getAttachments()
|
||||||
|
};
|
||||||
|
console.log(event);
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user