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"
|
||||
list="country.nameViews-list"
|
||||
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>
|
||||
<datalist id="country.nameViews-list">
|
||||
|
@ -180,7 +185,7 @@
|
|||
th:if="${nextPage != -1}"
|
||||
id="next-page-anchor"
|
||||
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"
|
||||
></div>
|
||||
|
||||
|
|
|
@ -33,15 +33,15 @@ case class Routes(countries: List[Country])(implicit
|
|||
private val pageSize = 12
|
||||
|
||||
@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 regions = countries.map(_.region).distinct.sorted.asJava
|
||||
val selectedCountries = region match {
|
||||
case None => countries
|
||||
case Some("") => countries
|
||||
case Some(selectedRegion) => countries.filter(_.region == selectedRegion)
|
||||
}
|
||||
val selectedCountries = getSelectedCountries(region, countryName)
|
||||
|
||||
val startIndex = page * pageSize
|
||||
val countriesPage =
|
||||
|
@ -53,7 +53,9 @@ case class Routes(countries: List[Country])(implicit
|
|||
context.setVariable("regionsSet", regions)
|
||||
context.setVariable("countriesList", countriesPage.asJava)
|
||||
context.setVariable("allCountriesList", countries.asJava)
|
||||
// for anchor to request next pages from same countries
|
||||
context.setVariable("selectedRegion", region.getOrElse(""))
|
||||
context.setVariable("countryName", countryName.getOrElse(""))
|
||||
|
||||
val indexPage = engine.process("index", context)
|
||||
Response(
|
||||
|
@ -68,22 +70,26 @@ case class Routes(countries: List[Country])(implicit
|
|||
* intended to be called from "next-page-anchor" with htmx
|
||||
*/
|
||||
@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 selectedCountries = region match {
|
||||
case None => countries
|
||||
case Some("") => countries
|
||||
case Some(selectedRegion) => countries.filter(_.region == selectedRegion)
|
||||
}
|
||||
val selectedCountries = getSelectedCountries(region, countryName)
|
||||
|
||||
val startIndex = page * pageSize
|
||||
val countriesPage =
|
||||
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
|
||||
val nextPage = if (countriesPage.length == pageSize) page + 1 else -1
|
||||
context.setVariable("countriesList", countriesPage.asJava)
|
||||
context.setVariable("selectedRegion", region.getOrElse(""))
|
||||
context.setVariable("nextPage", nextPage)
|
||||
|
||||
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")
|
||||
def getCountryPage(countryName: String) = {
|
||||
val context = new Context()
|
||||
|
|
Loading…
Reference in New Issue