Bitte geben Sie einen Grund für die Verwarnung an
Der Grund erscheint unter dem Beitrag.Bei einer weiteren Verwarnung wird das Mitglied automatisch gesperrt.
Abmeldungsplugin - Kann man Verlinkungen auf einer eigenen Seite einbauen?
#1 Abmeldungsplugin - Kann man Verlinkungen auf einer eigenen Seite einbauen?
ich schreibe gerade ein Plugin, was es den Usern ermöglicht sich mithilfe weniger Klicks abzumelden.
Jeder ist mal im Urlaub oder hat im echten Leben mal zu tun. Meist wird es mit allen Kontakten kommuniziert und auch mit dem Team. Vor allem im Rollenspiel ist dies wichtig, damit man nicht aufgrund von Inaktivität gelöscht wird. Sicherlich ist dies auch in anderen Foren so, dass Mitglieder, die mehrere Monate nicht online kamen, gelöscht werden.
Aktuell haben wir dazu einen Thread, wo man reinposten kann, von wann bis wann man abgemeldet ist, wo man auch seine Kontakte per Verlinkung informiert. Das Team trägt es dann im First Post übersichtlich zusammen.
Dies wollen wir gerade automatisieren und haben wie immer auf selbst gecodete Plugins zurückgegriffen. Die Idee an sich funktioniert auch einwandfrei. Man kann per Kalender den Abmeldezeitraum auswählen, mögliche Zweitaccounts angeben sowie per Checkbox markieren, ob man sporadisch abgemeldet ist oder für den Zeitraum ganz weg ist. Schickt man die Abmeldung ab, wird die Abmeldung je nach Zeitraum und ob es sporadisch ist oder nicht, in vier verschiedene Listen einsortiert. Das Plugin greift dabei aufs Datum zurück und löscht automatisch die Einträge aus der Liste heraus, die in der Vergangenheit liegen, sodass die Abmeldungsliste automatisch immer aktualisiert bleibt.
Das einzige Manko, was das Plugin aktuell für uns hat, ist, dass die betroffenen Kontakte, anders als im Thread, nicht mehr per Verlinkung über die Abmeldung informiert werden können. Aus dem Template hab ich mir schon den Code ziehen können, welcher das Verlinkungsmenü einfügt, sodass man in das Textfeld die User automatisch eintragen kann. Allerdings wird beim Abschicken der Abmeldung keine Verlinkungsnachricht an die verlinkten User geschickt.
Meine Frage wäre daher: Wie kann ich machen, dass auf der eigenen Seite die Verlinkungen wie bei den Posts/Threads und den Gästebüchern funktionieren und man eine Nachricht bekommt, wenn man Verlinkt wurde?
Schon einmal vielen Dank für eure Hilfe und liebe Grüße,
Grace
#2 RE: Abmeldungsplugin - Kann man Verlinkungen auf einer eigenen Seite einbauen?

