1// This file handles the actual search request to the server, processing user input, and updating the UI with search results. 2 3let cursorHistory = []; 4let currentCursorIndex = -1; 5 6function handleSearch(cursor = "*", sortBy = null) { 7 const expandedSearch = document.getElementById("enable-expanded-search").checked; 8 const typeFilters = Array.from(document.querySelectorAll('#search-filters input[name="filter"]:checked')) 9 .map((checkbox) => `type:${checkbox.value}`) 10 .filter((f) => f !== "type:all"); 11 const otherFilters = []; 12 13 const formData = new URLSearchParams(); 14 formData.append("action", "crossref_search"); 15 formData.append("cursor", cursor); 16 formData.append("expanded_search", expandedSearch); 17 formData.append("security", crossrefSearch.security); 18 19 // Always construct query_bibliographic from default fields 20 const title = document.getElementById("cr-search-title").value; 21 const author = document.getElementById("cr-search-author").value; 22 const containerTitle = document.getElementById("cr-search-container-title").value; 23 const publishDate = document.getElementById("cr-search-publish-date").value; 24 const doi = document.getElementById("cr-search-doi").value; 25 const issn = document.getElementById("cr-search-issn").value; 26 const isbn = document.getElementById("cr-search-isbn").value; 27 const keywords = document.getElementById("cr-search-keywords").value; 28 const queryBibliographic = 29 `${title} ${author} ${containerTitle} ${publishDate} ${doi} ${issn} ${isbn} ${keywords}`.trim(); 30 formData.append("query_bibliographic", queryBibliographic); 31 32 if (expandedSearch) { 33 const subject = document.getElementById("cr-search-subject").value; 34 if (subject) formData.append("query", subject); 35 36 // Add additional specific parameters 37 const affiliation = document.getElementById("cr-search-affiliation").value; 38 if (affiliation) formData.append("query.affiliation", affiliation); 39 40 const orcid = document.getElementById("cr-search-orcid").value; 41 if (orcid) otherFilters.push(`orcid:${orcid}`); 42 43 const funder = document.getElementById("cr-search-funder").value; 44 if (funder) otherFilters.push(`funder.name:${funder}`); 45 46 const award = document.getElementById("cr-search-award").value; 47 if (award) otherFilters.push(`award.number:${award}`); 48 49 const relationType = document.getElementById("cr-search-relation").value; 50 const relationDoi = document.getElementById("cr-search-relation-doi").value; 51 if (relationType && relationDoi) { 52 otherFilters.push(`relation.type:${relationType}`); 53 otherFilters.push(`relation.object:${relationDoi}`); 54 } 55 56 const startDate = document.getElementById("start-date").value; 57 const endDate = document.getElementById("end-date").value; 58 if (startDate) otherFilters.push(`from-pub-date:${startDate}`); 59 if (endDate) otherFilters.push(`until-pub-date:${endDate}`); 60 } 61 62 const allFilters = [...typeFilters, ...otherFilters]; 63 if (allFilters.length > 0) { 64 formData.append("filter", allFilters.join(",")); 65 } 66 67 if (sortBy && sortBy !== "relevance") { 68 formData.append("sort_by", sortBy); 69 } 70 71 // Hide instructions and display loading spinner 72 document.getElementById("instructions").style.display = "none"; 73 displayLoading(); 74 75 fetch(crossrefSearch.ajaxurl, { 76 method: "POST", 77 headers: { 78 "Content-Type": "application/x-www-form-urlencoded", 79 }, 80 body: formData.toString(), 81 }) 82 .then((response) => response.json()) 83 .then((data) => { 84 removeLoading(); // Remove loading animation 85 if (data.success) { 86 const items = data.data.message.items; 87 const totalResults = data.data.message["total-results"]; 88 const nextCursor = data.data.message["next-cursor"]; 89 90 // Update cursor history 91 if (currentCursorIndex === -1 || cursorHistory[currentCursorIndex] !== cursor) { 92 cursorHistory = cursorHistory.slice(0, currentCursorIndex + 1); 93 cursorHistory.push(cursor); 94 currentCursorIndex++; 95 } 96 97 renderSearchResults(items); 98 99 // Render the results info 100 document.getElementById("results-info").innerHTML = `
101 <div id="sort-options"> 102 <span class="sort-link ${sortBy === "relevance" ? "selected" : ""}" id="sort-relevance">RELEVANCE</span> | 103 <span class="sort-link ${sortBy === "published" ? "selected" : ""}" id="sort-publication">MOST RECENT</span> 104 </div> 105 <div id="results-count">Total results: ${totalResults}</div> 106 `; 107 108 document.getElementById("sort-options").style.display = "block"; // Show sort options 109 document.getElementById("sort-relevance").addEventListener("click", () => handleSearch(cursor, "relevance")); 110 document.getElementById("sort-publication").addEventListener("click", () => handleSearch(cursor, "published")); 111 112 renderPagination(nextCursor); 113 } else { 114 displayError(data.data.message || "An error occurred. Please try again later."); 115 } 116 }) 117 .catch((error) => { 118 removeLoading(); // Remove loading animation 119 console.error("Error:", error); 120 displayError("Request timed out. Please try again later."); 121 }); 122}
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.