Merge pull request #100 from hhu-propra2/import-csv-in-overview
Import csv in editMembers overview
This commit is contained in:
@ -5,36 +5,27 @@ import mops.gruppen2.domain.Exceptions.EventException;
|
|||||||
import mops.gruppen2.domain.Group;
|
import mops.gruppen2.domain.Group;
|
||||||
import mops.gruppen2.domain.Role;
|
import mops.gruppen2.domain.Role;
|
||||||
import mops.gruppen2.domain.User;
|
import mops.gruppen2.domain.User;
|
||||||
import mops.gruppen2.domain.Visibility;
|
|
||||||
import mops.gruppen2.domain.event.CreateGroupEvent;
|
|
||||||
import mops.gruppen2.domain.event.UpdateRoleEvent;
|
|
||||||
import mops.gruppen2.security.Account;
|
import mops.gruppen2.security.Account;
|
||||||
import mops.gruppen2.service.*;
|
import mops.gruppen2.service.*;
|
||||||
import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken;
|
import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.ui.Model;
|
import org.springframework.ui.Model;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.client.RestTemplate;
|
|
||||||
import org.springframework.web.context.annotation.SessionScope;
|
import org.springframework.web.context.annotation.SessionScope;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import org.springframework.web.server.ResponseStatusException;
|
import org.springframework.web.server.ResponseStatusException;
|
||||||
|
|
||||||
import javax.annotation.security.RolesAllowed;
|
import javax.annotation.security.RolesAllowed;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
@Controller
|
@Controller
|
||||||
@SessionScope
|
@SessionScope
|
||||||
@RequestMapping("/gruppen2")
|
@RequestMapping("/gruppen2")
|
||||||
public class Gruppen2Controller {
|
public class Gruppen2Controller {
|
||||||
|
|
||||||
@Autowired
|
|
||||||
Gruppen2Config gruppen2Config;
|
Gruppen2Config gruppen2Config;
|
||||||
|
|
||||||
private final KeyCloakService keyCloakService;
|
private final KeyCloakService keyCloakService;
|
||||||
private final EventService eventService;
|
private final EventService eventService;
|
||||||
private final GroupService groupService;
|
private final GroupService groupService;
|
||||||
@ -82,16 +73,31 @@ public class Gruppen2Controller {
|
|||||||
@RequestParam(value = "title") String title,
|
@RequestParam(value = "title") String title,
|
||||||
@RequestParam(value = "beschreibung") String beschreibung,
|
@RequestParam(value = "beschreibung") String beschreibung,
|
||||||
@RequestParam(value = "visibility", required = false) Boolean visibility,
|
@RequestParam(value = "visibility", required = false) Boolean visibility,
|
||||||
@RequestParam(value = "file") MultipartFile file) throws IOException, EventException {
|
@RequestParam(value = "file", required = false) MultipartFile file) throws IOException, EventException {
|
||||||
|
|
||||||
Account account = keyCloakService.createAccountFromPrincipal(token);
|
Account account = keyCloakService.createAccountFromPrincipal(token);
|
||||||
List<User> userList = CsvService.read(file.getInputStream());
|
List<User> userList = new ArrayList<>();
|
||||||
|
if (!file.isEmpty()) {
|
||||||
|
userList = CsvService.read(file.getInputStream());
|
||||||
|
}
|
||||||
visibility = visibility == null;
|
visibility = visibility == null;
|
||||||
controllerService.createLecture(account, title, beschreibung, visibility, userList);
|
controllerService.createLecture(account, title, beschreibung, visibility, userList);
|
||||||
|
|
||||||
return "redirect:/gruppen2/";
|
return "redirect:/gruppen2/";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@RolesAllowed({"ROLE_orga", "ROLE_actuator)"})
|
||||||
|
@PostMapping("/details/members/addUsersFromCsv")
|
||||||
|
public String addUsersFromCsv(@RequestParam (value = "group_id") Long group_id,
|
||||||
|
@RequestParam(value = "file", required = false) MultipartFile file) throws IOException {
|
||||||
|
List<User> userList = new ArrayList<>();
|
||||||
|
if (!file.isEmpty()) {
|
||||||
|
userList = CsvService.read(file.getInputStream());
|
||||||
|
}
|
||||||
|
controllerService.addUserList(userList, group_id);
|
||||||
|
return "redirect:/gruppen2/details/members/" + group_id;
|
||||||
|
}
|
||||||
|
|
||||||
@RolesAllowed({"ROLE_orga", "ROLE_studentin", "ROLE_actuator)"})
|
@RolesAllowed({"ROLE_orga", "ROLE_studentin", "ROLE_actuator)"})
|
||||||
@GetMapping("/createGroup")
|
@GetMapping("/createGroup")
|
||||||
public String createGroup(KeycloakAuthenticationToken token, Model model) {
|
public String createGroup(KeycloakAuthenticationToken token, Model model) {
|
||||||
@ -112,7 +118,6 @@ public class Gruppen2Controller {
|
|||||||
return "search";
|
return "search";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@RolesAllowed({"ROLE_orga", "ROLE_studentin", "ROLE_actuator"})
|
@RolesAllowed({"ROLE_orga", "ROLE_studentin", "ROLE_actuator"})
|
||||||
@PostMapping("/createGroup")
|
@PostMapping("/createGroup")
|
||||||
public String pCreateGroup(KeycloakAuthenticationToken token,
|
public String pCreateGroup(KeycloakAuthenticationToken token,
|
||||||
@ -196,6 +201,7 @@ public class Gruppen2Controller {
|
|||||||
Account account = keyCloakService.createAccountFromPrincipal(token);
|
Account account = keyCloakService.createAccountFromPrincipal(token);
|
||||||
Group group = userService.getGroupById(id);
|
Group group = userService.getGroupById(id);
|
||||||
if(group.getRoles().get(account.getName()) == Role.ADMIN) {
|
if(group.getRoles().get(account.getName()) == Role.ADMIN) {
|
||||||
|
model.addAttribute("account", account);
|
||||||
model.addAttribute("members", group.getMembers());
|
model.addAttribute("members", group.getMembers());
|
||||||
model.addAttribute("group", group);
|
model.addAttribute("group", group);
|
||||||
model.addAttribute("admin", Role.ADMIN);
|
model.addAttribute("admin", Role.ADMIN);
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
package mops.gruppen2.service;
|
package mops.gruppen2.service;
|
||||||
|
|
||||||
import mops.gruppen2.domain.*;
|
import mops.gruppen2.domain.*;
|
||||||
|
|
||||||
import mops.gruppen2.domain.Exceptions.EventException;
|
import mops.gruppen2.domain.Exceptions.EventException;
|
||||||
import mops.gruppen2.domain.event.*;
|
import mops.gruppen2.domain.event.*;
|
||||||
import mops.gruppen2.security.Account;
|
import mops.gruppen2.security.Account;
|
||||||
@ -15,7 +14,6 @@ import java.util.UUID;
|
|||||||
public class ControllerService {
|
public class ControllerService {
|
||||||
|
|
||||||
private final EventService eventService;
|
private final EventService eventService;
|
||||||
|
|
||||||
private final UserService userService;
|
private final UserService userService;
|
||||||
private final InviteLinkRepositoryService inviteLinkRepositoryService;
|
private final InviteLinkRepositoryService inviteLinkRepositoryService;
|
||||||
|
|
||||||
@ -25,20 +23,11 @@ public class ControllerService {
|
|||||||
this.inviteLinkRepositoryService = inviteLinkRepositoryService;
|
this.inviteLinkRepositoryService = inviteLinkRepositoryService;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Erzeugt eine neue Gruppe, fügt den User, der die Gruppe erstellt hat, hinzu und setzt seine Rolle als Admin fest.
|
|
||||||
* Zudem wird der Gruppentitel und die Gruppenbeschreibung erzeugt, welche vorher der Methode übergeben wurden.
|
|
||||||
* Aus diesen Event Objekten wird eine Liste erzeugt, welche daraufhin mithilfe des EventServices gesichert wird.
|
|
||||||
*
|
|
||||||
* @param account Keycloak-Account
|
|
||||||
* @param title Gruppentitel
|
|
||||||
* @param description Gruppenbeschreibung
|
|
||||||
*/
|
|
||||||
public void createGroup(Account account, String title, String description, Boolean visibility) throws EventException {
|
public void createGroup(Account account, String title, String description, Boolean visibility) throws EventException {
|
||||||
Visibility visibility1;
|
Visibility visibility1;
|
||||||
Long group_id = eventService.checkGroup();
|
Long group_id = eventService.checkGroup();
|
||||||
|
|
||||||
if(visibility) {
|
if (visibility) {
|
||||||
visibility1 = Visibility.PUBLIC;
|
visibility1 = Visibility.PUBLIC;
|
||||||
} else {
|
} else {
|
||||||
visibility1 = Visibility.PRIVATE;
|
visibility1 = Visibility.PRIVATE;
|
||||||
@ -90,7 +79,7 @@ public class ControllerService {
|
|||||||
if(member.getUser_id().equals(user_id)) user = member;
|
if(member.getUser_id().equals(user_id)) user = member;
|
||||||
}
|
}
|
||||||
assert user != null;
|
assert user != null;
|
||||||
if(group.getRoles().get(user.getUser_id()) == Role.ADMIN) {
|
if (group.getRoles().get(user.getUser_id()) == Role.ADMIN) {
|
||||||
updateRoleEvent = new UpdateRoleEvent(group_id, user.getUser_id(), Role.MEMBER);
|
updateRoleEvent = new UpdateRoleEvent(group_id, user.getUser_id(), Role.MEMBER);
|
||||||
} else {
|
} else {
|
||||||
updateRoleEvent = new UpdateRoleEvent(group_id, user.getUser_id(), Role.ADMIN);
|
updateRoleEvent = new UpdateRoleEvent(group_id, user.getUser_id(), Role.ADMIN);
|
||||||
@ -132,6 +121,5 @@ public class ControllerService {
|
|||||||
updateDescription(account, group_id, description);
|
updateDescription(account, group_id, description);
|
||||||
updateRole(account.getName(), group_id);
|
updateRole(account.getName(), group_id);
|
||||||
addUserList(users, group_id);
|
addUserList(users, group_id);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,6 +7,10 @@
|
|||||||
<title>Gruppenerstellung</title>
|
<title>Gruppenerstellung</title>
|
||||||
<th:block th:fragment="headcontent">
|
<th:block th:fragment="headcontent">
|
||||||
<!-- Links, Skripts, Styles hier einfügen! -->
|
<!-- Links, Skripts, Styles hier einfügen! -->
|
||||||
|
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css">
|
||||||
|
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
|
||||||
|
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"></script>
|
||||||
</th:block>
|
</th:block>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
@ -49,7 +53,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="form-group pt-4">
|
<div class="form-group pt-4">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-10">
|
<div class="col">
|
||||||
<div class="custom-file">
|
<div class="custom-file">
|
||||||
<input type="file" class="custom-file-input" id="file" th:name="file">
|
<input type="file" class="custom-file-input" id="file" th:name="file">
|
||||||
<label class="custom-file-label" for="file">CSV Datei von Mitgliedern hochladen</label>
|
<label class="custom-file-label" for="file">CSV Datei von Mitgliedern hochladen</label>
|
||||||
@ -65,6 +69,13 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<script>
|
||||||
|
// Add the following code if you want the name of the file appear on select
|
||||||
|
$(".custom-file-input").on("change", function() {
|
||||||
|
var fileName = $(this).val().split("\\").pop();
|
||||||
|
$(this).siblings(".custom-file-label").addClass("selected").html(fileName);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
</main>
|
</main>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
@ -30,36 +30,35 @@
|
|||||||
<main th:fragment="bodycontent">
|
<main th:fragment="bodycontent">
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
|
||||||
<div class="col-9 shadow-sm p-4" style="border: 10px solid aliceblue; background: aliceblue">
|
<div class="col-9 shadow-sm p-4" style="border: 10px solid aliceblue; background: aliceblue">
|
||||||
<h1 style="color: black; font-weight: bold" th:text="${group.getTitle()}"></h1>
|
<h1 style="color: black; font-weight: bold" th:text="${group.getTitle()}"></h1>
|
||||||
<h3>
|
<h3>
|
||||||
<span class="badge badge-pill badge-dark" style="background: darkslategray" th:if='${group.getVisibility() == group.getVisibility().PRIVATE }'>Private Gruppe</span>
|
<span class="badge badge-pill badge-dark" style="background: darkslategray" th:if='${group.getVisibility() == group.getVisibility().PRIVATE }'>Private Gruppe</span>
|
||||||
<span class="badge badge-pill badge-primary" th:if="${group.getVisibility() == group.getVisibility().PUBLIC}">Öffentliche Gruppe</span>
|
<span class="badge badge-pill badge-primary" th:if="${group.getVisibility() == group.getVisibility().PUBLIC}">Öffentliche Gruppe</span>
|
||||||
<span class="badge badge-pill badge-success" style="background: lightseagreen" th:if='${group.getType() == group.getType().LECTURE}'> Veranstaltung</span>
|
<span class="badge badge-pill badge-success" style="background: lightseagreen" th:if='${group.getType() == group.getType().LECTURE}'> Veranstaltung</span>
|
||||||
</h3>
|
</h3>
|
||||||
<br>
|
<br>
|
||||||
<div class="shadow-sm p-4" style="background: white">
|
<div class="shadow-sm p-4" style="background: white">
|
||||||
<p style="overflow-wrap: break-word" th:text="${group.getDescription()}"></p>
|
<p style="overflow-wrap: break-word" th:text="${group.getDescription()}"></p>
|
||||||
</div>
|
</div>
|
||||||
<br>
|
<br>
|
||||||
<div class="text-right btn-toolbar" style="float: right" role="toolbar">
|
<div class="text-right btn-toolbar" style="float: right" role="toolbar">
|
||||||
<button class="btn btn-primary" style="background: dodgerblue; border: none; margin: 5px">
|
<button class="btn btn-primary" style="background: dodgerblue; border: none; margin: 5px">
|
||||||
<a th:href="@{/gruppen2}" style="color: white">Zurück</a>
|
<a th:href="@{/gruppen2}" style="color: white">Zurück</a>
|
||||||
</button>
|
</button>
|
||||||
<form method="post" action="/gruppen2/leaveGroup">
|
<form method="post" action="/gruppen2/leaveGroup">
|
||||||
<button th:value="${group.getId()}" th:name="group_id" class="btn btn-danger" type="submit" style="border-style: none; margin: 5px">Gruppe verlassen</button>
|
<button th:value="${group.getId()}" th:name="group_id" class="btn btn-danger" type="submit" style="border-style: none; margin: 5px">Gruppe verlassen</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-3" style="white-space: nowrap">
|
<div class="col-3" style="white-space: nowrap">
|
||||||
<div style="display: inline-block; margin: 0">
|
<div style="display: inline-block; margin: 0">
|
||||||
<h2>Mitglieder</h2>
|
<h2>Mitglieder</h2>
|
||||||
<div th:if='${group.getRoles().get(user.getUser_id()) == admin}'>
|
<div th:if='${group.getRoles().get(user.getUser_id()) == admin}'>
|
||||||
<form method="get" th:action="@{/gruppen2/details/members/{id}(id=${group.getId()})}">
|
<form method="get" th:action="@{/gruppen2/details/members/{id}(id=${group.getId()})}">
|
||||||
<button class="btn btn-secondary" style="background: slategrey; float: right" >
|
<button class="btn btn-secondary" style="background: slategrey; float: right">
|
||||||
Mitglieder bearbeiten
|
Mitglieder bearbeiten
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<br>
|
<br>
|
||||||
|
|||||||
@ -32,22 +32,22 @@
|
|||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-9">
|
<div class="col-9">
|
||||||
<div class="shadow-sm p-4" style="border: 10px solid aliceblue; background: aliceblue">
|
<div class="shadow-sm p-4" style="border: 10px solid aliceblue; background: aliceblue">
|
||||||
<h1 style="color: black; font-weight: bold" th:text="${group.getTitle()}"></h1>
|
<h1 style="color: black; font-weight: bold" th:text="${group.getTitle()}"></h1>
|
||||||
<h3>
|
<h3>
|
||||||
<span class="badge badge-pill badge-dark" style="background: darkslategray" th:if='${group.getVisibility() == group.getVisibility().PRIVATE }'>Private Gruppe</span>
|
<span class="badge badge-pill badge-dark" style="background: darkslategray" th:if='${group.getVisibility() == group.getVisibility().PRIVATE }'>Private Gruppe</span>
|
||||||
<span class="badge badge-pill badge-primary" th:if="${group.getVisibility() == group.getVisibility().PUBLIC}">Öffentliche Gruppe</span>
|
<span class="badge badge-pill badge-primary" th:if="${group.getVisibility() == group.getVisibility().PUBLIC}">Öffentliche Gruppe</span>
|
||||||
<span class="badge badge-pill badge-success" style="background: lightseagreen" th:if='${group.getType() == group.getType().LECTURE}'> Veranstaltung</span>
|
<span class="badge badge-pill badge-success" style="background: lightseagreen" th:if='${group.getType() == group.getType().LECTURE}'> Veranstaltung</span>
|
||||||
</h3>
|
</h3>
|
||||||
<div class="shadow-sm p-4" style="background: white">
|
<div class="shadow-sm p-4" style="background: white">
|
||||||
<p style="overflow-wrap: break-word" th:text="${group.getDescription()}"></p>
|
<p style="overflow-wrap: break-word" th:text="${group.getDescription()}"></p>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div class="text-right">
|
<div class="text-right">
|
||||||
<form method="post" action="/gruppen2/detailsBeitreten">
|
<form method="post" action="/gruppen2/detailsBeitreten">
|
||||||
<button type="submit" th:href="@{/gruppen2/detailsBeitreten(id=${group.getId()})}" th:name="id" th:value="${group.id}" class="btn btn-primary" style="border-style: none;">Gruppe beitreten</button>
|
<button type="submit" th:href="@{/gruppen2/detailsBeitreten(id=${group.getId()})}" th:name="id" th:value="${group.id}" class="btn btn-primary" style="border-style: none;">Gruppe beitreten</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -6,6 +6,10 @@
|
|||||||
<title>Gruppendetails</title>
|
<title>Gruppendetails</title>
|
||||||
<th:block th:fragment="headcontent">
|
<th:block th:fragment="headcontent">
|
||||||
<!-- Links, Skripts, Styles hier einfügen! -->
|
<!-- Links, Skripts, Styles hier einfügen! -->
|
||||||
|
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css">
|
||||||
|
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
|
||||||
|
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"></script>
|
||||||
</th:block>
|
</th:block>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
@ -21,6 +25,9 @@
|
|||||||
<li>
|
<li>
|
||||||
<a th:href="@{/gruppen2/findGroup}" href="/findGroup">Suche</a>
|
<a th:href="@{/gruppen2/findGroup}" href="/findGroup">Suche</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li th:if="${account.getRoles().contains('orga')}">
|
||||||
|
<a th:href="@{/gruppen2/createLecture}" href="/createLecture">Veranstaltung</a>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
@ -29,6 +36,22 @@
|
|||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-9">
|
<div class="col-9">
|
||||||
<div class="shadow p-2" style="border: 10px solid aliceblue; background: aliceblue">
|
<div class="shadow p-2" style="border: 10px solid aliceblue; background: aliceblue">
|
||||||
|
<!-- absichern im controller nicht vergessen -->
|
||||||
|
<div class="form-group pt-4" th:if="${account.getRoles().contains('orga')}">
|
||||||
|
<form method="post" action="/gruppen2/details/members/addUsersFromCsv" enctype="multipart/form-data">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-9">
|
||||||
|
<div class="custom-file">
|
||||||
|
<input type="file" class="custom-file-input" id="file" th:name="file">
|
||||||
|
<label class="custom-file-label" for="file">CSV Datei von Mitgliedern hochladen</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-3">
|
||||||
|
<button th:name="group_id" th:value="${group.getId()}" class="btn btn-primary" type="submit" style="background: #52a1eb; border-style: none">Mitglieder hinzufügen</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
<table class="table">
|
<table class="table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
@ -67,4 +90,11 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<script>
|
||||||
|
// Add the following code if you want the name of the file appear on select
|
||||||
|
$(".custom-file-input").on("change", function() {
|
||||||
|
var fileName = $(this).val().split("\\").pop();
|
||||||
|
$(this).siblings(".custom-file-label").addClass("selected").html(fileName);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
</main>
|
</main>
|
||||||
|
|||||||
@ -43,7 +43,6 @@
|
|||||||
<br>
|
<br>
|
||||||
<div th:each="gruppe: ${gruppen}">
|
<div th:each="gruppe: ${gruppen}">
|
||||||
<div class="shadow-sm p-4" style="border: none; background: aliceblue">
|
<div class="shadow-sm p-4" style="border: none; background: aliceblue">
|
||||||
|
|
||||||
<h3 style="color: dodgerblue; font-weight: bold;">
|
<h3 style="color: dodgerblue; font-weight: bold;">
|
||||||
<a th:href="@{/gruppen2/details/{id}(id=${gruppe.getId()})}" th:text="${gruppe.getTitle()}"></a>
|
<a th:href="@{/gruppen2/details/{id}(id=${gruppe.getId()})}" th:text="${gruppe.getTitle()}"></a>
|
||||||
</h3>
|
</h3>
|
||||||
|
|||||||
Reference in New Issue
Block a user