Das hört sich schon recht fortgeschritten an. Eventuell könntest du versuchen, per AJAX mit einem Post-Call einen Beitrag im Forum zu erstellen um die Abwesenheitsinfo zu posten. Darin kannst du dann ganz normal die @-Verlinkung nutzen.
#3 RE: Abmeldungsplugin - Kann man Verlinkungen auf einer eigenen Seite einbauen?
wenn man die @Verlinkung nur beim Schreiben eines neuen Beitrags auslösen kann,
könnte man das, was in der eigenen Seite passiert, in die Antwortseite integrieren.
Dazu kann man in der Iconbar ein HTML-Modul nutzen.
#4 RE: Abmeldungsplugin - Kann man Verlinkungen auf einer eigenen Seite einbauen?
vielen Danke für eure Antworten
@Ingmar ist es denn möglich per AJAX gezielt in einem bestimmten Thread einen Post zu integrieren, indem man den Link des Threads in das Plugin integriert? Sodass man einmal die eigene Seite mit den automatischen Sortierungen hat und einmal den Thread, wo dann die Verlinkungen funktionieren und auch die verlinkten Mitglieder eine PN bekommen?
@l2otbart_57 Wie meinst du das genau? Dass man in der Iconbar sozusagen das Plugin integriert, samt den bestehenden Feldern, sodass man im Abmeldungs-Thread den Eintrag per Iconbar posten kann? Und der Inhalt wird dann zugleich auch wieder auf die eigene Seite geschickt, wo alle sautomatisiert ist?
Wäre da dann nicht der Nachteil, dass das von der Iconbar in jedem Thread sichtbar wäre, wodurch Abmeldungs-Posts überall im Forum gepostet werden können?
LG Grace
#5 RE: Abmeldungsplugin - Kann man Verlinkungen auf einer eigenen Seite einbauen?
Zitat von TWD_Grace im Beitrag #4
@l2otbart_57 Wie meinst du das genau? Dass man in der Iconbar sozusagen das Plugin integriert, samt den bestehenden Feldern, sodass man im Abmeldungs-Thread den Eintrag per Iconbar posten kann? Und der Inhalt wird dann zugleich auch wieder auf die eigene Seite geschickt, wo alle sautomatisiert ist?Wäre da dann nicht der Nachteil, dass das von der Iconbar in jedem Thread sichtbar wäre, wodurch Abmeldungs-Posts überall im Forum gepostet werden können?
ich würde die Termineingabe, Verarbeitung und Speicherung nur im Thread erledigen und das Eingabe-Icon nur für diesen Thread aktivieren.
die eigene Seite wäre bei mir zunächst nicht mehr notwendig,
wenn das Script für die Verarbeitung der Daten zu gross ist, könnte man es in eine eigene *.js-Datei auslagern und einbinden
Admin → Layout → Iconbar → HTML
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<div class="xob_icon_cont float-left" id="cal_icon" style="display: none;">
<span title="Kalender Menue">📅Cal</span></div>
<script>
CAL1=new function(){
const thread_id=336;
const icon=document.getElementById("cal_icon");
if(icon && location.search.includes(`hread=${thread_id}&`)){
icon.style.setProperty("display","inline-block");
icon.onclick=function(){
alert("Formulareingabe")
}
}
}
</script>
demnächst werde ich hier weiterbasteln
vG Bernd
#6 RE: Abmeldungsplugin - Kann man Verlinkungen auf einer eigenen Seite einbauen?
@Ingmar ich hab gerade es endlich zeitlich geschafft, das mit der AJAX Methode auszuprobieren und mich etwas dort etwas eingelesen. In der Xobor Plugin API habe ich für die AJAX Methode jedoch nichts genaueres gefunden, wo ein Post generiert wird.
Könntest du mir ein Code Snippet zur Verfügung stellen, wo dies schon umgesetzt wird, sodass ich ein Fall Beispiel habe und es dementsprechend auch für mein Plugin umschreiben kann.
Zudem hätte ich noch eine Frage: Muss ich auch für das Posten eines Beitrages etwas in "Thread Flat" als Plugin Komponente oder in "Neuen Beitrag schreiben" anlegen?
Vielen Dank und liebe Grüße,
Grace
#7 RE: Abmeldungsplugin - Kann man Verlinkungen auf einer eigenen Seite einbauen?
Kleiner Nachrtrag (ich kann leider den alten Beitrag nicht mehr anpassen). Das wäre mein aktueller Code, sodass du auch weißt, was ich bisher versucht habe:
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
<div style="background-color: {{global_profile_left}}; border: 2px solid {{global_input_bg}}; border-radius: 10px; height: auto; width: 1155px; padding: 10px; margin-left: 15px; margin-top: 10px; display: flex; justify-content: space-between; align-items: center;">
<p style="flex: 1; text-align: center; text-transform: uppercase; font-size: 45px; font-family: 'Pirates of Cydonia'; color: {{global_h2_color}};">Abmeldungen</p>
</div>
<div style="display: flex; justify-content: space-between; margin: 0px 0 0px 10px;">
<div style="margin-top: 10px; flex: 1;">
<div class="Listenstyleing" style="height: 150px; width: 585px; padding-top: 10px; display: grid; place-items: center;
background-image: url('https://i.imgur.com/Lefr8lL.png'); background-size: cover; background-position: center; ">
<p class="Textsytling" style="font-size: 35px;">
Kurzzeiturlauber
</p>
</div>
<div class="Listenstyleing" style="width: 565px; padding: 10px; margin-top: 10px;">
<div class="TextOverflow" style="height: 350px;">
<div id="Kurzzeiturlauber_text" style="height: auto;"></div>
</div>
</div>
</div>
<div style="margin-top: 10px; flex: 1;">
<div class="Listenstyleing" style="height: 150px; width: 585px; padding-top: 10px; display: grid; place-items: center;
background-image: url('https://i.imgur.com/Lefr8lL.png'); background-size: cover; background-position: center; ">
<p class="Textsytling" style="font-size: 35px;">
Mehr als 2 Wochen abgemeldet
</p>
</div>
<div class="Listenstyleing" style="width: 565px; padding: 10px; margin-top: 10px;">
<div class="TextOverflow" style="height: 350px;">
<div id="twoWeeks_text" style="height: auto;"></div>
</div>
</div>
</div>
</div>
<div style="display: flex; justify-content: space-between; margin: 0px 0 10px 10px;">
<div style="margin-top: 10px; flex: 1;">
<div class="Listenstyleing" style="height: 150px; width: 585px; padding-top: 10px; display: grid; place-items: center;
background-image: url('https://i.imgur.com/Lefr8lL.png'); background-size: cover; background-position: center; ">
<p class="Textsytling" style="font-size: 35px;">
Eiszeit
</p>
</div>
<div class="Listenstyleing" style="width: 565px; padding: 10px; margin-top: 10px;">
<div class="TextOverflow" style="height: 350px;">
<div id="Eiszeit_text" style="height: auto;"></div>
</div>
</div>
</div>
<div style="margin-top: 10px; flex: 1;">
<div class="Listenstyleing" style="height: 150px; width: 585px; padding-top: 10px; display: grid; place-items: center;
background-image: url('https://i.imgur.com/Lefr8lL.png'); background-size: cover; background-position: center; ">
<p class="Textsytling" style="font-size: 35px;">
sporadische Abmeldungen
</p>
</div>
<div class="Listenstyleing" style="width: 565px; padding: 10px; margin-top: 10px;">
<div class="TextOverflow" style="height: 350px;">
<div id="sporadisch_text" style="height: auto;"></div>
</div>
</div>
</div>
</div>
<div style="background-color: {{global_profile_left}}; border: 2px solid {{global_input_bg}}; border-radius: 10px; height: auto; width: 1160px; padding: 10px; margin-left: 10px; margin-top: 10px;">
<p style="flex: 1; text-align: center; text-transform: uppercase; font-size: 25px; font-family: 'Pirates of Cydonia'; color: {{global_h2_color}};">Abmeldung einreichen</p>
<br>
<table align="center" style="margin-left: 30px;">
<tr>
<td width="200px;">
<label for="AbmeldungStartInput" style="color: {{global_h2_color}};">Startdatum:</label><br>
</td>
<td>
<input id="AbmeldungStartInput" type="date" style="width: 852px; padding: 10px; border: 2px solid {{global_input_border}}; border-radius: 5px; background-color: {{global_input_bg}};">
<div id="AbmeldungStart" style="margin-bottom: 10px; font-size: 14px; color: {{global_input_border}};"></div>
</td>
</tr>
<tr>
<td>
<label for="AbmeldungEndeInput" style="color: {{global_h2_color}};">Enddatum:</label><br>
</td>
<td>
<input id="AbmeldungEndeInput" type="date" style="width: 852px; padding: 10px; border: 2px solid {{global_input_border}}; border-radius: 5px; background-color: {{global_input_bg}};">
<div id="AbmeldungEnde" style="margin-bottom: 10px; font-size: 14px; color: {{global_input_border}};"></div>
</td>
</tr>
<tr>
<div id="AbmeldungEiszeit" style="margin-left: 30px; margin-right: 50px; margin-bottom: 10px; font-size: 14px; color: {{global_h2_color}};"></div>
</tr>
<tr>
<td>
<label for="AbmeldungCharaktere" style="color: {{global_h2_color}};">betroffene Charaktere:</label>
</td>
<td>
<input id="AbmeldungCharaktere" type="text" placeholder="Schreibe hier alle deine Charaktere rein, die abgemeldet werden sollen" style="width: 852px; padding: 10px; border: 2px solid {{global_input_border}}; border-radius: 5px; margin-bottom: 10px; background-color: {{global_input_bg}};">
</td>
</tr>
<tr>
<td>
<label for="inputbox" style="color: {{global_h2_color}};">betroffene Playpartner:</label>
</td>
<td>
<textarea name="nachricht" class="inputbox" id="messagetext" placeholder="Schreibe hier alle deine Playpartner rein, die über deine Abmeldung informiert werden sollen" style="width: 852px; padding: 10px; border: 2px solid {{global_input_border}}; border-radius: 5px; margin-bottom: 10px; background-color: {{global_input_bg}};">{{text}}</textarea>
</td>
</tr>
<tr>
<td>
<label for="AbmeldungSporadisch" style="color: {{global_h2_color}};">sporadische Abmeldungen?<br>
<small>möglicherweise findet man Zeit und Kopf zum Posten</small></label><br>
</td>
<td>
<input id="AbmeldungSporadisch" type="checkbox" style="width: 20px; padding: 10px; border: 2px solid {{global_input_border}}; border-radius: 5px; background-color: {{global_input_bg}};">
</td>
</tr>
</table>
<br>
<button method="post" onSubmit="return chkQuickFormular()" onclick="if(chkQuickFormular()){document.forms['newms'].submit();}" id="addNewAbmeldung" datausername="{{user_name}}" style="margin-left: 30px; cursor: pointer; width: 1080px; background-color: {{global_input_border}}; color: {{global_profile_left}}; border: none; border-radius: 10px; padding: 7px 9px; font-size: 15px; font-family: 'Pirates of Cydonia'; text-transform: uppercase;">Abmeldung einreichen</button>
</div>
{{user_admin==true.start}}
<div style="background-color: {{global_profile_left}}; border: 2px solid {{global_input_bg}}; border-radius: 10px; height: auto; width: 1170px; margin-left: 10px; margin-top: 10px; padding: 5px;">
<div id="Abmeldungen_div" style="overflow: auto; max-height: 450px; font-size: 14px;"></div>
</div>
{{user_admin==true.end}}
<br>
<actions>
<action name="post_reply" method="post_reply" />
</actions>
<script>
document.addEventListener("DOMContentLoaded", function () {
// Leeres Objekt für Abmeldungen initialisieren
let Abmeldungen = {
AbmeldungenArray: []
};
document.getElementById("AbmeldungStartInput").addEventListener("change", function() {
let startDate = this.value;
let endDateInput = document.getElementById("AbmeldungEndeInput");
// Setze das Mindestdatum für das Enddatum auf das Startdatum
endDateInput.min = startDate;
// Falls das Enddatum bereits gesetzt ist und vor dem Startdatum liegt, korrigieren
if (endDateInput.value && endDateInput.value < startDate) {
endDateInput.value = startDate;
}
});
// Funktion zum Posten des Abmeldungsbeitrags
function postAbmeldungThreadEntry(abmeldung) {
let beitragstext = `
[b]Charakter(e):[/b] ${abmeldung.Charaktere}
[b]Zeitraum:[/b] ${abmeldung.Startdatum} – ${abmeldung.Enddatum}
[b]Sporadisch:[/b] ${abmeldung.Sporadisch ? "Ja" : "Nein"}
[b]Informierte Playpartner:[/b] ${abmeldung.Playpartner}
`;
xobor.plugin("abmeldungsplugin").call("post_reply", {
thread_id: 47, // ID des Threads, in den gepostet wird
forum_id: 7216, // ID des Forums
posttext: beitragstext,
subject: "Abmeldung von " + abmeldung.Charaktere
}, function(res) {
if(res && !res.error) {
console.log("Beitrag erfolgreich erstellt", res);
} else {
console.error("Fehler beim Erstellen des Beitrags", res);
}
});
}
// Funktion zum Hinzufügen einer neuen Abmeldung
function addNewAbmeldungen(event) {
if(event) event.preventDefault(); // Falls von einem Formular
const AbmeldungCharaktere = document.getElementById("AbmeldungCharaktere").value.trim();
const AbmeldungStart = document.getElementById("AbmeldungStartInput").value;
const AbmeldungEnde = document.getElementById("AbmeldungEndeInput").value;
var author = document.getElementById("addNewAbmeldung").getAttribute("datausername");
const AbmeldungSporadisch = document.getElementById("AbmeldungSporadisch").checked;
const playpartner = document.getElementById("messagetext").value.trim();
if (!AbmeldungCharaktere) {
alert("Bitte gib mindestens einen Charakternamen ein.");
return;
}
if (!AbmeldungStart || !AbmeldungEnde) {
alert("Bitte wähle ein Start- und Enddatum.");
return;
}
// Funktion zum Formatieren des Datums
function formatDate(date) {
const d = new Date(date);
const day = ("0" + d.getDate()).slice(-2);
const month = ("0" + (d.getMonth() + 1)).slice(-2);
const year = d.getFullYear();
return `${day}.${month}.${year}`;
}
const formattedStartDate = formatDate(AbmeldungStart);
const formattedEndDate = formatDate(AbmeldungEnde);
const todayDate = formatDate(new Date());
const startDate = new Date(AbmeldungStart);
const endDate = new Date(AbmeldungEnde);
const daysAbsent = Math.ceil((endDate - startDate) / (1000 * 60 * 60 * 24)) + 1;
const newAbmeldung = {
Charaktere: AbmeldungCharaktere,
Startdatum: formattedStartDate,
Enddatum: formattedEndDate,
EingereichtVon: author,
Days: daysAbsent,
Sporadisch: AbmeldungSporadisch,
Einreichungsdatum: todayDate,
Playpartner: playpartner
};
Abmeldungen.AbmeldungenArray.push(newAbmeldung);
console.log("Neue Abmeldung hinzugefügt:", newAbmeldung);
xobor.plugin("abmeldungsplugin").setGlob("abmeldung_array_globvar", Abmeldungen, function (res) {
if(res && !res.error) {
console.log("Abmeldungen nach Hinzufügen aktualisiert:", res);
postAbmeldungThreadEntry(newAbmeldung);
// Eingabefelder zurücksetzen
document.getElementById("AbmeldungCharaktere").value = "";
document.getElementById("AbmeldungStartInput").value = "";
document.getElementById("AbmeldungEndeInput").value = "";
document.getElementById("messagetext").value = "";
// Aktualisierte Abmeldungen laden und anzeigen
loadAbmeldungen();
loadAbmeldungenOrdner();
} else {
alert("Fehler beim Speichern der Abmeldung. Bitte versuche es erneut.");
console.error("Fehler beim Speichern:", res);
}
});
}
function loadAbmeldungen() {
xobor.plugin("abmeldungsplugin").getGlob("abmeldung_array_globvar", function (res) {
if (res && res.AbmeldungenArray) {
Abmeldungen = res;
const AbmeldungenContainer = document.getElementById("Abmeldungen_div");
if (AbmeldungenContainer) {
AbmeldungenContainer.innerHTML = "";
// Sortiere nach Enddatum absteigend
const abmeldungenList = Abmeldungen.AbmeldungenArray.sort(function (a, b) {
const dateA = new Date(a.Enddatum.split(".").reverse().join("-"));
const dateB = new Date(b.Enddatum.split(".").reverse().join("-"));
return dateB - dateA;
});
abmeldungenList.forEach(function (abmeldung, index) {
const AbmeldungenElement = document.createElement("div");
AbmeldungenElement.innerHTML = `
<div style="margin-bottom: 10px; padding: 10px; border-radius: 10px; border: 2px dotted {{global_input_border}}; display: flex; justify-content: space-between; align-items: center; font-size: 14px;">
<div style="flex: 1;" class="messagetext xquoteable" id="xquoteable_p">
<p><b>${abmeldung.Charaktere}</b> - eingereicht von ${abmeldung.EingereichtVon} am ${abmeldung.Einreichungsdatum}</p>
${abmeldung.Startdatum} - ${abmeldung.Enddatum}<br>
${abmeldung.Days} Tage abgemeldet<br>
sporadische Abmeldung: ${abmeldung.Sporadisch}<br>
benachrichtigte Playpartner: ${abmeldung.Playpartner}
</div>
<div style="display: flex; justify-content: flex-end; align-items: center; gap: 10px; margin-left: 20px;">
<button class="editAbmeldungBtn" data-index="${index}" style="background-color: {{global_button_bg}}; color: {{global_link_color}}; border: none; padding: 5px 10px; border-radius: 5px; cursor: pointer;">✎</button>
<button class="deleteAbmeldungBtn" data-index="${index}" style="background-color: {{global_button_bg}}; color: {{global_link_color}}; border: none; padding: 5px 10px; border-radius: 5px; cursor: pointer;">X</button>
</div>
</div>
`;
AbmeldungenContainer.appendChild(AbmeldungenElement);
});
// Event-Listener für Bearbeiten- und Löschen-Buttons
const editButtons = document.querySelectorAll(".editAbmeldungBtn");
editButtons.forEach(function(button) {
button.addEventListener("click", function() {
const index = button.getAttribute("data-index");
editAbmeldungen(index);
});
});
const deleteButtons = document.querySelectorAll(".deleteAbmeldungBtn");
deleteButtons.forEach(function(button) {
button.addEventListener("click", function() {
const index = button.getAttribute("data-index");
deleteAbmeldungen(index);
});
});
console.log("Abmeldungen erfolgreich geladen:", res);
}
} else {
console.log("Keine gespeicherten Abmeldungen gefunden.");
}
});
}
function editAbmeldungen(index) {
let abmeldung = Abmeldungen.AbmeldungenArray[index];
// Den entsprechenden Eintrag im Container finden
let abmeldungDiv = document.querySelectorAll("#Abmeldungen_div > div")[index];
// Falls es bereits ein Bearbeitungsformular gibt, abbrechen
if (abmeldungDiv.querySelector(".edit-form")) return;
// Originalen Inhalt speichern
let originalHTML = abmeldungDiv.innerHTML;
// Bearbeitungsformular generieren
abmeldungDiv.innerHTML = `
<div class="edit-form" style="display: flex; flex-direction: column; gap: 5px; padding: 10px; border: 2px dashed {{global_input_border}}; border-radius: 5px;">
<label>Charakter(e): <input type="text" id="editCharaktere" value="${abmeldung.Charaktere}" style="width: 100%;"></label>
<label>Startdatum: <input type="date" id="editStartdatum" value="${abmeldung.Startdatum.split('.').reverse().join('-')}" style="width: 100%;"></label>
<label>Enddatum: <input type="date" id="editEnddatum" value="${abmeldung.Enddatum.split('.').reverse().join('-')}" style="width: 100%;"></label>
<label><input type="checkbox" id="editSporadisch" ${abmeldung.Sporadisch ? "checked" : ""}> Sporadisch</label>
<div style="display: flex; justify-content: space-between; margin-top: 10px;">
<button id="saveEdit" style="background-color: {{global_button_bg}}; color: {{global_link_color}}; padding: 5px 10px; border: none; border-radius: 5px; cursor: pointer;">Speichern</button>
<button id="cancelEdit" style="background-color: #ff4d4d; color: white; padding: 5px 10px; border: none; border-radius: 5px; cursor: pointer;">Abbrechen</button>
</div>
</div>
`;
// Event-Listener für Speichern-Button
document.getElementById("saveEdit").addEventListener("click", function() {
let updatedCharaktere = document.getElementById("editCharaktere").value.trim();
let updatedStartdatum = document.getElementById("editStartdatum").value;
let updatedEnddatum = document.getElementById("editEnddatum").value;
let updatedSporadisch = document.getElementById("editSporadisch").checked;
if (!updatedCharaktere) {
alert("Bitte gib mindestens einen Charakternamen ein.");
return;
}
if (!updatedStartdatum || !updatedEnddatum) {
alert("Bitte wähle ein Start- und Enddatum.");
return;
}
// Umformatieren der Daten in DD.MM.YYYY
function formatDate(date) {
let d = new Date(date);
let day = ("0" + d.getDate()).slice(-2);
let month = ("0" + (d.getMonth() + 1)).slice(-2);
let year = d.getFullYear();
return `${day}.${month}.${year}`;
}
let formattedStartdatum = formatDate(updatedStartdatum);
let formattedEnddatum = formatDate(updatedEnddatum);
let daysAbsent = Math.ceil((new Date(updatedEnddatum) - new Date(updatedStartdatum)) / (1000 * 60 * 60 * 24)) + 1;
// Daten in der Abmeldungs-Liste aktualisieren
Abmeldungen.AbmeldungenArray[index] = {
Charaktere: updatedCharaktere,
Startdatum: formattedStartdatum,
Enddatum: formattedEnddatum,
EingereichtVon: abmeldung.EingereichtVon,
Days: daysAbsent,
Sporadisch: updatedSporadisch,
Einreichungsdatum: abmeldung.Einreichungsdatum
};
// Speichern
xobor.plugin("abmeldungsplugin").setGlob("abmeldung_array_globvar", Abmeldungen, function(res) {
console.log("Abmeldung erfolgreich aktualisiert:", res);
loadAbmeldungen();
loadAbmeldungenOrdner();
});
});
// Event-Listener für Abbrechen-Button
document.getElementById("cancelEdit").addEventListener("click", function() {
abmeldungDiv.innerHTML = originalHTML; // Ursprünglichen Inhalt wiederherstellen
attachEventListenersToButtons();
});
}
// Event-Listener für die Buttons nach Bearbeitung neu setzen
function attachEventListenersToButtons() {
document.querySelectorAll(".editAbmeldungBtn").forEach(button => {
button.addEventListener("click", function() {
editAbmeldungen(button.getAttribute("data-index"));
});
});
document.querySelectorAll(".deleteAbmeldungBtn").forEach(button => {
button.addEventListener("click", function() {
deleteAbmeldungen(button.getAttribute("data-index"));
});
});
}
// Funktion zum Erstellen des HTML-Inhalts für eine Abmeldung
function createAbmeldungHTML(abmeldung) {
return `
<div style="margin-bottom: 10px;">
<h3 style="font-size: 15px;">${abmeldung.Charaktere}</h3>
${abmeldung.Startdatum} - ${abmeldung.Enddatum}<br>
{{user_admin==true.start}}${abmeldung.Days} Tage{{user_admin==true.end}}
</div>
`;
}
function loadAbmeldungenOrdner() {
xobor.plugin("abmeldungsplugin").getGlob("abmeldung_array_globvar", function (res) {
if (res && res.AbmeldungenArray) {
Abmeldungen = res;
const categories = {
kurzzeiturlauber: document.getElementById("Kurzzeiturlauber_text"),
twoWeeks: document.getElementById("twoWeeks_text"),
eiszeit: document.getElementById("Eiszeit_text"),
sporadisch: document.getElementById("sporadisch_text")
};
// Erstmal alle Inhalte der Kategorien leeren
Object.values(categories).forEach(el => el.innerHTML = "");
const currentDate = new Date();
currentDate.setHours(0, 0, 0, 0);
// Filtere auf zukünftige Abmeldungen und sortiere nach Enddatum aufsteigend
const sortedFutureAbmeldungen = Abmeldungen.AbmeldungenArray
.filter(abmeldung => {
const endDate = new Date(abmeldung.Enddatum.split('.').reverse().join('-'));
return endDate >= currentDate;
})
.sort((a, b) => {
const dateA = new Date(a.Enddatum.split('.').reverse().join('-'));
const dateB = new Date(b.Enddatum.split('.').reverse().join('-'));
return dateA - dateB; // nächstes Datum zuerst
});
sortedFutureAbmeldungen.forEach(abmeldung => {
let targetCategory = null;
let abmeldungHTML = createAbmeldungHTML(abmeldung);
// Abmeldungen basierend auf der Dauer einsortieren
if (abmeldung.Days >= 1 && abmeldung.Days <= 13) {
targetCategory = categories.kurzzeiturlauber;
} else if (abmeldung.Days >= 14 && abmeldung.Days <= 30) {
targetCategory = categories.twoWeeks;
} else if (abmeldung.Days > 30) {
targetCategory = categories.eiszeit;
}
// Falls eine Kategorie gefunden wurde, füge die Abmeldung hinzu
if (targetCategory) {
targetCategory.innerHTML += abmeldungHTML;
}
// Falls die Abmeldung als "sporadisch" markiert ist, kommt sie ZUSÄTZLICH in "sporadisch_text"
if (abmeldung.Sporadisch) {
categories.sporadisch.innerHTML += abmeldungHTML;
}
});
console.log("Abmeldungen erfolgreich geladen:", res);
} else {
console.log("Keine gespeicherten Abmeldungen gefunden.");
}
});
}
function deleteAbmeldungen(index) {
if (confirm("Bist du sicher, dass du diese Abmeldung löschen möchtest?")) {
Abmeldungen.AbmeldungenArray.splice(index, 1);
xobor.plugin("abmeldungsplugin").setGlob("abmeldung_array_globvar", Abmeldungen, function (res) {
console.log("Abmeldung erfolgreich gelöscht:", res);
loadAbmeldungen();
loadAbmeldungenOrdner();
});
}
}
if (document.getElementById("addNewAbmeldung")) {
document.getElementById("addNewAbmeldung").addEventListener("click", addNewAbmeldungen);
}
loadAbmeldungenOrdner();
if (document.getElementById("Abmeldungen_div")) {
loadAbmeldungen();
}
function updateEiszeitWarning() {
let startDate = document.getElementById("AbmeldungStartInput").value;
let endDate = document.getElementById("AbmeldungEndeInput").value;
let eiszeitDiv = document.getElementById("AbmeldungEiszeit");
if (startDate && endDate) {
let start = new Date(startDate);
let end = new Date(endDate);
let daysAbsent = Math.ceil((end - start) / (1000 * 60 * 60 * 24)) + 1;
if (daysAbsent > 30) {
eiszeitDiv.innerHTML = "Eine Abmeldung über 30 Tage gilt als Eiszeit. Eine Eiszeit-Abmeldung muss mit dem Team abgesprochen werden und kann auch vom Team abgelehnt werden, wenn zuvor schon eine oder mehrere längere Eiszeiten bestanden haben oder die Charaktere über einen längeren Zeitraum als inaktiv anzusehen sind.";
} else {
eiszeitDiv.innerHTML = "";
}
} else {
eiszeitDiv.innerHTML = "";
}
}
document.getElementById("AbmeldungStartInput").addEventListener("change", function() {
document.getElementById("AbmeldungEndeInput").min = this.value;
updateEiszeitWarning();
});
document.getElementById("AbmeldungEndeInput").addEventListener("change", updateEiszeitWarning);
});
</script>
<script>
var at_username_target_textarea = '#messagetext';
var theDivUserSearch = '{[user_finder_div_at_tag]}';
var theDivUserDisable ='{[user_disable_div_at_tag]}';
</script>
<script type="text/javascript" src="{{link_new_message_js}}"></script>
<link rel="stylesheet" type="text/css" href="{{link_atusername_css}}" />
{{user_registered==true.end}}
{{user_at_link==true.end}}
<script type="text/javascript">
/*check form Function*/
function chkFormular() {
var errormess = 0;
var mxt = document.getElementById('messagetext').value;
var mst = document.getElementById('messagetitle').value;
mxtrep = mxt.replace(/^\s*(S)\s*$/, '$1');
mstrep = mst.replace(/^\s*(S)\s*$/, '$1');
if( mxtrep.length <= 2 ) {
document.getElementById('messagetext_e').style.border='2px solid #a71111';
document.getElementById('messagetext_e_m').style.display='inline';
document.getElementById('messagetext').focus();
errormess = 1;
}
else
{
document.getElementById('messagetext_e').style.border='none';
document.getElementById('messagetext_e_m').style.display='none';
}
if( mstrep.length <= 2) {
document.getElementById('messagetitle_e').style.border='2px solid #a71111';
document.getElementById('messagetitle_e_m').style.display='inline';
document.getElementById('messagetitle').focus();
errormess = 1;
}
else
{
document.getElementById('messagetitle_e').style.border='none';
document.getElementById('messagetitle_e_m').style.display='none';
}
if (errormess == 1 ) {return false;}
else {return true;}
}
</script>
<script type="text/javascript">
{{reply==true.start}}
document.getElementById('messagetext').focus();
{{reply==true.end}}
</script>
{[modal_box_code]}
{[file_insert_dialogue_code]}
<script type="text/javascript">FitToContent(document.getElementById("messagetext"),800);</script>
#8 RE: Abmeldungsplugin - Kann man Verlinkungen auf einer eigenen Seite einbauen?
ich kann mir auf Ingmars Andeutungen auch keinen Reim machen.
dein Quelltext sieht so aufwendig und durchdacht aus, dass ich fast geglaubt hätte, dass es schon funktioniert
aber es hängt an dieser Funktion, die leider nicht unterstützt wird
2
3
4
5
6
7
8
9
10
11
12
13
xobor.plugin("plugin_xy").call("post_reply", {
thread_id: 183, // ID des Threads, in den gepostet wird
forum_id: 55720, // ID des Forums
posttext: "Beispiel Text",
subject: "Abmeldung Test "
}, function(res) {
if(res && !res.error) {
prompt("res:",res);
console.log("Beitrag erfolgreich erstellt", res);
} else {
console.error("Fehler beim Erstellen des Beitrags", res);
}
});
und nur das Ergebnis liefert: function _plugin_api_post_reply not found
vG Bernd
#9 RE: Abmeldungsplugin - Kann man Verlinkungen auf einer eigenen Seite einbauen?
@l2otbart_57 vielen Dank für deine Worte und dass du es dir angeschaut hast. An der Fehlermeldung "function _plugin_api_post_reply not found" bin ich auch hängen geblieben und kam nicht weiter, wie ich das umsetzen kann. Chat GPT hat mir vorgeschlagen, dass ich eine PHP Datei anlege, doch ich wüsste nicht, wie ich das bei dem Plugin System von Xobor umsetzen kann. Deswegen die Nachfrage hier ^^
Wahrscheinlich werde ich noch ein paar Sachen ausprobieren, mal schauen, ob ich es anders umgehen kann.
Eine weitere Idee von mir war, dass ich es schaffe den Inhalt in "Neuen Beitrag schreiben" schicken kann, sodass das Input Feld dort ausgefüllt wird und automatisch der Absenden Button getriggert wird, sodass der Post gepostet wird. Daran werde ich mich auch nachher mal setzen.
Sonst baue ich auf die Hilfe von Ingmar bezüglich AJAX
Andernfalls kann eventuell noch @Mike48 helfen? Wie hast du beim Account Switcher es gelöst, dass per Klick zwischen den Accounts gewechselt wird? Dafür werden im Hintergrund schließlich auch Daten weitergeleitet auf die Login Seite. Ich denke das könnte ähnlich vom Prinzip sein, sodass ich es auf mein Problem in umgewandelter Form anwenden kann.
#10 RE: Abmeldungsplugin - Kann man Verlinkungen auf einer eigenen Seite einbauen?
Kurzes Update:
Ich hab eine Lösung gefunden!
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function postAbmeldungThreadEntry(abmeldung) {
let beitragstext = `
[b]Charakter(e):[/b] ${abmeldung.Charaktere}
[b]Zeitraum:[/b] ${abmeldung.Startdatum} – ${abmeldung.Enddatum}
[b]Sporadisch:[/b] ${abmeldung.Sporadisch ? "Ja" : "Nein"}
[b]Informierte Playpartner:[/b] ${abmeldung.Playpartner}
`;
// Beitragstext in globale Variable speichern
xobor.plugin("abmeldungsplugin").setGlob("abmeldungsend_text_globvar", beitragstext, function(res) {
console.log("Abmeldungstext gespeichert:", res);
// Weiterleitung zur Abmeldeseite mit Schnellantwort
window.location.href = "https://lyas-musterforum.xobor.de/t47f7216-Abmeldungen.html#msg315";
});
}
Die Funktion leitet einen automatisch auf "Thread Flat" weiter, wo dann dieser Cod getriggert wird:
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
<script>
window.addEventListener('load', function () {
try {
const plugin = xobor.plugin('abmeldungsplugin');
// 1. Zugriff auf den global gespeicherten Text per Callback
plugin.getGlob('abmeldungsend_text_globvar', function (text) {
if (!text) return; // Abbrechen, wenn kein Text vorhanden
// 2. Finde das Textfeld für die Schnellantwort
const textarea = document.querySelector('textarea#messagetext');
if (textarea) {
textarea.value = text;
// 3. Kleiner Timeout, um sicherzugehen, dass alles geladen ist
setTimeout(function () {
// 4. Formular-Check und automatische Absendung
if (typeof chkQuickFormular === 'function' && chkQuickFormular()) {
// 5. Globale Variable zurücksetzen, bevor gesendet wird
plugin.setGlob('abmeldungsend_text_globvar', '');
// 6. Redirect-Markierung setzen, damit man danach weiß, dass es ein Autosubmit war
sessionStorage.setItem("autoAbmeldungDone", "true");
// 7. Formular absenden
document.forms['newms'].submit();
} else {
console.warn("chkQuickFormular fehlgeschlagen oder nicht vorhanden.");
}
}, 500);
} else {
console.warn("Textarea #messagetext nicht gefunden.");
}
});
// 8. Nach automatischer Abmeldung zurück zur Übersicht leiten
if (sessionStorage.getItem("autoAbmeldungDone") === "true") {
sessionStorage.removeItem("autoAbmeldungDone");
setTimeout(() => {
window.location.href = "https://lyas-musterforum.xobor.de/abmeldungen.html";
}, 2000); // Optional etwas warten, damit Xobor den Post verarbeiten kann
}
} catch (e) {
console.error('Automatische Schnellantwort fehlgeschlagen:', e);
}
});
</script>
So wird durch die Schnellantwort ein Post mit den zwischengespeicherten Daten gepostet, samt den Verlinkungen.
Jetzt muss ich nur noch schauen, dass man eventuell nicht hin und her springt, sondern es irgendwie im Hintergrund aufgerufen wird ^^
#11 RE: Abmeldungsplugin - Kann man Verlinkungen auf einer eigenen Seite einbauen?

