Widget:SearchBox: Unterschied zwischen den Versionen

Aus MediaWiki
Wechseln zu:Navigation, Suche
Die Seite wurde neu angelegt: „<includeonly> <div id="api-search-widget"> <form id="api-search-form"> <input type="text" id="api-search-input" placeholder="Suche…" /> <button type="submit">Suchen</button> </form> <div id="api-search-results"></div> </div> <style> #api-search-widget { max-width: 600px; } #api-search-form { display: flex; gap: 8px; margin-bottom: 12px; } #api-search-input { flex: 1; padding: 8px; font-size: 14px; border: 1px solid #a2a9b1…“
 
Keine Bearbeitungszusammenfassung
 
(2 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt)
Zeile 10: Zeile 10:
<style>
<style>
#api-search-widget {
#api-search-widget {
   max-width: 600px;
   max-width: 720px;
  font-family: -apple-system, "system-ui", "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  color: #212529;
}
}
#api-search-form {
#api-search-form {
   display: flex;
   display: flex;
   gap: 8px;
   gap: 0;
   margin-bottom: 12px;
   margin-bottom: 16px;
}
}
#api-search-input {
#api-search-input {
   flex: 1;
   flex: 1;
   padding: 8px;
   padding: 10px 14px;
   font-size: 14px;
   font-size: 16px;
   border: 1px solid #a2a9b1;
   border: 2px solid #a2a9b1;
   border-radius: 2px;
  border-right: none;
   border-radius: 4px 0 0 4px;
  outline: none;
  transition: border-color 0.2s;
  color: #212529;
  background: #fff;
}
#api-search-input:focus {
  border-color: #355B84;
}
}
#api-search-form button {
#api-search-form button {
   padding: 8px 16px;
   padding: 10px 20px;
   font-size: 14px;
  font-size: 16px;
   font-weight: 500;
   cursor: pointer;
   cursor: pointer;
  background: #355B84;
  color: #fff;
  border: 2px solid #355B84;
  border-radius: 0 4px 4px 0;
  transition: background 0.2s;
}
#api-search-form button:hover {
  background: #2a4a6b;
  border-color: #2a4a6b;
}
}
#api-search-results {
#api-search-results {
   white-space: pre-wrap;
   display: none;
   font-family: monospace;
}
#api-search-results.visible {
  display: block;
}
.search-status {
  padding: 16px;
  text-align: center;
  color: #555;
   font-size: 15px;
}
.search-status.error {
  color: #a00;
  background: #fef2f2;
  border: 1px solid #fca5a5;
  border-radius: 4px;
}
@keyframes pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.5; }
}
.search-loading {
  animation: pulse 1.5s ease-in-out infinite;
}
.search-result-card {
  padding: 16px;
  margin-bottom: 12px;
  border: 1px solid #dee2e6;
  border-radius: 4px;
  background: #fff;
  transition: box-shadow 0.15s;
}
.search-result-card:hover {
  box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}
.search-result-card h4 {
  margin: 0 0 6px 0;
  font-size: 17px;
  font-weight: 500;
}
.search-result-card h4 a {
  color: #1B599B;
  text-decoration: none;
}
.search-result-card h4 a:hover {
  text-decoration: underline;
}
.search-result-snippet {
  font-size: 14px;
  line-height: 1.5;
  color: #333;
  margin-bottom: 8px;
}
.search-result-meta {
  display: flex;
  gap: 12px;
  font-size: 12px;
  color: #6c757d;
}
.search-result-meta span {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}
.search-score-bar {
  display: inline-block;
  width: 40px;
  height: 6px;
  background: #dee2e6;
  border-radius: 3px;
  overflow: hidden;
  vertical-align: middle;
}
.search-score-fill {
  height: 100%;
  background: #355B84;
  border-radius: 3px;
}
.search-result-count {
   font-size: 13px;
   font-size: 13px;
   background: #f8f9fa;
   color: #6c757d;
   padding: 12px;
   margin-bottom: 12px;
  border: 1px solid #eaecf0;
  border-radius: 2px;
  display: none;
}
}
</style>
</style>
Zeile 47: Zeile 141:
   var results = document.getElementById('api-search-results');
   var results = document.getElementById('api-search-results');
   var apiHost = 'api.' + location.hostname.split('.').slice(1).join('.');
   var apiHost = 'api.' + location.hostname.split('.').slice(1).join('.');
  function escapeHtml(str) {
    var d = document.createElement('div');
    d.textContent = str;
    return d.innerHTML;
  }
  function truncate(str, len) {
    if (str.length <= len) return str;
    return str.substring(0, len).replace(/\s+\S*$/, '') + '…';
  }
  function renderResults(data) {
    if (!data.results || data.results.length === 0) {
      results.innerHTML = '<div class="search-status">Keine Ergebnisse gefunden.</div>';
      return;
    }
    var html = '<div class="search-result-count">' + data.results.length + ' Ergebnis' + (data.results.length !== 1 ? 'se' : '') + '</div>';
    data.results.forEach(function(r) {
      if (typeof r === 'string') {
        html += '<div class="search-result-card">'
          + '<div class="search-result-snippet">' + escapeHtml(r) + '</div>'
          + '</div>';
      } else {
        var pct = Math.round((r.similarity_score || 0) * 100);
        var wikiUrl = '/wiki/' + encodeURIComponent((r.page_title || '').replace(/ /g, '_'));
        html += '<div class="search-result-card">'
          + '<h4><a href="' + wikiUrl + '">' + escapeHtml(r.page_title || 'Ohne Titel') + '</a></h4>'
          + '<div class="search-result-snippet">' + escapeHtml(truncate(r.content_text || '', 250)) + '</div>'
          + '<div class="search-result-meta">'
          + '<span>Relevanz: <span class="search-score-bar"><span class="search-score-fill" style="width:' + pct + '%"></span></span> ' + pct + '%</span>'
          + (r.source ? '<span>Quelle: ' + escapeHtml(r.source) + '</span>' : '')
          + '</div></div>';
      }
    });
    results.innerHTML = html;
  }


   form.addEventListener('submit', function(e) {
   form.addEventListener('submit', function(e) {
Zeile 53: Zeile 184:
     if (!query) return;
     if (!query) return;


     results.style.display = 'block';
     results.className = 'visible';
     results.textContent = 'Laden…';
     results.innerHTML = '<div class="search-status search-loading">Suche läuft…</div>';


     var url = location.protocol + '//' + apiHost + '/search?query=' + encodeURIComponent(query);
     var url = location.protocol + '//' + apiHost + '/search?q=' + encodeURIComponent(query);


     fetch(url)
     fetch(url)
Zeile 64: Zeile 195:
       })
       })
       .then(function(data) {
       .then(function(data) {
         results.textContent = JSON.stringify(data, null, 2);
         renderResults(data);
       })
       })
       .catch(function(err) {
       .catch(function(err) {
         results.textContent = 'Fehler: ' + err.message;
         results.innerHTML = '<div class="search-status error">Fehler: ' + escapeHtml(err.message) + '</div>';
       });
       });
   });
   });

Aktuelle Version vom 6. März 2026, 12:40 Uhr