-
Notifications
You must be signed in to change notification settings - Fork 0
/
script.js
275 lines (225 loc) · 9.89 KB
/
script.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
let currentFilter = null; // Track the current category filter
// Fetch the dictionary data from the JSON file
fetch('dictionary.json')
.then(response => response.json())
.then(data => {
initializeAvailableWords(data); // Initialize available words section
generateAlphabetButtons(); // Generate alphabet buttons
})
.catch(error => console.error('Error loading dictionary:', error));
// Function to initialize available words based on dictionary data
function initializeAvailableWords(words) {
const categoriesContainer = document.getElementById('categories-container');
const categories = {};
// Group words by category
words.forEach(word => {
if (!categories[word.category]) {
categories[word.category] = [];
}
categories[word.category].push(word);
});
// Create a section for each category
for (const [category, words] of Object.entries(categories)) {
const categorySection = document.createElement('div');
categorySection.classList.add('category-list');
categorySection.dataset.category = category;
const categoryTitle = document.createElement('h3');
categoryTitle.classList.add('category-title');
categoryTitle.textContent = category;
const categoryContainer = document.createElement('div');
categoryContainer.classList.add('category-container');
words.forEach(word => {
const cardElement = createCard(word);
categoryContainer.appendChild(cardElement);
});
categorySection.appendChild(categoryTitle);
categorySection.appendChild(categoryContainer);
categoriesContainer.appendChild(categorySection);
}
// Initialize cards with category data attribute
initializeCards(words);
}
// Function to create a card element
function createCard(card) {
const cardElement = document.createElement('div');
cardElement.classList.add('card');
cardElement.innerHTML = `
<div class="front">${card.chinese}</div>
<div class="back">
<div>Pinyin<br> <strong>${card.pinyin}</strong></div>
<div>Meaning<br> <strong>${card.meaning}</strong></div>
</div>
`;
// Adding click event to flip the card
cardElement.addEventListener('click', function() {
cardElement.classList.toggle('flipped');
});
// Adding drag and drop functionality
cardElement.draggable = true;
cardElement.addEventListener('dragstart', function(event) {
// Set data for the drag
event.dataTransfer.setData('application/json', JSON.stringify(card));
event.dataTransfer.effectAllowed = 'move';
// Optional: Add a class to indicate dragging
cardElement.classList.add('dragging');
});
// Optional: Remove the dragging class when drag ends
cardElement.addEventListener('dragend', function() {
cardElement.classList.remove('dragging');
});
// Set the category data attribute for filtering
cardElement.dataset.category = card.category; // Use category for filtering
return cardElement;
}
// Function to generate alphabet buttons from A to Z and a clear button
function generateAlphabetButtons() {
const alphabetIndex = document.getElementById('category-index');
const alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ#±'.split('');
// Clear existing buttons
alphabetIndex.innerHTML = '';
// Create buttons for each letter in the alphabet
alphabet.forEach(letter => {
const button = document.createElement('button');
button.textContent = letter;
button.onclick = () => filterByCategory(letter);
alphabetIndex.appendChild(button);
});
// Add a clear button
const clearButton = document.createElement('button');
clearButton.textContent = 'Clear';
clearButton.onclick = clearFilter;
alphabetIndex.appendChild(clearButton);
}
// Function to filter cards based on category
function filterByCategory(category) {
const categoriesContainer = document.getElementById('categories-container');
const categorySections = categoriesContainer.getElementsByClassName('category-list');
// If the same category is clicked again, clear the filter
if (currentFilter === category) {
clearFilter();
return;
}
// Set the current filter
currentFilter = category;
for (let section of categorySections) {
if (section.dataset.category === category) {
section.style.display = 'block'; // Show the matching category section
} else {
section.style.display = 'none'; // Hide non-matching category sections
}
}
}
// Function to clear the category filter
function clearFilter() {
const categoriesContainer = document.getElementById('categories-container');
const categorySections = categoriesContainer.getElementsByClassName('category-list');
for (let section of categorySections) {
section.style.display = 'block'; // Show all category sections
}
currentFilter = null; // Reset the current filter
}
// Function to initialize the cards with category data-attribute
function initializeCards(words) {
const categoriesContainer = document.getElementById('categories-container');
const cards = categoriesContainer.getElementsByClassName('card');
for (let card of cards) {
// Use the already available category data for filtering
const chineseChar = card.innerText.trim();
const entry = words.find(entry => entry.chinese === chineseChar);
if (entry) {
card.dataset.category = entry.category; // Set the category data attribute
}
}
}
// Function to clear the sentence board
function clearSentenceBoard() {
const sentenceDropzone = document.getElementById('sentence-dropzone');
sentenceDropzone.innerHTML = ''; // Clear all child elements
// Show instructions if no cards are left
const sentenceInstructions = document.getElementById('sentence-instructions');
sentenceInstructions.style.display = 'block';
}
// Adding drop event for sentence board
const sentenceDropzone = document.getElementById('sentence-dropzone');
const sentenceInstructions = document.getElementById('sentence-instructions');
// Prevent default drag behaviors to allow drops
['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
sentenceDropzone.addEventListener(eventName, preventDefaults, false);
});
function preventDefaults(event) {
event.preventDefault();
event.stopPropagation();
}
// Highlight drop zone when a draggable element enters
sentenceDropzone.addEventListener('dragenter', function() {
sentenceDropzone.classList.add('highlight');
});
// Remove highlight from drop zone when a draggable element leaves
sentenceDropzone.addEventListener('dragleave', function() {
sentenceDropzone.classList.remove('highlight');
});
// Handle the drop event to add a card to the sentence board
sentenceDropzone.addEventListener('drop', function(event) {
const cardData = event.dataTransfer.getData('application/json');
if (cardData) {
const card = JSON.parse(cardData);
// Remove sentence instructions once a card is dropped
sentenceInstructions.style.display = 'none';
// Create a new span element for the dropped card
const droppedCard = document.createElement('span');
droppedCard.textContent = card.chinese;
droppedCard.classList.add('dropped-card');
// Append the dropped card to the sentence dropzone
sentenceDropzone.appendChild(droppedCard);
// Add event listener to each dropped card for removal
droppedCard.addEventListener('click', function() {
sentenceDropzone.removeChild(droppedCard);
// Show instructions if no cards are left
if (sentenceDropzone.children.length === 0) {
sentenceInstructions.style.display = 'block';
}
});
// Allow reordering of cards in the sentence dropzone
droppedCard.draggable = true;
droppedCard.addEventListener('dragstart', function(event) {
event.dataTransfer.setData('text/plain', droppedCard.textContent);
event.dataTransfer.effectAllowed = 'move';
});
// Handle dropping within the dropzone to reorder
droppedCard.addEventListener('dragover', preventDefaults);
droppedCard.addEventListener('drop', reorderCards);
// Remove highlight from drop zone
sentenceDropzone.classList.remove('highlight');
}
});
// Function to reorder cards within the sentence dropzone
function reorderCards(event) {
const chineseCharacter = event.dataTransfer.getData('text/plain');
const target = event.target;
if (target.classList.contains('dropped-card')) {
const newCard = document.createElement('span');
newCard.textContent = chineseCharacter;
newCard.classList.add('dropped-card');
target.insertAdjacentElement('beforebegin', newCard);
target.parentElement.removeChild(event.target);
// Add event listener for the newly inserted card
newCard.addEventListener('click', function() {
sentenceDropzone.removeChild(newCard);
// Show instructions if no cards are left
if (sentenceDropzone.children.length === 0) {
sentenceInstructions.style.display = 'block';
}
});
// Allow reordering of newly inserted card
newCard.draggable = true;
newCard.addEventListener('dragstart', function(event) {
event.dataTransfer.setData('text/plain', newCard.textContent);
event.dataTransfer.effectAllowed = 'move';
});
// Handle dropping within the dropzone to reorder
newCard.addEventListener('dragover', preventDefaults);
newCard.addEventListener('drop', reorderCards);
}
}
// Initialize Pinyin display as hidden
document.getElementById('pinyin-display').style.display = 'none';