Ich mische mich mal ein.
Ich habe mal ein Plugin geschrieben um eine komplette Liste der Kategorien und Foren eines Forums zu erstellen. Die entsprechenden Forenvariablen dafür stehen einem zum Beispiel beim Beitrag bearben zur Verfügung.
Also habe ich eiin Thema erstellt und mit dem Plugin wird der Themen Beitrag im Bearbeiten-Modus geöffnet und damit in Globelen Variablen für die Listen erstellt.
Man könnte ein Thema in einem nur für Admins zugänglichen Forum erstellen und erstellt dort mit Trigger auf den Antwort-Button einen Beitrag und füllt den mit dem Plugin-Element Beitrag erstellen aus und schickt ihn mit trigger auf Save ab. Dann muss man noch die ID heraus bekommen um den Beitrag, wenn er nicht mehr benötigt wieder zu löschen.
www.friends-of-xobor.de (621181 - Template kann wechsel bei Plungin Tests)
www.seniorenclub-sel-koeln.de (578865 - V6 Template)
#12 RE: Abmeldungsplugin - Kann man Verlinkungen auf einer eigenen Seite einbauen?

Ich
Zitat von l2otbart_57 im Beitrag #8
ich kann mir auf Ingmars Andeutungen auch keinen Reim machen
Ich meinte damit eine ganz "dreckige" Lösung ohne das Pluginsystem.
Wenn ich per Ajax einen Post-Call auf die korrekte URL mache:
posturl = "/new.php?thread=HIER_THREAD_ID&forum=HIER_FORUM_ID&reply=1&replyid=HIER_ID_DES_ERSTEN_BEITRAGS"
und dann als payload die gleichen Parameter mitsende, die auch beim schreiben des Beitragsgesendet werden:
Das "unique" kann dabei ein zufälliger String sein, solange man keine Dateianhänge mitsenden möchte.
Dann sollte der Beitrag ganz normal gespeichert werden.
#13 RE: Abmeldungsplugin - Kann man Verlinkungen auf einer eigenen Seite einbauen?

