feat: active search on main page
over english and native nave, nice also putting url into history, and also setting up the load anchor
This commit is contained in:
parent
b8d0dc96fd
commit
ee914c8014
|
@ -87,6 +87,11 @@
|
||||||
name="countryName"
|
name="countryName"
|
||||||
list="country.nameViews-list"
|
list="country.nameViews-list"
|
||||||
placeholder="Search for a country..."
|
placeholder="Search for a country..."
|
||||||
|
th:hx-get="@{~/}"
|
||||||
|
hx-trigger="keyup changed delay:500ms"
|
||||||
|
hx-select="#countries-main-list"
|
||||||
|
hx-target="#countries-main-list"
|
||||||
|
hx-swap="outerHTML"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<datalist id="country.nameViews-list">
|
<datalist id="country.nameViews-list">
|
||||||
|
@ -180,7 +185,7 @@
|
||||||
th:if="${nextPage != -1}"
|
th:if="${nextPage != -1}"
|
||||||
id="next-page-anchor"
|
id="next-page-anchor"
|
||||||
hx-trigger="revealed"
|
hx-trigger="revealed"
|
||||||
th:hx-get="@{~/countries-cards(region=${selectedRegion},page=${nextPage})}"
|
th:hx-get="@{~/countries-cards(region=${selectedRegion},page=${nextPage},countryName=${countryName})}"
|
||||||
hx-swap="outerHTML"
|
hx-swap="outerHTML"
|
||||||
></div>
|
></div>
|
||||||
|
|
||||||
|
|
|
@ -33,15 +33,15 @@ case class Routes(countries: List[Country])(implicit
|
||||||
private val pageSize = 12
|
private val pageSize = 12
|
||||||
|
|
||||||
@cask.get("/")
|
@cask.get("/")
|
||||||
def indexPage(region: Option[String] = None, page: Int = 0) = {
|
def indexPage(
|
||||||
|
region: Option[String] = None,
|
||||||
|
page: Int = 0,
|
||||||
|
countryName: Option[String] = None
|
||||||
|
) = {
|
||||||
val context = new Context()
|
val context = new Context()
|
||||||
|
|
||||||
val regions = countries.map(_.region).distinct.sorted.asJava
|
val regions = countries.map(_.region).distinct.sorted.asJava
|
||||||
val selectedCountries = region match {
|
val selectedCountries = getSelectedCountries(region, countryName)
|
||||||
case None => countries
|
|
||||||
case Some("") => countries
|
|
||||||
case Some(selectedRegion) => countries.filter(_.region == selectedRegion)
|
|
||||||
}
|
|
||||||
|
|
||||||
val startIndex = page * pageSize
|
val startIndex = page * pageSize
|
||||||
val countriesPage =
|
val countriesPage =
|
||||||
|
@ -53,7 +53,9 @@ case class Routes(countries: List[Country])(implicit
|
||||||
context.setVariable("regionsSet", regions)
|
context.setVariable("regionsSet", regions)
|
||||||
context.setVariable("countriesList", countriesPage.asJava)
|
context.setVariable("countriesList", countriesPage.asJava)
|
||||||
context.setVariable("allCountriesList", countries.asJava)
|
context.setVariable("allCountriesList", countries.asJava)
|
||||||
|
// for anchor to request next pages from same countries
|
||||||
context.setVariable("selectedRegion", region.getOrElse(""))
|
context.setVariable("selectedRegion", region.getOrElse(""))
|
||||||
|
context.setVariable("countryName", countryName.getOrElse(""))
|
||||||
|
|
||||||
val indexPage = engine.process("index", context)
|
val indexPage = engine.process("index", context)
|
||||||
Response(
|
Response(
|
||||||
|
@ -68,22 +70,26 @@ case class Routes(countries: List[Country])(implicit
|
||||||
* intended to be called from "next-page-anchor" with htmx
|
* intended to be called from "next-page-anchor" with htmx
|
||||||
*/
|
*/
|
||||||
@cask.get("/countries-cards")
|
@cask.get("/countries-cards")
|
||||||
def getPageOfCountriesCards(region: Option[String] = None, page: Int = 0) = {
|
def getPageOfCountriesCards(
|
||||||
|
region: Option[String] = None,
|
||||||
|
page: Int = 0,
|
||||||
|
countryName: Option[String] = None
|
||||||
|
) = {
|
||||||
val context = new Context()
|
val context = new Context()
|
||||||
|
|
||||||
val selectedCountries = region match {
|
val selectedCountries = getSelectedCountries(region, countryName)
|
||||||
case None => countries
|
|
||||||
case Some("") => countries
|
|
||||||
case Some(selectedRegion) => countries.filter(_.region == selectedRegion)
|
|
||||||
}
|
|
||||||
|
|
||||||
val startIndex = page * pageSize
|
val startIndex = page * pageSize
|
||||||
val countriesPage =
|
val countriesPage =
|
||||||
selectedCountries.slice(startIndex, startIndex + pageSize)
|
selectedCountries.slice(startIndex, startIndex + pageSize)
|
||||||
|
context.setVariable("countriesList", countriesPage.asJava)
|
||||||
|
|
||||||
|
// for anchor to request next pages from same countries
|
||||||
|
context.setVariable("selectedRegion", region.getOrElse(""))
|
||||||
|
context.setVariable("countryName", countryName.getOrElse(""))
|
||||||
|
|
||||||
// if current page is not full - there will be no next page
|
// if current page is not full - there will be no next page
|
||||||
val nextPage = if (countriesPage.length == pageSize) page + 1 else -1
|
val nextPage = if (countriesPage.length == pageSize) page + 1 else -1
|
||||||
context.setVariable("countriesList", countriesPage.asJava)
|
|
||||||
context.setVariable("selectedRegion", region.getOrElse(""))
|
|
||||||
context.setVariable("nextPage", nextPage)
|
context.setVariable("nextPage", nextPage)
|
||||||
|
|
||||||
val cards = engine.process(
|
val cards = engine.process(
|
||||||
|
@ -103,6 +109,36 @@ case class Routes(countries: List[Country])(implicit
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private def getSelectedCountries(
|
||||||
|
region: Option[String] = None,
|
||||||
|
countryName: Option[String] = None
|
||||||
|
) = {
|
||||||
|
val countriesFromSelectedRegion = region match {
|
||||||
|
case None => countries
|
||||||
|
case Some("") => countries
|
||||||
|
case Some(selectedRegion) => countries.filter(_.region == selectedRegion)
|
||||||
|
}
|
||||||
|
// applying country name filtering, can be partial name
|
||||||
|
val selectedCountries = countryName match {
|
||||||
|
case None => countriesFromSelectedRegion
|
||||||
|
case Some("") => countriesFromSelectedRegion
|
||||||
|
case Some(partialSearchString) =>
|
||||||
|
val lowerSearch = partialSearchString.toLowerCase()
|
||||||
|
countriesFromSelectedRegion
|
||||||
|
.filter(country => {
|
||||||
|
val nameContainsPartialMatch =
|
||||||
|
country.name.common.toLowerCase().contains(lowerSearch) ||
|
||||||
|
country.name.nativeName.values.foldLeft(false) {
|
||||||
|
(acc, nativeName) =>
|
||||||
|
acc || nativeName.common.toLowerCase().contains(lowerSearch)
|
||||||
|
}
|
||||||
|
|
||||||
|
nameContainsPartialMatch
|
||||||
|
})
|
||||||
|
}
|
||||||
|
selectedCountries
|
||||||
|
}
|
||||||
|
|
||||||
@cask.get("/country")
|
@cask.get("/country")
|
||||||
def getCountryPage(countryName: String) = {
|
def getCountryPage(countryName: String) = {
|
||||||
val context = new Context()
|
val context = new Context()
|
||||||
|
|
Loading…
Reference in New Issue