קוד ל- treeview ב- html כולל חיפוש
-
קוד ל- treeview ב- html כולל חיפוש - אשמח לקבל משוב - תודה
עריכה: עשיתי המון שיפורים מצו"ב דוגמא מליאה.
בגירסה זו ה-treeview נוצר באופן דינאמי לפי הכותרות שבמסמך
(נחסם לי משום מה בנטפרי ה-jsfiddle שלו תוכלו להעתיק את הקוד לכאן כדי לראות את התוצאה).<!DOCTYPE html> <html lang="he"> <head> <meta charset="UTF-8"> <style> html, body { height: 100%; margin: 0; padding: 0; } .container { display: flex; height: 100%; } .textContentBox { background-color: white; flex: 1; height: 100%; margin: 5px; padding: 5px; overflow-y: auto; } .treeView-container { -webkit-touch-callout: none; /* iOS Safari */ -webkit-user-select: none; /* Safari */ -khtml-user-select: none; /* Konqueror HTML */ -moz-user-select: none; /* Firefox */ -ms-user-select: none; /* Internet Explorer/Edge */ user-select: none; /* Non-prefixed version, currently supported by Chrome and Opera */ max-width: 35%; background-color: whitesmoke; display: flex; flex-direction: column; margin: 5px; padding: 5px; height: 100%; } #treeView-SearchInput { height:25px; border: 1px solid #ccc; } #treeView-SearchInput:focus { outline: none; } .treeView { height:100%; overflow: auto; margin-top: 5px; white-space: nowrap; text-indent: -40px; } .treeView details { border-top: 1px solid #eaeaea; border-bottom: 1px solid #eaeaea; } .treeView summary::-webkit-details-marker { display: none; } .treeView summary { transition: background-color 0.3s ease; list-style: none; } .treeView summary:hover { background-color: #eaeaea; } .treeView Button { background: none; border: none; cursor: pointer; font-weight: 500; margin: 5px; transition: background-color 0.3s ease; border-radius: 50px; } .treeView button:hover { background-color: #eaeaea; } </style> </head> <body dir="rtl"> <div class="container"> <div class="treeView-container"> <input type="text" id="treeView-SearchInput" onkeyup="findAndSelectItem()" placeholder="חפש כותרת..."> <div class="treeView" id="treeView"> </div> </div> <div class="textContentBox" id="contentBox"> <h2 id="בעל הטורים בראשית המאור, פרק א">פרק א</h2> <h3 id="בעל הטורים בראשית המאור, פרק א, פסוק א">פסוק א</h3> בראשית ברא. בגימטריא בראש השנה נברא (העולם), בראשית נוטריקון בראשונה ראה אלהים שיקבלו ישראל תורה.<p> בראשית ברא אלהים ס''ת אמת מלמד שברא העולם באמת כמו שנאמר ראש דברך אמת וכן יש הרבה פסוקים ס''ת אמת:<p> <h3 id="בעל הטורים בראשית המאור, פרק א, פסוק ב">פסוק ב</h3> "תֹהוּ וָבֹהוּ" – ב'. הכא, ואידך: "רָאִיתִי אֶת הָאָרֶץ וְהִנֵּה תֹהוּ וָבֹהוּ" (ירמיהו ד כג). מלמד שצפה הקב"ה בבריאת העולם בחורבן הבית, שנחרב בשנת תה"ו, שהרי הבית הראשון עמד ת"י שנה, ונחרב בשנת תי"א. ובית שני עמד כמנין הית"ה, וזהו "וְהָאָרֶץ הָיְתָה". ואחר כך "חֹשֶׁךְ", רמז לגלויות. וכן דורש בבראשית רבה. דבר אחר: "וְהָאָרֶץ הָיְתָה תֹהוּ וָבֹהוּ" – בגימטריא "אלפים שנה בלי תורה".<p> "וְרוּחַ אֱלֹהִים מְרַחֶפֶת" – בגימטריא: "זו היא רוחו של מלך המשיח".<p> "וְחֹשֶׁךְ עַל פְּנֵי תְהוֹם" – ב' במסורת. הכא, ואידך: "וְחֹשֶׁךְ אֵי זֶה מְקֹמוֹ" (איוב לח יט). זה הוא שאמרו (חגיגה יא ב), שאין לשאול: "מה לפנים? מה לאחור?" "וְחֹשֶׁךְ אֵי זֶה מְקֹמוֹ", פירוש, שאין לשאול אי זה היה מקום החושך תחילה.<p> "וְרוּחַ אֱלֹהִים" – ב' דסמיכי. הכא, ואידך: "וְרוּחַ אֱלֹהִים לָבְשָׁה אֶת זְכַרְיָה" (דברי הימים ב כד כ). קרי ביה הכא נמי: "וְרוּחַ אֱלֹהִים לָבְשָׁה". פירוש, שעל ידי לבושו אמר "וַיְהִי אוֹר", דכתיב בתריה: "וַיֹּאמֶר אֱלֹהִים יְהִי אוֹר". וזה הוא שדרשו רז"ל (ב"ר פרשה ג): ממעטה לבושו נבראת האורה.<p> <h2 id="בעל הטורים בראשית המאור, פרק לח">פרק לח</h2> <h3 id="בעל הטורים בראשית המאור, פרק לח, פסוק טו">פסוק טו</h3> פרק לח, טו <p> ויחשבה. ג' במסורה. הכא. ואידך: בפרשת לך לך (לעיל טו, ו) ויחשבה לו צדקה. ואידך: ויחשבה עלי לשכורה (ש"א א, יג): <p> לזונה. ב' במסורה. ויחשבה לזונה. איכה היתה לזונה (ישעיה א, כא). מה תמר בבזיון ולבסוף בכבוד אף ירושלים סופה בכבוד, כדכתיב (זכריה ב, ט) ולכבוד אהיה בתוכה. וזהו זאת קומתך דמתה לתמר (שה"ש ז, ח).<p> <h2 id="בעל הטורים בראשית המאור, פרק מד">פרק מד</h2> <h3 id="בעל הטורים בראשית המאור, פרק מד, פסוק יח">פסוק יח</h3> ויגש אליו יהודה: ס"ת שוא. שאמר לו אני שוה לך שכמו שאתה מלך גם אני מלך. ועל זה דורש במדרש (ברשית רבה צ"נ:ב') כי הנה המלכים נועדו (תהילים מ"ח:ה'):<p> <h2 id="בעל הטורים בראשית המאור, פרק מט">פרק מט</h2> <h3 id="בעל הטורים בראשית המאור, פרק מט, פסוק א">פסוק א</h3> ויקרא יעקב אל בניו: שביקש לגלות להם הקץ ונסתם ממנו (פסחים נו.). אמר יעקב שמא יש בכם חטא. אמרו לו תדקדק בשמותנו ולא תמצא בהם אותיות חט. ואמר להם קם אין בהם אותיות קץ (עיין ירושלמי יומא ס״פ ז׳, בבלי שם עג:).<p> </div> </div> <script> function populateTreeView() { const contentBox = document.getElementById('contentBox'); const treeView = document.getElementById('treeView'); let currentDetails = treeView; let currentIndentLevel = 0; // Loop through each heading element in contentBox contentBox.querySelectorAll('h1, h2, h3, h4, h5, h6').forEach(heading => { const indentLevel = parseInt(heading.tagName[1]); // If the current heading has a lower or equal indent level to the previous one, // we need to move up the tree to the appropriate parent details element while (currentIndentLevel >= indentLevel) { currentDetails = currentDetails.parentElement; currentIndentLevel--; } // Create a new details and summary elements const details = document.createElement('details'); const summary = document.createElement('summary'); const button = document.createElement('button'); summary.style.paddingRight = 20 * indentLevel + 'px'; button.textContent = '👁'; button.setAttribute('onclick', `treeViewSelection('${heading.id}')`); button.setAttribute('title', 'הצג'); summary.appendChild(button); summary.appendChild(document.createTextNode(heading.textContent)); details.appendChild(summary); // Append the new details element to the currentDetails currentDetails.appendChild(details); // Update the currentDetails and currentIndentLevel for the next iteration currentDetails = details; currentIndentLevel = indentLevel; }); } function treeViewSelection(id) { // Scroll the corresponding heading into view const heading = document.getElementById(id); if (heading) { heading.scrollIntoView({ behavior: 'smooth', block: 'start' }); } } // Populate the tree view on page load window.onload = populateTreeView; // //treeView-Search // function findAndSelectItem() { var input = document.getElementById("treeView-SearchInput"); var filter = input.value.trim().toUpperCase().replace(/,/g, ''); var details = document.querySelectorAll("details"); var firstMatchFound = false; // Collapse all details if filter is empty if (filter === "") { for (var i = 0; i < details.length; i++) { details[i].open = false; var summary = details[i].querySelector("summary"); details[i].style.display = ""; } return; // Exit function } for (var i = 0; i < details.length; i++) { var summary = details[i].querySelector("summary"); if (summary) { var parentPath = getParentText(details[i]).replace(/👁/g, '').toUpperCase(); var summaryPath = summary.textContent.replace(/👁/g, '').trim().toUpperCase(); var fullPath = parentPath + " " + summaryPath; // Highlight matching summaries if (fullPath.includes(filter)) { details[i].open = true; details[i].style.display = ""; if (!firstMatchFound) { summary.scrollIntoView({ behavior: 'smooth', block: 'center' }); firstMatchFound = true; } // Open parent details elements recursively var parentDetails = details[i].parentNode; while (parentDetails.tagName === 'DETAILS') { parentDetails.open = true; parentDetails.style.display = ""; parentDetails = parentDetails.parentNode; } } else { details[i].open = false; details[i].style.display = "none"; } } } } function getParentText(element) { var text = ""; var parent = element.parentNode; while (parent && parent.tagName.toLowerCase() === 'details') { var summary = parent.querySelector("summary"); if (summary) { text = summary.textContent.trim() + " " + text; } parent = parent.parentNode; } return text.trim(); } </script> </body> </html>
-
דוגמא נוספת כאן העץ מוסתר ואפשר לגשת אליו על ידי הצמדת העכבר לצד ימין של המסך.
<!DOCTYPE html> <html lang="he"> <head> <meta charset="UTF-8"> <style> html, body { height: 100%; margin: 0; padding: 0; background-color: whitesmoke; } .container { display: flex; height: 100%; } .textContentBox { background-color: white; flex: 1; height: 100%; padding: 10px; overflow-y: auto; } .treeView-container { display: flex; flex-direction: column; height: 100%; transition: 0.5s; max-width:0.5%; -webkit-touch-callout: none; /* iOS Safari */ -webkit-user-select: none; /* Safari */ -khtml-user-select: none; /* Konqueror HTML */ -moz-user-select: none; /* Firefox */ -ms-user-select: none; /* Internet Explorer/Edge */ user-select: none; /* Non-prefixed version, currently supported by Chrome and Opera */ } #treeView-SearchInput { margin: 10px; height:25px; border: 1px solid #ccc; } #treeView-SearchInput:focus { outline: none; } .treeView { height:100%; overflow: auto; margin-top: 5px; white-space: nowrap; text-indent: -40px; } .treeView details { border-top: 1px solid #eaeaea; border-bottom: 1px solid #eaeaea; } .treeView summary::-webkit-details-marker { display: none; } .treeView summary { transition: background-color 0.3s ease; list-style: none; } .treeView summary:hover { background-color: #eaeaea; } .treeView Button { background: none; border: none; cursor: pointer; font-weight: 500; margin: 5px; transition: background-color 0.3s ease; border-radius: 50px; } .treeView button:hover { background-color: #eaeaea; } </style> </head> <body dir="rtl"> <div class="container"> <div id="treeView-container" class="treeView-container" onmouseover="toggleTreeViewWidth()" onmouseout="toggleTreeViewWidth()"> <input type="text" id="treeView-SearchInput" onkeyup="findAndSelectItem()" placeholder="חפש כותרת..."> <div class="treeView" id="treeView"> </div> </div> <div class="textContentBox" id="contentBox"> <h2 id="בעל הטורים בראשית המאור, פרק א">פרק א</h2> <h3 id="בעל הטורים בראשית המאור, פרק א, פסוק א">פסוק א</h3> בראשית ברא. בגימטריא בראש השנה נברא (העולם), בראשית נוטריקון בראשונה ראה אלהים שיקבלו ישראל תורה.<p> בראשית ברא אלהים ס''ת אמת מלמד שברא העולם באמת כמו שנאמר ראש דברך אמת וכן יש הרבה פסוקים ס''ת אמת:<p> <h3 id="בעל הטורים בראשית המאור, פרק א, פסוק ב">פסוק ב</h3> "תֹהוּ וָבֹהוּ" – ב'. הכא, ואידך: "רָאִיתִי אֶת הָאָרֶץ וְהִנֵּה תֹהוּ וָבֹהוּ" (ירמיהו ד כג). מלמד שצפה הקב"ה בבריאת העולם בחורבן הבית, שנחרב בשנת תה"ו, שהרי הבית הראשון עמד ת"י שנה, ונחרב בשנת תי"א. ובית שני עמד כמנין הית"ה, וזהו "וְהָאָרֶץ הָיְתָה". ואחר כך "חֹשֶׁךְ", רמז לגלויות. וכן דורש בבראשית רבה. דבר אחר: "וְהָאָרֶץ הָיְתָה תֹהוּ וָבֹהוּ" – בגימטריא "אלפים שנה בלי תורה".<p> "וְרוּחַ אֱלֹהִים מְרַחֶפֶת" – בגימטריא: "זו היא רוחו של מלך המשיח".<p> "וְחֹשֶׁךְ עַל פְּנֵי תְהוֹם" – ב' במסורת. הכא, ואידך: "וְחֹשֶׁךְ אֵי זֶה מְקֹמוֹ" (איוב לח יט). זה הוא שאמרו (חגיגה יא ב), שאין לשאול: "מה לפנים? מה לאחור?" "וְחֹשֶׁךְ אֵי זֶה מְקֹמוֹ", פירוש, שאין לשאול אי זה היה מקום החושך תחילה.<p> "וְרוּחַ אֱלֹהִים" – ב' דסמיכי. הכא, ואידך: "וְרוּחַ אֱלֹהִים לָבְשָׁה אֶת זְכַרְיָה" (דברי הימים ב כד כ). קרי ביה הכא נמי: "וְרוּחַ אֱלֹהִים לָבְשָׁה". פירוש, שעל ידי לבושו אמר "וַיְהִי אוֹר", דכתיב בתריה: "וַיֹּאמֶר אֱלֹהִים יְהִי אוֹר". וזה הוא שדרשו רז"ל (ב"ר פרשה ג): ממעטה לבושו נבראת האורה.<p> <h2 id="בעל הטורים בראשית המאור, פרק לח">פרק לח</h2> <h3 id="בעל הטורים בראשית המאור, פרק לח, פסוק טו">פסוק טו</h3> פרק לח, טו <p> ויחשבה. ג' במסורה. הכא. ואידך: בפרשת לך לך (לעיל טו, ו) ויחשבה לו צדקה. ואידך: ויחשבה עלי לשכורה (ש"א א, יג): <p> לזונה. ב' במסורה. ויחשבה לזונה. איכה היתה לזונה (ישעיה א, כא). מה תמר בבזיון ולבסוף בכבוד אף ירושלים סופה בכבוד, כדכתיב (זכריה ב, ט) ולכבוד אהיה בתוכה. וזהו זאת קומתך דמתה לתמר (שה"ש ז, ח).<p> <h2 id="בעל הטורים בראשית המאור, פרק מד">פרק מד</h2> <h3 id="בעל הטורים בראשית המאור, פרק מד, פסוק יח">פסוק יח</h3> ויגש אליו יהודה: ס"ת שוא. שאמר לו אני שוה לך שכמו שאתה מלך גם אני מלך. ועל זה דורש במדרש (ברשית רבה צ"נ:ב') כי הנה המלכים נועדו (תהילים מ"ח:ה'):<p> <h2 id="בעל הטורים בראשית המאור, פרק מט">פרק מט</h2> <h3 id="בעל הטורים בראשית המאור, פרק מט, פסוק א">פסוק א</h3> ויקרא יעקב אל בניו: שביקש לגלות להם הקץ ונסתם ממנו (פסחים נו.). אמר יעקב שמא יש בכם חטא. אמרו לו תדקדק בשמותנו ולא תמצא בהם אותיות חט. ואמר להם קם אין בהם אותיות קץ (עיין ירושלמי יומא ס״פ ז׳, בבלי שם עג:).<p> </div> </div> <script> function populateTreeView() { const contentBox = document.getElementById('contentBox'); const treeView = document.getElementById('treeView'); let currentDetails = treeView; let currentIndentLevel = 0; // Loop through each heading element in contentBox contentBox.querySelectorAll('h1, h2, h3, h4, h5, h6').forEach(heading => { const indentLevel = parseInt(heading.tagName[1]); // If the current heading has a lower or equal indent level to the previous one, // we need to move up the tree to the appropriate parent details element while (currentIndentLevel >= indentLevel) { currentDetails = currentDetails.parentElement; currentIndentLevel--; } // Create a new details and summary elements const details = document.createElement('details'); const summary = document.createElement('summary'); const button = document.createElement('button'); summary.style.paddingRight = 20 * indentLevel + 'px'; button.textContent = '👁'; button.setAttribute('onclick', `treeViewSelection('${heading.id}')`); button.setAttribute('title', 'הצג'); summary.appendChild(button); summary.appendChild(document.createTextNode(heading.textContent)); details.appendChild(summary); // Append the new details element to the currentDetails currentDetails.appendChild(details); // Update the currentDetails and currentIndentLevel for the next iteration currentDetails = details; currentIndentLevel = indentLevel; }); } function treeViewSelection(id) { // Scroll the corresponding heading into view const heading = document.getElementById(id); if (heading) { heading.scrollIntoView({ behavior: 'smooth', block: 'start' }); } } // Populate the tree view on page load window.onload = populateTreeView; // //treeView-Search // function findAndSelectItem() { var input = document.getElementById("treeView-SearchInput"); var filter = input.value.trim().toUpperCase().replace(/,/g, ''); var details = document.querySelectorAll("details"); var firstMatchFound = false; // Collapse all details if filter is empty if (filter === "") { for (var i = 0; i < details.length; i++) { details[i].open = false; var summary = details[i].querySelector("summary"); details[i].style.display = ""; } return; // Exit function } for (var i = 0; i < details.length; i++) { var summary = details[i].querySelector("summary"); if (summary) { var parentPath = getParentText(details[i]).replace(/👁/g, '').toUpperCase(); var summaryPath = summary.textContent.replace(/👁/g, '').trim().toUpperCase(); var fullPath = parentPath + " " + summaryPath; // Highlight matching summaries if (fullPath.includes(filter)) { details[i].open = true; details[i].style.display = ""; if (!firstMatchFound) { summary.scrollIntoView({ behavior: 'smooth', block: 'center' }); firstMatchFound = true; } // Open parent details elements recursively var parentDetails = details[i].parentNode; while (parentDetails.tagName === 'DETAILS') { parentDetails.open = true; parentDetails.style.display = ""; parentDetails = parentDetails.parentNode; } } else { details[i].open = false; details[i].style.display = "none"; } } } } function getParentText(element) { var text = ""; var parent = element.parentNode; while (parent && parent.tagName.toLowerCase() === 'details') { var summary = parent.querySelector("summary"); if (summary) { text = summary.textContent.trim() + " " + text; } parent = parent.parentNode; } return text.trim(); } function toggleTreeViewWidth() { var element = document.getElementById("treeView-container"); if (!element) { alert("Element with ID 'treeView-container' not found."); return; // Exit the function if element is not found } if (element.style.maxWidth === "35%") { element.style.maxWidth = "0.5%" } else { element.style.maxWidth = "35%"; } } </script> </body> </html>