Wenn mal die Action-Elemente im Plugin wider gehen würde, könnte man bestimmt damit etwas machen. Es gibt die Action Themen erstellen und Beitrag erstellen.
Die gehen aber schon lange nicht mehr. Ich habe auch Plugins mit Action-Elementen veröffentlcht die nicht mehr funktionieren.
Zum Beispiel das Plugin UserToGroup. Beim schreiben von Beiträgen werden Mitgieder ab bestimmter Anzahl Beiträgen in andere Gruppe verschoben.
www.friends-of-xobor.de (621181 - Template kann wechsel bei Plungin Tests)
www.seniorenclub-sel-koeln.de (578865 - V6 Template)
#14 RE: Abmeldungsplugin - Kann man Verlinkungen auf einer eigenen Seite einbauen?

Zitat von Mike48 im Beitrag #13
Wenn mal die Action-Elemente im Plugin wider gehen würde, könnte man bestimmt damit etwas machen.
Das ist richtig. Über die Action-Elemente gäbe es eine "saubere" Lösung für dieses Problem.
Es sieht leider aktuell nicht danach aus, als ob das in absehbarer Zukunft wieder gehen wird. Die von uns damals verwendete Technik, um Javascript-Code auf dem Server auszuführen, ist nach aktuellem Stand schlicht nicht mehr sicher genug.
#15 RE: Abmeldungsplugin - Kann man Verlinkungen auf einer eigenen Seite einbauen?

