Merge branch 'dev' into 'main'
Teil 2 See merge request eb2342s/swe-b1-a!34
This commit was merged in pull request #94.
This commit is contained in:
@@ -18,6 +18,8 @@ Um die Webseite auszuführen, benötigen Sie:
|
|||||||
|
|
||||||
### 2. PHP aktivieren
|
### 2. PHP aktivieren
|
||||||
|
|
||||||
|
- Aktivieren Sie die PHP-Extension "mbstring" (extension=mbstring) in Ihrer verwendeten php.ini Konfigurationsdatei
|
||||||
|
|
||||||
#### a) Apache
|
#### a) Apache
|
||||||
- Stellen Sie sicher, dass das Modul `mod_php` aktiviert ist.
|
- Stellen Sie sicher, dass das Modul `mod_php` aktiviert ist.
|
||||||
- Überprüfen Sie die Apache-Konfigurationsdatei (z. B. `httpd.conf`), und stellen Sie sicher, dass PHP korrekt eingebunden ist:
|
- Überprüfen Sie die Apache-Konfigurationsdatei (z. B. `httpd.conf`), und stellen Sie sicher, dass PHP korrekt eingebunden ist:
|
||||||
|
|||||||
@@ -208,14 +208,147 @@ body {
|
|||||||
|
|
||||||
/* List style improvement */
|
/* List style improvement */
|
||||||
.content-text li {
|
.content-text li {
|
||||||
position: relative;
|
margin-left: 1.5rem;
|
||||||
padding-left: 1.5rem;
|
padding-left: 0.5rem;
|
||||||
margin-bottom: 0.5rem;
|
margin-bottom: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.content-text li::before {
|
.content-text ul li {
|
||||||
content: '•';
|
list-style-type: disc;
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.content-text ol li {
|
||||||
|
list-style-type: decimal;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Einzelne Toast Styles */
|
||||||
|
.toast-content {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
border-radius: 12px; /* Abgerundete Ecken */
|
||||||
|
padding: 20px;
|
||||||
|
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
||||||
|
min-width: 200px;
|
||||||
|
max-width: 80%;
|
||||||
|
transition: opacity 0.5s ease, transform 0.5s ease;
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(-20px);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Spezifische Klassen für verschiedene Toast-Typen */
|
||||||
|
.toast-success {
|
||||||
|
background-color: #38a169; /* Grüner Hintergrund */
|
||||||
|
}
|
||||||
|
|
||||||
|
.toast-error {
|
||||||
|
background-color: #e53e3e; /* Roter Hintergrund */
|
||||||
|
}
|
||||||
|
|
||||||
|
.toast-info {
|
||||||
|
background-color: #4299e1; /* Blauer Hintergrund */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Sichtbarkeit */
|
||||||
|
.toast-content.show {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Icon Styling */
|
||||||
|
.toast-icon {
|
||||||
|
font-size: 32px; /* Größeres Icon */
|
||||||
|
margin-right: 20px; /* Abstand zwischen Icon und Text */
|
||||||
|
color: white; /* Icons sollen immer weiß sein */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Nachrichten-Text Styling */
|
||||||
|
.toast-message {
|
||||||
|
color: white;
|
||||||
|
font-size: 18px; /* Größere Schriftgröße */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.task-container {
|
||||||
|
border-radius: 20px;
|
||||||
|
padding: 2rem;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
/*box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);*/
|
||||||
|
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.variable-input{
|
||||||
|
border: 2px solid;
|
||||||
|
border-radius: 8px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Einzelne Toast Styles */
|
||||||
|
.toast-content {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
border-radius: 12px; /* Abgerundete Ecken */
|
||||||
|
padding: 20px;
|
||||||
|
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
||||||
|
min-width: 200px;
|
||||||
|
max-width: 80%;
|
||||||
|
transition: opacity 0.5s ease, transform 0.5s ease;
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(-20px);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Spezifische Klassen für verschiedene Toast-Typen */
|
||||||
|
.toast-success {
|
||||||
|
background-color: #38a169; /* Grüner Hintergrund */
|
||||||
|
}
|
||||||
|
|
||||||
|
.toast-error {
|
||||||
|
background-color: #e53e3e; /* Roter Hintergrund */
|
||||||
|
}
|
||||||
|
|
||||||
|
.toast-info {
|
||||||
|
background-color: #4299e1; /* Blauer Hintergrund */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Sichtbarkeit */
|
||||||
|
.toast-content.show {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Icon Styling */
|
||||||
|
.toast-icon {
|
||||||
|
font-size: 32px; /* Größeres Icon */
|
||||||
|
margin-right: 20px; /* Abstand zwischen Icon und Text */
|
||||||
|
color: white; /* Icons sollen immer weiß sein */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Nachrichten-Text Styling */
|
||||||
|
.toast-message {
|
||||||
|
color: white;
|
||||||
|
font-size: 18px; /* Größere Schriftgröße */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.task-container {
|
||||||
|
border-radius: 20px;
|
||||||
|
padding: 2rem;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
/*box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);*/
|
||||||
|
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.variable-input{
|
||||||
|
border: 2px solid;
|
||||||
|
border-radius: 8px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
margin: auto;
|
||||||
|
padding: 2rem;
|
||||||
|
background: white;
|
||||||
|
border-radius: 1rem;
|
||||||
|
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
171
webseite/assets/js/dropdown_menu.js
Normal file
171
webseite/assets/js/dropdown_menu.js
Normal file
@@ -0,0 +1,171 @@
|
|||||||
|
// JavaScript to handle opening and closing of the change password popup
|
||||||
|
const changePasswordButton = document.getElementById('changePasswordButton');
|
||||||
|
const changePasswordPopup = document.getElementById('changePasswordPopup');
|
||||||
|
const closeChangePasswordPopupButton = document.getElementById('closeChangePasswordPopupButton');
|
||||||
|
|
||||||
|
if (changePasswordButton) { // Überprüfen, ob das Element vorhanden ist
|
||||||
|
changePasswordButton.addEventListener('click', function () {
|
||||||
|
if (changePasswordPopup) {
|
||||||
|
changePasswordPopup.classList.remove('hidden');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (closeChangePasswordPopupButton) {
|
||||||
|
closeChangePasswordPopupButton.addEventListener('click', function () {
|
||||||
|
if (changePasswordPopup) {
|
||||||
|
changePasswordPopup.classList.add('hidden');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
window.addEventListener('click', function (event) {
|
||||||
|
if (event.target === changePasswordPopup) {
|
||||||
|
changePasswordPopup.classList.add('hidden');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Close popup with ESC key
|
||||||
|
document.addEventListener('keydown', function (event) {
|
||||||
|
if (event.key === "Escape" && !changePasswordPopup.classList.contains('hidden')) {
|
||||||
|
changePasswordPopup.classList.add('hidden');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Zeige Fehlermeldung beim Passwort ändern an
|
||||||
|
window.addEventListener('DOMContentLoaded', () => {
|
||||||
|
const urlParams = new URLSearchParams(window.location.search);
|
||||||
|
|
||||||
|
if (urlParams.has('password_error')) {
|
||||||
|
const changePasswordPopup = document.getElementById('changePasswordPopup');
|
||||||
|
const changePasswordErrorMessage = document.getElementById('changePasswordErrorMessage');
|
||||||
|
const errorType = urlParams.get('password_error');
|
||||||
|
|
||||||
|
changePasswordPopup.classList.remove('hidden');
|
||||||
|
changePasswordErrorMessage.classList.remove('hidden');
|
||||||
|
|
||||||
|
switch (errorType) {
|
||||||
|
case 'wrong_current_password':
|
||||||
|
changePasswordErrorMessage.textContent = 'Das aktuelle Passwort ist falsch.';
|
||||||
|
break;
|
||||||
|
case 'password_mismatch':
|
||||||
|
changePasswordErrorMessage.textContent = 'Die neuen Passwörter stimmen nicht überein.';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
changePasswordErrorMessage.textContent = 'Fehler beim Ändern des Passworts.';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Zeige Erfolgspopup beim Passwortwechsel an
|
||||||
|
window.addEventListener('DOMContentLoaded', (event) => {
|
||||||
|
const urlParams = new URLSearchParams(window.location.search);
|
||||||
|
|
||||||
|
if (urlParams.has('password_success')) {
|
||||||
|
const passwordSuccessPopup = document.getElementById('passwordSuccessPopup');
|
||||||
|
if (passwordSuccessPopup) {
|
||||||
|
passwordSuccessPopup.classList.remove('hidden');
|
||||||
|
}
|
||||||
|
const closeSuccessPopup = document.getElementById('closeSuccessPopup');
|
||||||
|
if (closeSuccessPopup) {
|
||||||
|
closeSuccessPopup.addEventListener('click', () => {
|
||||||
|
passwordSuccessPopup.classList.add('hidden');
|
||||||
|
// Optional: Entferne den URL-Parameter ohne Neuladen
|
||||||
|
const newUrl = window.location.href.split('?')[0];
|
||||||
|
window.history.replaceState({}, document.title, newUrl);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Dropdown öffnen/schließen
|
||||||
|
const userDropdownToggle = document.getElementById('userDropdownToggle');
|
||||||
|
const userDropdownMenu = document.getElementById('userDropdownMenu');
|
||||||
|
|
||||||
|
if (userDropdownToggle && userDropdownMenu) {
|
||||||
|
userDropdownToggle.addEventListener('click', (event) => {
|
||||||
|
event.stopPropagation(); // Verhindert das Schließen des Menüs bei Klick auf den Button
|
||||||
|
userDropdownMenu.classList.toggle('hidden');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Schließe Dropdown, wenn außerhalb geklickt wird
|
||||||
|
window.addEventListener('click', () => {
|
||||||
|
if (!userDropdownMenu.classList.contains('hidden')) {
|
||||||
|
userDropdownMenu.classList.add('hidden');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Schließe Dropdown mit ESC
|
||||||
|
document.addEventListener('keydown', (event) => {
|
||||||
|
if (event.key === "Escape" && !userDropdownMenu.classList.contains('hidden')) {
|
||||||
|
userDropdownMenu.classList.add('hidden');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Passwort ändern über Dropdown öffnen
|
||||||
|
const dropdownChangePasswordButton = document.getElementById('dropdownChangePasswordButton');
|
||||||
|
if (dropdownChangePasswordButton) {
|
||||||
|
dropdownChangePasswordButton.addEventListener('click', () => {
|
||||||
|
const changePasswordPopup = document.getElementById('changePasswordPopup');
|
||||||
|
if (changePasswordPopup) {
|
||||||
|
changePasswordPopup.classList.remove('hidden');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
document.getElementById('openSearchDialog').addEventListener('click', function () {
|
||||||
|
document.getElementById('searchDialog').classList.remove('hidden');
|
||||||
|
});
|
||||||
|
|
||||||
|
document.getElementById('closeSearchDialog').addEventListener('click', function () {
|
||||||
|
document.getElementById('searchDialog').classList.add('hidden');
|
||||||
|
});
|
||||||
|
|
||||||
|
function debounce(func, delay) {
|
||||||
|
let debounceTimer;
|
||||||
|
return function () {
|
||||||
|
const context = this;
|
||||||
|
const args = arguments;
|
||||||
|
clearTimeout(debounceTimer);
|
||||||
|
debounceTimer = setTimeout(() => func.apply(context, args), delay);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const searchInput = document.getElementById('searchInput');
|
||||||
|
const resultsContainer = document.getElementById('searchResults');
|
||||||
|
|
||||||
|
searchInput.addEventListener('input', debounce(function () {
|
||||||
|
const query = this.value.toLowerCase();
|
||||||
|
resultsContainer.innerHTML = '';
|
||||||
|
|
||||||
|
if (query.length > 0) {
|
||||||
|
fetch('search.php?query=' + query)
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
data.forEach(item => {
|
||||||
|
const resultItem = document.createElement('div');
|
||||||
|
resultItem.classList.add('p-4', 'mb-2', 'rounded-lg', 'bg-white', 'hover:bg-gray-100', 'transition', 'duration-100', 'flex', 'items-center', 'space-x-2', 'cursor-pointer');
|
||||||
|
|
||||||
|
const subjectSpan = document.createElement('span');
|
||||||
|
subjectSpan.classList.add('font-bold');
|
||||||
|
subjectSpan.textContent = item.displayName.split(' - ')[0];
|
||||||
|
|
||||||
|
const breadcrumbSpan = document.createElement('span');
|
||||||
|
breadcrumbSpan.classList.add('text-gray-500');
|
||||||
|
breadcrumbSpan.textContent = item.displayName.split(' - ').slice(1).join(' > ');
|
||||||
|
|
||||||
|
resultItem.appendChild(subjectSpan);
|
||||||
|
resultItem.appendChild(breadcrumbSpan);
|
||||||
|
|
||||||
|
resultItem.addEventListener('click', function () {
|
||||||
|
if (item.type === 'subject') {
|
||||||
|
window.location.href = 'subject.php?subject=' + item.id;
|
||||||
|
} else {
|
||||||
|
window.location.href = 'topic.php?subject=' + item.subjectId + '&topic=' + item.id;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
resultsContainer.appendChild(resultItem);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, 300));
|
||||||
158
webseite/assets/js/formula.js
Normal file
158
webseite/assets/js/formula.js
Normal file
@@ -0,0 +1,158 @@
|
|||||||
|
function createFormula(text = "") {
|
||||||
|
const formulaInputs = document.querySelector('#formulaInputs');
|
||||||
|
|
||||||
|
const formulaElement = document.createElement('div');
|
||||||
|
formulaElement.classList.add('input-formula', "pb-10");
|
||||||
|
formulaElement.id = "f-" + crypto.randomUUID();
|
||||||
|
|
||||||
|
const textElement = document.createElement('textarea');
|
||||||
|
textElement.type = 'text';
|
||||||
|
textElement.classList.add('input-text');
|
||||||
|
textElement.classList.add("w-full", "px-4", "py-3", "border", "rounded-lg", "focus:outline-none", "focus:ring-2", "focus:ring-blue-500", "text-lg", "enabled:hover:border-gray-400");
|
||||||
|
textElement.rows = 3;
|
||||||
|
textElement.placeholder = "Aufgabentext";
|
||||||
|
textElement.innerText = text;
|
||||||
|
textElement.onchange = updateFormulaText;
|
||||||
|
|
||||||
|
formulaElement.appendChild(textElement);
|
||||||
|
|
||||||
|
const variableSection = document.createElement('div');
|
||||||
|
variableSection.classList.add("input-variable-section");
|
||||||
|
formulaElement.appendChild(variableSection)
|
||||||
|
|
||||||
|
const buttonRow = document.createElement('div');
|
||||||
|
buttonRow.classList.add("flex", "flow-root");
|
||||||
|
|
||||||
|
const removeFormulaButton = document.createElement('button');
|
||||||
|
removeFormulaButton.type = "button";
|
||||||
|
removeFormulaButton.innerText = "Aufgabe löschen";
|
||||||
|
removeFormulaButton.classList.add("px-4", "py-3", "border", "rounded-lg", "focus:outline-none", "focus:ring-2", "focus:ring-blue-500", "text-lg", "enabled:hover:border-gray-400");
|
||||||
|
removeFormulaButton.onclick = () => {
|
||||||
|
formulaElement.remove();
|
||||||
|
};
|
||||||
|
buttonRow.appendChild(removeFormulaButton);
|
||||||
|
|
||||||
|
const addVariableButton = document.createElement('button');
|
||||||
|
addVariableButton.type = "button";
|
||||||
|
addVariableButton.innerText = "+";
|
||||||
|
addVariableButton.classList.add("w-2/12", "md:w-1/12", "float-right", "px-4", "py-3", "border", "rounded-lg", "focus:outline-none", "focus:ring-2", "focus:ring-blue-500", "text-lg", "enabled:hover:border-gray-400");
|
||||||
|
addVariableButton.onclick = () => {
|
||||||
|
createVariable(formulaElement.id);
|
||||||
|
};
|
||||||
|
buttonRow.appendChild(addVariableButton);
|
||||||
|
|
||||||
|
formulaElement.appendChild(buttonRow);
|
||||||
|
|
||||||
|
formulaInputs.appendChild(formulaElement);
|
||||||
|
|
||||||
|
return formulaElement.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
function createVariable(formulaUID, variableText = "", valueText = "") {
|
||||||
|
const element = document.querySelector("#" + formulaUID).querySelector(".input-variable-section");
|
||||||
|
|
||||||
|
const variableValueElement = document.createElement('div');
|
||||||
|
variableValueElement.classList.add('input-variables');
|
||||||
|
|
||||||
|
const variableElement = document.createElement('input');
|
||||||
|
variableElement.type = 'text';
|
||||||
|
variableElement.classList.add('input-variable');
|
||||||
|
variableElement.classList.add("w-5/12", "md:w-6/12", "px-4", "py-3", "border", "rounded-lg", "focus:outline-none", "focus:ring-2", "focus:ring-blue-500", "text-lg", "enabled:hover:border-gray-400")
|
||||||
|
variableElement.value = variableText;
|
||||||
|
variableElement.placeholder = "Variable";
|
||||||
|
variableElement.onchange = updateFormulaText;
|
||||||
|
variableValueElement.appendChild(variableElement);
|
||||||
|
|
||||||
|
const valueElement = document.createElement('input');
|
||||||
|
valueElement.type = 'text';
|
||||||
|
valueElement.classList.add('input-value');
|
||||||
|
valueElement.classList.add("w-5/12", "md:w-5/12", "px-4", "py-3", "border", "rounded-lg", "focus:outline-none", "focus:ring-2", "focus:ring-blue-500", "text-lg", "enabled:hover:border-gray-400")
|
||||||
|
valueElement.value = valueText;
|
||||||
|
valueElement.placeholder = "Richtiger Wert";
|
||||||
|
valueElement.onchange = updateFormulaText;
|
||||||
|
variableValueElement.appendChild(valueElement);
|
||||||
|
|
||||||
|
const removeButton = document.createElement('button');
|
||||||
|
removeButton.type = "button";
|
||||||
|
removeButton.innerText = "-"
|
||||||
|
removeButton.classList.add("w-2/12", "md:w-1/12", "px-4", "py-3", "border", "rounded-lg", "focus:outline-none", "focus:ring-2", "focus:ring-blue-500", "text-lg", "enabled:hover:border-gray-400");
|
||||||
|
removeButton.onclick = () => {
|
||||||
|
variableValueElement.remove();
|
||||||
|
updateFormulaText();
|
||||||
|
};
|
||||||
|
variableValueElement.appendChild(removeButton);
|
||||||
|
|
||||||
|
element.appendChild(variableValueElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
function createFormulaWithVariable() {
|
||||||
|
const uuid = createFormula();
|
||||||
|
createVariable(uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
function createFormulasFromString(string) {
|
||||||
|
const taskStrings = string.split(";;;;");
|
||||||
|
taskStrings.forEach((taskString) => {
|
||||||
|
const elements = taskString.split(";;");
|
||||||
|
if(elements.length < 2) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const text = elements[0];
|
||||||
|
const variables = elements.slice(1, elements.length);
|
||||||
|
|
||||||
|
const uid = createFormula(text);
|
||||||
|
|
||||||
|
variables.forEach((variableValuePair) => {
|
||||||
|
const arr = variableValuePair.split("::");
|
||||||
|
if(arr.length !== 2) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
createVariable(uid, arr[0], arr[1]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function getFormulasAsString() {
|
||||||
|
const formulaInputs = document.querySelector('#formulaInputs');
|
||||||
|
|
||||||
|
let formulas = [];
|
||||||
|
formulaInputs.querySelectorAll('.input-formula').forEach((formulaElement) => {
|
||||||
|
const text = formulaElement.querySelector(".input-text").value;
|
||||||
|
if(text.includes(";;")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let variables = [];
|
||||||
|
formulaElement.querySelectorAll(".input-variables").forEach((variableValueElement) => {
|
||||||
|
const variable = variableValueElement.querySelector(".input-variable");
|
||||||
|
const value = variableValueElement.querySelector(".input-value");
|
||||||
|
|
||||||
|
if(variable == null || value == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(variable.value.trim() === "" || value.value.trim() === "") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(variable.value.includes(";;") || variable.value.includes("::")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(value.value.includes(";;") || value.value.includes("::")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
variables.push(variable.value + "::" + value.value);
|
||||||
|
});
|
||||||
|
|
||||||
|
formulas.push(text + ";;" + variables.join(";;"));
|
||||||
|
});
|
||||||
|
|
||||||
|
return formulas.join(';;;;');
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateFormulaText() {
|
||||||
|
document.querySelector('#formulas').value = getFormulasAsString();
|
||||||
|
}
|
||||||
392
webseite/assets/js/katex_autorender_mod.js
Normal file
392
webseite/assets/js/katex_autorender_mod.js
Normal file
@@ -0,0 +1,392 @@
|
|||||||
|
(function webpackUniversalModuleDefinition(root, factory) {
|
||||||
|
if (typeof exports === 'object' && typeof module === 'object')
|
||||||
|
module.exports = factory(require("katex"));
|
||||||
|
else if (typeof define === 'function' && define.amd)
|
||||||
|
define(["katex"], factory);
|
||||||
|
else if (typeof exports === 'object')
|
||||||
|
exports["renderMathInElement"] = factory(require("katex"));
|
||||||
|
else
|
||||||
|
root["renderMathInElement"] = factory(root["katex"]);
|
||||||
|
})((typeof self !== 'undefined' ? self : this), function (__WEBPACK_EXTERNAL_MODULE__757__) {
|
||||||
|
return /******/ (function () { // webpackBootstrap
|
||||||
|
/******/
|
||||||
|
"use strict";
|
||||||
|
/******/
|
||||||
|
var __webpack_modules__ = ({
|
||||||
|
|
||||||
|
/***/ 757:
|
||||||
|
/***/ (function (module) {
|
||||||
|
|
||||||
|
module.exports = __WEBPACK_EXTERNAL_MODULE__757__;
|
||||||
|
|
||||||
|
/***/
|
||||||
|
})
|
||||||
|
|
||||||
|
/******/
|
||||||
|
});
|
||||||
|
/************************************************************************/
|
||||||
|
/******/ // The module cache
|
||||||
|
/******/
|
||||||
|
var __webpack_module_cache__ = {};
|
||||||
|
/******/
|
||||||
|
/******/ // The require function
|
||||||
|
/******/
|
||||||
|
function __webpack_require__(moduleId) {
|
||||||
|
/******/ // Check if module is in cache
|
||||||
|
/******/
|
||||||
|
var cachedModule = __webpack_module_cache__[moduleId];
|
||||||
|
/******/
|
||||||
|
if (cachedModule !== undefined) {
|
||||||
|
/******/
|
||||||
|
return cachedModule.exports;
|
||||||
|
/******/
|
||||||
|
}
|
||||||
|
/******/ // Create a new module (and put it into the cache)
|
||||||
|
/******/
|
||||||
|
var module = __webpack_module_cache__[moduleId] = {
|
||||||
|
/******/ // no module.id needed
|
||||||
|
/******/ // no module.loaded needed
|
||||||
|
/******/ exports: {}
|
||||||
|
/******/
|
||||||
|
};
|
||||||
|
/******/
|
||||||
|
/******/ // Execute the module function
|
||||||
|
/******/
|
||||||
|
__webpack_modules__[moduleId](module, module.exports, __webpack_require__);
|
||||||
|
/******/
|
||||||
|
/******/ // Return the exports of the module
|
||||||
|
/******/
|
||||||
|
return module.exports;
|
||||||
|
/******/
|
||||||
|
}
|
||||||
|
|
||||||
|
/******/
|
||||||
|
/************************************************************************/
|
||||||
|
/******/ /* webpack/runtime/compat get default export */
|
||||||
|
/******/
|
||||||
|
!function () {
|
||||||
|
/******/ // getDefaultExport function for compatibility with non-harmony modules
|
||||||
|
/******/
|
||||||
|
__webpack_require__.n = function (module) {
|
||||||
|
/******/
|
||||||
|
var getter = module && module.__esModule ?
|
||||||
|
/******/ function () {
|
||||||
|
return module['default'];
|
||||||
|
} :
|
||||||
|
/******/ function () {
|
||||||
|
return module;
|
||||||
|
};
|
||||||
|
/******/
|
||||||
|
__webpack_require__.d(getter, {a: getter});
|
||||||
|
/******/
|
||||||
|
return getter;
|
||||||
|
/******/
|
||||||
|
};
|
||||||
|
/******/
|
||||||
|
}();
|
||||||
|
/******/
|
||||||
|
/******/ /* webpack/runtime/define property getters */
|
||||||
|
/******/
|
||||||
|
!function () {
|
||||||
|
/******/ // define getter functions for harmony exports
|
||||||
|
/******/
|
||||||
|
__webpack_require__.d = function (exports, definition) {
|
||||||
|
/******/
|
||||||
|
for (var key in definition) {
|
||||||
|
/******/
|
||||||
|
if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
|
||||||
|
/******/
|
||||||
|
Object.defineProperty(exports, key, {enumerable: true, get: definition[key]});
|
||||||
|
/******/
|
||||||
|
}
|
||||||
|
/******/
|
||||||
|
}
|
||||||
|
/******/
|
||||||
|
};
|
||||||
|
/******/
|
||||||
|
}();
|
||||||
|
/******/
|
||||||
|
/******/ /* webpack/runtime/hasOwnProperty shorthand */
|
||||||
|
/******/
|
||||||
|
!function () {
|
||||||
|
/******/
|
||||||
|
__webpack_require__.o = function (obj, prop) {
|
||||||
|
return Object.prototype.hasOwnProperty.call(obj, prop);
|
||||||
|
}
|
||||||
|
/******/
|
||||||
|
}();
|
||||||
|
/******/
|
||||||
|
/************************************************************************/
|
||||||
|
var __webpack_exports__ = {};
|
||||||
|
|
||||||
|
// EXPORTS
|
||||||
|
__webpack_require__.d(__webpack_exports__, {
|
||||||
|
"default": function () {
|
||||||
|
return /* binding */ auto_render;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// EXTERNAL MODULE: external "katex"
|
||||||
|
var external_katex_ = __webpack_require__(757);
|
||||||
|
var external_katex_default = /*#__PURE__*/__webpack_require__.n(external_katex_);
|
||||||
|
;// CONCATENATED MODULE: ./contrib/auto-render/splitAtDelimiters.js
|
||||||
|
/* eslint no-constant-condition:0 */
|
||||||
|
const findEndOfMath = function (delimiter, text, startIndex) {
|
||||||
|
// Adapted from
|
||||||
|
// https://github.com/Khan/perseus/blob/master/src/perseus-markdown.jsx
|
||||||
|
let index = startIndex;
|
||||||
|
let braceLevel = 0;
|
||||||
|
const delimLength = delimiter.length;
|
||||||
|
|
||||||
|
while (index < text.length) {
|
||||||
|
const character = text[index];
|
||||||
|
|
||||||
|
if (braceLevel <= 0 && text.slice(index, index + delimLength) === delimiter) {
|
||||||
|
return index;
|
||||||
|
} else if (character === "\\") {
|
||||||
|
index++;
|
||||||
|
} else if (character === "{") {
|
||||||
|
braceLevel++;
|
||||||
|
} else if (character === "}") {
|
||||||
|
braceLevel--;
|
||||||
|
}
|
||||||
|
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
};
|
||||||
|
|
||||||
|
const escapeRegex = function (string) {
|
||||||
|
return string.replace(/[-/\\^$*+?.()|[\]{}]/g, "\\$&");
|
||||||
|
};
|
||||||
|
|
||||||
|
const amsRegex = /^\\begin{/;
|
||||||
|
|
||||||
|
const splitAtDelimiters = function (text, delimiters) {
|
||||||
|
let index;
|
||||||
|
const data = [];
|
||||||
|
const regexLeft = new RegExp("(" + delimiters.map(x => escapeRegex(x.left)).join("|") + ")");
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
index = text.search(regexLeft);
|
||||||
|
|
||||||
|
if (index === -1) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (index > 0) {
|
||||||
|
data.push({
|
||||||
|
type: "text",
|
||||||
|
data: text.slice(0, index)
|
||||||
|
});
|
||||||
|
text = text.slice(index); // now text starts with delimiter
|
||||||
|
} // ... so this always succeeds:
|
||||||
|
|
||||||
|
|
||||||
|
const i = delimiters.findIndex(delim => text.startsWith(delim.left));
|
||||||
|
index = findEndOfMath(delimiters[i].right, text, delimiters[i].left.length);
|
||||||
|
|
||||||
|
if (index === -1) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
const rawData = text.slice(0, index + delimiters[i].right.length);
|
||||||
|
const math = amsRegex.test(rawData) ? rawData : text.slice(delimiters[i].left.length, index);
|
||||||
|
data.push({
|
||||||
|
type: "math",
|
||||||
|
data: math,
|
||||||
|
rawData,
|
||||||
|
display: delimiters[i].display
|
||||||
|
});
|
||||||
|
text = text.slice(index + delimiters[i].right.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (text !== "") {
|
||||||
|
data.push({
|
||||||
|
type: "text",
|
||||||
|
data: text
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* harmony default export */
|
||||||
|
var auto_render_splitAtDelimiters = (splitAtDelimiters);
|
||||||
|
;// CONCATENATED MODULE: ./contrib/auto-render/auto-render.js
|
||||||
|
/* eslint no-console:0 */
|
||||||
|
|
||||||
|
|
||||||
|
/* Note: optionsCopy is mutated by this method. If it is ever exposed in the
|
||||||
|
* API, we should copy it before mutating.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const renderMathInText = function (text, optionsCopy) {
|
||||||
|
const data = auto_render_splitAtDelimiters(text, optionsCopy.delimiters);
|
||||||
|
|
||||||
|
if (data.length === 1 && data[0].type === 'text') {
|
||||||
|
// There is no formula in the text.
|
||||||
|
// Let's return null which means there is no need to replace
|
||||||
|
// the current text node with a new one.
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const fragment = document.createDocumentFragment();
|
||||||
|
|
||||||
|
for (let i = 0; i < data.length; i++) {
|
||||||
|
if (data[i].type === "text") {
|
||||||
|
fragment.appendChild(document.createTextNode(data[i].data));
|
||||||
|
} else {
|
||||||
|
const span = document.createElement("span");
|
||||||
|
let math = data[i].data; // Override any display mode defined in the settings with that
|
||||||
|
// defined by the text itself
|
||||||
|
|
||||||
|
optionsCopy.displayMode = data[i].display;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (optionsCopy.preProcess) {
|
||||||
|
math = optionsCopy.preProcess(math);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Modified segment (two lines):
|
||||||
|
makes the rendered Formula compatible with Quill by adding the required Data
|
||||||
|
*/
|
||||||
|
span.classList.add('ql-formula');
|
||||||
|
span.setAttribute('data-value', math);
|
||||||
|
|
||||||
|
external_katex_default().render(math, span, optionsCopy);
|
||||||
|
} catch (e) {
|
||||||
|
if (!(e instanceof (external_katex_default()).ParseError)) {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
|
||||||
|
optionsCopy.errorCallback("KaTeX auto-render: Failed to parse `" + data[i].data + "` with ", e);
|
||||||
|
fragment.appendChild(document.createTextNode(data[i].rawData));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
fragment.appendChild(span);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return fragment;
|
||||||
|
};
|
||||||
|
|
||||||
|
const renderElem = function (elem, optionsCopy) {
|
||||||
|
for (let i = 0; i < elem.childNodes.length; i++) {
|
||||||
|
const childNode = elem.childNodes[i];
|
||||||
|
|
||||||
|
if (childNode.nodeType === 3) {
|
||||||
|
// Text node
|
||||||
|
// Concatenate all sibling text nodes.
|
||||||
|
// Webkit browsers split very large text nodes into smaller ones,
|
||||||
|
// so the delimiters may be split across different nodes.
|
||||||
|
let textContentConcat = childNode.textContent;
|
||||||
|
let sibling = childNode.nextSibling;
|
||||||
|
let nSiblings = 0;
|
||||||
|
|
||||||
|
while (sibling && sibling.nodeType === Node.TEXT_NODE) {
|
||||||
|
textContentConcat += sibling.textContent;
|
||||||
|
sibling = sibling.nextSibling;
|
||||||
|
nSiblings++;
|
||||||
|
}
|
||||||
|
|
||||||
|
const frag = renderMathInText(textContentConcat, optionsCopy);
|
||||||
|
|
||||||
|
if (frag) {
|
||||||
|
// Remove extra text nodes
|
||||||
|
for (let j = 0; j < nSiblings; j++) {
|
||||||
|
childNode.nextSibling.remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
i += frag.childNodes.length - 1;
|
||||||
|
elem.replaceChild(frag, childNode);
|
||||||
|
} else {
|
||||||
|
// If the concatenated text does not contain math
|
||||||
|
// the siblings will not either
|
||||||
|
i += nSiblings;
|
||||||
|
}
|
||||||
|
} else if (childNode.nodeType === 1) {
|
||||||
|
// Element node
|
||||||
|
const className = ' ' + childNode.className + ' ';
|
||||||
|
const shouldRender = optionsCopy.ignoredTags.indexOf(childNode.nodeName.toLowerCase()) === -1 && optionsCopy.ignoredClasses.every(x => className.indexOf(' ' + x + ' ') === -1);
|
||||||
|
|
||||||
|
if (shouldRender) {
|
||||||
|
renderElem(childNode, optionsCopy);
|
||||||
|
}
|
||||||
|
} // Otherwise, it's something else, and ignore it.
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const renderMathInElement = function (elem, options) {
|
||||||
|
if (!elem) {
|
||||||
|
throw new Error("No element provided to render");
|
||||||
|
}
|
||||||
|
|
||||||
|
const optionsCopy = {}; // Object.assign(optionsCopy, option)
|
||||||
|
|
||||||
|
for (const option in options) {
|
||||||
|
if (options.hasOwnProperty(option)) {
|
||||||
|
optionsCopy[option] = options[option];
|
||||||
|
}
|
||||||
|
} // default options
|
||||||
|
|
||||||
|
|
||||||
|
optionsCopy.delimiters = optionsCopy.delimiters || [{
|
||||||
|
left: "$$",
|
||||||
|
right: "$$",
|
||||||
|
display: true
|
||||||
|
}, {
|
||||||
|
left: "\\(",
|
||||||
|
right: "\\)",
|
||||||
|
display: false
|
||||||
|
}, // LaTeX uses $…$, but it ruins the display of normal `$` in text:
|
||||||
|
// {left: "$", right: "$", display: false},
|
||||||
|
// $ must come after $$
|
||||||
|
// Render AMS environments even if outside $$…$$ delimiters.
|
||||||
|
{
|
||||||
|
left: "\\begin{equation}",
|
||||||
|
right: "\\end{equation}",
|
||||||
|
display: true
|
||||||
|
}, {
|
||||||
|
left: "\\begin{align}",
|
||||||
|
right: "\\end{align}",
|
||||||
|
display: true
|
||||||
|
}, {
|
||||||
|
left: "\\begin{alignat}",
|
||||||
|
right: "\\end{alignat}",
|
||||||
|
display: true
|
||||||
|
}, {
|
||||||
|
left: "\\begin{gather}",
|
||||||
|
right: "\\end{gather}",
|
||||||
|
display: true
|
||||||
|
}, {
|
||||||
|
left: "\\begin{CD}",
|
||||||
|
right: "\\end{CD}",
|
||||||
|
display: true
|
||||||
|
}, {
|
||||||
|
left: "\\[",
|
||||||
|
right: "\\]",
|
||||||
|
display: true
|
||||||
|
}];
|
||||||
|
optionsCopy.ignoredTags = optionsCopy.ignoredTags || ["script", "noscript", "style", "textarea", "pre", "code", "option"];
|
||||||
|
optionsCopy.ignoredClasses = optionsCopy.ignoredClasses || [];
|
||||||
|
optionsCopy.errorCallback = optionsCopy.errorCallback || console.error; // Enable sharing of global macros defined via `\gdef` between different
|
||||||
|
// math elements within a single call to `renderMathInElement`.
|
||||||
|
|
||||||
|
optionsCopy.macros = optionsCopy.macros || {};
|
||||||
|
renderElem(elem, optionsCopy);
|
||||||
|
};
|
||||||
|
|
||||||
|
/* harmony default export */
|
||||||
|
var auto_render = (renderMathInElement);
|
||||||
|
__webpack_exports__ = __webpack_exports__["default"];
|
||||||
|
/******/
|
||||||
|
return __webpack_exports__;
|
||||||
|
/******/
|
||||||
|
})()
|
||||||
|
;
|
||||||
|
});
|
||||||
41
webseite/assets/js/login.js
Normal file
41
webseite/assets/js/login.js
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
// JavaScript to handle opening and closing of the login popup
|
||||||
|
const loginButton = document.getElementById('loginButton');
|
||||||
|
const loginPopup = document.getElementById('loginPopup');
|
||||||
|
const closePopupButton = document.getElementById('closePopupButton');
|
||||||
|
const usernameInput = document.getElementById('username');
|
||||||
|
const errorMessage = document.getElementById('errorMessage');
|
||||||
|
|
||||||
|
if (loginButton) { // Überprüfen, ob das Element vorhanden ist
|
||||||
|
loginButton.addEventListener('click', function () {
|
||||||
|
loginPopup.classList.remove('hidden');
|
||||||
|
usernameInput.focus(); // Set focus to username field
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (closePopupButton) { // Überprüfen, ob das Element vorhanden ist
|
||||||
|
closePopupButton.addEventListener('click', function () {
|
||||||
|
loginPopup.classList.add('hidden');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
window.addEventListener('click', function (event) {
|
||||||
|
if (event.target === loginPopup) {
|
||||||
|
loginPopup.classList.add('hidden');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Schließe Popup mit ESC
|
||||||
|
document.addEventListener('keydown', function (event) {
|
||||||
|
if (event.key === "Escape" && !loginPopup.classList.contains('hidden')) {
|
||||||
|
loginPopup.classList.add('hidden');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Zeige Fehlermeldung beim Login an
|
||||||
|
window.addEventListener('DOMContentLoaded', (event) => {
|
||||||
|
const urlParams = new URLSearchParams(window.location.search);
|
||||||
|
if (urlParams.has('error') && urlParams.get('error') === '1') {
|
||||||
|
loginPopup.classList.remove('hidden');
|
||||||
|
errorMessage.classList.remove('hidden');
|
||||||
|
}
|
||||||
|
});
|
||||||
7236
webseite/assets/js/quill_mod.js
Normal file
7236
webseite/assets/js/quill_mod.js
Normal file
File diff suppressed because it is too large
Load Diff
118
webseite/assets/js/tasks.js
Normal file
118
webseite/assets/js/tasks.js
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
|
console.log('tasks.js wurde geladen.');
|
||||||
|
|
||||||
|
// Funktion zum Anzeigen des Toasts
|
||||||
|
function showToast(message, type = 'success') {
|
||||||
|
const toastsContainer = document.getElementById('toasts');
|
||||||
|
|
||||||
|
// Erstellen eines neuen Toast-Elements
|
||||||
|
const toast = document.createElement('div');
|
||||||
|
toast.classList.add('toast-content', `toast-${type}`);
|
||||||
|
|
||||||
|
// Erstellen des Icons
|
||||||
|
const icon = document.createElement('i');
|
||||||
|
icon.classList.add('fa-solid');
|
||||||
|
switch (type) {
|
||||||
|
case 'success':
|
||||||
|
icon.classList.add('fa-check');
|
||||||
|
break;
|
||||||
|
case 'error':
|
||||||
|
icon.classList.add('fa-times');
|
||||||
|
break;
|
||||||
|
case 'info':
|
||||||
|
icon.classList.add('fa-info-circle');
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
icon.classList.add('fa-check');
|
||||||
|
}
|
||||||
|
icon.classList.add('toast-icon'); // Hinzufügen der CSS-Klasse für das Icon
|
||||||
|
|
||||||
|
// Erstellen des Nachrichten-Elements
|
||||||
|
const toastMessage = document.createElement('span');
|
||||||
|
toastMessage.textContent = message;
|
||||||
|
toastMessage.classList.add('toast-message'); // Hinzufügen der CSS-Klasse für den Text
|
||||||
|
|
||||||
|
// Fügen Sie Icon und Nachricht zum Toast hinzu
|
||||||
|
toast.appendChild(icon);
|
||||||
|
toast.appendChild(toastMessage);
|
||||||
|
|
||||||
|
// Fügen Sie den Toast zum Container hinzu
|
||||||
|
toastsContainer.appendChild(toast);
|
||||||
|
|
||||||
|
// Anzeigen des Toasts mit Animation
|
||||||
|
requestAnimationFrame(() => {
|
||||||
|
toast.classList.add('show');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Automatisches Ausblenden nach 3 Sekunden
|
||||||
|
setTimeout(() => {
|
||||||
|
toast.classList.remove('show');
|
||||||
|
// Entfernen des Toasts nach der Animation
|
||||||
|
setTimeout(() => {
|
||||||
|
toast.remove();
|
||||||
|
}, 500); // Muss mit der CSS-Transition übereinstimmen
|
||||||
|
}, 3000);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Event-Delegation für "Antwort prüfen" Buttons
|
||||||
|
document.querySelectorAll('.check-answer').forEach(function (button, index) {
|
||||||
|
button.addEventListener('click', function () {
|
||||||
|
console.log(`Antwort prüfen Button geklickt. Button Index: ${index}`);
|
||||||
|
const variableContainer = this.closest('.variable-container');
|
||||||
|
if (!variableContainer) {
|
||||||
|
console.error('Variable Container nicht gefunden für Button:', this);
|
||||||
|
showToast('Interner Fehler: Container nicht gefunden.', 'error');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const input = variableContainer.querySelector('input');
|
||||||
|
if (!input) {
|
||||||
|
console.error('Input Feld nicht gefunden in Variable Container:', variableContainer);
|
||||||
|
showToast('Interner Fehler: Eingabefeld nicht gefunden.', 'error');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const userAnswer = input.value.trim();
|
||||||
|
const correctAnswer = input.getAttribute('data-correct-answer');
|
||||||
|
if (!correctAnswer) {
|
||||||
|
console.error('Data-Correct-Answer Attribut fehlt im Input:', input);
|
||||||
|
showToast('Interner Fehler: Richtige Antwort nicht verfügbar.', 'error');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`Benutzerantwort: "${userAnswer}", Richtige Antwort: "${correctAnswer}"`);
|
||||||
|
|
||||||
|
if (userAnswer.toLowerCase() === correctAnswer.trim().toLowerCase()) {
|
||||||
|
showToast('Richtig!', 'success');
|
||||||
|
} else {
|
||||||
|
showToast('Falsch.', 'error');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Event-Delegation für "Antwort anzeigen" Buttons
|
||||||
|
document.querySelectorAll('.show-answer').forEach(function (button, index) {
|
||||||
|
button.addEventListener('click', function () {
|
||||||
|
console.log(`Antwort anzeigen Button geklickt. Button Index: ${index}`);
|
||||||
|
const variableContainer = this.closest('.variable-container');
|
||||||
|
if (!variableContainer) {
|
||||||
|
console.error('Variable Container nicht gefunden für Button:', this);
|
||||||
|
showToast('Interner Fehler: Container nicht gefunden.', 'error');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const input = variableContainer.querySelector('input');
|
||||||
|
if (!input) {
|
||||||
|
console.error('Input Feld nicht gefunden in Variable Container:', variableContainer);
|
||||||
|
showToast('Interner Fehler: Eingabefeld nicht gefunden.', 'error');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const correctAnswer = input.getAttribute('data-correct-answer');
|
||||||
|
if (!correctAnswer) {
|
||||||
|
console.error('Data-Correct-Answer Attribut fehlt im Input:', input);
|
||||||
|
showToast('Interner Fehler: Richtige Antwort nicht verfügbar.', 'error');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`Richtige Antwort: "${correctAnswer}"`);
|
||||||
|
showToast(`Richtige Antwort: ${correctAnswer}`, 'info');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -243,6 +243,11 @@ class SubjectData
|
|||||||
|
|
||||||
public function setId(string $id): void
|
public function setId(string $id): void
|
||||||
{
|
{
|
||||||
|
rename(
|
||||||
|
Config::getSubjectDirectory($this->getId()),
|
||||||
|
Config::getSubjectDirectory($id)
|
||||||
|
);
|
||||||
|
|
||||||
$this->id = $id;
|
$this->id = $id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
48
webseite/classes/Task.php
Normal file
48
webseite/classes/Task.php
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class Task
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var string Aufgabentext kann z.B. auch LaTeX-Notation enthalten
|
||||||
|
*/
|
||||||
|
private string $text;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array Alle verwendeten Variablen mit key als Variable und value als richtigen Wert
|
||||||
|
*/
|
||||||
|
private array $variables;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Erstellt eine neue Aufgabe
|
||||||
|
* @param string $text Aufgabentext, kann z.B. auch LaTeX-Notation enthalten
|
||||||
|
* @param array $variables Assoziatives Array mit Variable → Richtiger Wert
|
||||||
|
*/
|
||||||
|
public function __construct(string $text, array $variables)
|
||||||
|
{
|
||||||
|
$this->text = $text;
|
||||||
|
$this->variables = array();
|
||||||
|
foreach ($variables as $variable => $value) {
|
||||||
|
if(!is_string($value)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->variables[$variable] = $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string Aufgabentext
|
||||||
|
*/
|
||||||
|
public function getText(): string
|
||||||
|
{
|
||||||
|
return $this->text;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array Assoziatives Array mit Variable → Richtiger Wert
|
||||||
|
*/
|
||||||
|
public function getVariables(): array
|
||||||
|
{
|
||||||
|
return $this->variables;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,8 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use exception\SubjectDoesNotExistException;
|
require_once("Task.php");
|
||||||
use exception\TopicAlreadyExistsException;
|
|
||||||
|
|
||||||
require_once("Config.php");
|
require_once("Config.php");
|
||||||
require_once("Util.php");
|
require_once("Util.php");
|
||||||
|
|
||||||
@@ -46,7 +44,13 @@ class TopicData
|
|||||||
/**
|
/**
|
||||||
* @var string Der gesamte Erklärungstext zum Thema, enthält fertiges HTML und LATEX Formelsyntax für MathJax https://docs.mathjax.org/en/latest/basic/mathematics.html
|
* @var string Der gesamte Erklärungstext zum Thema, enthält fertiges HTML und LATEX Formelsyntax für MathJax https://docs.mathjax.org/en/latest/basic/mathematics.html
|
||||||
*/
|
*/
|
||||||
public string $article;
|
private string $article;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array Alle zugehörigen Formelaufgaben als Task
|
||||||
|
* @see Task
|
||||||
|
*/
|
||||||
|
private array $tasks;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Erstellt ein neues Thema. Es wird noch nichts gespeichert!
|
* Erstellt ein neues Thema. Es wird noch nichts gespeichert!
|
||||||
@@ -91,6 +95,8 @@ class TopicData
|
|||||||
|
|
||||||
$result->article = $article;
|
$result->article = $article;
|
||||||
|
|
||||||
|
$result->tasks = array();
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,7 +124,14 @@ class TopicData
|
|||||||
{
|
{
|
||||||
$result = array();
|
$result = array();
|
||||||
|
|
||||||
|
if(!is_dir(Config::getTopicsDirectory($subjectId))) {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
$topicNames = scandir(Config::getTopicsDirectory($subjectId));
|
$topicNames = scandir(Config::getTopicsDirectory($subjectId));
|
||||||
|
if(!$topicNames) {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
usort($topicNames, function ($a, $b) {
|
usort($topicNames, function ($a, $b) {
|
||||||
return strcmp($a, $b);
|
return strcmp($a, $b);
|
||||||
@@ -191,10 +204,29 @@ class TopicData
|
|||||||
if (!isset($article)) {
|
if (!isset($article)) {
|
||||||
$article = "Kein Erklärtext vorhanden";
|
$article = "Kein Erklärtext vorhanden";
|
||||||
}
|
}
|
||||||
$result->article = str_replace('$TOPICPATH', Config::getTopicDirectory($subjectId, $topicId) . "images", $article);
|
$result->article = $article;
|
||||||
|
|
||||||
|
$taskJson = Util::readFileContent(Config::getTopicDirectory($subjectId, $topicId) . "tasks.json");
|
||||||
|
$result->tasks = array();
|
||||||
|
if(isset($taskJson)) {
|
||||||
|
$arr = json_decode($taskJson, true);
|
||||||
|
foreach ($arr as $rawTask) {
|
||||||
|
$text = $rawTask["text"];
|
||||||
|
if(!isset($text)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$vars = $rawTask["vars"];
|
||||||
|
if (!isset($vars)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$result->tasks[] = new Task($text, $vars);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$result->cleanupRelatedTopics();
|
$result->cleanupRelatedTopics();
|
||||||
$result->cleanupFiles();
|
//$result->cleanupFiles();
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
@@ -206,14 +238,13 @@ class TopicData
|
|||||||
public function save(): bool
|
public function save(): bool
|
||||||
{
|
{
|
||||||
$this->cleanupRelatedTopics();
|
$this->cleanupRelatedTopics();
|
||||||
$this->cleanupFiles();
|
//$this->cleanupFiles();
|
||||||
|
|
||||||
$data = array();
|
$data = array();
|
||||||
$data["displayName"] = $this->displayName;
|
$data["displayName"] = $this->displayName;
|
||||||
$data["icon"] = $this->icon;
|
$data["icon"] = $this->icon;
|
||||||
$data["description"] = $this->description;
|
$data["description"] = $this->description;
|
||||||
$data["relatedTopics"] = $this->relatedTopics;
|
$data["relatedTopics"] = $this->relatedTopics;
|
||||||
$data["files"] = $this->files;
|
|
||||||
|
|
||||||
$json = json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
|
$json = json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
|
||||||
if (!$json) {
|
if (!$json) {
|
||||||
@@ -229,8 +260,23 @@ class TopicData
|
|||||||
mkdir($topicDirectory, 0777, true);
|
mkdir($topicDirectory, 0777, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$taskArray = array();
|
||||||
|
foreach ($this->tasks as $task) {
|
||||||
|
$element = array();
|
||||||
|
$element["text"] = $task->getText();
|
||||||
|
$element["vars"] = $task->getVariables();
|
||||||
|
$taskArray[] = $element;
|
||||||
|
}
|
||||||
|
|
||||||
|
$taskJson = json_encode($taskArray, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
|
||||||
|
if (!$taskJson) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (!(Util::writeFileContent($topicDirectory . "properties.json", $json)
|
if (!(Util::writeFileContent($topicDirectory . "properties.json", $json)
|
||||||
&& Util::writeFileContent($topicDirectory . "article.html", $json))
|
&& Util::writeFileContent($topicDirectory . "article.html", $this->article)
|
||||||
|
&& Util::writeFileContent($topicDirectory . "tasks.json", $taskJson)
|
||||||
|
)
|
||||||
) {
|
) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -270,11 +316,13 @@ class TopicData
|
|||||||
*/
|
*/
|
||||||
public function deleteDownload(string $name): bool
|
public function deleteDownload(string $name): bool
|
||||||
{
|
{
|
||||||
if (!isset($this->files[$name])) {
|
if (!in_array($name, $this->files)) {
|
||||||
|
echo "a";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!unlink(Config::getTopicDirectory($this->getSubjectId(), $this->getId()) . "downloads/$name")) {
|
if (!unlink(Config::getTopicDirectory($this->getSubjectId(), $this->getId()) . "downloads/$name")) {
|
||||||
|
echo "b";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -306,6 +354,52 @@ class TopicData
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Erstellt eine Datei aus übergebenen Daten
|
||||||
|
* @param string $name Dateiname
|
||||||
|
* @param string $image Bilddaten als Dateiinhalt, z.B. von file_get_contents()
|
||||||
|
* @return bool true wenn erfolgreich, sonst false
|
||||||
|
*/
|
||||||
|
public function uploadImage(string $name, string $image): bool
|
||||||
|
{
|
||||||
|
$imageDirectory = Config::getTopicDirectory($this->getSubjectId(), $this->getId()) . "images/";
|
||||||
|
|
||||||
|
if (!is_dir($imageDirectory)) {
|
||||||
|
if (!mkdir($imageDirectory)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!file_put_contents("$imageDirectory/$name", $image)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Löscht alle derzeit gespeicherten Bilder des Themas
|
||||||
|
* @return bool true wenn erfolgreich, sonst false
|
||||||
|
*/
|
||||||
|
public function deleteAllImages(): bool
|
||||||
|
{
|
||||||
|
return Util::delete(Config::getTopicDirectory($this->getSubjectId(), $this->getId()) . "images/");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Löscht ein Bild des Themas
|
||||||
|
* @param string $name Dateiname
|
||||||
|
* @return bool true, wenn erfolgreich, sonst false
|
||||||
|
*/
|
||||||
|
public function deleteImage(string $name): bool
|
||||||
|
{
|
||||||
|
if (!unlink(Config::getTopicDirectory($this->getSubjectId(), $this->getId()) . "images/$name")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prüft für alle verwandten Themen, ob diese auch existieren. Wenn nicht, wird es aus der Liste entfernt
|
* Prüft für alle verwandten Themen, ob diese auch existieren. Wenn nicht, wird es aus der Liste entfernt
|
||||||
* @return bool true, wenn Elemente entfernt wurden, sonst false
|
* @return bool true, wenn Elemente entfernt wurden, sonst false
|
||||||
@@ -356,20 +450,6 @@ class TopicData
|
|||||||
return $changed;
|
return $changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Löscht ein Bild des Themas
|
|
||||||
* @param string $name Dateiname
|
|
||||||
* @return bool true, wenn erfolgreich, sonst false
|
|
||||||
*/
|
|
||||||
public function deleteImage(string $name): bool
|
|
||||||
{
|
|
||||||
if (!unlink(Config::getTopicDirectory($this->getSubjectId(), $this->getId()) . "images/$name")) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Löscht das Thema inklusive aller zugehörigen Dateien
|
* Löscht das Thema inklusive aller zugehörigen Dateien
|
||||||
* @return bool true, wenn erfolgreich gelöscht, sonst false
|
* @return bool true, wenn erfolgreich gelöscht, sonst false
|
||||||
@@ -383,6 +463,23 @@ class TopicData
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function addTask(Task $task): bool
|
||||||
|
{
|
||||||
|
$this->tasks[] = $task;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function removeTask(Task $task): bool
|
||||||
|
{
|
||||||
|
$this->tasks = array_diff($this->tasks, [$task]);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function removeAllTasks()
|
||||||
|
{
|
||||||
|
$this->tasks = array();
|
||||||
|
}
|
||||||
|
|
||||||
public function getId(): string
|
public function getId(): string
|
||||||
{
|
{
|
||||||
return $this->id;
|
return $this->id;
|
||||||
@@ -390,6 +487,11 @@ class TopicData
|
|||||||
|
|
||||||
public function setId(string $id): void
|
public function setId(string $id): void
|
||||||
{
|
{
|
||||||
|
rename(
|
||||||
|
Config::getTopicDirectory($this->getSubjectId(), $this->getId()),
|
||||||
|
Config::getTopicDirectory($this->getSubjectId(), $id)
|
||||||
|
);
|
||||||
|
|
||||||
$this->id = $id;
|
$this->id = $id;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -400,6 +502,11 @@ class TopicData
|
|||||||
|
|
||||||
public function setSubjectId(string $subjectId): void
|
public function setSubjectId(string $subjectId): void
|
||||||
{
|
{
|
||||||
|
rename(
|
||||||
|
Config::getTopicDirectory($this->getSubjectId(), $this->getId()),
|
||||||
|
Config::getTopicDirectory($subjectId, $this->getId())
|
||||||
|
);
|
||||||
|
|
||||||
$this->subjectId = $subjectId;
|
$this->subjectId = $subjectId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -453,6 +560,17 @@ class TopicData
|
|||||||
$this->files = $files;
|
$this->files = $files;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gibt anders als getArticle() Bildpfade richtig aus
|
||||||
|
* @return string HTML Quelltext für den Erklärtext
|
||||||
|
*/
|
||||||
|
public function getFinishedArticle(): string
|
||||||
|
{
|
||||||
|
$a = str_replace('__TOPICPATH__', Config::getTopicDirectory($this->subjectId, $this->id) . "images", $this->article);
|
||||||
|
|
||||||
|
return $a;
|
||||||
|
}
|
||||||
|
|
||||||
public function getArticle(): string
|
public function getArticle(): string
|
||||||
{
|
{
|
||||||
return $this->article;
|
return $this->article;
|
||||||
@@ -463,5 +581,13 @@ class TopicData
|
|||||||
$this->article = $article;
|
$this->article = $article;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getTasks(): array
|
||||||
|
{
|
||||||
|
return $this->tasks;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setTasks(array $tasks): void
|
||||||
|
{
|
||||||
|
$this->tasks = $tasks;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -112,7 +112,7 @@ class Util
|
|||||||
|
|
||||||
self::delete($path . "/" . $entry);
|
self::delete($path . "/" . $entry);
|
||||||
}
|
}
|
||||||
|
rmdir($path);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"displayName": "Deutsch",
|
"displayName": "Deutsch",
|
||||||
"description": "Deutsch ist rot",
|
"description": "Deutsch ist rot",
|
||||||
"color": "#ef4444",
|
"color": "#ef4444",
|
||||||
"icon": "fa-book"
|
"icon": "fa-book"
|
||||||
}
|
}
|
||||||
@@ -1,46 +1 @@
|
|||||||
Adverbiale Bestimmungen sind ein wichtiger Teil eines Satzes, weil sie uns zusätzliche Informationen geben. Sie erklären, wann, wo, wie oder warum etwas passiert. Ohne adverbiale Bestimmungen wären viele Sätze unvollständig oder weniger genau. Sie sind also sehr hilfreich, um unsere Sprache klarer und lebendiger zu machen.
|
<p><p>Adverbiale Bestimmungen sind ein wichtiger Teil eines Satzes, weil sie uns zusätzliche Informationen geben. Sie erklären, wann, wo, wie oder warum etwas passiert. Ohne adverbiale Bestimmungen wären viele Sätze unvollständig oder weniger genau. Sie sind also sehr hilfreich, um unsere Sprache klarer und lebendiger zu machen.</p><p><strong>Arten von adverbialen Bestimmungen</strong></p><br><p>Es gibt vier Hauptarten von adverbialen Bestimmungen. Lass uns jede genauer anschauen:</p><br><p>1. Adverbiale Bestimmung der Zeit (Temporal)</p><p>Diese Art von adverbialer Bestimmung gibt an, wann etwas passiert. Sie beantwortet die Frage "Wann?".</p><ul><li>Beispiel: Morgen gehe ich schwimmen.</li><li>Hier gibt "morgen" an, wann das Schwimmen stattfindet.</li></ul><br><p>2. Adverbiale Bestimmung des Ortes (Lokal)</p><p>Diese adverbiale Bestimmung sagt uns, wo etwas geschieht. Sie beantwortet die Frage "Wo?".</p><ul><li>Beispiel: Der Hund bellt im Garten.</li><li>"im Garten" zeigt, an welchem Ort der Hund bellt.</li></ul><br><p>3. Adverbiale Bestimmung der Art und Weise (Modal)</p><p>Diese Art gibt an, wie etwas passiert. Sie beantwortet die Frage "Wie?".</p><ul><li>Beispiel: Der Hund bellt laut.</li><li>"laut" gibt an, auf welche Weise der Hund bellt.</li></ul><br><p>4. Adverbiale Bestimmung des Grundes (Kausal)</p><p>Diese adverbiale Bestimmung erklärt, warum etwas passiert. Sie beantwortet die Frage "Warum?".</p><ul><li>Beispiel: Der Hund bellt wegen des Lärms.</li><li>"wegen des Lärms" gibt den Grund an, warum der Hund bellt.</li></ul><br><p><strong>Wie erkennt man adverbiale Bestimmungen?</strong></p><br><p>Eine einfache Methode, um adverbiale Bestimmungen zu erkennen, ist, die Fragen "Wann?", "Wo?", "Wie?" oder "Warum?" zu stellen. Wenn eine Wortgruppe diese Fragen beantwortet, handelt es sich wahrscheinlich um eine adverbiale Bestimmung. Ein weiterer Hinweis ist, dass adverbiale Bestimmungen oft im Satz verschoben werden können, ohne dass der Satz unverständlich wird.</p><br><p><strong>Beispiele für das Erkennen von adverbialen Bestimmungen</strong></p><br><ul><li>Der Lehrer erklärt am Morgen die Hausaufgaben. ("am Morgen" ist die adverbiale Bestimmung der Zeit, weil sie sagt, wann etwas passiert.)</li><li>Die Katze schläft auf dem Sofa. ("auf dem Sofa" ist die adverbiale Bestimmung des Ortes, weil sie angibt, wo etwas passiert.)</li><li>Der Junge rennt schnell zur Schule. ("schnell" ist die adverbiale Bestimmung der Art und Weise, weil sie beschreibt, wie er rennt.)</li><li>Wegen des Regens bleiben wir zu Hause. ("wegen des Regens" ist die adverbiale Bestimmung des Grundes, weil sie erklärt, warum etwas passiert.)</li></ul><br><p><strong>Zusammenfassung</strong></p><br><p>Adverbiale Bestimmungen machen unsere Sätze detaillierter und genauer. Sie geben uns mehr Informationen darüber, wann, wo, wie oder warum etwas geschieht. Die vier Hauptarten der adverbialen Bestimmungen sind Zeit, Ort, Art und Weise und Grund. Wenn du die passenden Fragen stellst, kannst du adverbiale Bestimmungen leicht erkennen und deine eigenen Sätze damit besser machen!</p></p>
|
||||||
<br><br>
|
|
||||||
<strong>Arten von adverbialen Bestimmungen</strong>
|
|
||||||
<br><br>
|
|
||||||
Es gibt vier Hauptarten von adverbialen Bestimmungen. Lass uns jede genauer anschauen:
|
|
||||||
<br><br>
|
|
||||||
1. Adverbiale Bestimmung der Zeit (Temporal)<br>
|
|
||||||
Diese Art von adverbialer Bestimmung gibt an, wann etwas passiert. Sie beantwortet die Frage "Wann?". <br>
|
|
||||||
- Beispiel: Morgen gehe ich schwimmen. <br>
|
|
||||||
- Hier gibt "morgen" an, wann das Schwimmen stattfindet. <br>
|
|
||||||
<br>
|
|
||||||
2. Adverbiale Bestimmung des Ortes (Lokal) <br>
|
|
||||||
Diese adverbiale Bestimmung sagt uns, wo etwas geschieht. Sie beantwortet die Frage "Wo?". <br>
|
|
||||||
- Beispiel: Der Hund bellt im Garten. <br>
|
|
||||||
- "im Garten" zeigt, an welchem Ort der Hund bellt. <br>
|
|
||||||
<br>
|
|
||||||
3. Adverbiale Bestimmung der Art und Weise (Modal) <br>
|
|
||||||
Diese Art gibt an, wie etwas passiert. Sie beantwortet die Frage "Wie?". <br>
|
|
||||||
- Beispiel: Der Hund bellt laut. <br>
|
|
||||||
- "laut" gibt an, auf welche Weise der Hund bellt. <br>
|
|
||||||
<br>
|
|
||||||
4. Adverbiale Bestimmung des Grundes (Kausal) <br>
|
|
||||||
Diese adverbiale Bestimmung erklärt, warum etwas passiert. Sie beantwortet die Frage "Warum?". <br>
|
|
||||||
- Beispiel: Der Hund bellt wegen des Lärms. <br>
|
|
||||||
- "wegen des Lärms" gibt den Grund an, warum der Hund bellt. <br>
|
|
||||||
<br>
|
|
||||||
<strong>Wie erkennt man adverbiale Bestimmungen?</strong> <br>
|
|
||||||
<br>
|
|
||||||
Eine einfache Methode, um adverbiale Bestimmungen zu erkennen, ist, die Fragen "Wann?", "Wo?", "Wie?" oder "Warum?" zu stellen. Wenn eine Wortgruppe diese Fragen beantwortet, handelt es sich wahrscheinlich um eine adverbiale Bestimmung. Ein weiterer Hinweis ist, dass adverbiale Bestimmungen oft im Satz verschoben werden können, ohne dass der Satz unverständlich wird.
|
|
||||||
<br><br>
|
|
||||||
|
|
||||||
<strong>Beispiele für das Erkennen von adverbialen Bestimmungen</strong> <br><br>
|
|
||||||
|
|
||||||
- Der Lehrer erklärt am Morgen die Hausaufgaben. ("am Morgen" ist die adverbiale Bestimmung der Zeit, weil sie sagt, wann etwas passiert.)
|
|
||||||
<br>
|
|
||||||
- Die Katze schläft auf dem Sofa. ("auf dem Sofa" ist die adverbiale Bestimmung des Ortes, weil sie angibt, wo etwas passiert.)
|
|
||||||
<br>
|
|
||||||
- Der Junge rennt schnell zur Schule. ("schnell" ist die adverbiale Bestimmung der Art und Weise, weil sie beschreibt, wie er rennt.)
|
|
||||||
<br>
|
|
||||||
- Wegen des Regens bleiben wir zu Hause. ("wegen des Regens" ist die adverbiale Bestimmung des Grundes, weil sie erklärt, warum etwas passiert.)
|
|
||||||
<br><br>
|
|
||||||
|
|
||||||
<strong>Zusammenfassung</strong> <br><br>
|
|
||||||
|
|
||||||
Adverbiale Bestimmungen machen unsere Sätze detaillierter und genauer. Sie geben uns mehr Informationen darüber, wann, wo, wie oder warum etwas geschieht. Die vier Hauptarten der adverbialen Bestimmungen sind Zeit, Ort, Art und Weise und Grund. Wenn du die passenden Fragen stellst, kannst du adverbiale Bestimmungen leicht erkennen und deine eigenen Sätze damit besser machen!
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
{
|
{
|
||||||
"displayName": "Adverbiale Bestimmung",
|
"displayName": "Adverbiale Bestimmung",
|
||||||
"icon": "fa-map-pin",
|
"icon": "fa-map-pin",
|
||||||
"description": "Adverbiale Bestimmungen sind Satzteile, die zusätzliche Informationen über Umstände wie Zeit, Ort, Grund oder Art und Weise geben und dadurch die Handlung des Satzes genauer beschreiben.",
|
"description": "Adverbiale Bestimmungen sind Satzteile, die zusätzliche Informationen über Umstände wie Zeit, Ort, Grund oder Art und Weise geben und dadurch die Handlung des Satzes genauer beschreiben.",
|
||||||
"relatedTopics": [
|
"relatedTopics": [
|
||||||
"wortarten", "vier-faelle"
|
"wortarten",
|
||||||
]
|
"vier-faelle"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
[]
|
||||||
@@ -1,28 +1 @@
|
|||||||
|
<p><img src="__TOPICPATH__/img.png" alt="Ein Bild"><p><strong>Geschichten Erzählen: Warum sie so wichtig sind</strong></p><br><p>Hast du schon mal eine spannende Geschichte gehört und konntest es kaum erwarten zu erfahren, wie sie endet? Geschichten zu erzählen ist etwas, das Menschen schon seit vielen tausend Jahren machen. Aber warum erzählen wir überhaupt Geschichten, und was macht sie so besonders?</p><br><p>Geschichten zu erzählen ist eine der ältesten Arten, wie Menschen miteinander reden. Schon früher, als es keine Bücher oder das Internet gab, haben sich die Leute am Lagerfeuer versammelt und erzählt, was sie erlebt haben. Geschichten halfen ihnen, ihr Wissen weiterzugeben, sich gegenseitig zu unterhalten und über ihre Gefühle zu sprechen. Das ist auch heute noch so: Geschichten verbinden uns und lassen uns Neues lernen.</p><br><p>In Geschichten geht es oft um Helden, Abenteuer oder Probleme, die gelöst werden müssen. Dabei gibt es viele spannende, lustige oder traurige Momente, die uns neugierig machen. Geschichten können uns zum Lachen bringen, uns Angst machen oder uns Mut geben. Manchmal lernen wir sogar etwas Neues über die Welt oder uns selbst.</p><br><p>Um eine gute Geschichte zu erzählen, braucht man ein paar wichtige Bausteine. Erstmal braucht man eine Hauptfigur, auch Protagonist genannt. Diese Figur erlebt Abenteuer oder muss Probleme lösen. Eine Geschichte hat auch einen Anfang, der uns die Hauptfigur vorstellt, einen spannenden Mittelteil, in dem die Herausforderungen beschrieben werden, und ein Ende, in dem alles aufgelöst wird. Vielleicht hast du schon mal gemerkt, dass eine Geschichte besonders spannend wird, wenn es einen großen Konflikt oder ein Problem gibt, das gelöst werden muss.</p><br><p>Hier sind ein paar Beispiele für gute Geschichten:</p><br><p>1. Rotkäppchen: In dieser klassischen Märchengeschichte geht es um ein kleines Mädchen, das seine Großmutter besuchen möchte. Auf dem Weg trifft sie den bösen Wolf, der versucht, sie und ihre Großmutter zu täuschen. Das Abenteuer von Rotkäppchen zeigt, wie Mut und Klugheit helfen können, schwierige Situationen zu meistern.</p><br><p>2. Harry Potter: Harry ist ein Junge, der erfährt, dass er ein Zauberer ist. Er erlebt viele Abenteuer in der Zauberschule Hogwarts und muss gegen den bösen Zauberer Voldemort kämpfen. Diese Geschichte zeigt, wie wichtig Freundschaft, Mut und das Gute im Leben sind.</p><br><p>3. Der kleine Prinz: In dieser Geschichte geht es um einen kleinen Jungen, der von einem fernen Planeten kommt und viele seltsame Charaktere trifft. Der kleine Prinz lehrt uns, wie wichtig Freundschaft, Liebe und Verständnis sind.</p><br><p>4. Deine eigene Geschichte: Stell dir vor, du hast einen Tag, an dem du ein spannendes Abenteuer erlebst. Zum Beispiel könntest du dich verlaufen und dabei neue Orte entdecken. Diese kleinen Erlebnisse können in einer Geschichte spannend erzählt werden, indem du beschreibst, wie du dich gefühlt hast und welche besonderen Dinge du gesehen hast.</p><br><p>Du kannst auch selbst Geschichten erzählen! Das kann etwas sein, das du selbst erlebt hast, oder etwas, das du dir ausgedacht hast. Wichtig ist, dass du die Zuhörer mit deinen Worten mitnimmst. Verwende viele Details, beschreibe, wie sich die Figuren fühlen, und lass sie miteinander reden. So wird deine Geschichte lebendig und spannend.</p><br><p>Also, worauf wartest du noch? Fang an, deine eigenen Geschichten zu erzählen und lass andere an deinen Ideen und Abenteuern teilhaben. Geschichten haben die Macht, uns zu verändern, uns zu trösten und uns zu unterhalten – und das ist das Schöne daran!</p>
|
||||||
<img alt="Ein Bild" src="$TOPICPATH/img.png">
|
|
||||||
<br>
|
|
||||||
|
|
||||||
<strong>Geschichten Erzählen: Warum sie so wichtig sind</strong>
|
|
||||||
|
|
||||||
<br><br>
|
|
||||||
Hast du schon mal eine spannende Geschichte gehört und konntest es kaum erwarten zu erfahren, wie sie endet? Geschichten zu erzählen ist etwas, das Menschen schon seit vielen tausend Jahren machen. Aber warum erzählen wir überhaupt Geschichten, und was macht sie so besonders?
|
|
||||||
<br><br>
|
|
||||||
Geschichten zu erzählen ist eine der ältesten Arten, wie Menschen miteinander reden. Schon früher, als es keine Bücher oder das Internet gab, haben sich die Leute am Lagerfeuer versammelt und erzählt, was sie erlebt haben. Geschichten halfen ihnen, ihr Wissen weiterzugeben, sich gegenseitig zu unterhalten und über ihre Gefühle zu sprechen. Das ist auch heute noch so: Geschichten verbinden uns und lassen uns Neues lernen.
|
|
||||||
<br><br>
|
|
||||||
In Geschichten geht es oft um Helden, Abenteuer oder Probleme, die gelöst werden müssen. Dabei gibt es viele spannende, lustige oder traurige Momente, die uns neugierig machen. Geschichten können uns zum Lachen bringen, uns Angst machen oder uns Mut geben. Manchmal lernen wir sogar etwas Neues über die Welt oder uns selbst.
|
|
||||||
<br><br>
|
|
||||||
Um eine gute Geschichte zu erzählen, braucht man ein paar wichtige Bausteine. Erstmal braucht man eine Hauptfigur, auch Protagonist genannt. Diese Figur erlebt Abenteuer oder muss Probleme lösen. Eine Geschichte hat auch einen Anfang, der uns die Hauptfigur vorstellt, einen spannenden Mittelteil, in dem die Herausforderungen beschrieben werden, und ein Ende, in dem alles aufgelöst wird. Vielleicht hast du schon mal gemerkt, dass eine Geschichte besonders spannend wird, wenn es einen großen Konflikt oder ein Problem gibt, das gelöst werden muss.
|
|
||||||
<br><br>
|
|
||||||
Hier sind ein paar Beispiele für gute Geschichten:
|
|
||||||
<br><br>
|
|
||||||
1. Rotkäppchen: In dieser klassischen Märchengeschichte geht es um ein kleines Mädchen, das seine Großmutter besuchen möchte. Auf dem Weg trifft sie den bösen Wolf, der versucht, sie und ihre Großmutter zu täuschen. Das Abenteuer von Rotkäppchen zeigt, wie Mut und Klugheit helfen können, schwierige Situationen zu meistern.
|
|
||||||
<br><br>
|
|
||||||
2. Harry Potter: Harry ist ein Junge, der erfährt, dass er ein Zauberer ist. Er erlebt viele Abenteuer in der Zauberschule Hogwarts und muss gegen den bösen Zauberer Voldemort kämpfen. Diese Geschichte zeigt, wie wichtig Freundschaft, Mut und das Gute im Leben sind.
|
|
||||||
<br><br>
|
|
||||||
3. Der kleine Prinz: In dieser Geschichte geht es um einen kleinen Jungen, der von einem fernen Planeten kommt und viele seltsame Charaktere trifft. Der kleine Prinz lehrt uns, wie wichtig Freundschaft, Liebe und Verständnis sind.
|
|
||||||
<br><br>
|
|
||||||
4. Deine eigene Geschichte: Stell dir vor, du hast einen Tag, an dem du ein spannendes Abenteuer erlebst. Zum Beispiel könntest du dich verlaufen und dabei neue Orte entdecken. Diese kleinen Erlebnisse können in einer Geschichte spannend erzählt werden, indem du beschreibst, wie du dich gefühlt hast und welche besonderen Dinge du gesehen hast.
|
|
||||||
<br><br>
|
|
||||||
Du kannst auch selbst Geschichten erzählen! Das kann etwas sein, das du selbst erlebt hast, oder etwas, das du dir ausgedacht hast. Wichtig ist, dass du die Zuhörer mit deinen Worten mitnimmst. Verwende viele Details, beschreibe, wie sich die Figuren fühlen, und lass sie miteinander reden. So wird deine Geschichte lebendig und spannend.
|
|
||||||
<br><br>
|
|
||||||
Also, worauf wartest du noch? Fang an, deine eigenen Geschichten zu erzählen und lass andere an deinen Ideen und Abenteuern teilhaben. Geschichten haben die Macht, uns zu verändern, uns zu trösten und uns zu unterhalten – und das ist das Schöne daran!
|
|
||||||
@@ -1,8 +1,9 @@
|
|||||||
{
|
{
|
||||||
"displayName": "Geschichten erzählen",
|
"displayName": "Geschichten erzählen",
|
||||||
"icon": "fa-feather-pointed",
|
"icon": "fa-feather-pointed",
|
||||||
"description": "Das Thema \"Geschichten erzählen\" umfasst das kreative Gestalten und Vermitteln von Erlebnissen oder Fantasien durch eine spannende Handlung, interessante Charaktere und lebendige Beschreibungen, um die Zuhörer oder Leser zu fesseln.",
|
"description": "Das Thema \"Geschichten erzählen\" umfasst das kreative Gestalten und Vermitteln von Erlebnissen oder Fantasien durch eine spannende Handlung, interessante Charaktere und lebendige Beschreibungen, um die Zuhörer oder Leser zu fesseln.",
|
||||||
"relatedTopics": [
|
"relatedTopics": [
|
||||||
"satzglieder", "personalpronomen"
|
"satzglieder",
|
||||||
]
|
"personalpronomen"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
[]
|
||||||
@@ -1,50 +1 @@
|
|||||||
<img alt="Ein Bild" src="$TOPICPATH/img.png">
|
<p><p><img src="__TOPICPATH__/img.png" alt="Ein Bild"></p><p>Personalpronomen sind Wörter, die wir anstelle von Namen oder anderen Nomen verwenden. Sie helfen uns, Sätze kürzer und einfacher zu machen, ohne immer wieder die gleichen Wörter zu wiederholen. Personalpronomen können Dinge, Personen oder Tiere ersetzen und machen unsere Sprache verständlicher und natürlicher. Lass uns anschauen, welche Personalpronomen es gibt und wie man sie benutzt.</p><br><p><strong>Beispiele für Personalpronomen</strong></p><br><p>Es gibt verschiedene Personalpronomen, je nachdem, wer oder was gemeint ist. Hier sind die wichtigsten Personalpronomen im Deutschen:</p><br><p>- Ich: Wenn man über sich selbst spricht. Beispiel: Ich gehe heute ins Kino.</p><p>- Du: Wenn man jemanden direkt anspricht. Beispiel: Du hast eine schöne Jacke.</p><p>- Er/ Sie/ Es: Wenn man über eine andere Person, ein Tier oder eine Sache spricht. Beispiel: Er liest ein Buch, sie spielt im Garten, es regnet gerade.</p><p>- Wir: Wenn man über sich und andere Personen zusammen spricht. Beispiel: Wir gehen später Eis essen.</p><p>- Ihr: Wenn man mehrere Personen direkt anspricht. Beispiel: Ihr habt gute Arbeit geleistet.</p><p>- Sie: Wenn man über mehrere Personen spricht oder wenn man jemanden höflich anspricht. Beispiel: Sie spielen heute Fußball, oder: Sie (höflich) haben eine Frage gestellt.</p><br><p><strong>Wann benutzt man Personalpronomen?</strong></p><br><p>Personalpronomen benutzen wir, damit wir nicht ständig die gleichen Namen oder Nomen wiederholen müssen. Stell dir vor, du erzählst eine Geschichte über deinen Freund Max. Ohne Personalpronomen würde das so klingen:</p><p>- Max geht zur Schule. Max hat heute seine Lieblingshose an. Max freut sich auf den Sportunterricht.</p><br><p>Das ist ziemlich wiederholend, oder? Mit Personalpronomen klingt es viel besser:</p><p>- Max geht zur Schule. Er hat heute seine Lieblingshose an. Er freut sich auf den Sportunterricht.</p><br><p><strong>Übersicht der Personalpronomen</strong></p><p>Hier sind die Personalpronomen für die verschiedenen Personen:</p><p>- 1. Person Singular: ich</p><p>- 2. Person Singular: du</p><p>- 3. Person Singular: er, sie, es</p><p>- 1. Person Plural: wir</p><p>- 2. Person Plural: ihr</p><p>- 3. Person Plural: sie</p><p>- Höflichkeitsform: Sie (immer großgeschrieben)</p><br><p><strong>Beispiele in Sätzen</strong></p><br><p>- Ich mag Schokolade.</p><p>- Du bist mein bester Freund.</p><p>- Er spielt gerne Fußball, während sie lieber tanzt.</p><p>- Wir machen zusammen Hausaufgaben.</p><p>- Ihr seid heute sehr leise.</p><p>- Sie (Plural) haben viel Spaß im Park.</p><p>- Sie (Höflichkeitsform) sind sehr nett.</p><br><p>Personalpronomen sind sehr hilfreich, weil sie die Sprache lebendiger machen und dafür sorgen, dass wir nicht immer wieder das gleiche Wort benutzen müssen. Wenn du die Personalpronomen gut kennst, kannst du Sätze abwechslungsreicher und verständlicher gestalten!</p></p>
|
||||||
<br>
|
|
||||||
|
|
||||||
Personalpronomen sind Wörter, die wir anstelle von Namen oder anderen Nomen verwenden. Sie helfen uns, Sätze kürzer und einfacher zu machen, ohne immer wieder die gleichen Wörter zu wiederholen. Personalpronomen können Dinge, Personen oder Tiere ersetzen und machen unsere Sprache verständlicher und natürlicher. Lass uns anschauen, welche Personalpronomen es gibt und wie man sie benutzt.
|
|
||||||
<br><br>
|
|
||||||
<strong>Beispiele für Personalpronomen</strong>
|
|
||||||
<br><br>
|
|
||||||
Es gibt verschiedene Personalpronomen, je nachdem, wer oder was gemeint ist. Hier sind die wichtigsten Personalpronomen im Deutschen:
|
|
||||||
<br><br>
|
|
||||||
- Ich: Wenn man über sich selbst spricht. Beispiel: Ich gehe heute ins Kino. <br>
|
|
||||||
- Du: Wenn man jemanden direkt anspricht. Beispiel: Du hast eine schöne Jacke. <br>
|
|
||||||
- Er/ Sie/ Es: Wenn man über eine andere Person, ein Tier oder eine Sache spricht. Beispiel: Er liest ein Buch, sie spielt im Garten, es regnet gerade.
|
|
||||||
<br>
|
|
||||||
- Wir: Wenn man über sich und andere Personen zusammen spricht. Beispiel: Wir gehen später Eis essen. <br>
|
|
||||||
- Ihr: Wenn man mehrere Personen direkt anspricht. Beispiel: Ihr habt gute Arbeit geleistet. <br>
|
|
||||||
- Sie: Wenn man über mehrere Personen spricht oder wenn man jemanden höflich anspricht. Beispiel: Sie spielen heute Fußball, oder: Sie (höflich) haben eine Frage gestellt.
|
|
||||||
<br><br>
|
|
||||||
<strong>Wann benutzt man Personalpronomen?</strong>
|
|
||||||
<br><br>
|
|
||||||
Personalpronomen benutzen wir, damit wir nicht ständig die gleichen Namen oder Nomen wiederholen müssen. Stell dir vor, du erzählst eine Geschichte über deinen Freund Max. Ohne Personalpronomen würde das so klingen:
|
|
||||||
<br>
|
|
||||||
- Max geht zur Schule. Max hat heute seine Lieblingshose an. Max freut sich auf den Sportunterricht.
|
|
||||||
<br><br>
|
|
||||||
Das ist ziemlich wiederholend, oder? Mit Personalpronomen klingt es viel besser:
|
|
||||||
<br>
|
|
||||||
- Max geht zur Schule. Er hat heute seine Lieblingshose an. Er freut sich auf den Sportunterricht.
|
|
||||||
<br><br>
|
|
||||||
<strong>Übersicht der Personalpronomen</strong>
|
|
||||||
<br>
|
|
||||||
Hier sind die Personalpronomen für die verschiedenen Personen:
|
|
||||||
<br>
|
|
||||||
- 1. Person Singular: ich <br>
|
|
||||||
- 2. Person Singular: du <br>
|
|
||||||
- 3. Person Singular: er, sie, es <br>
|
|
||||||
- 1. Person Plural: wir <br>
|
|
||||||
- 2. Person Plural: ihr <br>
|
|
||||||
- 3. Person Plural: sie <br>
|
|
||||||
- Höflichkeitsform: Sie (immer großgeschrieben)
|
|
||||||
<br><br>
|
|
||||||
<strong>Beispiele in Sätzen</strong>
|
|
||||||
<br><br>
|
|
||||||
- Ich mag Schokolade. <br>
|
|
||||||
- Du bist mein bester Freund. <br>
|
|
||||||
- Er spielt gerne Fußball, während sie lieber tanzt. <br>
|
|
||||||
- Wir machen zusammen Hausaufgaben. <br>
|
|
||||||
- Ihr seid heute sehr leise. <br>
|
|
||||||
- Sie (Plural) haben viel Spaß im Park. <br>
|
|
||||||
- Sie (Höflichkeitsform) sind sehr nett.
|
|
||||||
<br><br>
|
|
||||||
Personalpronomen sind sehr hilfreich, weil sie die Sprache lebendiger machen und dafür sorgen, dass wir nicht immer wieder das gleiche Wort benutzen müssen. Wenn du die Personalpronomen gut kennst, kannst du Sätze abwechslungsreicher und verständlicher gestalten!
|
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
{
|
{
|
||||||
"displayName": "Personalpronomen",
|
"displayName": "Personalpronomen",
|
||||||
"icon": "fa-person",
|
"icon": "fa-person",
|
||||||
"description": "Personalpronomen sind Wörter, die anstelle von Personen oder Dingen verwendet werden, wie zum Beispiel \"ich\", \"du\", \"er\", \"sie\" oder \"es\", um Wiederholungen zu vermeiden und Sätze flüssiger zu gestalten.",
|
"description": "Personalpronomen sind Wörter, die anstelle von Personen oder Dingen verwendet werden, wie zum Beispiel \"ich\", \"du\", \"er\", \"sie\" oder \"es\", um Wiederholungen zu vermeiden und Sätze flüssiger zu gestalten.",
|
||||||
"relatedTopics": [
|
"relatedTopics": [
|
||||||
"wortarten", "geschichten-erzaehlen"
|
"wortarten",
|
||||||
]
|
"geschichten-erzaehlen"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
[]
|
||||||
@@ -1,51 +1 @@
|
|||||||
Sätze bestehen aus verschiedenen Teilen, die man Satzglieder nennt. Satzglieder sind Gruppen von Wörtern, die im Satz zusammengehören und eine bestimmte Funktion haben. Sie lassen sich im Satz verschieben, ohne dass der Sinn verloren geht. Die wichtigsten Satzglieder sind Subjekt, Prädikat, Objekt und adverbiale Bestimmungen. Lass uns die Satzglieder genauer anschauen und mit Beispielen verstehen, wie sie funktionieren.
|
<p><p>Sätze bestehen aus verschiedenen Teilen, die man Satzglieder nennt. Satzglieder sind Gruppen von Wörtern, die im Satz zusammengehören und eine bestimmte Funktion haben. Sie lassen sich im Satz verschieben, ohne dass der Sinn verloren geht. Die wichtigsten Satzglieder sind Subjekt, Prädikat, Objekt und adverbiale Bestimmungen. Lass uns die Satzglieder genauer anschauen und mit Beispielen verstehen, wie sie funktionieren.</p><p>1. <strong>Subjekt</strong></p><p>Das Subjekt ist derjenige oder dasjenige, das etwas tut oder von dem etwas ausgesagt wird. Es steht im Nominativ und beantwortet die Frage "Wer oder was?".</p><ul><li>Beispiel: Der Hund bellt.</li><li>Hier ist "der Hund" das Subjekt, weil es die Handlung (bellen) ausführt.</li></ul><br><p>2. <strong>Prädikat</strong></p><p>Das Prädikat ist das Satzglied, das sagt, was passiert oder was getan wird. Es besteht meistens aus einem Verb.</p><ul><li>Beispiel: Der Hund bellt.</li><li>"bellt" ist hier das Prädikat, weil es die Handlung beschreibt.</li></ul><br><p>3. <strong>Objekt</strong></p><p>Das Objekt ist das Satzglied, das angibt, auf wen oder was sich die Handlung bezieht. Es gibt verschiedene Arten von Objekten, zum Beispiel:</p><ul><li>Akkusativobjekt (Wen-Fall): Es beantwortet die Frage "Wen oder was?".</li><li>Beispiel: Der Hund jagt die Katze.</li><li>"die Katze" ist das Akkusativobjekt, weil es das Ziel der Handlung ist.</li><li>Dativobjekt (Wem-Fall): Es beantwortet die Frage "Wem?".</li><li>Beispiel: Ich gebe dem Kind einen Ball.</li><li>"dem Kind" ist das Dativobjekt, weil es angibt, wem etwas gegeben wird.</li></ul><br><p>4. <strong>Adverbiale Bestimmungen</strong></p><p>Adverbiale Bestimmungen geben uns zusätzliche Informationen darüber, wann, wo, wie oder warum etwas passiert. Es gibt verschiedene Arten von adverbialen Bestimmungen:</p><ul><li>Zeit (Wann?): Beispiel: Morgen gehe ich schwimmen.</li><li>Ort (Wo?): Beispiel: Der Hund bellt im Garten.</li><li>Art und Weise (Wie?): Beispiel: Der Hund bellt laut.</li><li>Grund (Warum?): Beispiel: Der Hund bellt wegen des Lärms.</li></ul><br><p><strong>Wie erkenne ich Satzglieder?</strong></p><br><p>Satzglieder lassen sich im Satz verschieben. Das bedeutet, dass wir die Reihenfolge der Satzglieder ändern können, ohne dass der Satz unverständlich wird. Zum Beispiel:</p><ul><li>Der Hund bellt laut im Garten.</li><li>Laut im Garten bellt der Hund.</li><li>Im Garten bellt der Hund laut.</li></ul><br><p>Alle diese Varianten sind möglich, weil die Satzglieder ihre Bedeutung behalten, auch wenn sie die Position wechseln. Das Verschieben hilft uns, die Satzglieder zu erkennen.</p><br><p><strong>Zusammenfassung der Satzglieder</strong></p><ul><li>Subjekt: Wer oder was tut etwas? (z.B. Der Lehrer erklärt den Stoff.)</li><li>Prädikat: Was passiert oder wird getan? (z.B. Der Lehrer erklärt den Stoff.)</li><li>Objekt: Auf wen oder was bezieht sich die Handlung? (z.B. Der Lehrer erklärt den Schülern den Stoff.)</li><li>Adverbiale Bestimmungen: Wann, wo, wie oder warum passiert etwas? (z.B. Der Lehrer erklärt den Stoff am Vormittag.)</li></ul><br><p>Wenn du die verschiedenen Satzglieder kennst, kannst du Sätze besser verstehen und auch selbst klarere Sätze bilden. Satzglieder helfen uns, die Struktur eines Satzes zu erkennen und unsere Sprache vielseitig und genau zu gestalten!</p></p>
|
||||||
<br><br>
|
|
||||||
1. <strong>Subjekt</strong> <br>
|
|
||||||
Das Subjekt ist derjenige oder dasjenige, das etwas tut oder von dem etwas ausgesagt wird. Es steht im Nominativ und beantwortet die Frage "Wer oder was?".
|
|
||||||
<br>
|
|
||||||
- Beispiel: Der Hund bellt. <br>
|
|
||||||
- Hier ist "der Hund" das Subjekt, weil es die Handlung (bellen) ausführt. <br>
|
|
||||||
<br>
|
|
||||||
2. <strong>Prädikat</strong> <br>
|
|
||||||
Das Prädikat ist das Satzglied, das sagt, was passiert oder was getan wird. Es besteht meistens aus einem Verb. <br>
|
|
||||||
- Beispiel: Der Hund bellt. <br>
|
|
||||||
- "bellt" ist hier das Prädikat, weil es die Handlung beschreibt. <br>
|
|
||||||
<br>
|
|
||||||
3. <strong>Objekt</strong> <br>
|
|
||||||
Das Objekt ist das Satzglied, das angibt, auf wen oder was sich die Handlung bezieht. Es gibt verschiedene Arten von Objekten, zum Beispiel:
|
|
||||||
<br>
|
|
||||||
- Akkusativobjekt (Wen-Fall): Es beantwortet die Frage "Wen oder was?". <br>
|
|
||||||
- Beispiel: Der Hund jagt die Katze. <br>
|
|
||||||
- "die Katze" ist das Akkusativobjekt, weil es das Ziel der Handlung ist. <br>
|
|
||||||
- Dativobjekt (Wem-Fall): Es beantwortet die Frage "Wem?". <br>
|
|
||||||
- Beispiel: Ich gebe dem Kind einen Ball. <br>
|
|
||||||
- "dem Kind" ist das Dativobjekt, weil es angibt, wem etwas gegeben wird. <br>
|
|
||||||
<br>
|
|
||||||
4. <strong>Adverbiale Bestimmungen</strong> <br>
|
|
||||||
Adverbiale Bestimmungen geben uns zusätzliche Informationen darüber, wann, wo, wie oder warum etwas passiert. Es gibt verschiedene Arten von adverbialen Bestimmungen:
|
|
||||||
<br>
|
|
||||||
- Zeit (Wann?): Beispiel: Morgen gehe ich schwimmen. <br>
|
|
||||||
- Ort (Wo?): Beispiel: Der Hund bellt im Garten. <br>
|
|
||||||
- Art und Weise (Wie?): Beispiel: Der Hund bellt laut. <br>
|
|
||||||
- Grund (Warum?): Beispiel: Der Hund bellt wegen des Lärms. <br>
|
|
||||||
<br>
|
|
||||||
<strong>Wie erkenne ich Satzglieder?</strong> <br>
|
|
||||||
<br>
|
|
||||||
Satzglieder lassen sich im Satz verschieben. Das bedeutet, dass wir die Reihenfolge der Satzglieder ändern können, ohne dass der Satz unverständlich wird. Zum Beispiel:
|
|
||||||
<br>
|
|
||||||
|
|
||||||
- Der Hund bellt laut im Garten. <br>
|
|
||||||
- Laut im Garten bellt der Hund. <br>
|
|
||||||
- Im Garten bellt der Hund laut. <br>
|
|
||||||
<br>
|
|
||||||
Alle diese Varianten sind möglich, weil die Satzglieder ihre Bedeutung behalten, auch wenn sie die Position wechseln. Das Verschieben hilft uns, die Satzglieder zu erkennen.
|
|
||||||
<br><br>
|
|
||||||
|
|
||||||
<strong>Zusammenfassung der Satzglieder</strong> <br>
|
|
||||||
|
|
||||||
- Subjekt: Wer oder was tut etwas? (z.B. Der Lehrer erklärt den Stoff.) <br>
|
|
||||||
- Prädikat: Was passiert oder wird getan? (z.B. Der Lehrer erklärt den Stoff.) <br>
|
|
||||||
- Objekt: Auf wen oder was bezieht sich die Handlung? (z.B. Der Lehrer erklärt den Schülern den Stoff.) <br>
|
|
||||||
- Adverbiale Bestimmungen: Wann, wo, wie oder warum passiert etwas? (z.B. Der Lehrer erklärt den Stoff am Vormittag.)
|
|
||||||
<br><br>
|
|
||||||
Wenn du die verschiedenen Satzglieder kennst, kannst du Sätze besser verstehen und auch selbst klarere Sätze bilden. Satzglieder helfen uns, die Struktur eines Satzes zu erkennen und unsere Sprache vielseitig und genau zu gestalten!
|
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
{
|
{
|
||||||
"displayName": "Satzglieder",
|
"displayName": "Satzglieder",
|
||||||
"icon": "fa-link",
|
"icon": "fa-link",
|
||||||
"description": "Satzglieder sind die Bausteine eines Satzes, die jeweils eine bestimmte Funktion erfüllen, wie Subjekt, Prädikat, Objekt oder adverbiale Bestimmung, und sich gemeinsam verschieben lassen, ohne die grammatische Korrektheit des Satzes zu verändern.",
|
"description": "Satzglieder sind die Bausteine eines Satzes, die jeweils eine bestimmte Funktion erfüllen, wie Subjekt, Prädikat, Objekt oder adverbiale Bestimmung, und sich gemeinsam verschieben lassen, ohne die grammatische Korrektheit des Satzes zu verändern.",
|
||||||
"relatedTopics": [
|
"relatedTopics": [
|
||||||
"wortarten", "vier-faelle"
|
"wortarten",
|
||||||
]
|
"vier-faelle"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
[]
|
||||||
@@ -1,36 +1 @@
|
|||||||
Im Deutschen gibt es vier Fälle, die man auch "Kasus" nennt. Sie helfen uns zu verstehen, welche Rolle ein Nomen oder Pronomen im Satz hat. Die vier Fälle sind Nominativ, Genitiv, Dativ und Akkusativ. Lass uns jeden Fall einzeln anschauen und mit einfachen Beispielen verstehen, wie sie funktionieren.
|
<p><p>Im Deutschen gibt es vier Fälle, die man auch "Kasus" nennt. Sie helfen uns zu verstehen, welche Rolle ein Nomen oder Pronomen im Satz hat. Die vier Fälle sind Nominativ, Genitiv, Dativ und Akkusativ. Lass uns jeden Fall einzeln anschauen und mit einfachen Beispielen verstehen, wie sie funktionieren.</p><p>1. <strong>Nominativ (Wer-Fall)</strong></p><p>Der Nominativ ist der Fall des Subjekts, also die Person oder Sache, die etwas tut. Du kannst die Frage "Wer oder was?" stellen, um den Nominativ zu finden.</p><ul><li>Beispiel: Der Hund bellt.</li><li>Hier ist "der Hund" das Subjekt, das etwas tut. Deshalb steht es im Nominativ.</li></ul><br><p>2. <strong>Genitiv (Wessen-Fall)</strong></p><p>Der Genitiv zeigt, wem etwas gehört. Du kannst die Frage "Wessen?" stellen, um den Genitiv zu finden.</p><ul><li>Beispiel: Das ist das Haus des Mannes.</li><li>Hier zeigt "des Mannes", dass das Haus dem Mann gehört.</li></ul><br><p>3. <strong>Dativ (Wem-Fall)</strong></p><p>Der Dativ beschreibt, wem etwas gegeben wird oder für wen etwas passiert. Du stellst die Frage "Wem?".</p><ul><li>Beispiel: Ich gebe dem Kind einen Ball.</li><li>Hier steht "dem Kind" im Dativ, weil es zeigt, wem der Ball gegeben wird.</li></ul><br><p>4. <strong>Akkusativ (Wen-Fall)</strong></p><p>Der Akkusativ ist der Fall des direkten Objekts, also das, worauf sich die Handlung bezieht. Du stellst die Frage "Wen oder was?".</p><ul><li>Beispiel: Der Hund sieht die Katze.</li><li>Hier ist "die Katze" das direkte Objekt, weil sie das ist, was gesehen wird.</li></ul><br><p><strong>Zusammenfassung der Fälle mit Fragen</strong></p><br><ul><li>Nominativ (Wer oder was?): Das Subjekt des Satzes.</li><li>Beispiel: Der Lehrer erklärt den Stoff.</li><li>Genitiv (Wessen?): Zeigt Besitz oder Zugehörigkeit.</li><li>Beispiel: Das Fahrrad des Jungen ist neu.</li><li>Dativ (Wem?): Das indirekte Objekt, das von der Handlung betroffen ist.</li><li>Beispiel: Sie schenkt dem Freund ein Buch.</li><li>Akkusativ (Wen oder was?): Das direkte Objekt der Handlung.</li><li>Beispiel: Der Junge spielt den Ball.</li></ul><br><p>Diese vier Fälle helfen uns dabei, Sätze richtig zu bilden und zu verstehen, wie die verschiedenen Teile eines Satzes zusammengehören. Wenn du die Fragen zu jedem Fall im Kopf behältst, kannst du ganz leicht erkennen, welcher Fall verwendet werden muss!</p></p>
|
||||||
<br><br>
|
|
||||||
1. <strong>Nominativ (Wer-Fall)</strong> <br>
|
|
||||||
Der Nominativ ist der Fall des Subjekts, also die Person oder Sache, die etwas tut. Du kannst die Frage "Wer oder was?" stellen, um den Nominativ zu finden.
|
|
||||||
<br>
|
|
||||||
- Beispiel: Der Hund bellt. <br>
|
|
||||||
- Hier ist "der Hund" das Subjekt, das etwas tut. Deshalb steht es im Nominativ.
|
|
||||||
<br><br>
|
|
||||||
2. <strong>Genitiv (Wessen-Fall)</strong> <br>
|
|
||||||
Der Genitiv zeigt, wem etwas gehört. Du kannst die Frage "Wessen?" stellen, um den Genitiv zu finden. <br>
|
|
||||||
- Beispiel: Das ist das Haus des Mannes. <br>
|
|
||||||
- Hier zeigt "des Mannes", dass das Haus dem Mann gehört.
|
|
||||||
<br><br>
|
|
||||||
3. <strong>Dativ (Wem-Fall)</strong> <br>
|
|
||||||
Der Dativ beschreibt, wem etwas gegeben wird oder für wen etwas passiert. Du stellst die Frage "Wem?". <br>
|
|
||||||
- Beispiel: Ich gebe dem Kind einen Ball. <br>
|
|
||||||
- Hier steht "dem Kind" im Dativ, weil es zeigt, wem der Ball gegeben wird.
|
|
||||||
<br><br>
|
|
||||||
4. <strong>Akkusativ (Wen-Fall)</strong> <br>
|
|
||||||
Der Akkusativ ist der Fall des direkten Objekts, also das, worauf sich die Handlung bezieht. Du stellst die Frage "Wen oder was?".
|
|
||||||
<br>
|
|
||||||
- Beispiel: Der Hund sieht die Katze. <br>
|
|
||||||
- Hier ist "die Katze" das direkte Objekt, weil sie das ist, was gesehen wird.
|
|
||||||
<br><br>
|
|
||||||
<strong>Zusammenfassung der Fälle mit Fragen</strong>
|
|
||||||
<br><br>
|
|
||||||
- Nominativ (Wer oder was?): Das Subjekt des Satzes. <br>
|
|
||||||
- Beispiel: Der Lehrer erklärt den Stoff. <br>
|
|
||||||
- Genitiv (Wessen?): Zeigt Besitz oder Zugehörigkeit. <br>
|
|
||||||
- Beispiel: Das Fahrrad des Jungen ist neu. <br>
|
|
||||||
- Dativ (Wem?): Das indirekte Objekt, das von der Handlung betroffen ist. <br>
|
|
||||||
- Beispiel: Sie schenkt dem Freund ein Buch. <br>
|
|
||||||
- Akkusativ (Wen oder was?): Das direkte Objekt der Handlung. <br>
|
|
||||||
- Beispiel: Der Junge spielt den Ball.
|
|
||||||
<br><br>
|
|
||||||
Diese vier Fälle helfen uns dabei, Sätze richtig zu bilden und zu verstehen, wie die verschiedenen Teile eines Satzes zusammengehören. Wenn du die Fragen zu jedem Fall im Kopf behältst, kannst du ganz leicht erkennen, welcher Fall verwendet werden muss!
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
{
|
{
|
||||||
"displayName": "Vier Fälle",
|
"displayName": "Vier Fälle",
|
||||||
"icon": "fa-4",
|
"icon": "fa-4",
|
||||||
"description": "Die vier Fälle im Deutschen - Nominativ, Genitiv, Dativ und Akkusativ - beschreiben die verschiedenen grammatischen Funktionen eines Nomens oder Pronomens im Satz, wie Subjekt, Besitz, indirektes Objekt oder direktes Objekt.",
|
"description": "Die vier Fälle im Deutschen - Nominativ, Genitiv, Dativ und Akkusativ - beschreiben die verschiedenen grammatischen Funktionen eines Nomens oder Pronomens im Satz, wie Subjekt, Besitz, indirektes Objekt oder direktes Objekt.",
|
||||||
"relatedTopics": [
|
"relatedTopics": [
|
||||||
"satzglieder"
|
"satzglieder"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
[]
|
||||||
@@ -1,33 +1 @@
|
|||||||
<img alt="Ein Bild" src="$TOPICPATH/img.png">
|
<p><p><img src="__TOPICPATH__/img.png" alt="Ein Bild"></p><p>Wenn wir sprechen oder schreiben, benutzen wir verschiedene Arten von Wörtern, die unterschiedliche Aufgaben haben. Diese Arten von Wörtern nennt man Wortarten. Jede Wortart hilft uns, Sätze zu bilden und unsere Gedanken klar auszudrücken. Lass uns die wichtigsten Wortarten anschauen, die wir im Deutschen verwenden.</p><br><p>1. <strong>Nomen (Namenwörter)</strong> Nomen sind Wörter, die Dinge, Personen, Tiere oder Orte benennen. Zum Beispiel: "Haus", "Hund", "Schule" oder "Freundin". Man erkennt Nomen daran, dass sie großgeschrieben werden. Sie sind die Hauptfiguren in einem Satz, weil sie das Thema angeben, worüber wir sprechen. Ein Beispiel: "Der Hund läuft schnell." Hier ist "Hund" das Nomen.</p><br><p>2. <strong>Verben (Tunwörter)</strong> Verben sind Wörter, die eine Handlung oder einen Zustand beschreiben. Sie zeigen, was jemand tut oder was passiert. Beispiele sind: "laufen", "essen", "schlafen" oder "denken". Verben sind wichtig, denn sie bringen Bewegung in den Satz. Ein Beispiel: "Die Katze schläft auf dem Sofa." Hier ist "schläft" das Verb.</p><br><p>3. <strong>Adjektive (Eigenschaftswörter)</strong> Adjektive beschreiben, wie etwas ist. Sie geben mehr Informationen über ein Nomen. Zum Beispiel: "groß", "schnell", "fröhlich" oder "lecker". Adjektive helfen uns, uns Dinge besser vorzustellen, weil sie Details liefern. Ein Beispiel: "Das große Haus steht am Ende der Straße." Hier beschreibt "groß" das Haus.</p><br><p>4. <strong>Pronomen (Fürwörter)</strong> Pronomen ersetzen Nomen, damit wir nicht immer das gleiche Wort wiederholen müssen. Beispiele sind: "ich", "du", "er", "sie", "es", "wir" oder "mein". Sie machen unsere Sätze abwechslungsreicher und verständlicher. Ein Beispiel: "Anna ist meine Freundin. Sie ist sehr nett." Hier ersetzt "sie" das Nomen "Anna".</p><br><p>5. <strong>Artikel (Begleiter)</strong> Artikel sind kleine Wörter, die vor einem Nomen stehen und uns sagen, ob wir über etwas Bestimmtes oder etwas Allgemeines sprechen. Zum Beispiel: "der", "die", "das", "ein", "eine". Artikel helfen uns zu verstehen, worum es genau geht. Ein Beispiel: "Das Auto ist rot." Hier ist "das" der Artikel, der das Nomen "Auto" begleitet.</p><br><p>6. <strong>Adverbien (Umstandswörter)</strong> Adverbien geben mehr Informationen über ein Verb, ein Adjektiv oder ein anderes Adverb. Sie erklären zum Beispiel, wann, wo oder wie etwas passiert. Beispiele sind: "heute", "draußen", "schnell" oder "sehr". Adverbien machen Sätze lebendiger und genauer. Ein Beispiel: "Der Junge rennt schnell." Hier erklärt "schnell", wie der Junge rennt.</p><br><p>7. <strong>Präpositionen (Verhältniswörter)</strong> Präpositionen zeigen die Beziehung zwischen Dingen. Sie sagen uns, wo etwas ist oder in welchem Verhältnis etwas steht. Zum Beispiel: "auf", "unter", "neben", "vor" oder "hinter". Diese Wörter helfen uns zu verstehen, wo etwas ist. Ein Beispiel: "Der Ball liegt unter dem Tisch." Hier zeigt "unter" die Position des Balls an.</p><br><p>8. <strong>Konjunktionen (Bindewörter)</strong> Konjunktionen verbinden Wörter oder Sätze miteinander. Beispiele sind: "und", "oder", "weil", "aber". Sie helfen uns, längere Sätze zu bilden und unsere Gedanken miteinander zu verbinden. Ein Beispiel: "Ich mag Äpfel und Bananen." Hier verbindet "und" die beiden Nomen "Äpfel" und "Bananen".</p><br><p>9. <strong>Interjektionen (Ausrufewörter)</strong> Interjektionen sind kurze Ausrufe, die unsere Gefühle ausdrücken. Zum Beispiel: "Oh!", "Aua!", "Wow!" oder "Hey!". Sie bringen Emotionen in unsere Sprache und machen sie lebendiger. Ein Beispiel: "Wow! Das war ein tolles Spiel!" Hier drückt "Wow!" Begeisterung aus.</p><br><p>Jede Wortart hat ihre eigene Aufgabe, und zusammen bilden sie die Sprache, die wir jeden Tag benutzen. Wenn wir die verschiedenen Wortarten kennen, können wir bessere Sätze bilden und uns klarer ausdrücken. Also, wenn du das nächste Mal einen Satz schreibst, schau mal, welche Wortarten du benutzt hast – sie sind die Bausteine, die alles zusammenhalten!</p></p>
|
||||||
<br>
|
|
||||||
|
|
||||||
Wenn wir sprechen oder schreiben, benutzen wir verschiedene Arten von Wörtern, die unterschiedliche Aufgaben haben. Diese Arten von Wörtern nennt man Wortarten. Jede Wortart hilft uns, Sätze zu bilden und unsere Gedanken klar auszudrücken. Lass uns die wichtigsten Wortarten anschauen, die wir im Deutschen verwenden.
|
|
||||||
<br><br>
|
|
||||||
1. <strong>Nomen (Namenwörter)</strong>
|
|
||||||
Nomen sind Wörter, die Dinge, Personen, Tiere oder Orte benennen. Zum Beispiel: "Haus", "Hund", "Schule" oder "Freundin". Man erkennt Nomen daran, dass sie großgeschrieben werden. Sie sind die Hauptfiguren in einem Satz, weil sie das Thema angeben, worüber wir sprechen. Ein Beispiel: "Der Hund läuft schnell." Hier ist "Hund" das Nomen.
|
|
||||||
<br><br>
|
|
||||||
2. <strong>Verben (Tunwörter)</strong>
|
|
||||||
Verben sind Wörter, die eine Handlung oder einen Zustand beschreiben. Sie zeigen, was jemand tut oder was passiert. Beispiele sind: "laufen", "essen", "schlafen" oder "denken". Verben sind wichtig, denn sie bringen Bewegung in den Satz. Ein Beispiel: "Die Katze schläft auf dem Sofa." Hier ist "schläft" das Verb.
|
|
||||||
<br><br>
|
|
||||||
3. <strong>Adjektive (Eigenschaftswörter)</strong>
|
|
||||||
Adjektive beschreiben, wie etwas ist. Sie geben mehr Informationen über ein Nomen. Zum Beispiel: "groß", "schnell", "fröhlich" oder "lecker". Adjektive helfen uns, uns Dinge besser vorzustellen, weil sie Details liefern. Ein Beispiel: "Das große Haus steht am Ende der Straße." Hier beschreibt "groß" das Haus.
|
|
||||||
<br><br>
|
|
||||||
4. <strong>Pronomen (Fürwörter)</strong>
|
|
||||||
Pronomen ersetzen Nomen, damit wir nicht immer das gleiche Wort wiederholen müssen. Beispiele sind: "ich", "du", "er", "sie", "es", "wir" oder "mein". Sie machen unsere Sätze abwechslungsreicher und verständlicher. Ein Beispiel: "Anna ist meine Freundin. Sie ist sehr nett." Hier ersetzt "sie" das Nomen "Anna".
|
|
||||||
<br><br>
|
|
||||||
5. <strong>Artikel (Begleiter)</strong>
|
|
||||||
Artikel sind kleine Wörter, die vor einem Nomen stehen und uns sagen, ob wir über etwas Bestimmtes oder etwas Allgemeines sprechen. Zum Beispiel: "der", "die", "das", "ein", "eine". Artikel helfen uns zu verstehen, worum es genau geht. Ein Beispiel: "Das Auto ist rot." Hier ist "das" der Artikel, der das Nomen "Auto" begleitet.
|
|
||||||
<br><br>
|
|
||||||
6. <strong>Adverbien (Umstandswörter)</strong>
|
|
||||||
Adverbien geben mehr Informationen über ein Verb, ein Adjektiv oder ein anderes Adverb. Sie erklären zum Beispiel, wann, wo oder wie etwas passiert. Beispiele sind: "heute", "draußen", "schnell" oder "sehr". Adverbien machen Sätze lebendiger und genauer. Ein Beispiel: "Der Junge rennt schnell." Hier erklärt "schnell", wie der Junge rennt.
|
|
||||||
<br><br>
|
|
||||||
7. <strong>Präpositionen (Verhältniswörter)</strong>
|
|
||||||
Präpositionen zeigen die Beziehung zwischen Dingen. Sie sagen uns, wo etwas ist oder in welchem Verhältnis etwas steht. Zum Beispiel: "auf", "unter", "neben", "vor" oder "hinter". Diese Wörter helfen uns zu verstehen, wo etwas ist. Ein Beispiel: "Der Ball liegt unter dem Tisch." Hier zeigt "unter" die Position des Balls an.
|
|
||||||
<br><br>
|
|
||||||
8. <strong>Konjunktionen (Bindewörter)</strong>
|
|
||||||
Konjunktionen verbinden Wörter oder Sätze miteinander. Beispiele sind: "und", "oder", "weil", "aber". Sie helfen uns, längere Sätze zu bilden und unsere Gedanken miteinander zu verbinden. Ein Beispiel: "Ich mag Äpfel und Bananen." Hier verbindet "und" die beiden Nomen "Äpfel" und "Bananen".
|
|
||||||
<br><br>
|
|
||||||
9. <strong>Interjektionen (Ausrufewörter)</strong>
|
|
||||||
Interjektionen sind kurze Ausrufe, die unsere Gefühle ausdrücken. Zum Beispiel: "Oh!", "Aua!", "Wow!" oder "Hey!". Sie bringen Emotionen in unsere Sprache und machen sie lebendiger. Ein Beispiel: "Wow! Das war ein tolles Spiel!" Hier drückt "Wow!" Begeisterung aus.
|
|
||||||
<br><br>
|
|
||||||
Jede Wortart hat ihre eigene Aufgabe, und zusammen bilden sie die Sprache, die wir jeden Tag benutzen. Wenn wir die verschiedenen Wortarten kennen, können wir bessere Sätze bilden und uns klarer ausdrücken. Also, wenn du das nächste Mal einen Satz schreibst, schau mal, welche Wortarten du benutzt hast – sie sind die Bausteine, die alles zusammenhalten!
|
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
{
|
{
|
||||||
"displayName": "Wortarten",
|
"displayName": "Wortarten",
|
||||||
"icon": "fa-sitemap",
|
"icon": "fa-sitemap",
|
||||||
"description": "Wortarten sind Kategorien, in die Wörter anhand ihrer grammatischen Funktion und Bedeutung eingeteilt werden, wie zum Beispiel Nomen, Verben, Adjektive und Adverbien.",
|
"description": "Wortarten sind Kategorien, in die Wörter anhand ihrer grammatischen Funktion und Bedeutung eingeteilt werden, wie zum Beispiel Nomen, Verben, Adjektive und Adverbien.",
|
||||||
"relatedTopics": [
|
"relatedTopics": [
|
||||||
"satzglieder", "adverbiale-bestimmung", "personalpronomen"
|
"satzglieder",
|
||||||
]
|
"adverbiale-bestimmung",
|
||||||
|
"personalpronomen"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
[]
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"displayName": "Englisch",
|
"displayName": "Englisch",
|
||||||
"description": "He she it das s muss mit!",
|
"description": "He she it das s muss mit!",
|
||||||
"color": "#17B750",
|
"color": "#17b750",
|
||||||
"icon": "fa-language"
|
"icon": "fa-language"
|
||||||
}
|
}
|
||||||
@@ -1,9 +1 @@
|
|||||||
<img alt="Ein Bild" src="$TOPICPATH/img.png">
|
<p><img src="__TOPICPATH__/img.png" alt="Ein Bild"><p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</p><br><p>Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.</p><br><p>Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.</p><p>Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer</p></p>
|
||||||
<br>
|
|
||||||
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
|
|
||||||
<br><br>
|
|
||||||
Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.
|
|
||||||
<br><br>
|
|
||||||
Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.
|
|
||||||
<br>
|
|
||||||
Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer
|
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
{
|
{
|
||||||
"displayName": "Lorem Ipsum",
|
"displayName": "Lorem Ipsum",
|
||||||
"icon": "fa-sitemap",
|
"icon": "fa-sitemap",
|
||||||
"description": "Lorem Ipsum",
|
"description": "Lorem Ipsum",
|
||||||
"relatedTopics": [
|
"relatedTopics": []
|
||||||
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
[]
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"displayName": "Mathe",
|
"displayName": "Mathe",
|
||||||
"description": "Mathe ist blau",
|
"description": "Mathe ist rot",
|
||||||
"color": "#3b82f6",
|
"color": "#626cd0",
|
||||||
"icon": "fa-square-root-alt"
|
"icon": "fa-square-root-alt"
|
||||||
}
|
}
|
||||||
@@ -1,46 +1,25 @@
|
|||||||
Brüche werden verwendet, um Anteile an einem Ganzen darzustellen. So kann es vorkommen, dass nur ein Teil einer Pizza gegessen wird oder nur ein Teil einer Flasche getrunken wird. In der Mathematik wird ein solcher Anteil durch einen Bruch dargestellt. In der folgenden Grafik wird gezeigt, wie 3 von 7 Kästchen gelb markiert werden, und wie der entsprechende Bruch dargestellt wird.
|
<p>Brüche werden verwendet, um Anteile an einem Ganzen darzustellen. So kann es vorkommen, dass nur ein Teil einer Pizza
|
||||||
<br><br> Ein Bruch setzt sich aus einem Zähler, einem Bruchstrich und einem Nenner zusammen. Der Zähler wird über dem Bruchstrich geschrieben, der Nenner darunter.
|
gegessen wird oder nur ein Teil einer Flasche getrunken wird. In der Mathematik wird ein solcher Anteil durch einen
|
||||||
<br><br>
|
Bruch dargestellt. In der folgenden Grafik wird gezeigt, wie 3 von 7 Kästchen gelb markiert werden, und wie der
|
||||||
$$
|
entsprechende Bruch dargestellt wird.</p><br>
|
||||||
\begin{array}{c@{\quad}l}
|
|
||||||
3 & \text{Zahler} \\
|
|
||||||
- & \text{Bruchstrich} \\
|
|
||||||
7 & \text{Nenner} \\
|
|
||||||
|
|
||||||
\end{array}
|
<p>Ein Bruch setzt sich aus einem Zähler, einem Bruchstrich und einem Nenner zusammen. Der Zähler wird über dem Bruchstrich geschrieben, der Nenner darunter.</p>
|
||||||
$$
|
|
||||||
|
|
||||||
<strong>Brüche addieren und subtrahieren</strong> <br><br> Brüche mit gleichen Nennern (= gleichnamige Brüche) werden addiert, indem die Zähler addiert und der Nenner beibehalten wird. So werden aus 2 von 6 Stücken plus 3 von 6 Stücken insgesamt 5 von 6 Stücken.
|
<p><span>$$\begin{array}{cl} 3 & \text{Zahler} \\ - & \text{Bruchstrich} \\ 7 & \text{Nenner} \\ \end{array}$$</span></p>
|
||||||
|
|
||||||
$$
|
<p><strong>Brüche addieren und subtrahieren</strong></p><br>
|
||||||
\frac{2}{6} + \frac{3}{6} = \frac{5}{6}
|
|
||||||
$$
|
|
||||||
|
|
||||||
<br><br>
|
<p>Brüche mit gleichen Nennern (= gleichnamige Brüche)
|
||||||
|
werden addiert, indem die Zähler addiert und der Nenner beibehalten wird. So werden aus 2 von 6 Stücken plus 3 von 6
|
||||||
|
Stücken insgesamt 5 von 6 Stücken.</p><br>
|
||||||
|
<p><span>$$\frac{2}{6} + \frac{3}{6} = \frac{5}{6}$$</span></p><br>
|
||||||
|
<p>Zur Subtraktion gleichnamiger Brüche werden die Zähler subtrahiert und der Nenner beibehalten. Wenn von 5 von 6 Stücken 3 von 6 Stücke weggenommen werden, bleiben 2 der 6 Stücke übrig.</p><br>
|
||||||
|
<p><span>$$\frac{5}{6} - \frac{3}{6} = \frac{2}{6}$$</span></p><br>
|
||||||
|
|
||||||
Zur Subtraktion gleichnamiger Brüche werden die Zähler subtrahiert und der Nenner beibehalten. Wenn von 5 von 6 Stücken 3 von 6 Stücke weggenommen werden, bleiben 2 der 6 Stücke übrig.
|
<p><strong>Brüche multiplizieren und dividieren</strong></p><br>
|
||||||
|
<p>Brüche werden multipliziert, indem die Zähler und Nenner jeweils miteinander multipliziert werden: Zähler mal Zähler und Nenner mal Nenner. Beim Bruchrechnen mit der Grundrechenart Multiplikation spielt es keine Rolle, ob die Nenner gleich oder verschieden sind.</p><br>
|
||||||
$$
|
<p><span>$$\frac{2}{9} \cdot \frac{5}{9} = \frac{10}{81}$$</span></p><br>
|
||||||
\frac{5}{6} - \frac{3}{6} = \frac{2}{6}
|
<p>Bei der Multiplikation von Brüchen mit unterschiedlichen Nennern (= ungleichnamige Brüche) werden ebenfalls die Zähler und Nenner jeweils miteinander multipliziert. Im Gegensatz zur Addition müssen die Brüche dabei nicht auf einen gemeinsamen Nenner gebracht werden.</p><br>
|
||||||
$$
|
<p><span>$$\frac{4}{5} \cdot \frac{2}{3} = \frac{8}{15}$$</span></p><br>
|
||||||
|
<p>Die Division von Brüchen basiert auf der Multiplikation von Brüchen. Um zwei Brüche zu dividieren, wird aus der Division eine Multiplikation gemacht. Das Geteiltzeichen wird durch ein Malzeichen ersetzt. Dafür wird beim zweiten Bruch der Zähler und der Nenner vertauscht.</p><br>
|
||||||
<br><br>
|
<p><span>$$\frac{5}{8} : \frac{4}{7} = \frac{5}{8} \cdot \frac{7}{4} = \frac{35}{32}$$</span></p>
|
||||||
|
|
||||||
<strong>Brüche multiplizieren und dividieren</strong>
|
|
||||||
<br><br>
|
|
||||||
Brüche werden multipliziert, indem die Zähler und Nenner jeweils miteinander multipliziert werden: Zähler mal Zähler und Nenner mal Nenner. Beim Bruchrechnen mit der Grundrechenart Multiplikation spielt es keine Rolle, ob die Nenner gleich oder verschieden sind.
|
|
||||||
|
|
||||||
$$
|
|
||||||
\frac{2}{9} \cdot \frac{5}{9} = \frac{10}{81}
|
|
||||||
$$
|
|
||||||
Bei der Multiplikation von Brüchen mit unterschiedlichen Nennern (= ungleichnamige Brüche) werden ebenfalls die Zähler und Nenner jeweils miteinander multipliziert. Im Gegensatz zur Addition müssen die Brüche dabei nicht auf einen gemeinsamen Nenner gebracht werden.
|
|
||||||
|
|
||||||
$$
|
|
||||||
\frac{4}{5} \cdot \frac{2}{3} = \frac{8}{15}
|
|
||||||
$$
|
|
||||||
|
|
||||||
Die Division von Brüchen basiert auf der Multiplikation von Brüchen. Um zwei Brüche zu dividieren, wird aus der Division eine Multiplikation gemacht. Das Geteiltzeichen wird durch ein Malzeichen ersetzt. Dafür wird beim zweiten Bruch der Zähler und der Nenner vertauscht.
|
|
||||||
|
|
||||||
$$
|
|
||||||
\frac{5}{8} : \frac{4}{7} = \frac{5}{8} \cdot \frac{7}{4} = \frac{35}{32}
|
|
||||||
$$
|
|
||||||
@@ -1,8 +1,7 @@
|
|||||||
{
|
{
|
||||||
"displayName": "Bruchrechnung",
|
"displayName": "Bruchrechnung",
|
||||||
"icon": "fa-chart-pie",
|
"icon": "fa-chart-pie",
|
||||||
"description": "Die Bruchrechnung ist ein Teil der Mathematik, der das Rechnen mit Brüchen beinhaltet, also das Teilen eines Ganzen in gleich große Teile, und umfasst Operationen wie Addition, Subtraktion, Multiplikation und Division von Brüchen.",
|
"description": "Die Bruchrechnung ist ein Teil der Mathematik, der das Rechnen mit Brüchen beinhaltet, also das Teilen eines Ganzen in gleich große Teile, und umfasst Operationen wie Addition, Subtraktion, Multiplikation und Division von Brüchen.",
|
||||||
"relatedTopics": [
|
"relatedTopics": [
|
||||||
"schriftliches-multiplizieren", "schriftliches-dividieren", "punkt-vor-strichrechnung", "rechnen-mit-klammern"
|
]
|
||||||
]
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"text": "$$\\frac{3}{5} + \\frac{1}{5} = ? $$",
|
||||||
|
"vars": {
|
||||||
|
"?": "4/5"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "$$\\frac{4}{7} - \\frac{2}{7} = ? $$",
|
||||||
|
"vars": {
|
||||||
|
"?": "2/7"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Kürze $$\\frac{6}{9}$$",
|
||||||
|
"vars": {
|
||||||
|
"?": "2/3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Erweitere $$\\frac{1}{3}$$ mit 5",
|
||||||
|
"vars": {
|
||||||
|
"?": "5/15"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
<b>Grundbegriffe des Dezimalsystems</b> <br>
|
||||||
|
Das Dezimalsystem verwendet die Basis 10. Jede Stelle repräsentiert eine Potenz von 10. <br><br>
|
||||||
|
Beispiel:
|
||||||
|
|
||||||
|
$$435,12 = 4 \times 100 + 3 \times 10 + 5 \times 1 + 1 \times 0,1 + 2 \times 0,02$$
|
||||||
|
|
||||||
|
<b>Dezimalzahlen auf eine bestimmte Stelle runden</b> <br>
|
||||||
|
Runde immer zur nächsten Zahl auf oder ab, je nachdem, ob die Zahl über oder unter 5 liegt. <br><br>
|
||||||
|
Beispiel:
|
||||||
|
Rundung auf die zweite Nachkommastelle
|
||||||
|
$$3.146 \approx 3.15$$
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"displayName": "Rechnen mit Dezimalzahlen",
|
||||||
|
"icon": "fa-table-columns",
|
||||||
|
"description": "Rechnen mit Dezimalzahlen bedeutet, dass wir Zahlen mit Komma, wie 3,5 oder 7,25, zusammenzählen, abziehen, multiplizieren oder teilen. Es ist wie normales Rechnen, nur dass wir besonders auf das Komma achten müssen.",
|
||||||
|
"relatedTopics": [
|
||||||
|
"prozentrechnung"
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"text": "Zerlege 732.45 in seine Bestandteile",
|
||||||
|
"vars": {
|
||||||
|
"?": "700 + 30 + 2 + 0,4 + 0,05"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Was bedeutet die Zahl 56789 im Dezimalsystem?",
|
||||||
|
"vars": {
|
||||||
|
"?": "700 + 30 + 2 + 0,4 + 0,05"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Runde 2,849 auf zwei Dezimalstellen.",
|
||||||
|
"vars": {
|
||||||
|
"?": "2,85"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Runde 7,235 auf eine Dezimalstelle.",
|
||||||
|
"vars": {
|
||||||
|
"?": "7,2"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
29
webseite/config/subjects/mathe/topics/geometrie/article.html
Normal file
29
webseite/config/subjects/mathe/topics/geometrie/article.html
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
<b>Fläche eines Rechtecks</b> <br>
|
||||||
|
Die Fläche eines Rechtecks oder Quadrats berechnet sich durch Laenge x Breite. <br>
|
||||||
|
Formel: $$A = l \times b$$
|
||||||
|
Beispiel: <br>
|
||||||
|
$$l = 5 cm, b = 3 cm \\ A = 5 \times 3 = 15 cm^{2}$$
|
||||||
|
<br> <br>
|
||||||
|
|
||||||
|
<b>Umfangs von Rechtecken und Quadraten</b> <br>
|
||||||
|
Formel: $$U = 2 \times (l + b)$$
|
||||||
|
Beispiel: <br>
|
||||||
|
$$l = 5 cm , b = 3 cm\\ U = 2 \times (5 + 3) = 16 cm$$
|
||||||
|
<br> <br>
|
||||||
|
|
||||||
|
|
||||||
|
<b>Flaechenberechnung bei Dreiecken</b> <br>
|
||||||
|
Formel: $$A = \frac{1}{2} \times G \times h$$
|
||||||
|
Beispiel: <br>
|
||||||
|
Ein Dreieck mit einer Grundlinie von 6 cm und einer Hoehe von 4 cm: <br>
|
||||||
|
$$A = \frac{1}{2} \times 6 \times 4 = 12 cm^{2}$$
|
||||||
|
|
||||||
|
<b>Umfang und Fläche eines Kreises</b> <br>
|
||||||
|
Formel: $$U = 2 \times \pi \times r \\ A = \pi x r^{2}$$
|
||||||
|
Beispiel: <br>
|
||||||
|
Kreis mit $$r = 3 cm \\ U = 2 \times 3,14 \times 3 = 18,84 cm \\ A = 3.14 \times 9 = 28,26 cm^{2}$$
|
||||||
|
|
||||||
|
|
||||||
|
<b>Volumenberechnung bei Quadern</b> <br>
|
||||||
|
Formel: $$V = l \times b \times h$$
|
||||||
|
Beispiel: Ein Quader mit $$l = 5 cm, b = 3 cm, h = 2 cm\\ V = 5 \times 3 \times 2 = 30 cm{3}$$
|
||||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"displayName": "Geometrie",
|
||||||
|
"icon": "fa-compass-drafting",
|
||||||
|
"description": "Geometrie geht es um Formen, Linien, Flächen und Körpern. Man lernt dabei, wie man Figuren wie Kreise, Dreiecke oder Würfel misst, zeichnet und versteht.",
|
||||||
|
"relatedTopics": [
|
||||||
|
"dezimalsystem"
|
||||||
|
]
|
||||||
|
}
|
||||||
56
webseite/config/subjects/mathe/topics/geometrie/tasks.json
Normal file
56
webseite/config/subjects/mathe/topics/geometrie/tasks.json
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"text": "Ein Quadrat mit Seitenlänge \\(a = 4 cm\\) berechne die Fläche",
|
||||||
|
"vars": {
|
||||||
|
"Fläche in cm^2": "16"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Ein Rechteck mit \\(l = 7 cm\\) und \\(b = 2 cm\\) berechne die Fläche",
|
||||||
|
"vars": {
|
||||||
|
"Fläche in cm^2": "14"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Berechne den Umfang \\(U\\) eines Quadrats mit \\(a = 6 cm\\)",
|
||||||
|
"vars": {
|
||||||
|
"U in cm": "24"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Berechne den Umfang \\(U\\) eines Rechteck mit \\(l = 8 cm\\) und \\(b = 4 cm\\)",
|
||||||
|
"vars": {
|
||||||
|
"?": "24"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Ein Dreieck mit der Grundlinie \\(G = 8cm\\) und einer Höhe \\(h= 5cm\\) berechne die Fläche",
|
||||||
|
"vars": {
|
||||||
|
"Fläche in cm^2": "20"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Ein Dreieck mit der Grundlinie \\(G = 10cm\\) und einer Höhe \\(h= 7cm\\) berechne die Fläche",
|
||||||
|
"vars": {
|
||||||
|
"Fläche in cm^2": "35"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Ein Kreis hat den Radius \\(r = 5cm\\) Berechne den Umfang. Runde auf eine NkSt",
|
||||||
|
"vars": {
|
||||||
|
"Umfang in cm": "31,4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Ein Quader hat den die Länge \\(l = 4cm\\) Breite \\(b = 3cm\\) und Höhe \\(h=2cm\\) Berechne das Volumen \\(V\\)",
|
||||||
|
"vars": {
|
||||||
|
"Volumen in cm^3": "24"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Ein Quader hat den die Länge \\(l = 6cm\\) Breite \\(b = 4cm\\) und Höhe \\(h=3cm\\) Berechne das Volumen \\(V\\)",
|
||||||
|
"vars": {
|
||||||
|
"Volumen in cm^3": "72"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
<b>Einfache Darstellung von Daten</b> <br>
|
||||||
|
|
||||||
|
Graphen und Diagramme stellen Daten visuell dar, z.B. als Balkendiagramm oder Kreisdiagramm. <br><br>
|
||||||
|
Beispiel: <br>
|
||||||
|
Erstelle ein Balkendiagramm fuer die Anzahl der Schueler in jeder Klasse (Klasse A: 20, Klasse B: 18, Klasse C: 22).
|
||||||
|
<br>
|
||||||
|
<img src="__TOPICPATH__/diagramm.png" alt="Ein Bild">
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 51 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 61 KiB |
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"displayName": "Graphen & Diagramme",
|
||||||
|
"icon": "fa-chart-column",
|
||||||
|
"description": "Diagramme und Graphen helfen uns, Zahlen und Daten auf einfache Weise darzustellen. Zum Beispiel können Balkendiagramme, Kreisdiagramme oder Liniendiagramme zeigen, wie etwas wächst, sich verändert oder verteilt ist.",
|
||||||
|
"relatedTopics": [
|
||||||
|
"prozentrechnung"
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"text": "Zeichne ein Kreisdiagramm fuer die Aufteilung der Lieblingstiere in einer Gruppe (Hund: 40 %,\nKatze: 30 %, Vogel: 20 %, Fisch: 10 %).",
|
||||||
|
"vars": {
|
||||||
|
"Schau in A1.png": "Schau in A1.png"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
<b>Grundlegende Prozentrechnung</b> <br>
|
||||||
|
|
||||||
|
Formel: $$Prozentsatz = \frac{Teil}{Ganzes}\times 100$$
|
||||||
|
Beispiel: <br>
|
||||||
|
20 von 100 Schuelern haben eine Eins: $$\frac{20}{100}\times 100 = 20\%$$
|
||||||
|
<br>
|
||||||
|
<b>Einfache Zinsrechnung</b> <br>
|
||||||
|
|
||||||
|
Formel: $$Zinsen = \frac{(Kapital \times Zinssatz \times Zeit)}{100}$$
|
||||||
|
Beispiel: <br>
|
||||||
|
Ein Kapital von 1000 Euro bei 5 % Zinsen für 1 Jahr:
|
||||||
|
$$Zinsen = \frac{(1000 \times 5 \times 1)}{100} = 50 Euro$$
|
||||||
|
|
||||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"displayName": "Prozent- & Zinsrechnung",
|
||||||
|
"icon": "fa-percent",
|
||||||
|
"description": "Die Prozentrechnung zeigt, wie viel von einem Ganzen in Teilen ausgedrückt wird, z. B. 50 % bedeutet die Hälfte. Bei der Zinsrechnung geht es darum, wie Geld wächst, wenn man es verleiht oder spart, z. B. bekommst du Zinsen, wenn du Geld auf ein Sparkonto legst.",
|
||||||
|
"relatedTopics": [
|
||||||
|
"wahrscheinlichkeitsrechnung"
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"text": "Berechne, wie viel Prozent 25 von 200 sind.",
|
||||||
|
"vars": {
|
||||||
|
"%": "12,5"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Wenn 15 von 60 Schülern Sport machen, wie viel Prozent sind das?",
|
||||||
|
"vars": {
|
||||||
|
"%": "25"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Kapital $$K = 2000 €$$ Zinssatz $$z = 4 \\%$$ Zeit $$t = 2 J$$ Berechne den Zins $$Z$$",
|
||||||
|
"vars": {
|
||||||
|
"Z": "160"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Kapital $$K = 1500 €$$ Zinssatz $$z = 3 \\%$$ Zeit $$t = 1 J$$ Berechne den Zins $$Z$$",
|
||||||
|
"vars": {
|
||||||
|
"Z": "45"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
Diese Regel besagt, dass zuerst Multiplikationen und Divisionen und danach Additionen oder Subtraktionen durchgeführt werden. Anhand eines Beispiels wird nun gezeigt, wie diese Regel angewendet wird (und wie Fehler dabei passieren können).
|
|
||||||
<br><br>
|
|
||||||
a) 5 + 2 · 4 = 5 + 8 = 13 (richtige Lösung) <br>
|
|
||||||
b) 5 + 2 · 4 = 7 · 4 = 28 (falsche Lösung) <br>
|
|
||||||
|
|
||||||
<br>
|
|
||||||
|
|
||||||
<strong>Erklärung: </strong><br>
|
|
||||||
In beiden Fällen wird das Ergebnis der Aufgabe 5 + 2 · 4 gesucht. Im Fall a) wurde die Aufgabe richtig gelöst, indem zuerst die Multiplikation berechnet wurde. Das ergibt 2 · 4 = 8. Anschließend wurde 5 + 8 = 13 gerechnet. Wie zu sehen ist, wurde erst die Multiplikation ausgeführt, bevor die beiden Zahlen addiert wurden. Im Fall b) wurde jedoch ein Fehler gemacht, da hier erst addiert und dann multipliziert wurde. Das Ergebnis wurde dadurch falsch berechnet
|
|
||||||
<br><br>
|
|
||||||
<strong>Noch eine kleine Anmerkung:</strong> <br>
|
|
||||||
Links des "=" muss immer dasselbe stehen wie rechts des "=". Wenn so gerechnet wird, wie es in den Beispielen gezeigt wird, passiert das automatisch. Dies wird hier erwähnt, weil es in einem späteren Kapitel – in den sogenannten Gleichungen mit Unbekannten – noch genauer besprochen wird. Zu diesem Zeitpunkt sollte jedoch einfach versucht werden, den Beispielen zu folgen und das Konzept in den Übungsaufgaben selbst anzuwenden.
|
|
||||||
<br><br>
|
|
||||||
Das vorherige Beispiel sollte noch einmal durchgegangen werden. Anschließend folgen eine Reihe weiterer Beispiele. Jedes sollte genau angesehen werden, um die Berechnung zu verfolgen.
|
|
||||||
<br><br>
|
|
||||||
Auch hier gilt: Zuerst Multiplikation oder Division, danach Addition oder Subtraktion.
|
|
||||||
|
|
||||||
<br><br>
|
|
||||||
|
|
||||||
Aufgabe: 8 · 3 + 2 = ? <br>
|
|
||||||
Lösung: 8 · 3 + 2 = 24 + 2 = 26 <br> <br>
|
|
||||||
Aufgabe: 2 + 3 · 4 = ? <br>
|
|
||||||
Lösung: 2 + 3 · 4 = 2 + 12 = 14 <br> <br>
|
|
||||||
Aufgabe: 6 : 3 + 2 = ? <br>
|
|
||||||
Lösung: 6 : 3 + 2 = 2 + 2 = 4 <br> <br>
|
|
||||||
Aufgabe: 5 - 8 : 4 = ? <br>
|
|
||||||
Lösung: 5 - 8 : 4 = 5 - 2 = 3 <br> <br>
|
|
||||||
Aufgabe: 5 · 3 + 8 : 4 = ? <br>
|
|
||||||
Lösung: 5 · 3 + 8 : 4 = 15 + 2 = 17 <br> <br>
|
|
||||||
|
|
||||||
<strong>Erläuterungen:</strong> <br>
|
|
||||||
In den ersten vier Beispielen wurde konsequent die Punkt-vor-Strich-Regel beachtet. Es wurde zuerst multipliziert oder dividiert und danach addiert oder subtrahiert. Beim letzten Beispiel mussten sowohl eine Multiplikation als auch eine Division durchgeführt werden. Es spielt dabei keine Rolle, in welcher Reihenfolge diese beiden Operationen ausgeführt werden – wichtig ist nur, dass die Addition aufgrund der Punkt-vor-Strich-Regel am Ende berechnet wird. Das bedeutet also, dass erst 5 · 3 sowie 8 : 4 berechnet werden müssen und danach die beiden Ergebnisse addiert werden.
|
|
||||||
<br><br>
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
{
|
|
||||||
"displayName": "Punkt- vor Strichrechnung",
|
|
||||||
"icon": "fa-plus-minus",
|
|
||||||
"description": "Die Regel \"Punkt vor Strichrechnung\" besagt, dass bei mathematischen Berechnungen Multiplikation und Division immer vor Addition und Subtraktion ausgeführt werden müssen, um das richtige Ergebnis zu erhalten.",
|
|
||||||
"relatedTopics": [
|
|
||||||
"rechnen-mit-klammern", "bruchrechnung"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
File diff suppressed because one or more lines are too long
@@ -1,8 +1,9 @@
|
|||||||
{
|
{
|
||||||
"displayName": "Rechnen mit Einheiten",
|
"displayName": "Rechnen mit Einheiten",
|
||||||
"icon": "fa-clock",
|
"icon": "fa-clock",
|
||||||
"description": "Rechnen mit Einheiten bedeutet, Größen mit verschiedenen Maßeinheiten wie Meter, Kilogramm oder Liter rechnerisch zu verarbeiten, dabei die Einheiten korrekt umzurechnen und sicherzustellen, dass das Ergebnis in der richtigen Einheit angegeben wird.",
|
"description": "Rechnen mit Einheiten bedeutet, Größen mit verschiedenen Maßeinheiten wie Meter, Kilogramm oder Liter rechnerisch zu verarbeiten, dabei die Einheiten korrekt umzurechnen und sicherzustellen, dass das Ergebnis in der richtigen Einheit angegeben wird.",
|
||||||
"relatedTopics": [
|
"relatedTopics": [
|
||||||
"schriftliches-dividieren", "bruchrechnung"
|
"schriftliches-dividieren",
|
||||||
]
|
"bruchrechnung"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
[]
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
Wie wird es gemacht, wenn bei einer Aufgabe zunächst eine Addition ausgeführt werden soll und danach eine Multiplikation? Die Antwort lautet: Es wird eine Klammer gesetzt. Die mathematische Regel lautet dann ganz einfach "Eine Klammer wird zuerst berechnet". Um bei den ganzen Klammern, Punkt vor Strich usw. nicht durcheinander zu kommen, folgt hier noch einmal ein kurzer Leitfaden:
|
|
||||||
|
|
||||||
<br><br>
|
|
||||||
|
|
||||||
1. Wenn eine Klammer in der Aufgabe vorhanden ist, wird diese zuerst berechnet <br>
|
|
||||||
|
|
||||||
2. Danach werden Multiplikation und Division ausgeführt <br>
|
|
||||||
|
|
||||||
3. Als letztes folgen Addition und Subtraktion <br>
|
|
||||||
<br>
|
|
||||||
|
|
||||||
Der Leitfaden von oben sollte gemerkt werden, um dann die folgenden Beispiele zu verstehen:
|
|
||||||
<br><br>
|
|
||||||
Aufgabe: (2 + 3) · 5 = ? <br>
|
|
||||||
Lösung: (2 + 3) · 5 = 5 · 5 = 25 <br><br>
|
|
||||||
Aufgabe: 8 · (3 + 4) = ? <br>
|
|
||||||
Lösung: 8 · (3 + 4) = 8 · 7 = 56 <br><br>
|
|
||||||
Aufgabe: 2 · (1 + 2) + 5 = ? <br>
|
|
||||||
Lösung: 2 · (1 + 2) + 5 = 2 · 3 + 5 = 6 + 5 = 11 <br><br>
|
|
||||||
Aufgabe: 3 · (8 + 2) : 10 + 1 = ? <br>
|
|
||||||
Lösung: 3 · (8 + 2) : 10 + 1 = 3 · 10 : 10 + 1 = 30 : 10 + 1 = 3 + 1 = 4 <br><br>
|
|
||||||
|
|
||||||
|
|
||||||
<strong>Erklärungen: </strong> <br>
|
|
||||||
Gerade die beiden letzten Aufgaben könnten abschreckend wirken. Es wird jedoch mit den ersten beiden Aufgaben begonnen: In beiden Fällen wurde zunächst die Klammer berechnet. Das Ergebnis wurde dann mit der dahinter oder davor stehenden Zahl multipliziert. Bei der dritten Aufgabe wurde zuerst die Klammer berechnet, dann die Multiplikation und schließlich die Addition ausgeführt.
|
|
||||||
<br><br>
|
|
||||||
Kommen wir zur letzten Aufgabe: Auch hier wurde zunächst die Klammer berechnet. Mit dem Ergebnis der Klammer konnte dann entweder als erstes multipliziert oder dividiert werden, das ist mathematisch gleichgültig. In meinem Rechenweg wurde zunächst multipliziert, dann dividiert, und schließlich addiert. Die Aufgabe sollte noch einmal Stück für Stück durchgegangen werden, um Klarheit zu erhalten.
|
|
||||||
<br><br>
|
|
||||||
|
|
||||||
<strong>Priorität bei Klammern / mehrere Klammern</strong> <br>
|
|
||||||
Eine kleine Schwierigkeit muss zu guter Letzt noch angesprochen werden: Was passiert bei mehreren Klammern und verschachtelten Klammern? Dazu folgen zunächst zwei kleine Beispiele samt Lösungen, danach die Erklärung.
|
|
||||||
<br><br>
|
|
||||||
Aufgabe: (5 + 3) + (1 + 2) = ? <br>
|
|
||||||
Lösung: (5 + 3) + (1 + 2) = 8 + 3 = 11 <br><br>
|
|
||||||
Aufgabe: ((3 + 4) + 2) + 1 = ? <br>
|
|
||||||
Lösung: [( 3 + 4 ) + 2 ] + 1 = (7 + 2) + 1 = 10 <br><br>
|
|
||||||
|
|
||||||
|
|
||||||
<strong>Erklärung: </strong> <br>
|
|
||||||
Im ersten Beispiel gibt es zwei Klammern. Welche davon zuerst berechnet wird, ist vollkommen egal. Beide Klammern werden einzeln ausgerechnet und die Ergebnisse anschließend addiert. Kommen wir zum zweiten Beispiel: Hier gibt es zwei ineinander verschachtelte Klammern. Die Rechenregel dabei lautet ganz einfach: Immer zuerst die innere Klammer berechnen.
|
|
||||||
<br><br>
|
|
||||||
Zur besseren Übersicht bei verschachtelten Klammern sehen diese meist etwas unterschiedlich aus: Die innere Klammer wird üblicherweise mit "(" und ")" gekennzeichnet, während die äußere Klammer mit "[" und "]" versehen wird. Natürlich gilt wie immer: Um die Rechenregeln wirklich zu beherrschen, sollten die Übungsaufgaben bearbeitet werden.
|
|
||||||
<br><br>
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
{
|
|
||||||
"displayName": "Rechnen mit Klammern",
|
|
||||||
"icon": "fa-code",
|
|
||||||
"description": "Beim Rechnen mit Klammern werden die Rechenoperationen innerhalb der Klammern zuerst ausgeführt, bevor die restlichen Berechnungen im Ausdruck vorgenommen werden, um die korrekte Reihenfolge der Rechenschritte einzuhalten.",
|
|
||||||
"relatedTopics": [
|
|
||||||
"punkt-vor-strichrechnung", "bruchrechnung"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
Bei der Addition und Subtraktion grosser Zahlen hilft es, die Zahlen stellengerecht untereinander zu schreiben.
|
||||||
|
<br>
|
||||||
|
Beispiel: <br>
|
||||||
|
$$
|
||||||
|
\begin{align*}
|
||||||
|
7421&\\
|
||||||
|
+5634&\\
|
||||||
|
\hline
|
||||||
|
13055&
|
||||||
|
\end{align*}
|
||||||
|
$$
|
||||||
|
|
||||||
|
$$
|
||||||
|
\begin{align*}
|
||||||
|
9876&\\
|
||||||
|
-1234&\\
|
||||||
|
\hline
|
||||||
|
8642&
|
||||||
|
\end{align*}
|
||||||
|
$$
|
||||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"displayName": "Schriftliches Addieren und Subtrahieren",
|
||||||
|
"icon": "fa-plus-minus",
|
||||||
|
"description": "Bei der schriftlichen Addition und Subtraktion rechnest du größere Zahlen Schritt für Schritt untereinander. Du fängst rechts bei den Einerstellen an und arbeitest dich nach links, wobei du manchmal Zahlen \"übergibst\" oder \"ausleihst\".",
|
||||||
|
"relatedTopics": [
|
||||||
|
"schriftliches-multiplizieren",
|
||||||
|
"schriftliches-dividieren"
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"text": "$$6342 + 9873 = ?$$",
|
||||||
|
"vars": {
|
||||||
|
"?": "16215"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "$$4521 - 1234 = ?$$",
|
||||||
|
"vars": {
|
||||||
|
"?": "3287"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
$$
|
<p><br><p><span>$$
|
||||||
\begin{array}{r@{}r@{}r@{}r}
|
\begin{array}{rrrr}
|
||||||
& 8 & 4 & 0 & : & 4 & = & 2&1&0 \\
|
& 8 & 4 & 0 & : & 4 & = & 2&1&0 \\
|
||||||
\hline
|
\hline
|
||||||
- & 8 & & \\ % Erste Subtraktion
|
- & 8 & & \\ % Erste Subtraktion
|
||||||
@@ -9,16 +9,4 @@ $$
|
|||||||
- & & & 0 & \\ % Letzte Subtraktion
|
- & & & 0 & \\ % Letzte Subtraktion
|
||||||
& & & 0 & % Endergebnis null
|
& & & 0 & % Endergebnis null
|
||||||
\end{array}
|
\end{array}
|
||||||
$$
|
$$</span></p><br><p>1. Die vorderste Stelle des Dividenden wird genommen, das heißt, die 8. Nun wird geprüft, wie oft der Divisor - also die 4 - in die 8 passt. Dies passt 2 Mal. Daher wird die 2 in das Ergebnis (auch Quotient genannt) geschrieben.</p><br><p>2. Im nächsten Schritt wird zurückmultipliziert. Die 2 aus dem Ergebnis wird mit dem Divisor multipliziert: 2 · 4 = 8. Diese 8 wird vorne unter die andere 8 notiert.</p><br><p>3. Im dritten Rechenschritt wird eine Subtraktion durchgeführt. Es wird 8 - 8 = 0 gerechnet, und diese 0 wird unter dem Strich notiert.</p><br><p>4. Als nächstes wird die nächste Stelle der Zahl heruntergezogen. In diesem Beispiel ist dies die 4.</p><br><p>5. Die zuvor durchgeführten Rechenschritte beginnen nun von vorne. Wie oft passt der Divisor (4) in die 04? Dies passt genau 1 Mal, weshalb eine 1 in das Ergebnis geschrieben wird.</p><br><p>6. Erneut wird multipliziert. Die neue 1 aus dem Ergebnis wird mit dem Divisor (4) multipliziert, und man erhält 1 · 4 = 4. Diese 4 wird unter die 04 notiert. Es ist darauf zu achten, dass die letzte Stelle jeweils untereinander steht.</p><br><p>7. Als nächstes wird subtrahiert: 04 - 4 = 0. Anschließend wird die letzte Stelle der Zahl 840 nach unten gezogen, das heißt, die 0.</p><br><p>8. Wie oft passt die 0 in die 0? Dies passt 0 Mal. Alternativ lässt sich sagen: 0 : 4 = 0. Diese 0 wird ebenfalls in das Ergebnis geschrieben.</p><br><p>9. Nun wird wieder zurückmultipliziert: 0 · 4 = 0. Bei der Subtraktion bleibt nichts übrig, und es gibt keine weiteren Stellen mehr.</p><br><p>10. Das Endergebnis lautet somit: 840 : 4 = 210.</p></p>
|
||||||
<br><br>
|
|
||||||
|
|
||||||
1. Die vorderste Stelle des Dividenden wird genommen, das heißt, die 8. Nun wird geprüft, wie oft der Divisor - also die 4 - in die 8 passt. Dies passt 2 Mal. Daher wird die 2 in das Ergebnis (auch Quotient genannt) geschrieben. <br><br>
|
|
||||||
2. Im nächsten Schritt wird zurückmultipliziert. Die 2 aus dem Ergebnis wird mit dem Divisor multipliziert: 2 · 4 = 8. Diese 8 wird vorne unter die andere 8 notiert. <br><br>
|
|
||||||
3. Im dritten Rechenschritt wird eine Subtraktion durchgeführt. Es wird 8 - 8 = 0 gerechnet, und diese 0 wird unter dem Strich notiert. <br><br>
|
|
||||||
4. Als nächstes wird die nächste Stelle der Zahl heruntergezogen. In diesem Beispiel ist dies die 4. <br><br>
|
|
||||||
5. Die zuvor durchgeführten Rechenschritte beginnen nun von vorne. Wie oft passt der Divisor (4) in die 04? Dies passt genau 1 Mal, weshalb eine 1 in das Ergebnis geschrieben wird. <br><br>
|
|
||||||
6. Erneut wird multipliziert. Die neue 1 aus dem Ergebnis wird mit dem Divisor (4) multipliziert, und man erhält 1 · 4 = 4. Diese 4 wird unter die 04 notiert. Es ist darauf zu achten, dass die letzte Stelle jeweils untereinander steht. <br><br>
|
|
||||||
7. Als nächstes wird subtrahiert: 04 - 4 = 0. Anschließend wird die letzte Stelle der Zahl 840 nach unten gezogen, das heißt, die 0. <br><br>
|
|
||||||
8. Wie oft passt die 0 in die 0? Dies passt 0 Mal. Alternativ lässt sich sagen: 0 : 4 = 0. Diese 0 wird ebenfalls in das Ergebnis geschrieben. <br><br>
|
|
||||||
9. Nun wird wieder zurückmultipliziert: 0 · 4 = 0. Bei der Subtraktion bleibt nichts übrig, und es gibt keine weiteren Stellen mehr. <br><br>
|
|
||||||
10. Das Endergebnis lautet somit: 840 : 4 = 210. <br><br>
|
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
{
|
{
|
||||||
"displayName": "Schriftliches Dividieren",
|
"displayName": "Schriftliches Dividieren",
|
||||||
"icon": "fa-divide",
|
"icon": "fa-divide",
|
||||||
"description": "Schriftliches Dividieren ist eine Methode zur schrittweisen Aufteilung einer Zahl durch eine andere, wobei man die Teilschritte nacheinander schriftlich notiert, um das Ergebnis systematisch zu berechnen.",
|
"description": "Schriftliches Dividieren ist eine Methode zur schrittweisen Aufteilung einer Zahl durch eine andere, wobei man die Teilschritte nacheinander schriftlich notiert, um das Ergebnis systematisch zu berechnen.",
|
||||||
"relatedTopics": [
|
"relatedTopics": [
|
||||||
"schriftliches-multiplizieren"
|
"schriftliches-multiplizieren",
|
||||||
]
|
"schriftliches-addieren-subtrahieren"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"text": "$$560 : 7 = ?$$",
|
||||||
|
"vars": {
|
||||||
|
"?": "80"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
@@ -1,36 +1,15 @@
|
|||||||
Kommen wir nun zur schriftlichen Multiplikation: Das Ziel dieses Artikels ist es, Multiplikationsaufgaben wie zum Beispiel 12 · 30 zu lösen. Die Aufgabe wird hier zunächst vorgerechnet – gefolgt von einem zweiten Beispiel – und die Vorgehensweise wird anschließend unterhalb der Rechnung erläutert.
|
<p><p>Kommen wir nun zur schriftlichen Multiplikation: Das Ziel dieses Artikels ist es, Multiplikationsaufgaben wie zum Beispiel 12 · 30 zu lösen. Die Aufgabe wird hier zunächst vorgerechnet – gefolgt von einem zweiten Beispiel – und die Vorgehensweise wird anschließend unterhalb der Rechnung erläutert.</p><br><p><span>$$
|
||||||
|
\begin{array}{rrrr}
|
||||||
<br><br>
|
|
||||||
$$
|
|
||||||
\begin{array}{r@{}r@{}r@{}r}
|
|
||||||
& 1 & 2 & \times & 3 & 2 & \\ \hline % mal 32
|
& 1 & 2 & \times & 3 & 2 & \\ \hline % mal 32
|
||||||
& & & 3 & 6 \\ % 12 * 2 = 36
|
& & & 3 & 6 \\ % 12 * 2 = 36
|
||||||
+ &&&& 2 & 4 \\ \hline % 12 * 3 mit Zehnerstelle = 240
|
+ &&&& 2 & 4 \\ \hline % 12 * 3 mit Zehnerstelle = 240
|
||||||
&&& 3 & 8 & 4 % Ergebnis
|
&&& 3 & 8 & 4 % Ergebnis
|
||||||
\end{array}
|
\end{array}
|
||||||
$$
|
$$</span></p><br><p>So wird es gemacht.</p><br><p>1. Die beiden Zahlen werden nebeneinander geschrieben und das Multiplikationszeichen dazwischen gesetzt. Darunter wird ein Strich gezogen.</p><p>2. Danach wird die erste Zahl mit der ersten Stelle des zweiten Faktors multipliziert. Auf gut Deutsch: 12 · 3 = 36. Die 36 wird unter der 3 notiert.</p><p>3. Dasselbe wird für die zweite Stelle durchgeführt: 12 · 2 = 24. Diese Zahl wird unter der 2 geschrieben.</p><p>4. Anschließend wird schriftlich addiert. Stelle für Stelle wird von rechts nach links addiert: 4 + 0 = 4; 6 + 2 = 8; 3 + 0 = 3.</p><p>Das Ergebnis ist somit 12 · 32 = 384.</p><br><br><p>Ein weiteres Beispiel</p><p><span>$$
|
||||||
<br><br>
|
\begin{array}{rrrrr}
|
||||||
|
|
||||||
So wird es gemacht.
|
|
||||||
|
|
||||||
<br><br>
|
|
||||||
|
|
||||||
1. Die beiden Zahlen werden nebeneinander geschrieben und das Multiplikationszeichen dazwischen gesetzt. Darunter wird ein Strich gezogen. <br>
|
|
||||||
2. Danach wird die erste Zahl mit der ersten Stelle des zweiten Faktors multipliziert. Auf gut Deutsch: 12 · 3 = 36. Die 36 wird unter der 3 notiert. <br>
|
|
||||||
3. Dasselbe wird für die zweite Stelle durchgeführt: 12 · 2 = 24. Diese Zahl wird unter der 2 geschrieben.<br>
|
|
||||||
4. Anschließend wird schriftlich addiert. Stelle für Stelle wird von rechts nach links addiert: 4 + 0 = 4; 6 + 2 = 8; 3 + 0 = 3.<br>
|
|
||||||
Das Ergebnis ist somit 12 · 32 = 384.<br>
|
|
||||||
<br> <br> Ein weiteres Beispiel <br>
|
|
||||||
|
|
||||||
$$
|
|
||||||
\begin{array}{r@{}r@{}r@{}r@{}r@{}r}
|
|
||||||
2 & 8 & 4 & 6 & 8 & \times & 1 & 6 \\ \hline % mal 16
|
2 & 8 & 4 & 6 & 8 & \times & 1 & 6 \\ \hline % mal 16
|
||||||
&& \textcolor{red}{2} & \textcolor{red}{8} & \textcolor{red}{4} & \textcolor{red}{6} & \textcolor{red}{8} \\ % 28468 * 6 (Einerstelle)
|
&& \textcolor{red}{2} & \textcolor{red}{8} & \textcolor{red}{4} & \textcolor{red}{6} & \textcolor{red}{8} \\ % 28468 * 6 (Einerstelle)
|
||||||
+ && \textcolor{green}{1} & \textcolor{green}{7} & \textcolor{green}{0} & \textcolor{green}{8} & \textcolor{green}{0} & \textcolor{green}{8} \\ \hline % 28468 * 10 (Zehnerstelle)
|
+ && \textcolor{green}{1} & \textcolor{green}{7} & \textcolor{green}{0} & \textcolor{green}{8} & \textcolor{green}{0} & \textcolor{green}{8} \\ \hline % 28468 * 10 (Zehnerstelle)
|
||||||
&& 4 & 5 & 5 & 4 & 8 & 8 % Ergebnis
|
&& 4 & 5 & 5 & 4 & 8 & 8 % Ergebnis
|
||||||
\end{array}
|
\end{array}
|
||||||
$$
|
$$</span></p><p>1. Es wird 28468 · 1 mit der bekannten Rechenweise aus den vorherigen Beispielen berechnet, und das Ergebnis wird so notiert, dass die letzte Stelle unter der 1 steht.</p><p>2. Es wird 28468 · 6 ebenfalls mit der bekannten Rechenweise berechnet, und das Ergebnis wird so eingetragen, dass die letzte Stelle unter der 6 steht.</p><p>3. Es wird eine schriftliche Addition durchgeführt (0 + 8 = 8, 8 + 0 = 8 usw.). Die übereinander stehenden Stellen werden jeweils addiert.</p></p>
|
||||||
<br>
|
|
||||||
1. Es wird 28468 · 1 mit der bekannten Rechenweise aus den vorherigen Beispielen berechnet, und das Ergebnis wird so notiert, dass die letzte Stelle unter der 1 steht. <br>
|
|
||||||
2. Es wird 28468 · 6 ebenfalls mit der bekannten Rechenweise berechnet, und das Ergebnis wird so eingetragen, dass die letzte Stelle unter der 6 steht. <br>
|
|
||||||
3. Es wird eine schriftliche Addition durchgeführt (0 + 8 = 8, 8 + 0 = 8 usw.). Die übereinander stehenden Stellen werden jeweils addiert. <br><br>
|
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
{
|
{
|
||||||
"displayName": "Schriftliches Multiplizieren",
|
"displayName": "Schriftliches Multiplizieren",
|
||||||
"icon": "fa-x",
|
"icon": "fa-x",
|
||||||
"description": "Schriftliches Multiplizieren ist eine Rechenmethode, bei der zwei Zahlen schrittweise multipliziert werden, indem man die einzelnen Stellen der Zahlen nacheinander verrechnet, die Teilergebnisse notiert und am Ende addiert, um das Gesamtergebnis zu erhalten.",
|
"description": "Schriftliches Multiplizieren ist eine Rechenmethode, bei der zwei Zahlen schrittweise multipliziert werden, indem man die einzelnen Stellen der Zahlen nacheinander verrechnet, die Teilergebnisse notiert und am Ende addiert, um das Gesamtergebnis zu erhalten.",
|
||||||
"relatedTopics": [
|
"relatedTopics": [
|
||||||
"schriftliches-dividieren"
|
"schriftliches-dividieren",
|
||||||
]
|
"schriftliches-addieren-subtrahieren"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"text": "$$432 \\times 23 = ?$$",
|
||||||
|
"vars": {
|
||||||
|
"?": "9936"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
<b>Grundbegriffe der Wahrscheinlichkeitsrechnung</b> <br>
|
||||||
|
Formel: $$ Wahrscheinlichkeit = \frac{Gewünschte Ereignisse}{Mögliche Ereignisse}$$
|
||||||
|
Beispiel: <br>
|
||||||
|
Bei einem Würfel ist die Wahrscheinlichkeit für eine 6: $$\frac{1}{6}$$
|
||||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"displayName": "Wahrscheinlichkeitsrechnung",
|
||||||
|
"icon": "fa-percent",
|
||||||
|
"description": "Die Wahrscheinlichkeitsrechnung hilft uns herauszufinden, wie wahrscheinlich ein Ereignis ist, z. B. beim Würfeln eine 6 zu bekommen. Dabei rechnet man, wie viele Möglichkeiten es gibt und wie oft ein bestimmtes Ergebnis vorkommen kann.",
|
||||||
|
"relatedTopics": [
|
||||||
|
"graphen-diagramme"
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"text": "Was ist die Wahrscheinlichkeit \\(W\\), bei einem Würfel eine gerade Zahl zu würfeln?",
|
||||||
|
"vars": {
|
||||||
|
"W": "1\/2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Was ist die Wahrscheinlichkeit \\(W\\) für eine rote Karte aus einem Kartenspiel (52 Karten, 26 rot)",
|
||||||
|
"vars": {
|
||||||
|
"W": "26\/52"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
@@ -24,8 +24,7 @@
|
|||||||
</button>
|
</button>
|
||||||
|
|
||||||
<?php
|
<?php
|
||||||
require_once("classes/User.php");
|
|
||||||
session_start();
|
|
||||||
if (isset($_SESSION['user']) && $_SESSION['user']->isLoggedIn()) {
|
if (isset($_SESSION['user']) && $_SESSION['user']->isLoggedIn()) {
|
||||||
?>
|
?>
|
||||||
<div class="flex items-center space-x-4">
|
<div class="flex items-center space-x-4">
|
||||||
@@ -41,11 +40,6 @@
|
|||||||
<!-- Dropdown Menu -->
|
<!-- Dropdown Menu -->
|
||||||
<div id="userDropdownMenu"
|
<div id="userDropdownMenu"
|
||||||
class="hidden absolute right-0 mt-2 w-48 bg-white rounded-lg shadow-lg border">
|
class="hidden absolute right-0 mt-2 w-48 bg-white rounded-lg shadow-lg border">
|
||||||
<!-- TODO: Accountseite entsprechend verlinken -->
|
|
||||||
<a href="index.php"
|
|
||||||
class="block px-4 py-2 text-gray-700 hover:bg-gray-100 rounded-t-lg flex items-center">
|
|
||||||
<i class="fas fa-user mr-2"></i> Accountseite
|
|
||||||
</a>
|
|
||||||
<button id="dropdownChangePasswordButton"
|
<button id="dropdownChangePasswordButton"
|
||||||
class="block w-full text-left px-4 py-2 text-gray-700 hover:bg-gray-100 flex items-center">
|
class="block w-full text-left px-4 py-2 text-gray-700 hover:bg-gray-100 flex items-center">
|
||||||
<i class="fas fa-key mr-2"></i> Passwort ändern
|
<i class="fas fa-key mr-2"></i> Passwort ändern
|
||||||
@@ -59,10 +53,11 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Bearbeiten Button --> <!-- TODO: Korrekte/dynamische Verlinkung implementieren -->
|
<!--
|
||||||
<a href="index.php" class="bg-white text-[var(--primary-color)] border-2 border-[var(--primary-color)] w-10 h-10 flex items-center justify-center rounded-lg hover:bg-[var(--primary-color)] hover:text-white transition duration-300">
|
<a href="index.php" class="bg-white text-[var(--primary-color)] border-2 border-[var(--primary-color)] w-10 h-10 flex items-center justify-center rounded-lg hover:bg-[var(--primary-color)] hover:text-white transition duration-300">
|
||||||
<i class="fa-solid fa-pen-to-square"></i>
|
<i class="fa-solid fa-pen-to-square"></i>
|
||||||
</a>
|
</a>
|
||||||
|
-->
|
||||||
</div>
|
</div>
|
||||||
<?php
|
<?php
|
||||||
} else {
|
} else {
|
||||||
@@ -172,221 +167,6 @@ if (isset($_SESSION['user']) && $_SESSION['user']->isLoggedIn()) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<!-- JavaScript Login, User-Menu -->
|
||||||
// JavaScript to handle opening and closing of the login popup
|
<script src="assets/js/login.js"></script>
|
||||||
const loginButton = document.getElementById('loginButton');
|
<script src="assets/js/dropdown_menu.js"></script>
|
||||||
const loginPopup = document.getElementById('loginPopup');
|
|
||||||
const closePopupButton = document.getElementById('closePopupButton');
|
|
||||||
const usernameInput = document.getElementById('username');
|
|
||||||
const errorMessage = document.getElementById('errorMessage');
|
|
||||||
|
|
||||||
if (loginButton) { // Überprüfen, ob das Element vorhanden ist
|
|
||||||
loginButton.addEventListener('click', function () {
|
|
||||||
loginPopup.classList.remove('hidden');
|
|
||||||
usernameInput.focus(); // Set focus to username field
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (closePopupButton) { // Überprüfen, ob das Element vorhanden ist
|
|
||||||
closePopupButton.addEventListener('click', function () {
|
|
||||||
loginPopup.classList.add('hidden');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
window.addEventListener('click', function (event) {
|
|
||||||
if (event.target === loginPopup) {
|
|
||||||
loginPopup.classList.add('hidden');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Schließe Popup mit ESC
|
|
||||||
document.addEventListener('keydown', function (event) {
|
|
||||||
if (event.key === "Escape" && !loginPopup.classList.contains('hidden')) {
|
|
||||||
loginPopup.classList.add('hidden');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Zeige Fehlermeldung beim Login an
|
|
||||||
window.addEventListener('DOMContentLoaded', (event) => {
|
|
||||||
const urlParams = new URLSearchParams(window.location.search);
|
|
||||||
if (urlParams.has('error') && urlParams.get('error') === '1') {
|
|
||||||
loginPopup.classList.remove('hidden');
|
|
||||||
errorMessage.classList.remove('hidden');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// JavaScript to handle opening and closing of the change password popup
|
|
||||||
const changePasswordButton = document.getElementById('changePasswordButton');
|
|
||||||
const changePasswordPopup = document.getElementById('changePasswordPopup');
|
|
||||||
const closeChangePasswordPopupButton = document.getElementById('closeChangePasswordPopupButton');
|
|
||||||
|
|
||||||
if (changePasswordButton) { // Überprüfen, ob das Element vorhanden ist
|
|
||||||
changePasswordButton.addEventListener('click', function () {
|
|
||||||
if (changePasswordPopup) {
|
|
||||||
changePasswordPopup.classList.remove('hidden');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (closeChangePasswordPopupButton) {
|
|
||||||
closeChangePasswordPopupButton.addEventListener('click', function () {
|
|
||||||
if (changePasswordPopup) {
|
|
||||||
changePasswordPopup.classList.add('hidden');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
window.addEventListener('click', function (event) {
|
|
||||||
if (event.target === changePasswordPopup) {
|
|
||||||
changePasswordPopup.classList.add('hidden');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Close popup with ESC key
|
|
||||||
document.addEventListener('keydown', function (event) {
|
|
||||||
if (event.key === "Escape" && !changePasswordPopup.classList.contains('hidden')) {
|
|
||||||
changePasswordPopup.classList.add('hidden');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Zeige Fehlermeldung beim Passwort ändern an
|
|
||||||
window.addEventListener('DOMContentLoaded', () => {
|
|
||||||
const urlParams = new URLSearchParams(window.location.search);
|
|
||||||
|
|
||||||
if (urlParams.has('password_error')) {
|
|
||||||
const changePasswordPopup = document.getElementById('changePasswordPopup');
|
|
||||||
const changePasswordErrorMessage = document.getElementById('changePasswordErrorMessage');
|
|
||||||
const errorType = urlParams.get('password_error');
|
|
||||||
|
|
||||||
changePasswordPopup.classList.remove('hidden');
|
|
||||||
changePasswordErrorMessage.classList.remove('hidden');
|
|
||||||
|
|
||||||
switch (errorType) {
|
|
||||||
case 'wrong_current_password':
|
|
||||||
changePasswordErrorMessage.textContent = 'Das aktuelle Passwort ist falsch.';
|
|
||||||
break;
|
|
||||||
case 'password_mismatch':
|
|
||||||
changePasswordErrorMessage.textContent = 'Die neuen Passwörter stimmen nicht überein.';
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
changePasswordErrorMessage.textContent = 'Fehler beim Ändern des Passworts.';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Zeige Erfolgspopup beim Passwortwechsel an
|
|
||||||
window.addEventListener('DOMContentLoaded', (event) => {
|
|
||||||
const urlParams = new URLSearchParams(window.location.search);
|
|
||||||
|
|
||||||
if (urlParams.has('password_success')) {
|
|
||||||
const passwordSuccessPopup = document.getElementById('passwordSuccessPopup');
|
|
||||||
if (passwordSuccessPopup) {
|
|
||||||
passwordSuccessPopup.classList.remove('hidden');
|
|
||||||
}
|
|
||||||
const closeSuccessPopup = document.getElementById('closeSuccessPopup');
|
|
||||||
if (closeSuccessPopup) {
|
|
||||||
closeSuccessPopup.addEventListener('click', () => {
|
|
||||||
passwordSuccessPopup.classList.add('hidden');
|
|
||||||
// Optional: Entferne den URL-Parameter ohne Neuladen
|
|
||||||
const newUrl = window.location.href.split('?')[0];
|
|
||||||
window.history.replaceState({}, document.title, newUrl);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Dropdown öffnen/schließen
|
|
||||||
const userDropdownToggle = document.getElementById('userDropdownToggle');
|
|
||||||
const userDropdownMenu = document.getElementById('userDropdownMenu');
|
|
||||||
|
|
||||||
if (userDropdownToggle && userDropdownMenu) {
|
|
||||||
userDropdownToggle.addEventListener('click', (event) => {
|
|
||||||
event.stopPropagation(); // Verhindert das Schließen des Menüs bei Klick auf den Button
|
|
||||||
userDropdownMenu.classList.toggle('hidden');
|
|
||||||
});
|
|
||||||
|
|
||||||
// Schließe Dropdown, wenn außerhalb geklickt wird
|
|
||||||
window.addEventListener('click', () => {
|
|
||||||
if (!userDropdownMenu.classList.contains('hidden')) {
|
|
||||||
userDropdownMenu.classList.add('hidden');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Schließe Dropdown mit ESC
|
|
||||||
document.addEventListener('keydown', (event) => {
|
|
||||||
if (event.key === "Escape" && !userDropdownMenu.classList.contains('hidden')) {
|
|
||||||
userDropdownMenu.classList.add('hidden');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Passwort ändern über Dropdown öffnen
|
|
||||||
const dropdownChangePasswordButton = document.getElementById('dropdownChangePasswordButton');
|
|
||||||
if (dropdownChangePasswordButton) {
|
|
||||||
dropdownChangePasswordButton.addEventListener('click', () => {
|
|
||||||
const changePasswordPopup = document.getElementById('changePasswordPopup');
|
|
||||||
if (changePasswordPopup) {
|
|
||||||
changePasswordPopup.classList.remove('hidden');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
document.getElementById('openSearchDialog').addEventListener('click', function () {
|
|
||||||
document.getElementById('searchDialog').classList.remove('hidden');
|
|
||||||
});
|
|
||||||
|
|
||||||
document.getElementById('closeSearchDialog').addEventListener('click', function () {
|
|
||||||
document.getElementById('searchDialog').classList.add('hidden');
|
|
||||||
});
|
|
||||||
|
|
||||||
function debounce(func, delay) {
|
|
||||||
let debounceTimer;
|
|
||||||
return function () {
|
|
||||||
const context = this;
|
|
||||||
const args = arguments;
|
|
||||||
clearTimeout(debounceTimer);
|
|
||||||
debounceTimer = setTimeout(() => func.apply(context, args), delay);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const searchInput = document.getElementById('searchInput');
|
|
||||||
const resultsContainer = document.getElementById('searchResults');
|
|
||||||
|
|
||||||
searchInput.addEventListener('input', debounce(function () {
|
|
||||||
const query = this.value.toLowerCase();
|
|
||||||
resultsContainer.innerHTML = '';
|
|
||||||
|
|
||||||
if (query.length > 0) {
|
|
||||||
fetch('search.php?query=' + query)
|
|
||||||
.then(response => response.json())
|
|
||||||
.then(data => {
|
|
||||||
data.forEach(item => {
|
|
||||||
const resultItem = document.createElement('div');
|
|
||||||
resultItem.classList.add('p-4', 'mb-2', 'rounded-lg', 'bg-white', 'hover:bg-gray-100', 'transition', 'duration-100', 'flex', 'items-center', 'space-x-2', 'cursor-pointer');
|
|
||||||
|
|
||||||
const subjectSpan = document.createElement('span');
|
|
||||||
subjectSpan.classList.add('font-bold');
|
|
||||||
subjectSpan.textContent = item.displayName.split(' - ')[0];
|
|
||||||
|
|
||||||
const breadcrumbSpan = document.createElement('span');
|
|
||||||
breadcrumbSpan.classList.add('text-gray-500');
|
|
||||||
breadcrumbSpan.textContent = item.displayName.split(' - ').slice(1).join(' > ');
|
|
||||||
|
|
||||||
resultItem.appendChild(subjectSpan);
|
|
||||||
resultItem.appendChild(breadcrumbSpan);
|
|
||||||
|
|
||||||
resultItem.addEventListener('click', function () {
|
|
||||||
if (item.type === 'subject') {
|
|
||||||
window.location.href = 'subject.php?subject=' + item.id;
|
|
||||||
} else {
|
|
||||||
window.location.href = 'topic.php?subject=' + item.subjectId + '&topic=' + item.id;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
resultsContainer.appendChild(resultItem);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}, 300));
|
|
||||||
|
|
||||||
</script>
|
|
||||||
@@ -1,3 +1,8 @@
|
|||||||
|
<?php
|
||||||
|
require_once("classes/User.php");
|
||||||
|
session_start();
|
||||||
|
?>
|
||||||
|
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="de">
|
<html lang="de">
|
||||||
<head>
|
<head>
|
||||||
|
|||||||
@@ -1,3 +1,8 @@
|
|||||||
|
<?php
|
||||||
|
require_once("classes/User.php");
|
||||||
|
session_start();
|
||||||
|
?>
|
||||||
|
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<!--Homepage-->
|
<!--Homepage-->
|
||||||
<html lang="de">
|
<html lang="de">
|
||||||
@@ -10,7 +15,14 @@
|
|||||||
<link href="assets/css/styles.css" rel="stylesheet">
|
<link href="assets/css/styles.css" rel="stylesheet">
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/gsap.min.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/gsap.min.js"></script>
|
||||||
<script src="https://cdn.tailwindcss.com"></script>
|
<script src="https://cdn.tailwindcss.com"></script>
|
||||||
<script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.18/dist/katex.min.css"
|
||||||
|
integrity="sha384-veTAhWILPOotXm+kbR5uY7dRamYLJf58I7P+hJhjeuc7hsMAkJHTsPahAl0hBST0" crossorigin="anonymous">
|
||||||
|
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.18/dist/katex.min.js"
|
||||||
|
integrity="sha384-v6mkHYHfY/4BWq54f7lQAdtIsoZZIByznQ3ZqN38OL4KCsrxo31SLlPiak7cj/Mg"
|
||||||
|
crossorigin="anonymous"></script>
|
||||||
|
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.18/dist/contrib/auto-render.min.js"
|
||||||
|
integrity="sha384-hCXGrW6PitJEwbkoStFjeJxv+fSOOQKOPbJxSfM6G5sWZjAyWhXiTIIAmQqnlLlh" crossorigin="anonymous"
|
||||||
|
onload="renderMathInElement(document.body);"></script>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
|
|
||||||
@@ -43,10 +55,11 @@
|
|||||||
$subjects = SubjectData::getAll();
|
$subjects = SubjectData::getAll();
|
||||||
|
|
||||||
foreach ($subjects as $subject) {
|
foreach ($subjects as $subject) {
|
||||||
// receive number of exercises for all topics of a subject
|
$numOfFiles = 0;
|
||||||
$numOfExcercises = 0;
|
$numOfTasks = 0;
|
||||||
foreach ($subject->topics as $topic) {
|
foreach ($subject->topics as $topic) {
|
||||||
$numOfExcercises += count($topic->files);
|
$numOfFiles += count($topic->getFiles());
|
||||||
|
$numOfTasks += count($topic->getTasks());
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
?>
|
||||||
@@ -56,17 +69,21 @@
|
|||||||
<div class="w-12 h-12 rounded-lg bg-gray-100 flex items-center justify-center">
|
<div class="w-12 h-12 rounded-lg bg-gray-100 flex items-center justify-center">
|
||||||
<i class="fas <?php echo($subject->icon); ?> text-2xl text-[<?php echo($subject->color); ?>]"></i>
|
<i class="fas <?php echo($subject->icon); ?> text-2xl text-[<?php echo($subject->color); ?>]"></i>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex-1">
|
<div class="flex-1 overflow-hidden">
|
||||||
<h3 class="text-xl font-bold text-gray-900 mb-2"><?php echo($subject->displayName); ?></h3>
|
<h3 class="text-xl font-bold text-gray-900 mb-2"><?php echo($subject->displayName); ?></h3>
|
||||||
<p class="text-gray-600 mb-4"><?php echo($subject->description); ?></p>
|
<p class="text-gray-600 mb-4"><?php echo($subject->description); ?></p>
|
||||||
<div class="grid grid-cols-2 gap-4 mb-4">
|
<div class="grid grid-cols-3 gap-4 mb-4">
|
||||||
<div class="text-center p-2 rounded-lg bg-gray-100">
|
<div class="text-center p-2 rounded-lg bg-gray-100">
|
||||||
<div class="font-bold text-[<?php echo($subject->color); ?>]"><?php echo(count($subject->topics)); ?></div>
|
<div class="font-bold text-[<?php echo($subject->color); ?>]"><?php echo(count($subject->topics)); ?></div>
|
||||||
<div class="text-sm text-gray-600">Themen</div>
|
<div class="text-sm text-gray-600">Themen</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="text-center p-2 rounded-lg bg-gray-100">
|
<div class="text-center p-2 rounded-lg bg-gray-100">
|
||||||
<div class="font-bold text-[<?php echo($subject->color); ?>]"><?php echo($numOfExcercises); ?></div>
|
<div class="font-bold text-[<?php echo($subject->color); ?>]"><?php echo($numOfFiles); ?></div>
|
||||||
<div class="text-sm text-gray-600">Übungen</div>
|
<div class="text-sm text-gray-600">Dateien</div>
|
||||||
|
</div>
|
||||||
|
<div class="text-center p-2 rounded-lg bg-gray-100">
|
||||||
|
<div class="font-bold text-[<?php echo($subject->color); ?>]"><?php echo($numOfTasks); ?></div>
|
||||||
|
<div class="text-sm text-gray-600">Aufgaben</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -77,9 +94,19 @@
|
|||||||
<?php
|
<?php
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
if (isset($_SESSION['user']) && $_SESSION['user']->isLoggedIn()) {
|
||||||
|
?>
|
||||||
|
<a href="subjectEditor.php"
|
||||||
|
class="fixed z-90 w-14 h-14 bottom-20 right-5 flex items-center justify-center text-4xl text-white rounded-lg bg-[var(--primary-color)] hover:bg-[var(--accent-color)] transition duration-300">
|
||||||
|
<span class="pb-1.5">+</span>
|
||||||
|
</a>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
||||||
<footer class="sticky top-[100vh] w-full bg-white/80 backdrop-blur-lg shadow-sm p-5">
|
<footer class="sticky top-[100vh] w-full bg-white/80 backdrop-blur-lg shadow-sm p-5">
|
||||||
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
|
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
|
||||||
<div class="flex justify-between">
|
<div class="flex justify-between">
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ foreach ($subjects as $subject) {
|
|||||||
strpos(strtolower($subject->displayName), $query) !== false ||
|
strpos(strtolower($subject->displayName), $query) !== false ||
|
||||||
strpos(strtolower($topic->displayName), $query) !== false ||
|
strpos(strtolower($topic->displayName), $query) !== false ||
|
||||||
strpos(strtolower($topic->description), $query) !== false ||
|
strpos(strtolower($topic->description), $query) !== false ||
|
||||||
strpos(strtolower($topic->article), $query) !== false
|
strpos(strtolower($topic->getFinishedArticle()), $query) !== false
|
||||||
) {
|
) {
|
||||||
$results[] = [
|
$results[] = [
|
||||||
'type' => 'topic',
|
'type' => 'topic',
|
||||||
|
|||||||
@@ -3,6 +3,9 @@
|
|||||||
<?php
|
<?php
|
||||||
require_once("classes/SubjectData.php");
|
require_once("classes/SubjectData.php");
|
||||||
require_once("classes/TopicData.php");
|
require_once("classes/TopicData.php");
|
||||||
|
require_once("classes/User.php");
|
||||||
|
|
||||||
|
session_start();
|
||||||
|
|
||||||
if (!isset($_GET["subject"])) {
|
if (!isset($_GET["subject"])) {
|
||||||
die("Ungültige Seite");
|
die("Ungültige Seite");
|
||||||
@@ -24,7 +27,14 @@ $topics = $subjectData->topics;
|
|||||||
<link href="assets/css/subject.css" rel="stylesheet">
|
<link href="assets/css/subject.css" rel="stylesheet">
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/gsap.min.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/gsap.min.js"></script>
|
||||||
<script src="https://cdn.tailwindcss.com"></script>
|
<script src="https://cdn.tailwindcss.com"></script>
|
||||||
<script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.18/dist/katex.min.css"
|
||||||
|
integrity="sha384-veTAhWILPOotXm+kbR5uY7dRamYLJf58I7P+hJhjeuc7hsMAkJHTsPahAl0hBST0" crossorigin="anonymous">
|
||||||
|
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.18/dist/katex.min.js"
|
||||||
|
integrity="sha384-v6mkHYHfY/4BWq54f7lQAdtIsoZZIByznQ3ZqN38OL4KCsrxo31SLlPiak7cj/Mg"
|
||||||
|
crossorigin="anonymous"></script>
|
||||||
|
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.18/dist/contrib/auto-render.min.js"
|
||||||
|
integrity="sha384-hCXGrW6PitJEwbkoStFjeJxv+fSOOQKOPbJxSfM6G5sWZjAyWhXiTIIAmQqnlLlh" crossorigin="anonymous"
|
||||||
|
onload="renderMathInElement(document.body);"></script>
|
||||||
<script src="assets/js/sidebar.js"></script>
|
<script src="assets/js/sidebar.js"></script>
|
||||||
<script src="assets/js/search.js"></script>
|
<script src="assets/js/search.js"></script>
|
||||||
</head>
|
</head>
|
||||||
@@ -35,15 +45,15 @@ $topics = $subjectData->topics;
|
|||||||
|
|
||||||
<nav class="sidebar bg-[<?php echo($subjectData->color); ?>] pt-24">
|
<nav class="sidebar bg-[<?php echo($subjectData->color); ?>] pt-24">
|
||||||
<div class="sidebar-header">
|
<div class="sidebar-header">
|
||||||
<i class="fas fa-graduation-cap"></i>
|
<i class="fas <?php echo($subjectData->icon); ?>"></i>
|
||||||
|
|
||||||
<h2><?php echo($subjectData->displayName); ?></h2>
|
<h2 class="overflow-hidden"><?php echo($subjectData->displayName); ?></h2>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<a href="index.php" class="nav-link">
|
<a href="index.php" class="nav-link">
|
||||||
<i class="fas fa-home"></i> Startseite
|
<i class="fas fa-home"></i> Startseite
|
||||||
</a>
|
</a>
|
||||||
<a href="#" class="nav-link active">
|
<a href="#" class="nav-link active overflow-hidden">
|
||||||
<i class="fas fa-book"></i> <?php echo($subjectData->displayName); ?> Übersicht
|
<i class="fas fa-book"></i> <?php echo($subjectData->displayName); ?> Übersicht
|
||||||
</a>
|
</a>
|
||||||
</nav>
|
</nav>
|
||||||
@@ -59,7 +69,7 @@ $topics = $subjectData->topics;
|
|||||||
<div class="topic-card"
|
<div class="topic-card"
|
||||||
onclick="window.location.href='topic.php?subject=<?php echo($topicData->subjectId); ?>&topic=<?php echo($topicData->id); ?>'"
|
onclick="window.location.href='topic.php?subject=<?php echo($topicData->subjectId); ?>&topic=<?php echo($topicData->id); ?>'"
|
||||||
style="cursor: pointer;">
|
style="cursor: pointer;">
|
||||||
<div class="topic-header">
|
<div class="topic-header overflow-hidden">
|
||||||
<i class="fas <?php echo($topicData->icon); ?> topic-icon text-[<?php echo($subjectData->color); ?>]"></i>
|
<i class="fas <?php echo($topicData->icon); ?> topic-icon text-[<?php echo($subjectData->color); ?>]"></i>
|
||||||
<h3 class="topic-title"><?php echo($topicData->displayName); ?></h3>
|
<h3 class="topic-title"><?php echo($topicData->displayName); ?></h3>
|
||||||
</div>
|
</div>
|
||||||
@@ -92,6 +102,10 @@ $topics = $subjectData->topics;
|
|||||||
</ul>
|
</ul>
|
||||||
</div>-->
|
</div>-->
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
if(count($topicData->files) > 0) {
|
||||||
|
?>
|
||||||
<div class="download-section bg-gray-100 p-[20px] rounded-[20px]">
|
<div class="download-section bg-gray-100 p-[20px] rounded-[20px]">
|
||||||
<h4>Übungen herunterladen:</h4>
|
<h4>Übungen herunterladen:</h4>
|
||||||
<div class="download-links">
|
<div class="download-links">
|
||||||
@@ -112,6 +126,10 @@ $topics = $subjectData->topics;
|
|||||||
?>
|
?>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<?php
|
<?php
|
||||||
@@ -121,6 +139,21 @@ $topics = $subjectData->topics;
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
if (isset($_SESSION['user']) && $_SESSION['user']->isLoggedIn()) {
|
||||||
|
?>
|
||||||
|
<a href="subjectEditor.php?subject=<?php echo $subjectData->id ?>"
|
||||||
|
class="fixed z-90 w-14 h-14 bottom-40 right-5 flex items-center justify-center text-4xl text-white rounded-lg bg-[var(--primary-color)] hover:bg-[var(--accent-color)] transition duration-300">
|
||||||
|
<span class="pb-1.5">✎</span>
|
||||||
|
</a>
|
||||||
|
<a href="topicEditor.php?subject=<?php echo $subjectData->id ?>"
|
||||||
|
class="fixed z-90 w-14 h-14 bottom-20 right-5 flex items-center justify-center text-4xl text-white rounded-lg bg-[var(--primary-color)] hover:bg-[var(--accent-color)] transition duration-300">
|
||||||
|
<span class="pb-1.5">+</span>
|
||||||
|
</a>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
||||||
<footer class="sticky top-[100vh] lg:ms-[280px] w-full lg:w-auto bg-white/80 backdrop-blur-lg shadow-sm p-5">
|
<footer class="sticky top-[100vh] lg:ms-[280px] w-full lg:w-auto bg-white/80 backdrop-blur-lg shadow-sm p-5">
|
||||||
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
|
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
|
||||||
<div class="flex justify-between">
|
<div class="flex justify-between">
|
||||||
|
|||||||
228
webseite/subjectEditor.php
Normal file
228
webseite/subjectEditor.php
Normal file
@@ -0,0 +1,228 @@
|
|||||||
|
<?php
|
||||||
|
require_once("classes/User.php");
|
||||||
|
require_once("classes/SubjectData.php");
|
||||||
|
require_once("classes/TopicData.php");
|
||||||
|
|
||||||
|
session_start();
|
||||||
|
|
||||||
|
if (!isset($_SESSION['user']) || !$_SESSION['user']->isLoggedIn()) {
|
||||||
|
header("Location: index.php");
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
|
||||||
|
$allSubjects = SubjectData::getAll();
|
||||||
|
$editingSubject = null;
|
||||||
|
|
||||||
|
$defaultValues = array();
|
||||||
|
$defaultValues['displayName'] = "";
|
||||||
|
$defaultValues['id'] = "";
|
||||||
|
$defaultValues['description'] = "";
|
||||||
|
$defaultValues['color'] = "#3b82f6";
|
||||||
|
$defaultValues['icon'] = "fa-book";
|
||||||
|
|
||||||
|
$errors = array();
|
||||||
|
|
||||||
|
if (isset($_GET['subject'])) {
|
||||||
|
$editingSubject = $allSubjects[$_GET['subject']];
|
||||||
|
|
||||||
|
$defaultValues['displayName'] = $editingSubject->getDisplayName();
|
||||||
|
$defaultValues['id'] = $editingSubject->getId();
|
||||||
|
$defaultValues['description'] = $editingSubject->getDescription();
|
||||||
|
$defaultValues['color'] = $editingSubject->getColor();
|
||||||
|
$defaultValues['icon'] = $editingSubject->getIcon();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||||
|
foreach ($defaultValues as $key => $value) {
|
||||||
|
$defaultValues[$key] = $_POST[$key];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($_POST['displayName']) || trim($_POST['displayName']) == "") {
|
||||||
|
$errors["displayName"] = "Bitte geben Sie einen Namen an.";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($_POST['id']) || trim($_POST['id']) == "") {
|
||||||
|
$errors["id"] = "Bitte geben Sie eine ID an.";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($_POST['description']) || trim($_POST['description']) == "") {
|
||||||
|
$errors["description"] = "Bitte geben Sie eine Beschreibung an.";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($_POST['color']) || trim($_POST['color']) == "") {
|
||||||
|
$errors["color"] = "Bitte geben Sie eine Farbe an.";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($_POST['icon']) || trim($_POST['icon']) == "") {
|
||||||
|
$errors["icon"] = "Bitte geben Sie ein Icon an.";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($_POST['submit']) || !($_POST['submit'] == "Speichern" || $_POST['submit'] == "Fach löschen")) {
|
||||||
|
$errors["submit"] = "Ungültig abgeschickt!";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($errors)) {
|
||||||
|
$newSubject = false;
|
||||||
|
if (isset($allSubjects[$_POST['oldSubjectId']])) {
|
||||||
|
$newSubject = $allSubjects[$_POST['oldSubjectId']];
|
||||||
|
|
||||||
|
$newSubject->setId($_POST['id']);
|
||||||
|
$newSubject->setDisplayName($_POST['displayName']);
|
||||||
|
$newSubject->setDescription($_POST['description']);
|
||||||
|
$newSubject->setColor($_POST['color']);
|
||||||
|
$newSubject->setIcon($_POST['icon']);
|
||||||
|
} else {
|
||||||
|
$newSubject = SubjectData::createNew($_POST['id'], $_POST['displayName'], $_POST['description'], $_POST['color'], $_POST['icon'], array());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$newSubject) {
|
||||||
|
$errors["error"] = "Fehler beim Speichern des Faches.";
|
||||||
|
} else {
|
||||||
|
if ($_POST['submit'] == "Fach löschen") {
|
||||||
|
$newSubject->delete();
|
||||||
|
header("Location: " . "index.php");
|
||||||
|
} else {
|
||||||
|
$newSubject->save();
|
||||||
|
header("Location: " . "subject.php?subject=" . $newSubject->getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
|
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="de">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
|
||||||
|
<title>Lehrer Dashboard</title>
|
||||||
|
|
||||||
|
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
|
||||||
|
<link href="assets/css/styles.css" rel="stylesheet">
|
||||||
|
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/gsap.min.js"></script>
|
||||||
|
<script src="https://cdn.tailwindcss.com"></script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body class="min-h-screen bg-gray-50">
|
||||||
|
|
||||||
|
<?php include 'header.php'; ?>
|
||||||
|
|
||||||
|
<div class="content mt-24 max-w-7xl mx-[16px] xl:mx-auto">
|
||||||
|
<form id="subjectForm" method="post" onsubmit="handleSubjectSubmit(event)">
|
||||||
|
<div class="space-y-6">
|
||||||
|
<div>
|
||||||
|
<label class="block text-sm font-medium text-gray-700 mb-2">Name des Fachs</label>
|
||||||
|
<input type="text"
|
||||||
|
name="displayName"
|
||||||
|
required
|
||||||
|
class="w-full px-4 py-3 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 text-lg enabled:hover:border-gray-400"
|
||||||
|
placeholder="z.B. Mathematik"
|
||||||
|
value="<?php echo $defaultValues['displayName'] ?>">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label class="block text-sm font-medium text-gray-700 mb-2">ID des Fachs</label>
|
||||||
|
<input type="text"
|
||||||
|
name="id"
|
||||||
|
required
|
||||||
|
class="w-full px-4 py-3 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 text-lg enabled:hover:border-gray-400"
|
||||||
|
placeholder="z.B. mathe"
|
||||||
|
value="<?php echo $defaultValues['id'] ?>">
|
||||||
|
|
||||||
|
<input type="hidden" name="oldSubjectId" value="<?php echo $defaultValues['id']; ?>">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label class="block text-sm font-medium text-gray-700 mb-2">Beschreibung</label>
|
||||||
|
<textarea name="description"
|
||||||
|
required
|
||||||
|
class="w-full px-4 py-3 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 text-lg enabled:hover:border-gray-400"
|
||||||
|
rows="4"
|
||||||
|
placeholder="Kurze Beschreibung des Fachs"><?php echo $defaultValues['description'] ?></textarea>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||||
|
<div>
|
||||||
|
<label class="block text-sm font-medium text-gray-700 mb-2">Farbe</label>
|
||||||
|
<div class="flex items-center space-x-2 mb-2">
|
||||||
|
<input type="color" name="color" required
|
||||||
|
class="w-12 h-12 px-1 py-1 rounded-lg border-2 border-gray-300 focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||||
|
value="<?php echo $defaultValues['color'] ?>">
|
||||||
|
<button type="button" class="w-8 h-8 rounded-lg bg-blue-500 border-2 border-gray-300 hover:border-blue-500" onclick="setColor('#3b82f6')" title="Blau"></button>
|
||||||
|
<button type="button" class="w-8 h-8 rounded-lg bg-red-500 border-2 border-gray-300 hover:border-red-500" onclick="setColor('#ef4444')" title="Rot"></button>
|
||||||
|
<button type="button" class="w-8 h-8 rounded-lg bg-green-500 border-2 border-gray-300 hover:border-green-500" onclick="setColor('#10b981')" title="Grün"></button>
|
||||||
|
<button type="button" class="w-8 h-8 rounded-lg bg-yellow-500 border-2 border-gray-300 hover:border-yellow-500" onclick="setColor('#f59e0b')" title="Gelb"></button>
|
||||||
|
<button type="button" class="w-8 h-8 rounded-lg bg-purple-500 border-2 border-gray-300 hover:border-purple-500" onclick="setColor('#8b5cf6')" title="Lila"></button>
|
||||||
|
<button type="button" class="w-8 h-8 rounded-lg bg-pink-500 border-2 border-gray-300 hover:border-pink-500" onclick="setColor('#ec4899')" title="Pink"></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label class="block text-sm font-medium text-gray-700">Icon</label>
|
||||||
|
<div class="mt-2 h-[180px] overflow-y-auto grid grid-cols-5 sm:grid-cols-8 md:grid-cols-6 lg:grid-cols-8 xl:grid-cols-10 gap-2 p-1">
|
||||||
|
<?php
|
||||||
|
$icons = [
|
||||||
|
"fa-book", "fa-calculator", "fa-flask", "fa-atom", "fa-globe-europe", "fa-palette",
|
||||||
|
"fa-music", "fa-dumbbell", "fa-language", "fa-microscope", "fa-keyboard", "fa-dna",
|
||||||
|
"fa-brain", "fa-history", "fa-chart-line", "fa-draw-polygon", "fa-running", "fa-theater-masks",
|
||||||
|
"fa-chart-pie", "fa-plus-minus", "fa-clock", "fa-code", "fa-divide", "fa-x", "fa-sitemap",
|
||||||
|
"fa-map-pin", "fa-feather-pointed", "fa-person", "fa-link", "fa-4"
|
||||||
|
];
|
||||||
|
foreach ($icons as $icon) {
|
||||||
|
$selectedClass = $defaultValues['icon'] === $icon ? 'bg-blue-50 ring-2 ring-blue-500' : '';
|
||||||
|
echo "<div class='icon-option flex justify-center items-center w-12 h-12 p-2 border rounded-lg cursor-pointer $selectedClass' data-icon='$icon' onclick='selectIcon(this)'><i class='fas $icon'></i></div>";
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
<input type="hidden" id="selectedIcon" name="icon" value="<?php echo $defaultValues['icon']; ?>">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
foreach ($errors as $error) {
|
||||||
|
echo "<p class='text-red-800'>$error</p>";
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flow-root mt-8 gap-4">
|
||||||
|
<?php if (isset($editingSubject)) { ?>
|
||||||
|
<input type="submit" value="Fach löschen" name="submit"
|
||||||
|
class="float-left px-4 py-2 bg-red-600 text-white rounded-lg hover:bg-gray-200">
|
||||||
|
<?php } ?>
|
||||||
|
<input type="submit" value="Speichern" name="submit"
|
||||||
|
class="float-right px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700">
|
||||||
|
<input type="button" value="Abbrechen" onclick="history.back()"
|
||||||
|
class="float-right mx-2 px-4 py-2 bg-gray-100 text-gray-700 rounded-lg hover:bg-gray-200">
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function selectIcon(element) {
|
||||||
|
// Remove active class from all icons
|
||||||
|
document.querySelectorAll('.icon-option').forEach(el => {
|
||||||
|
el.classList.remove('bg-blue-50', 'ring-2', 'ring-blue-500');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Add active class to selected icon
|
||||||
|
element.classList.add('bg-blue-50', 'ring-2', 'ring-blue-500');
|
||||||
|
|
||||||
|
// Set the hidden input value
|
||||||
|
const iconInput = document.getElementById('selectedIcon');
|
||||||
|
iconInput.value = element.getAttribute('data-icon');
|
||||||
|
}
|
||||||
|
|
||||||
|
function setColor(color) {
|
||||||
|
document.querySelector('input[name="color"]').value = color;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -3,6 +3,9 @@
|
|||||||
<?php
|
<?php
|
||||||
require_once("classes/SubjectData.php");
|
require_once("classes/SubjectData.php");
|
||||||
require_once("classes/TopicData.php");
|
require_once("classes/TopicData.php");
|
||||||
|
require_once("classes/User.php");
|
||||||
|
|
||||||
|
session_start();
|
||||||
|
|
||||||
if (!isset($_GET["subject"])) {
|
if (!isset($_GET["subject"])) {
|
||||||
die("Ungültige Seite");
|
die("Ungültige Seite");
|
||||||
@@ -30,8 +33,39 @@ if (!isset($topicData)) {
|
|||||||
<link href="assets/css/topic.css" rel="stylesheet">
|
<link href="assets/css/topic.css" rel="stylesheet">
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/gsap.min.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/gsap.min.js"></script>
|
||||||
<script src="https://cdn.tailwindcss.com"></script>
|
<script src="https://cdn.tailwindcss.com"></script>
|
||||||
<script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
|
|
||||||
<script src="assets/js/sidebar.js"></script>
|
<script src="assets/js/sidebar.js"></script>
|
||||||
|
<script src="assets/js/tasks.js" defer></script>
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.18/dist/katex.min.css"
|
||||||
|
integrity="sha384-veTAhWILPOotXm+kbR5uY7dRamYLJf58I7P+hJhjeuc7hsMAkJHTsPahAl0hBST0" crossorigin="anonymous">
|
||||||
|
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.18/dist/katex.min.js"
|
||||||
|
integrity="sha384-v6mkHYHfY/4BWq54f7lQAdtIsoZZIByznQ3ZqN38OL4KCsrxo31SLlPiak7cj/Mg"
|
||||||
|
crossorigin="anonymous"></script>
|
||||||
|
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.18/dist/contrib/auto-render.min.js"
|
||||||
|
integrity="sha384-hCXGrW6PitJEwbkoStFjeJxv+fSOOQKOPbJxSfM6G5sWZjAyWhXiTIIAmQqnlLlh" crossorigin="anonymous"
|
||||||
|
onload="renderMathInElement(document.body);"></script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
document.addEventListener("DOMContentLoaded", function () {
|
||||||
|
renderMathInElement(document.body, {
|
||||||
|
// customised options
|
||||||
|
// • auto-render specific keys, e.g.:
|
||||||
|
delimiters: [
|
||||||
|
{left: "$$", right: "$$", display: true},
|
||||||
|
{left: "\\(", right: "\\)", display: false},
|
||||||
|
{left: "\\begin{equation}", right: "\\end{equation}", display: true},
|
||||||
|
{left: "\\begin{array}", right: "\\end{array}", display: true},
|
||||||
|
{left: "\\begin{align}", right: "\\end{align}", display: true},
|
||||||
|
{left: "\\begin{alignat}", right: "\\end{alignat}", display: true},
|
||||||
|
{left: "\\begin{gather}", right: "\\end{gather}", display: true},
|
||||||
|
{left: "\\begin{CD}", right: "\\end{CD}", display: true},
|
||||||
|
{left: "\\[", right: "\\]", display: true}
|
||||||
|
],
|
||||||
|
// • rendering keys, e.g.:
|
||||||
|
throwOnError: false
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
|
|
||||||
@@ -41,17 +75,17 @@ if (!isset($topicData)) {
|
|||||||
<!-- Left Sidebar -->
|
<!-- Left Sidebar -->
|
||||||
<nav class="sidebar bg-[<?php echo($subjectData->color); ?>] pt-24">
|
<nav class="sidebar bg-[<?php echo($subjectData->color); ?>] pt-24">
|
||||||
<div class="sidebar-header">
|
<div class="sidebar-header">
|
||||||
<i class="fas fa-graduation-cap"></i>
|
<i class="fas <?php echo($subjectData->icon); ?>"></i>
|
||||||
<h2><?php echo($subjectData->displayName); ?></h2>
|
<h2><?php echo($subjectData->displayName); ?></h2>
|
||||||
</div>
|
</div>
|
||||||
<a href="index.php" class="nav-link">
|
<a href="index.php" class="nav-link">
|
||||||
<i class="fas fa-home"></i> Startseite
|
<i class="fas fa-home"></i> Startseite
|
||||||
</a>
|
</a>
|
||||||
<a href="subject.php?subject=<?php echo($subjectData->id); ?>" class="nav-link">
|
<a href="subject.php?subject=<?php echo($subjectData->id); ?>" class="nav-link overflow-hidden">
|
||||||
<i class="fas fa-book"></i> <?php echo($subjectData->displayName); ?> Übersicht
|
<i class="fas fa-book"></i> <?php echo($subjectData->displayName); ?> Übersicht
|
||||||
</a>
|
</a>
|
||||||
<a href="#" class="nav-link active">
|
<a href="#" class="nav-link active overflow-hidden">
|
||||||
<i class="fas fa-calculator"></i> <?php echo($topicData->displayName); ?>
|
<i class="fas <?php echo($topicData->icon); ?>"></i> <?php echo($topicData->displayName); ?>
|
||||||
</a>
|
</a>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
@@ -60,6 +94,11 @@ if (!isset($topicData)) {
|
|||||||
<div class="max-w-7xl mx-auto mt-5">
|
<div class="max-w-7xl mx-auto mt-5">
|
||||||
<div class="mt-16"></div>
|
<div class="mt-16"></div>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
if(count($topicData->relatedTopics) > 0) {
|
||||||
|
?>
|
||||||
|
|
||||||
|
<!-- Related Topics -->
|
||||||
<div class="related-topics bg-gray-100 p-4 rounded-lg">
|
<div class="related-topics bg-gray-100 p-4 rounded-lg">
|
||||||
<h4>Verwandte Themen:</h4>
|
<h4>Verwandte Themen:</h4>
|
||||||
<ul class="flex flex-wrap gap-2">
|
<ul class="flex flex-wrap gap-2">
|
||||||
@@ -83,15 +122,23 @@ if (!isset($topicData)) {
|
|||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
||||||
|
<!-- Topic Content -->
|
||||||
<div class="content-card mt-[8px]">
|
<div class="content-card mt-[8px]">
|
||||||
<h1 class="content-title"><?php echo($topicData->displayName); ?></h1>
|
<h1 class="content-title"><?php echo($topicData->displayName); ?></h1>
|
||||||
<p class="content-text">
|
<p class="content-text">
|
||||||
<?php echo($topicData->description); ?>
|
<?php echo($topicData->description); ?>
|
||||||
</p>
|
</p>
|
||||||
<p class="content-text article-section">
|
<div class="content-text article-section">
|
||||||
<?php echo($topicData->article); ?>
|
<?php echo($topicData->getFinishedArticle()); ?>
|
||||||
</p>
|
</div>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
if(count($topicData->files) > 0) {
|
||||||
|
?>
|
||||||
<div class="exercise-section bg-gray-100">
|
<div class="exercise-section bg-gray-100">
|
||||||
<h3 style="margin-bottom: 1rem;" class="text-[var(--primary-color)]">Übungen herunterladen:</h3>
|
<h3 style="margin-bottom: 1rem;" class="text-[var(--primary-color)]">Übungen herunterladen:</h3>
|
||||||
<div style="display: flex; flex-wrap: wrap; gap: 0.5rem;">
|
<div style="display: flex; flex-wrap: wrap; gap: 0.5rem;">
|
||||||
@@ -111,8 +158,72 @@ if (!isset($topicData)) {
|
|||||||
?>
|
?>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Tasks -->
|
||||||
|
<?php
|
||||||
|
$tasks = $topicData->getTasks();
|
||||||
|
// nur anzeigen, wenn Aufgaben vorhanden sind
|
||||||
|
if ($tasks != null) {
|
||||||
|
?>
|
||||||
|
<div class="content-card mt-[8px]">
|
||||||
|
<h1 class="content-title">Aufgaben</h1>
|
||||||
|
<div style="display: flex; flex-wrap: wrap; gap: 0.5rem;">
|
||||||
|
<?php
|
||||||
|
foreach ($tasks as $taskIndex => $task) {
|
||||||
|
$taskId = $taskIndex;
|
||||||
|
?>
|
||||||
|
<div class="task-container border-2 border-[var(--primary-color)] p-4 rounded-xl"
|
||||||
|
data-task-id="<?php echo htmlspecialchars($taskId, ENT_QUOTES, 'UTF-8'); ?>">
|
||||||
|
<p>
|
||||||
|
<?php echo '<b>Aufgabe ' . ($taskIndex + 1) . ':</b> </br>' . htmlspecialchars($task->getText(), ENT_QUOTES, 'UTF-8') . '</br></br>'; ?>
|
||||||
|
</p>
|
||||||
|
<!-- Diesen Bereich für jeden Eintrag in Variables anzeigen lassen, z.B. x = [Textfeld] ... -->
|
||||||
|
<?php
|
||||||
|
$variables = $task->getVariables();
|
||||||
|
foreach ($variables as $variableIndex => $variable) {
|
||||||
|
$correctAnswer = $variable;
|
||||||
|
?>
|
||||||
|
<div class="variable-container" style="display: flex; flex-wrap: wrap; gap: 0.5rem; ">
|
||||||
|
<label for="answer<?php echo $taskId . '_' . $variableIndex; ?>"></label>
|
||||||
|
<input class="variable-input border-2 border-[var(--primary-color)]" id="answer<?php echo $taskId . '_' . $variableIndex; ?>" type="text"
|
||||||
|
placeholder="<?php echo $variableIndex; ?>" data-correct-answer="<?php echo $correctAnswer; ?>"/>
|
||||||
|
<button class="check-answer bg-white text-[var(--primary-color)] border-2 border-[var(--primary-color)] w-10 h-10 flex items-center justify-center rounded-lg hover:bg-[var(--primary-color)] hover:text-white transition duration-300">
|
||||||
|
<i class="fa-solid fa-check"></i>
|
||||||
|
</button>
|
||||||
|
<button class="show-answer bg-white text-[var(--primary-color)] border-2 border-[var(--primary-color)] w-10 h-10 flex items-center justify-center rounded-lg hover:bg-[var(--primary-color)] hover:text-white transition duration-300">
|
||||||
|
<i class="fa-solid fa-eye"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<hr>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- Toasts Container -->
|
||||||
|
<div id="toasts" class="fixed top-5 right-5 flex flex-col items-end space-y-4 z-50">
|
||||||
|
<!-- Einzelne Toasts werden hier dynamisch hinzugefügt -->
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
||||||
|
|
||||||
|
<?php
|
||||||
|
if(count($topicData->relatedTopics) > 0) {
|
||||||
|
?>
|
||||||
|
<!-- Related Topics -->
|
||||||
<div class="related-topics bg-gray-100 p-4 rounded-lg">
|
<div class="related-topics bg-gray-100 p-4 rounded-lg">
|
||||||
<h4>Verwandte Themen:</h4>
|
<h4>Verwandte Themen:</h4>
|
||||||
<ul class="flex flex-wrap gap-2">
|
<ul class="flex flex-wrap gap-2">
|
||||||
@@ -135,9 +246,24 @@ if (!isset($topicData)) {
|
|||||||
?>
|
?>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
if (isset($_SESSION['user']) && $_SESSION['user']->isLoggedIn()) {
|
||||||
|
?>
|
||||||
|
<a href="topicEditor.php?subject=<?php echo $subjectData->id ?>&topic=<?php echo $topicData->id ?>"
|
||||||
|
class="fixed z-90 w-14 h-14 bottom-20 right-5 flex items-center justify-center text-4xl text-white rounded-lg bg-[var(--primary-color)] hover:bg-[var(--accent-color)] transition duration-300">
|
||||||
|
<span class="pb-1.5">✎</span>
|
||||||
|
</a>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
||||||
<footer class="sticky top-[100vh] lg:ms-[280px] w-full lg:w-auto bg-white/80 backdrop-blur-lg shadow-sm p-5">
|
<footer class="sticky top-[100vh] lg:ms-[280px] w-full lg:w-auto bg-white/80 backdrop-blur-lg shadow-sm p-5">
|
||||||
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
|
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
|
||||||
<div class="flex justify-between">
|
<div class="flex justify-between">
|
||||||
|
|||||||
584
webseite/topicEditor.php
Normal file
584
webseite/topicEditor.php
Normal file
@@ -0,0 +1,584 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
require_once("classes/User.php");
|
||||||
|
require_once("classes/SubjectData.php");
|
||||||
|
require_once("classes/TopicData.php");
|
||||||
|
require_once("classes/Task.php");
|
||||||
|
|
||||||
|
session_start();
|
||||||
|
|
||||||
|
if (!isset($_SESSION['user']) || !$_SESSION['user']->isLoggedIn()) {
|
||||||
|
header("Location: index.php");
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
|
||||||
|
$allSubjects = SubjectData::getAll();
|
||||||
|
$editingTopic = null;
|
||||||
|
|
||||||
|
$defaultValues = array();
|
||||||
|
$defaultValues['displayName'] = "";
|
||||||
|
$defaultValues['id'] = "";
|
||||||
|
$defaultValues['subjectId'] = "";
|
||||||
|
$defaultValues['description'] = "";
|
||||||
|
$defaultValues['icon'] = "fa-book";
|
||||||
|
$defaultValues['relatedTopics'] = "";
|
||||||
|
$defaultValues['existing_files'] = "";
|
||||||
|
$defaultValues['formulas'] = "";
|
||||||
|
$defaultValues['article'] = "";
|
||||||
|
|
||||||
|
$errors = array();
|
||||||
|
|
||||||
|
if (isset($_GET['subject']) && isset($_GET['topic'])) {
|
||||||
|
if (isset($allSubjects[$_GET['subject']]->getTopics()[$_GET['topic']])) {
|
||||||
|
$editingTopic = $allSubjects[$_GET['subject']]->getTopics()[$_GET['topic']];
|
||||||
|
|
||||||
|
$defaultValues['displayName'] = $editingTopic->getDisplayName();
|
||||||
|
$defaultValues['id'] = $editingTopic->getId();
|
||||||
|
$defaultValues['subjectId'] = $editingTopic->getSubjectId();
|
||||||
|
$defaultValues['description'] = $editingTopic->getDescription();
|
||||||
|
$defaultValues['icon'] = $editingTopic->getIcon();
|
||||||
|
$defaultValues['relatedTopics'] = implode(", ", $editingTopic->getRelatedTopics());
|
||||||
|
$defaultValues['existing_files'] = implode(", ", $editingTopic->getFiles());
|
||||||
|
|
||||||
|
$tasks = array();
|
||||||
|
foreach($editingTopic->getTasks() as $task) {
|
||||||
|
$variables = array();
|
||||||
|
foreach($task->getVariables() as $name => $variable) {
|
||||||
|
$variables[] = $name . "::" . $variable;
|
||||||
|
}
|
||||||
|
|
||||||
|
$tasks[] = $task->getText() . ";;" . implode(";;", $variables);
|
||||||
|
}
|
||||||
|
$defaultValues['formulas'] = implode(";;;;", $tasks);
|
||||||
|
$defaultValues['article'] = $editingTopic->getFinishedArticle();
|
||||||
|
}
|
||||||
|
} else if (isset($_GET['subject'])) {
|
||||||
|
$defaultValues['subjectId'] = $_GET['subject'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||||
|
foreach ($defaultValues as $key => $value) {
|
||||||
|
$defaultValues[$key] = $_POST[$key];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($_POST['displayName']) || trim($_POST['displayName']) == "") {
|
||||||
|
$errors["displayName"] = "Bitte geben Sie einen Namen an.";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($_POST['id']) || trim($_POST['id']) == "") {
|
||||||
|
$errors["id"] = "Bitte geben Sie eine ID an.";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($_POST['subjectId']) || trim($_POST['subjectId']) == "") {
|
||||||
|
$errors["subjectId"] = "Bitte geben Sie ein Fach an.";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($_POST['description']) || trim($_POST['description']) == "") {
|
||||||
|
$errors["description"] = "Bitte geben Sie eine Beschreibung an.";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($_POST['icon']) || trim($_POST['icon']) == "") {
|
||||||
|
$errors["icon"] = "Bitte geben Sie ein Icon an.";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($_POST['relatedTopics'])) {
|
||||||
|
$errors["relatedTopics"] = "Feld relatedTopics nicht mitgesendet!";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($_POST['existing_files'])) {
|
||||||
|
$errors["existing_files"] = "Feld existing_files nicht mitgesendet!";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($_POST['formulas'])) {
|
||||||
|
$errors["formulas"] = "Feld formulas nicht mitgesendet!";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($_POST['article']) || trim($_POST['article']) == "") {
|
||||||
|
$errors["article"] = "Bitte geben Sie einen Erklärtext an.";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($_POST['submit']) || !($_POST['submit'] == "Speichern" || $_POST['submit'] == "Thema löschen")) {
|
||||||
|
$errors["submit"] = "Ungültig abgeschickt!";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($errors)) {
|
||||||
|
$newTopic = false;
|
||||||
|
|
||||||
|
$relatedTopics = array();
|
||||||
|
foreach (explode(",", $_POST['relatedTopics']) as $relatedTopic) {
|
||||||
|
$relatedTopic = trim($relatedTopic);
|
||||||
|
if ($relatedTopic == "") {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$relatedTopics[] = $relatedTopic;
|
||||||
|
}
|
||||||
|
|
||||||
|
$existingFiles = array();
|
||||||
|
foreach (explode(",", $_POST['existing_files']) as $existingTopic) {
|
||||||
|
$existingTopic = trim($existingTopic);
|
||||||
|
if ($existingTopic == "") {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$existingFiles[] = trim($existingTopic);
|
||||||
|
}
|
||||||
|
|
||||||
|
$formulas = array();
|
||||||
|
foreach (explode(";;;;", $_POST['formulas']) as $formulaString) {
|
||||||
|
$text = false;
|
||||||
|
$answers = array();
|
||||||
|
foreach (explode(";;", $formulaString) as $formulaEntry) {
|
||||||
|
if(!$text) {
|
||||||
|
$text = trim($formulaEntry);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$answer = explode("::", $formulaEntry);
|
||||||
|
if(count($answer) != 2) {
|
||||||
|
$errors['formulas'] = "Jede Formel muss einen Text und mindestens eine Antwortmöglichkeit haben!";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
$answers[trim($answer[0])] = trim($answer[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!$text) {
|
||||||
|
$errors['formulas'] = "Jede Formel muss einen Text haben!";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(count($answers) == 0) {
|
||||||
|
$errors['formulas'] = "Jede Formel muss mindestens eine Antwortmöglichkeit haben!";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
$formulas[] = new Task($text, $answers);
|
||||||
|
}
|
||||||
|
|
||||||
|
$article = mb_convert_encoding($_POST['article'], 'HTML-ENTITIES', 'UTF-8');
|
||||||
|
$dom = new DOMDocument();
|
||||||
|
$dom->loadHTML($article, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
|
||||||
|
$htmlImages = $dom->getElementsByTagName('img');
|
||||||
|
$newImages = array();
|
||||||
|
foreach ($htmlImages as $htmlImage) {
|
||||||
|
$src = $htmlImage->getAttribute('src');
|
||||||
|
if (str_starts_with($src, "data:image")) {
|
||||||
|
$image = file_get_contents($src);
|
||||||
|
if (!$image) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$image_format = false;
|
||||||
|
if (str_starts_with($src, 'data:image/jpeg;')) {
|
||||||
|
$image_format = "jpg";
|
||||||
|
} else if (str_starts_with($src, 'data:image/png;')) {
|
||||||
|
$image_format = "png";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$image_format) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$imagename = uniqid("image_", true) . ".$image_format";
|
||||||
|
$newImages[$imagename] = $image;
|
||||||
|
} else {
|
||||||
|
$imagePath = explode("/", $src);
|
||||||
|
$imagename = end($imagePath);
|
||||||
|
}
|
||||||
|
$htmlImage->setAttribute("src", '__TOPICPATH__/' . $imagename);
|
||||||
|
}
|
||||||
|
|
||||||
|
// extension=mbstring in php.ini muss aktiviert sein!
|
||||||
|
$article = mb_convert_encoding($dom->saveHTML(), 'UTF-8', 'HTML-ENTITIES');
|
||||||
|
$article = preg_replace("/^[ \r\n\t]*<p><p>/", "<p>", $article);
|
||||||
|
$article = preg_replace("#</p></p>[ \r\n\t]*$#", "</p>", $article);
|
||||||
|
|
||||||
|
if (isset($allSubjects[$_POST['oldSubjectId']]->getTopics()[$_POST['oldTopicId']])) {
|
||||||
|
$newTopic = $allSubjects[$_POST['oldSubjectId']]->getTopics()[$_POST['oldTopicId']];
|
||||||
|
|
||||||
|
$newTopic->setId($_POST['id']);
|
||||||
|
$newTopic->setDisplayName($_POST['displayName']);
|
||||||
|
$newTopic->setSubjectId($_POST['subjectId']);
|
||||||
|
$newTopic->setDescription($_POST['description']);
|
||||||
|
$newTopic->setIcon($_POST['icon']);
|
||||||
|
$newTopic->setRelatedTopics($relatedTopics);
|
||||||
|
foreach ($newTopic->getFiles() as $file) {
|
||||||
|
if (!in_array($file, $existingFiles)) {
|
||||||
|
$newTopic->deleteDownload($file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$newTopic->setArticle($article);
|
||||||
|
$newTopic->removeAllTasks();
|
||||||
|
} else {
|
||||||
|
$newTopic = TopicData::createNew($_POST['id'], $_POST['subjectId'], $_POST['displayName'], $_POST['icon'], $_POST['description'], $relatedTopics, $article);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$newTopic) {
|
||||||
|
$errors["error"] = "Fehler beim Speichern des Themas.";
|
||||||
|
} else {
|
||||||
|
for ($i = 0; $i < count($_FILES['new_files']['name']); $i++) {
|
||||||
|
!$newTopic->addDownload($_FILES['new_files']['name'][$i], $_FILES['new_files']['tmp_name'][$i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($newImages as $name => $image) {
|
||||||
|
$newTopic->uploadImage($name, $image);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($formulas as $formula) {
|
||||||
|
$newTopic->addTask($formula);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($_POST['submit'] == "Thema löschen") {
|
||||||
|
$newTopic->delete();
|
||||||
|
header("Location: " . "subject.php?subject=" . $_POST['subjectId']);
|
||||||
|
} else {
|
||||||
|
$newTopic->save();
|
||||||
|
header("Location: " . "topic.php?subject=" . $newTopic->getSubjectId() . "&topic=" . $newTopic->getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
|
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="de">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
|
||||||
|
<title>Lehrer Dashboard</title>
|
||||||
|
|
||||||
|
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
|
||||||
|
<link href="assets/css/topic.css" rel="stylesheet">
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/quill@2.0.3/dist/quill.snow.css" rel="stylesheet"/>
|
||||||
|
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/gsap.min.js"></script>
|
||||||
|
<script src="https://cdn.tailwindcss.com"></script>
|
||||||
|
<script src="assets/js/quill_mod.js"></script>
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.19/dist/katex.min.css"
|
||||||
|
integrity="sha384-7lU0muIg/i1plk7MgygDUp3/bNRA65orrBub4/OSWHECgwEsY83HaS1x3bljA/XV" crossorigin="anonymous">
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/katex@0.16.19/dist/katex.min.js"
|
||||||
|
integrity="sha384-RdymN7NRJ+XoyeRY4185zXaxq9QWOOx3O7beyyrRK4KQZrPlCDQQpCu95FoCGPAE"
|
||||||
|
crossorigin="anonymous"></script>
|
||||||
|
<script src="assets/js/katex_autorender_mod.js"></script>
|
||||||
|
<script src="assets/js/formula.js"></script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body class="min-h-screen bg-gray-50">
|
||||||
|
|
||||||
|
<?php include 'header.php'; ?>
|
||||||
|
|
||||||
|
<div class="content mt-24 max-w-7xl mx-[16px] xl:mx-auto">
|
||||||
|
|
||||||
|
<form id="topicForm" method="post" enctype="multipart/form-data" class="space-y-8">
|
||||||
|
<div class="grid grid-cols-1 xl:grid-cols-2 gap-8">
|
||||||
|
<!-- Left column - Topic details -->
|
||||||
|
<div class="space-y-6">
|
||||||
|
<div>
|
||||||
|
<label for="topicNameSelect" class="block text-sm font-medium text-gray-700 mb-2">Themenname</label>
|
||||||
|
<input id="topicNameSelect" type="text" name="displayName"
|
||||||
|
class="w-full px-4 py-3 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 text-lg enabled:hover:border-gray-400"
|
||||||
|
required
|
||||||
|
value="<?php echo $defaultValues['displayName']; ?>">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label for="topicIdSelect" class="block text-sm font-medium text-gray-700 mb-2">ID</label>
|
||||||
|
<input id="topicIdSelect" type="text" name="id"
|
||||||
|
class="w-full px-4 py-3 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 text-lg enabled:hover:border-gray-400"
|
||||||
|
required
|
||||||
|
value="<?php echo $defaultValues['id']; ?>">
|
||||||
|
|
||||||
|
<input type="hidden" name="oldTopicId" value="<?php echo $defaultValues['id']; ?>">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label for="topicSubjectSelect" class="block text-sm font-medium text-gray-700 mb-2">Fach</label>
|
||||||
|
<div class="relative">
|
||||||
|
<select id="topicSubjectSelect" name="subjectId"
|
||||||
|
class="w-full px-4 py-3 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 text-lg enabled:hover:border-gray-400 appearance-none bg-white">
|
||||||
|
<?php
|
||||||
|
foreach ($allSubjects as $subject) {
|
||||||
|
$selected = "";
|
||||||
|
if ($defaultValues['subjectId'] === $subject->getId()) {
|
||||||
|
$selected = "selected";
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "<option $selected value='" . $subject->getId() . "'>" . $subject->getDisplayName() . "</option>";
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</select>
|
||||||
|
<div class="pointer-events-none absolute inset-y-0 right-0 flex items-center px-2 text-gray-700">
|
||||||
|
<svg class="fill-current h-4 w-4" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20">
|
||||||
|
<path d="M7 10l5 5 5-5H7z"/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<input type="hidden" name="oldSubjectId" value="<?php echo $defaultValues['subjectId']; ?>">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label for="topicDescriptionSelect" class="block text-sm font-medium text-gray-700 mb-2">Kurzbeschreibung</label>
|
||||||
|
<textarea id="topicDescriptionSelect" name="description" rows="5"
|
||||||
|
class="w-full px-4 py-3 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 text-lg enabled:hover:border-gray-400"
|
||||||
|
required><?php echo $defaultValues['description']; ?></textarea>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label class="block text-sm font-medium text-gray-700">Icon</label>
|
||||||
|
<div class="mt-2 h-[180px] overflow-y-auto grid grid grid-cols-5 sm:grid-cols-8 md:grid-cols-10 gap-2 p-1">
|
||||||
|
<?php
|
||||||
|
$icons = [
|
||||||
|
"fa-book", "fa-calculator", "fa-flask", "fa-atom", "fa-globe-europe", "fa-palette",
|
||||||
|
"fa-music", "fa-dumbbell", "fa-language", "fa-microscope", "fa-keyboard", "fa-dna",
|
||||||
|
"fa-brain", "fa-history", "fa-chart-line", "fa-draw-polygon", "fa-running", "fa-theater-masks",
|
||||||
|
"fa-chart-pie", "fa-plus-minus", "fa-clock", "fa-code", "fa-divide", "fa-x", "fa-sitemap",
|
||||||
|
"fa-map-pin", "fa-feather-pointed", "fa-person", "fa-link", "fa-4"
|
||||||
|
];
|
||||||
|
foreach ($icons as $icon) {
|
||||||
|
$selectedClass = $defaultValues['icon'] === $icon ? 'bg-blue-50 ring-2 ring-blue-500' : '';
|
||||||
|
echo "<div class='icon-option flex justify-center items-center w-12 h-12 p-2 border rounded-lg cursor-pointer $selectedClass' data-icon='$icon' onclick='selectIcon(this)'><i class='fas $icon'></i></div>";
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
<input type="hidden" id="selectedIcon" name="icon" value="<?php echo $defaultValues['icon']; ?>">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label for="relatedTopicSelect" class="block text-sm font-medium text-gray-700 mb-2">Verwandte Themen (IDs, kommagetrennt)</label>
|
||||||
|
<input type="text"
|
||||||
|
name="relatedTopics"
|
||||||
|
id="relatedTopicSelect"
|
||||||
|
class="w-full px-4 py-3 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 text-lg enabled:hover:border-gray-400"
|
||||||
|
value="<?php echo $defaultValues['relatedTopics']; ?>">
|
||||||
|
|
||||||
|
|
||||||
|
<?php
|
||||||
|
if ($defaultValues['subjectId'] !== "") {
|
||||||
|
?>
|
||||||
|
<select id="addRelatedTopic"
|
||||||
|
onchange="addSelectedRelatedTopic()"
|
||||||
|
class="w-full px-4 py-3 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 text-lg enabled:hover:border-gray-400 appearance-none bg-white">
|
||||||
|
<option selected value="">Thema hinzufügen</option>
|
||||||
|
<?php
|
||||||
|
|
||||||
|
foreach ($allSubjects[$defaultValues['subjectId']]->getTopics() as $topic) {
|
||||||
|
if(isset($editingTopic) && $topic->getId() === $editingTopic->getId()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "<option value='" . $topic->getId() . "'>" . $topic->getDisplayName() . "</option>";
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</select>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label for="existing_files" class="block text-sm font-medium text-gray-700 mb-2">Existierende Übungsblätter - Entfernen zum Löschen</label>
|
||||||
|
<input type="text"
|
||||||
|
name="existing_files"
|
||||||
|
id="existing_files"
|
||||||
|
class="w-full px-4 py-3 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 text-lg enabled:hover:border-gray-400"
|
||||||
|
value="<?php echo $defaultValues['existing_files']; ?>">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label for="new_files" class="block text-sm font-medium text-gray-700 mb-2">
|
||||||
|
Übungsblätter hinzufügen
|
||||||
|
</label>
|
||||||
|
<div class="relative border border-gray-300 rounded-lg p-2 bg-white shadow-sm">
|
||||||
|
<input type="file" name="new_files[]" id="new_files" multiple
|
||||||
|
class="absolute inset-0 w-full h-full opacity-0 cursor-pointer">
|
||||||
|
<div class="flex items-center justify-center h-full text-gray-500">
|
||||||
|
<i class="fas fa-upload mr-2"></i>
|
||||||
|
<span>Dateien hier ablegen oder klicken, um Dateien auszuwählen</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label for="formulas" class="block text-sm font-medium text-gray-700 mb-2">Aufgaben</label>
|
||||||
|
<input type="text"
|
||||||
|
name="formulas"
|
||||||
|
id="formulas"
|
||||||
|
class="w-full px-4 py-3 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 text-lg enabled:hover:border-gray-400"
|
||||||
|
placeholder="Format: aufgabentext1;;a::2,5;;b::3;;;;aufgabentext2;;a::1"
|
||||||
|
hidden="hidden"
|
||||||
|
value="<?php echo $defaultValues['formulas']; ?>">
|
||||||
|
|
||||||
|
<div id="formulaInputs">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button class="mt-0 border-2 border-blue-500 text-blue-500 w-full px-4 py-2 rounded-lg hover:bg-blue-500 hover:text-white transition duration-300 flex items-center"
|
||||||
|
onclick="createFormulaWithVariable()"
|
||||||
|
type="button">
|
||||||
|
<span>Neue Aufgabe</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Right column - Editor -->
|
||||||
|
<div>
|
||||||
|
<div class="mb-6">
|
||||||
|
<div class="flex justify-between items-center mb-2">
|
||||||
|
<label class="block text-sm font-medium text-gray-700">Erklärtext</label>
|
||||||
|
<div class="flex gap-2">
|
||||||
|
<button type="button" onclick="undo()"
|
||||||
|
class="text-gray-500 hover:text-gray-700 p-1">
|
||||||
|
<i class="fas fa-undo"></i>
|
||||||
|
</button>
|
||||||
|
<button type="button" onclick="redo()"
|
||||||
|
class="text-gray-500 hover:text-gray-700 p-1">
|
||||||
|
<i class="fas fa-redo"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="quillEditor" class="h-[600px] xl:h-auto bg-white border rounded-lg"><?php
|
||||||
|
$article = $defaultValues['article'];
|
||||||
|
|
||||||
|
echo $article;
|
||||||
|
|
||||||
|
?></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
foreach($errors as $error) {
|
||||||
|
echo $error;
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
||||||
|
<div class="flow-root gap-4">
|
||||||
|
<?php if (isset($editingTopic)) { ?>
|
||||||
|
<input type="submit" value="Thema löschen" name="submit"
|
||||||
|
class="float-left px-4 py-2 bg-red-600 text-white rounded-lg hover:bg-gray-200">
|
||||||
|
<?php } ?>
|
||||||
|
<input type="submit" value="Speichern" name="submit"
|
||||||
|
class="float-right px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700">
|
||||||
|
<input type="button" value="Abbrechen" onclick="history.back()"
|
||||||
|
class="float-right mx-2 px-4 py-2 bg-gray-100 text-gray-700 rounded-lg hover:bg-gray-200">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<input type="hidden" name="article" id="article-upload-field">
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
function renderFormulas() {
|
||||||
|
renderMathInElement(document.body, {
|
||||||
|
delimiters: [
|
||||||
|
{left: "$$", right: "$$", display: true},
|
||||||
|
{left: "\\(", right: "\\)", display: false},
|
||||||
|
{left: "\\begin{equation}", right: "\\end{equation}", display: true},
|
||||||
|
{left: "\\begin{array}", right: "\\end{array}", display: true},
|
||||||
|
{left: "\\begin{align}", right: "\\end{align}", display: true},
|
||||||
|
{left: "\\begin{alignat}", right: "\\end{alignat}", display: true},
|
||||||
|
{left: "\\begin{gather}", right: "\\end{gather}", display: true},
|
||||||
|
{left: "\\begin{CD}", right: "\\end{CD}", display: true},
|
||||||
|
{left: "\\[", right: "\\]", display: true}
|
||||||
|
],
|
||||||
|
throwOnError : false
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
createFormulasFromString(document.querySelector('#formulas').value);
|
||||||
|
renderFormulas();
|
||||||
|
|
||||||
|
const quill = new Quill('#quillEditor', {
|
||||||
|
modules: {
|
||||||
|
toolbar: [
|
||||||
|
[{'size': []}],
|
||||||
|
['bold', 'italic', 'underline', 'strike'],
|
||||||
|
[{'script': 'super'}, {'script': 'sub'}],
|
||||||
|
[{'list': 'ordered'}, {'list': 'bullet'}],
|
||||||
|
['link', 'image', 'formula'],
|
||||||
|
]
|
||||||
|
},
|
||||||
|
theme: 'snow'
|
||||||
|
});
|
||||||
|
|
||||||
|
quill.on('text-change', (delta, oldDelta, source) => {
|
||||||
|
let html = quill.getSemanticHTML().replace(/ /g, " ");
|
||||||
|
html = html.replaceAll("<p></p>", "<br>");
|
||||||
|
|
||||||
|
while (html.startsWith("<br>")) {
|
||||||
|
html = html.replace(/^<br>/g, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
while (html.endsWith("<br>")) {
|
||||||
|
html = html.replace(/<br>$/g, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
document.getElementById('article-upload-field').value = html;
|
||||||
|
});
|
||||||
|
quill.emitter.emit('text-change');
|
||||||
|
|
||||||
|
function undo() {
|
||||||
|
quill.history.undo();
|
||||||
|
}
|
||||||
|
|
||||||
|
function redo() {
|
||||||
|
quill.history.redo();
|
||||||
|
}
|
||||||
|
|
||||||
|
function selectIcon(element) {
|
||||||
|
// Remove active class from all icons
|
||||||
|
document.querySelectorAll('.icon-option').forEach(el => {
|
||||||
|
el.classList.remove('bg-blue-50', 'ring-2', 'ring-blue-500');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Add active class to selected icon
|
||||||
|
element.classList.add('bg-blue-50', 'ring-2', 'ring-blue-500');
|
||||||
|
|
||||||
|
// Set the hidden input value
|
||||||
|
const iconInput = document.getElementById('selectedIcon');
|
||||||
|
iconInput.value = element.getAttribute('data-icon');
|
||||||
|
}
|
||||||
|
|
||||||
|
function selectIcon(element) {
|
||||||
|
// Remove active class from all icons
|
||||||
|
document.querySelectorAll('.icon-option').forEach(el => {
|
||||||
|
el.classList.remove('bg-blue-50', 'ring-2', 'ring-blue-500');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Add active class to selected icon
|
||||||
|
element.classList.add('bg-blue-50', 'ring-2', 'ring-blue-500');
|
||||||
|
|
||||||
|
// Set the hidden input value
|
||||||
|
const iconInput = document.getElementById('selectedIcon');
|
||||||
|
iconInput.value = element.getAttribute('data-icon');
|
||||||
|
}
|
||||||
|
|
||||||
|
function addSelectedRelatedTopic() {
|
||||||
|
const input = document.querySelector('#relatedTopicSelect');
|
||||||
|
const selector = document.querySelector('#addRelatedTopic');
|
||||||
|
|
||||||
|
if(selector.value === "") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(input.value.includes(selector.value)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(input.value.trim() === "") {
|
||||||
|
input.value += selector.value;
|
||||||
|
} else {
|
||||||
|
input.value += ", " + selector.value;
|
||||||
|
}
|
||||||
|
selector.selectedIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Reference in New Issue
Block a user