PageSourceSearch

https://www.anschuetz.com/_assets/51b05ba2afb78bea9c9cd95c253cbd25/JavaScript/softgarden.js?1750407812

js anschuetz.com collected 2026-10-02 11:15:03 UTC 13,288 bytes, 357 lines download raw bytes

1//Function for limiting the selection to one checkbox within each group
2function limitSelectionToOne(groupClass) {
3    const checkboxes = document.querySelectorAll(groupClass);
4
5    checkboxes.forEach(checkbox => {
6        checkbox.addEventListener('change', () => {
7            if (checkbox.checked) {
8                // Deactivates all other checkboxes within the same group
9                checkboxes.forEach(otherCheckbox => {
10                    if (otherCheckbox !== checkbox) {
11                        otherCheckbox.checked = false;
12                    }
13                });
14            }
15        });
16    });
17}
18
19limitSelectionToOne('.audienceCheckbox');
20limitSelectionToOne('.categoryCheckbox');
21
22let currentPage = 1;
23const itemsPerPage = 10;
24let filteredJobs = [];
25const minKeywordLength = 3;
26let keyword = '';
27function ajaxHandler(url, method, data) {
28    data = data || {};
29    return new Promise((resolve, reject) => {
30        let xhr = new XMLHttpRequest();
31        xhr.open(method, url, true);
32        xhr.setRequestHeader('Content-Type', 'application/json');
33        xhr.setRequestHeader('Accept', 'application/json'); // Explizit JSON akzeptieren
34
35        xhr.onreadystatechange = function () {
36            if (xhr.readyState === XMLHttpRequest.DONE) {
37                if (xhr.status === 200) {
38                    try {
39                        let responseData = JSON.parse(xhr.responseText);
40                        resolve(responseData);
41                    } catch (e) {
42                        console.error('Error parsing the JSON response:', e);
43                        reject('Error parsing the response');
44                    }
45                } else {
46                    reject('Error: ' + xhr.status);
47                }
48            }
49        };
50
51        xhr.onerror = function () {
52            reject('Network error');
53        };
54
55        xhr.send(JSON.stringify(data));
56    });
57}
58
59function handleSelectionOnChange() {
60    return async function () {
61        const url = document.querySelector(`.job-list-container`).getAttribute('data-url');
62
63        const checkboxes = document.querySelectorAll('.job-filter .select-options-container input[type="checkbox"]');
64
65        // Array for saving the selected IDs
66        let selectedAudienceIds = [];
67        let selectedCategoryIds = [];
68
69        // Iterate over the checkboxes and collect the selected IDs
70        checkboxes.forEach(checkbox => {
71            if (checkbox.checked) {
72                if (checkbox.classList.contains('audienceCheckbox')) {
73                    selectedAudienceIds.push(checkbox.value);
74                } else if (checkbox.classList.contains('categoryCheckbox')) {
75                    selectedCategoryIds.push(checkbox.value);
76                }
77            }
78        });
79
80        let data = {
81            selectedAudienceIds: selectedAudienceIds,
82            selectedCategoryIds: selectedCategoryIds,
83            keyword: keyword.length >= minKeywordLength ? keyword : null,
84        };
85        try {
86            const result = await ajaxHandler(url, 'POST', data);
87            if (result.status === 200) {
88                filteredJobs = result.jobs;
89                currentPage = 1;
90                updateJobListView(result.categories);
91                if (data.keyword === null) {
92                    updateCounts(result.allJobs, selectedAudienceIds, selectedCategoryIds);
93                } else {
94                    updateCounts(filteredJobs, selectedAudienceIds, selectedCategoryIds);
95                }
96
97                const resultsSpan = document.querySelector('.job-results');
98                if (resultsSpan) {
99                    resultsSpan.textContent = filteredJobs.length;
100                }
101            } else {
102                console.log('Error when processing the enquiry.');
103            }
104        } catch (error) {
105            console.error('Error:', error);
106        }
107    };
108}
109
110// Event-Listener für das Suchfeld
111const searchInputElement = document.getElementById('job-search-input');
112
113if (searchInputElement) {
114    searchInputElement.addEventListener('input', async function (event) {
115        keyword = event.target.value.trim();
116        if (keyword.length >= minKeywordLength) {
117            handleSelectionOnChange()();
118        } else if (keyword === '') {
119            handleSelectionOnChange()();
120        }
121    });
122}
123
124function updateJobListView(categories) {
125    const jobListView = document.getElementById('job-list-view');
126
127    if (!jobListView) {
128        return;
129    }
130
131    // Delete actual content
132    try {
133        jobListView.innerHTML = '';
134    } catch (error) {
135        console.error('Failed to clear job list view:', error);
136        return;
137    }
138
139    const startIndex = (currentPage - 1) * itemsPerPage;
140    const endIndex = startIndex + itemsPerPage;
141    const jobsToDisplay = filteredJobs.slice(startIndex, endIndex);
142
143    // Generate new content based on the filtered jobs
144    jobsToDisplay.forEach(job => {
145        const jobItem = document.createElement('a');
146        const jobCategoryElements = job.jobCategories
147            .map(categoryId => categories[categoryId]?.title || categoryId)
148            .join(', ');
149        const formattedDate = formatDate(job.jobStartDate);
150        const detailUrl = job.detailUrl;
151
152        jobItem.classList.add('job-item');
153        jobItem.href = detailUrl;
154        jobItem.innerHTML = `
155            <div class="job-info">
156                <div class="fontsize-28-32 color-primary-base no-space-bottom job-info-headline">${job.externalPostingName}</div>
157                <div class="d-flex space-xs-top-10 job-list-info flex-wrap gap-10">
158                    <div class="job-postingtime space-xs-right-40 d-flex justify-content-center">
159                        <i class="job-info-icon icon icon-calendar color-primary-base d-flex justify-content-center space-xs-right-10"></i>
160                        <span class="job-info-text">${formattedDate}</span>
161                    </div>
162                    <div class="job-catogry space-xs-right-40 d-flex justify-content-center">
163                        <i class="job-info-icon icon icon-list color-primary-base  d-flex justify-content-center space-xs-right-10"></i>
164                        <span class="job-info-text">${jobCategoryElements}</span>
165                    </div>
166                    <div class="job-location d-flex justify-content-center">
167                         <i class="job-info-icon icon icon-location color-primary-base d-flex justify-content-center space-xs-right-10"></i>
168                         <span class="job-info-text">${job.geo_city}</span>
169                    </div>
170                </div>                   
171            </div>
172      
173
174            <div class="job-info-arrow"><i class="icon icon-arrow-right"></i></div>
175        `;
176        jobListView.appendChild(jobItem);
177    });
178    // Update Pagination
179    updatePagination(categories);
180}
181
182function updateCounts(jobsArray, selectedAudienceIds, selectedCategoryIds) {
183    // Initialize the counters
184    const {categoryCounts, audienceCounts} = initializeCounts();
185
186    jobsArray.forEach(job => {
187        const matchesSelectedCategory = selectedCategoryIds.length === 0 || job.jobCategories.some(cat => selectedCategoryIds.includes(cat));
188        const matchesSelectedAudience = selectedAudienceIds.length === 0 || job.audiences.some(aud => selectedAudienceIds.includes(aud));
189
190        // Update job categories if target group filter is selected or empty
191        if (matchesSelectedAudience) {
192            job.jobCategories.forEach(categoryId => {
193                if (categoryCounts[categoryId] !== undefined) {
194                    categoryCounts[categoryId]++;
195                }
196            });
197        }
198
199        // Update target groups if job category filter is selected or empty
200        if (matchesSelectedCategory) {
201            job.audiences.forEach(audienceId => {
202                if (audienceCounts[audienceId] !== undefined) {
203                    audienceCounts[audienceId]++;
204                }
205            });
206        }
207    });
208
209    // Update counts for categories and disable checkboxes if count is 0
210    Object.keys(categoryCounts).forEach(categoryId => {
211        const countElement = document.querySelector(`#${CSS.escape(categoryId)} + label .count`);
212        const checkbox = document.querySelector(`#${CSS.escape(categoryId)}`);
213
214        if (countElement) {
215            countElement.textContent = categoryCounts[categoryId];
216
217            if (categoryCounts[categoryId] === 0) {
218                // Disable the checkbox and apply 'disabled' style if count is 0
219                checkbox.disabled = true;
220                checkbox.parentElement.classList.add('disabled');
221            } else {
222                // Enable checkbox and remove 'disabled' style if count is greater than 0
223                checkbox.disabled = false;
224                checkbox.parentElement.classList.remove('disabled');
225            }
226        }
227    });
228
229    // Update counts for audiences and disable checkboxes if count is 0
230    Object.keys(audienceCounts).forEach(audienceId => {
231        const countElement = document.querySelector(`#${CSS.escape(audienceId)} + label .count`);
232        const checkbox = document.querySelector(`#${CSS.escape(audienceId)}`);
233
234        if (countElement) {
235            countElement.textContent = audienceCounts[audienceId];
236
237            if (audienceCounts[audienceId] === 0) {
238                // Disable the checkbox and apply 'disabled' style if count is 0
239                checkbox.disabled = true;
240                checkbox.parentElement.classList.add('disabled');
241            } else {
242                // Enable checkbox and remove 'disabled' style if count is greater than 0
243                checkbox.disabled = false;
244                checkbox.parentElement.classList.remove('disabled');
245            }
246        }
247    });
248}
249
250function initializeCounts() {
251    const categoryCounts = {};
252    const audienceCounts = {};
253
254    // Count job categories
255    const categoryCheckboxes = document.querySelectorAll('.categoryCheckbox');
256    categoryCheckboxes.forEach(checkbox => {
257        const categoryId = checkbox.value;
258        categoryCounts[categoryId] = 0; // Initialize the counter
259    });
260
261    // Count target groups
262    const audienceCheckboxes = document.querySelectorAll('.audienceCheckbox');
263    audienceCheckboxes.forEach(checkbox => {
264        const audienceId = checkbox.value;
265        audienceCounts[audienceId] = 0; // Initialize the counter
266    });
267
268    return {categoryCounts, audienceCounts};
269}
270
271function formatDate(timestamp) {
272    const date = new Date(timestamp);
273
274    const day = String(date.getDate()).padStart(2, '0');
275    const month = String(date.getMonth() + 1).padStart(2, '0');
276    const year = String(date.getFullYear()).slice(-2);
277
278    return `${day}.${month}.${year}`;
279}
280
281function updatePagination(categories) {
282    const paginationContainer = document.getElementById('pagination-container');
283
284    // Überprüfung: Wenn keine Jobs vorhanden sind, verstecken Sie das Pagination-Element
285    if (filteredJobs.length === 0) {
286        paginationContainer.style.display = 'none';
287        return;
288    } else {
289        paginationContainer.style.display = 'flex';
290    }
291
292    paginationContainer.innerHTML = '';
293
294    const totalPages = Math.ceil(filteredJobs.length / itemsPerPage);
295
296    // Prev arrow button
297    const prevButton = document.createElement('button');
298    prevButton.classList.add('pagination-arrow', 'prev-button', 'pagination-button');
299    prevButton.innerHTML = '<i class="icon icon-arrow-left"></i>';
300    if (currentPage > 1) {
301        prevButton.onclick = function () {
302            currentPage--;
303            updateJobListView(categories);
304        };
305    } else {
306        prevButton.disabled = true;
307        prevButton.classList.add('disabled');
308    }
309    paginationContainer.appendChild(prevButton);
310
311    // Pagenumbers
312    for (let i = 1; i <= totalPages; i++) {
313        const pageButton = document.createElement('button');
314        pageButton.textContent = i;
315        pageButton.classList.add('pagination-button');
316        pageButton.onclick = function () {
317            currentPage = i;
318            updateJobListView(categories);
319        };
320
321        if (i === currentPage) {
322            pageButton.classList.add('active');
323        }
324
325        paginationContainer.appendChild(pageButton);
326    }
327
328    // Next arrow button
329    const nextButton = document.createElement('button');
330    nextButton.classList.add('pagination-arrow', 'next-button', 'pagination-button');
331    nextButton.innerHTML = '<i class="icon icon-arrow-right"></i>';
332    if (currentPage < totalPages) {
333        nextButton.onclick = function () {
334            currentPage++;
335            updateJobListView(categories);
336        };
337    } else {
338        nextButton.disabled = true;
339        nextButton.classList.add('disabled');
340    }
341    paginationContainer.appendChild(nextButton);
342}
343
344
345document.addEventListener('DOMContentLoaded', function () {
346    const checkboxes = document.querySelectorAll('.job-filter .select-options-container input[type="checkbox"]');
347
348    checkboxes.forEach(checkbox => {
349        checkbox.addEventListener('change', handleSelectionOnChange());
350    });
351    // Direct call of handleSelectionOnChange() on page request
352    handleSelectionOnChange()();
353});
354
355
356
357

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.