@TWD_Grace
- sessionStorage.setItem
- sessionStorage.getItem
- sessionStorage.removeItem
Ist laut Miranus in Plugins nicht erlaubt. Freischaltung wird verweigert wenn entdedckt.
Stattdessen dürfen nur die API Funktionen verwenden werden
xobor.plugin("PLUGINID").sessionstorage.get(Key);
xobor.plugin("PLUGINID").sessionstorage.set(Key, Value);
xobor.plugin("PLUGINID").sessionstorage.del(Key);
Selbes Verfahren wie bei localstorage.
www.friends-of-xobor.de (621181 - Template kann wechsel bei Plungin Tests)
www.seniorenclub-sel-koeln.de (578865 - V6 Template)
- Informationen
- Aktuelle News
- Forum Tutorials - Tipps und Anleitungen
- SEO / Werbung fürs Forum
- Verwaltung
- Extras
- Design
- Plugin(system)
- Eure Fragen zu Tutorials
- Forum Support
- Fragen und Antworten
- Pluginsystem
- Plugins
- Templates & Sprachen
- Bugreport
- Verbesserungsvorschläge
- Sponsoren gesucht
- Das neue Xobor Business-Template
- News und Updates
- Bugreport
- Allgemeines Feedback
- Verbesserungsvorschläge
- Sonstiges
- Kaffeeklatsch
- Lob & Kritik
- Verbesserungsvorschläge
- Allgemeine Fragen
- Fehlermeldungen
- Verbesserungsvorschläge Responsive Design
- Bugreport Responsive Design
- Archiv - Alter Betatest
- Responsive Design - Verbesserungsvorschläge
- Responsive Design - Bugreport
- Fragen zum neuen Template
- Neue Administration Beta Test
- Bugreport Neue Administration
- Allgemeines Fragen & Feedback
- Verbesserungsvorschläge zur neuen Administration
- Shoutbox
Ähnliche Themen
Jetzt anmelden!
Jetzt registrieren!
© 2017 Xobor | Forum-Software