1, review
In the jQuery version, we have developed the homepage search function and news recommendation function. The next step is to improve the search function. The original search function only contains fuzzy queries, so we need to add two more search modes: Full-text index and custom word segmentation query, which is divided into TFIDF and Bayes query, also need to provide the lift sort option, of course, we also need to develop the page function, OK, next to do ~
2. Improve the home page
1. Develop search options
Open index.html, put the code for the search options between the search box and the search results, and set some options to be selected by default. Our default search mode is switched to a custom query. The sort field is TFIDF, so put checked properties on them
<! -- Search options Settings -->
<div class="search-options">
<span>Search mode:</span>
<label for="fuzzy">
<input type="radio" name="searchMode" id="fuzzy" value="fuzzy">Fuzzy query</label>
<label for="fulltext">
<input type="radio" name="searchMode" id="fulltext" value="fulltext">The full text indexing</label>
<label for="custom">
<input type="radio" name="searchMode" id="custom" value="custom" checked>Custom query</label>
</div>
<div class="search-options">
<span>Sort field:</span>
<label for="tfidf">
<input type="radio" name="orderBy" id="tfidf" value="tfidf" checked>tfidf
</label>
<label for="bayes">
<input type="radio" name="orderBy" id="bayes" value="bayes">bayes
</label>
</div>
<div class="search-options">
<span>Search results sorted by:</span>
<label for="asc">
<input type="radio" name="order" id="asc" value="asc">ascending</label>
<label for="desc">
<input type="radio" name="order" id="desc" value="desc" checked>Descending order</label>
</div>
Copy the code
Corresponding styles:
.search-options {
padding: 0 15px;
margin-bottom: 5px;
font-size: 14px;
}
Copy the code
Effect:
Note that the value of the name attribute for the same set of options must be set to the same value
Then start writing js, first getting the value of the selected option
// Get the search options
let searchMode = $('input[name="searchMode"]:checked').val()
let orderBy = $('input[name="orderBy"]:checked').val()
let order = $('input[name="order"]:checked').val()
Copy the code
Then we have to switch the URL according to the search mode, and if else is less elegant and less extensible, so we use the object:
// Background interface path
let searchUrl = {
// Fuzzy query
fuzzy: 'http://localhost:8080/demo/article-fuzzy'.// Full-text index
fulltext: 'http://localhost:8080/demo/article-fulltext'.// Custom participles
custom: 'http://localhost:8080/demo/article-custom'
}
Copy the code
Add pageNumber, pageSize, Order by, order by, of course, Order is used for custom segmentation queries. It is not used for other queries, so it is ok to pass it
$.ajax({
url: searchUrl[searchMode],
method: 'get'.data: {
word: word,
pageNumber: 1.pageSize: 10.orderBy: orderBy,
order: order
},
success: function (result) {
// ...}})Copy the code
Then you can test, all three are ok ~
But when switching search mode to search again, there is a problem!
The reason for this problem is that the template has been replaced. The following code does not report an error, but gets undefined
let template = $('#search-result-template').html();
Copy the code
So let’s just put it outside and make it a global variable
let searchResultTemplate = $('#search-result-template').html();
let resultInfoTemplate = $('#real-tips').html();
Copy the code
And then it’s OK
Final code:
// Initialize the mode box
let modal = new Modal({
width: 300.height: 200.title: "Tip".text: "Ongoing search..."
});
modal.init();
// Background interface path
let searchUrl = {
// Fuzzy query
fuzzy: 'http://localhost:8080/demo/article-fuzzy'.// Full-text index
fulltext: 'http://localhost:8080/demo/article-fulltext'.// Custom participles
custom: 'http://localhost:8080/demo/article-custom'
}
// Search the callback function
function search() {
// Get the input value of the search box and remove the first and last Spaces
let word = $('#search-input').val().trim();
// The keyword is empty or blank
if (word === "") {
// Prompt the user to enter keywords before searching
alert('What are you looking for, dear?');
return;
}
// Get the search options
let searchMode = $('input[name="searchMode"]:checked').val()
let orderBy = $('input[name="orderBy"]:checked').val()
let order = $('input[name="order"]:checked').val()
// Display the mode box
modal.show();
// Make a network request to invoke the back-end search interface
$.ajax({
url: searchUrl[searchMode],
method: 'get'.data: {
word: word,
pageNumber: 1.pageSize: 10.orderBy: orderBy,
order: order
},
success: function (result) {
console.log(result)
let html = ' ';
let baseUrl = "news-view.html? id=";
result.list.forEach(function (item) {
html += searchResultTemplate.replace('{url}', baseUrl + item.id)
.replace('{title}', item.title); $(})'#search-result').html(html);
// Render the search result information
let tips = resultInfoTemplate.replace('{word}', word)
.replace('{duration}', result.duration)
.replace('{size}', result.size);
$('#tips').html(tips);
// Hide the mode box
modal.hide()
}
})
}
// Search for related functions
let searchResultTemplate = $('#search-result-template').html();
let resultInfoTemplate = $('#real-tips').html();
$('#search-btn').click(search);
$('#search-input').keyup(function (e) {
if (e.code === "NumpadEnter" || e.code === "Enter") { search(); }})Copy the code
2. Develop paging
Now there is still a paging, for convenience, this time I will not hand tear, directly online to find the plug-in, after looking for a wave of transformation, now, I put it into jK-paging, including style and logic files, directly introduced in the home page ~ then you can start to use ~
Usage:
Create a new TAB on the page
<! - page - >
<div id="page"></div>
Copy the code
Use it in the Success callback for Ajax
// Render a new page
new Paging("page", {
nowPage: currentPage, // Current page number
pageNum: result.size, / / total page number
buttonNum: 5.// Number of pages to display
canJump: 0.// Whether it can jump. 0: do not display (default), 1: display
showOne: 0.// If only one page is displayed. 0: no display,1: display (default)
callback: function (num) {
// The callback function after clicking the button}});Copy the code
Each successful request rerenders the page. To do this, we need to set the current page number and the page number clicked by the user to global variables
let currentPage = 1;
let pageNumber = 1;
Copy the code
Then modify the data in Ajax:
data: {
word: word,
pageNumber: pageNumber, // The number of pages the user clicked on
pageSize: 10.orderBy: orderBy,
order: order
},
Copy the code
In the callback function after the button is clicked, we’re going to update the current page number and the page number that the user clicked on, and then we’re going to call the search function, which may be a little confusing here, so let’s just read it a few more times
// Re-render paging
new Paging("page", {
nowPage: currentPage, // Current page number
pageNum: result.pages, / / total page number
buttonNum: 5.// Number of pages to display
canJump: 0.// Whether it can jump. 0: do not display (default), 1: display
showOne: 0.// If only one page is displayed. 0: no display,1: display (default)
callback: function (num) {
// Update the page number that the user clicked on
pageNumber = num
// Update current page number
currentPage = pageNumber
search()
},
});
Copy the code
Then there you go:
However, when the search option is switched, there is a bug that the page does not reset, so we need to improve it by resetting the current page number and the page number clicked by the user whenever the search option changes
// Check whether the search options have changed. If so, both the current page number and the page number the user clicked on will be reset
if(searchMode ! == globalSearchMode || orderBy ! == globalOrderBy || order ! == globalOrder) { currentPage =1;
pageNumber = 1;
}
Copy the code
Global **** is a global variable, so we need to create three new global variables to store the search options for each search. Of course, we can combine them into objects, but I’ll use the former
let globalSearchMode, globalOrderBy, globalOrder;
Copy the code
or
let globalSearchOptions = { globalSearchMode: ' '.globalOrderBy: ' '.globalOrder: ' '}
Copy the code
Now the bug is solved
When the keyword changes, the page is not reset, so we need to improve the judgment
Add a global variable globalKeyWord to store the keyword
let globalSearchMode, globalOrderBy, globalOrder, globalKeyword;
Copy the code
Increase the judgment of keywords
// Store the search options for comparison on the next search
globalSearchMode = searchMode;
globalOrderBy = orderBy;
globalOrder = order;
globalKeyword = word;
Copy the code
Search the storage keyword to globalKeyWord
// Store the search options so that you can compare them to globalSearchMode = searchMode next time; globalOrderBy = orderBy; globalOrder = order; globalKeyword = word;
Copy the code
Complete code:
html:
<! DOCTYPEhtml>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>News Recommendation system</title>
<link rel="stylesheet" href="css/normalize.css">
<link rel="stylesheet" href="jk-modal/jk-modal.css">
<link rel="stylesheet" href="jk-paging/jk-paging.css">
<link rel="stylesheet" href="css/index.css">
<script src="js/jQuery.js"></script>
<script src="jk-modal/jk-modal.js"></script>
<script src="jk-paging/jk-paging.js"></script>
<script src="js/common.js"></script>
</head>
<body>
<! -- Page container -->
<div id="app">
<! - the head -- -- >
<div class="header">
<h3 class="header-title">NewsDemo</h3>
</div>
<! - main body - - >
<div class="main clearfix">
<! - the left column -- -- >
<div class="main-left">
<! -- Search box -->
<div class="search">
<label>
<input id="search-input" type="text" class="search-input">
</label>
<button id="search-btn" class="search-btn">search</button>
</div>
<! -- Search options Settings -->
<div class="search-options">
<span>Search mode:</span>
<label for="fuzzy">
<input type="radio" name="searchMode" id="fuzzy" value="fuzzy">Fuzzy query</label>
<label for="fulltext">
<input type="radio" name="searchMode" id="fulltext" value="fulltext">The full text indexing</label>
<label for="custom">
<input type="radio" name="searchMode" id="custom" value="custom" checked>Custom query</label>
</div>
<div class="search-options">
<span>Sort field:</span>
<label for="tfidf">
<input type="radio" name="orderBy" id="tfidf" value="tfidf" checked>tfidf
</label>
<label for="bayes">
<input type="radio" name="orderBy" id="bayes" value="bayes">bayes
</label>
</div>
<div class="search-options">
<span>Search results sorted by:</span>
<label for="asc">
<input type="radio" name="order" id="asc" value="asc">ascending</label>
<label for="desc">
<input type="radio" name="order" id="desc" value="desc" checked>Descending order</label>
</div>
<p id="tips" class="tips">
<template id="real-tips">Search keywords:<span>{word}</span>And time consuming:<span>{duration}</span>Milliseconds, return:<span>{size}</span>news</template>
</p>
<div class="container">
<h3 class="news-list-title">The search results</h3>
<ul id="search-result">
<template id="search-result-template">
<li class="news-list-item">
<a href="{url}" target="_blank">
{title}
</a>
</li>
</template>
</ul>
</div>
<! - page - >
<div id="page"></div>
</div>
<! -- > - the right hand column
<div class="main-right">
<div class="container">
<h3 class="news-list-title">The news is recommended</h3>
<ul id="recommend-result">
<template id="recommend-result-template">
<li class="news-list-item">
<a href="{url}" target="_blank">
{title}
</a>
</li>
</template>
</ul>
</div>
</div>
</div>
<! - the footer - >
<div class="footer">
<p>Copyright 2021-2077 Jack All rights reserved.</p>
</div>
</div>
<script src="js/index.js"></script>
</body>
</html>
Copy the code
js:
// Initialize the mode box
let modal = new Modal({
width: 300.height: 200.title: "Tip".text: "Ongoing search..."
});
modal.init();
// Background interface path
let searchUrl = {
// Fuzzy query
fuzzy: 'http://localhost:8080/demo/article-fuzzy'.// Full-text index
fulltext: 'http://localhost:8080/demo/article-fulltext'.// Custom participles
custom: 'http://localhost:8080/demo/article-custom'
}
// Search the callback function
function search() {
// Get the input value of the search box and remove the first and last Spaces
let word = $('#search-input').val().trim();
// The keyword is empty or blank
if (word === "") {
// Prompt the user to enter keywords before searching
alert('What are you looking for, dear?');
return;
}
// Get the search options
let searchMode = $('input[name="searchMode"]:checked').val()
let orderBy = $('input[name="orderBy"]:checked').val()
let order = $('input[name="order"]:checked').val()
// Compare keywords and search options. If so, the current page number and the page number the user clicked on should be reset
if(word ! == globalKeyword || searchMode ! == globalSearchMode || orderBy ! == globalOrderBy || order ! == globalOrder) { currentPage =1;
pageNumber = 1;
}
// Display the mode box
modal.show();
// Make a network request to invoke the back-end search interface
$.ajax({
url: searchUrl[searchMode],
method: 'get'.data: {
word: word,
pageNumber: pageNumber,
pageSize: 10.orderBy: orderBy,
order: order
},
success: function (result) {
// Render search results
let html = ' ';
let baseUrl = "news-view.html? id=";
result.list.forEach(function (item) {
html += searchResultTemplate.replace('{url}', baseUrl + item.id)
.replace('{title}', item.title); $(})'#search-result').html(html);
// Render the search result information
let tips = resultInfoTemplate.replace('{word}', word)
.replace('{duration}', result.duration)
.replace('{size}', result.size);
$('#tips').html(tips);
// Re-render paging
new Paging("page", {
nowPage: currentPage, // Current page number
pageNum: result.pages, / / total page number
buttonNum: 5.// Number of pages to display
canJump: 0.// Whether it can jump. 0: do not display (default), 1: display
showOne: 0.// If only one page is displayed. 0: no display,1: display (default)
callback: function (num) {
// Update the page number that the user clicked on
pageNumber = num;
// Update current page numbercurrentPage = pageNumber; search(); }});// Store the search options for comparison on the next search
globalSearchMode = searchMode;
globalOrderBy = orderBy;
globalOrder = order;
globalKeyword = word;
// Hide the mode box
modal.hide()
}
})
}
// Search for related functions
let searchResultTemplate = $('#search-result-template').html();
let resultInfoTemplate = $('#real-tips').html();
let currentPage = 1;
let pageNumber = 1;
let globalSearchMode, globalOrderBy, globalOrder, globalKeyword;
$('#search-btn').click(search);
$('#search-input').keyup(function (e) {
if (e.code === "NumpadEnter" || e.code === "Enter") { search(); }})Copy the code