Skip to content
Snippets Groups Projects
Commit fd1fc5b6 authored by Tormod Nygård's avatar Tormod Nygård
Browse files

Issue: Filtering and sorting by price (#32)

parent e45cffac
No related branches found
No related tags found
1 merge request!29Resolve "Filtrere annonser etter pris og sted"
...@@ -2,13 +2,42 @@ ...@@ -2,13 +2,42 @@
<h2>ANNONSER</h2> <h2>ANNONSER</h2>
</div> </div>
<div class="sortContainer">
<app-select [(inputModel)]="selectedSort" (change)="filterCategory()">
<option value="0" selected>Sorter etter . . .</option>
<option value="1" >Pris: Lav til høy</option>
<option value="2" >Pris: Høy til lav</option>
<option value="3" >Alfabetisk: A til Å</option>
<option value="4" >Alfabetisk: Å til A</option>
<option value="5" >Nyeste først</option>
<option value="6" >Eldste først</option>
</app-select>
</div>
<div class="container"> <div class="container">
<div class="filterContainer"> <div class="filterContainer">
<div class="whiteBox"> <div class="whiteBox">
<app-select id="categorySelect" [(inputModel)]="selectedCategory" (change)="filterCategory()"> <app-select [(inputModel)]="selectedCategory" (change)="filterCategory()">
<option value="0" selected>Velg kategori . . .</option> <option value="0" selected>Velg kategori . . .</option>
<option *ngFor="let category of categories" [value]="category.getCategoryId">{{category.getName}}</option> <option *ngFor="let category of categories" [value]="category.getCategoryId">{{category.getName}}</option>
</app-select> </app-select>
<!-- Doesn't do anything yet -->
<div class="areaContainer">
<u>Område</u>
<label *ngFor="let area of areas">
<input type="checkbox" [(ngModel)]="area.checked" class="checkbox">
{{area.name}}
</label>
</div>
<div class="priceRangeContainer">
<u>Pris</u>
<p>Fra kr {{priceMin}}</p>
<p id="rightText">Til kr {{priceMax}}</p>
<input type="range" min="0" [max]="postMaxPrice" [(ngModel)]="priceMin" class="priceRange" id="priceRangeMin" (change)="priceMinChange()">
<input type="range" min="0" [max]="postMaxPrice" [(ngModel)]="priceMax" class="priceRange" id="priceRangeMax" (change)="priceMaxChange()">
</div>
</div> </div>
</div> </div>
......
...@@ -21,7 +21,7 @@ div.container{ ...@@ -21,7 +21,7 @@ div.container{
div.filterContainer{ div.filterContainer{
background: linear-gradient(#24e072 0%, #14A35A 100%); background: linear-gradient(#24e072 0%, #14A35A 100%);
height: 250px; height: 600px;
padding: 15px; padding: 15px;
box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.5); box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.5);
...@@ -29,7 +29,67 @@ div.container{ ...@@ -29,7 +29,67 @@ div.container{
background-color: #fff; background-color: #fff;
padding: 20px; padding: 20px;
height: 100%; height: 100%;
box-shadow: inset 0px 4px 4px rgba(0, 0, 0, 0.5); box-shadow: inset 0px 4px 4px rgba(0, 0, 0, 0.5);
display: grid;
font-family: 'Josefin Sans', sans-serif;
font-size: 16pt;
gap: 20px;
div.areaContainer{
display: grid;
gap: 5px;
input.checkbox{
width: 16px;
height: 16px;
}
}
div.priceRangeContainer{
u{
display: block;
}
p{
display: inline;
}
p#rightText{
float: right;
}
input.priceRange{
-webkit-appearance: none;
width: 100%;
display: inline;
outline: none;
background: #aaaaaa;
height: 6px;
}
input.priceRange::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
width: 5px;
height: 18px;
border-radius: 40%;
background: #FFA1A1;
cursor: pointer;
}
input#priceRangeMin::-webkit-slider-thumb {
background: #e98686;
}
input#priceRangeMax::-webkit-slider-thumb{
position: relative;
top: -20px;
}
input#priceRangeMax::-webkit-slider-runnable-track {
background: white;
}
}
} }
} }
...@@ -39,4 +99,11 @@ div.container{ ...@@ -39,4 +99,11 @@ div.container{
grid-template-columns: repeat(auto-fill, 384px); grid-template-columns: repeat(auto-fill, 384px);
gap: 30px; gap: 30px;
} }
}
.sortContainer{
width: 250px;
float: right;
margin-right: 10%;
margin-top: 5%;
} }
\ No newline at end of file
...@@ -14,10 +14,29 @@ export class PostListComponent implements OnInit { ...@@ -14,10 +14,29 @@ export class PostListComponent implements OnInit {
categories: Array<Category> = []; categories: Array<Category> = [];
selectedCategory: number; selectedCategory: number;
selectedSort: number = 0;
postMaxPrice: number;
priceMin: number = 0;
priceMax: number = 0;
checked: boolean = false;
areas: Array<any> = [
{name: "Agder", checked: false},
{name: "Innlandet", checked: false},
{name: "Møre og Romsdal", checked: false},
{name: "Nordland", checked: false},
{name: "Oslo", checked: false},
{name: "Rogaland", checked: false},
{name: "Troms og Finnmark", checked: false},
{name: "Trøndelag", checked: false},
{name: "Vestfold og Telemark", checked: false},
{name: "Viken", checked: false}
];
constructor(private postService: PostService) { } constructor(private postService: PostService) { }
ngOnInit(): void { ngOnInit() {
// Gets all categories from database and displays them in dropdown // Gets all categories from database and displays them in dropdown
this.postService.getAllCategories().then(categories => { this.postService.getAllCategories().then(categories => {
this.categories = categories; this.categories = categories;
...@@ -32,22 +51,49 @@ export class PostListComponent implements OnInit { ...@@ -32,22 +51,49 @@ export class PostListComponent implements OnInit {
// Gets all posts from database, and displays them // Gets all posts from database, and displays them
this.postService.getAllPosts().then(posts => { this.postService.getAllPosts().then(posts => {
this.allPosts = posts; this.allPosts = posts;
// Gets the maximum price for a post
this.postMaxPrice = this.allPosts.map(p => p.getPrice).reduce((a, b) => Math.max(a, b));
if (this.priceMax >= this.postMaxPrice || this.priceMax == 0) {
this.priceMax = this.postMaxPrice;
}
}).catch(error => { }).catch(error => {
console.log(error); console.log(error);
}); });
} }
filterCategory() { filterCategory() {
if (this.selectedCategory > 0) { // Gets all posts by selected category
// Gets all posts by selected category this.postService.getPostsByCategory(this.selectedCategory, this.selectedSort, this.priceMin, this.priceMax).then(posts => {
this.postService.getPostsByCategory(this.selectedCategory).then(posts => { this.allPosts = posts;
this.allPosts = posts; // this.sortPosts();
}).catch(error => {
console.log(error); // Gets the maximum price for a post
}); this.postMaxPrice = this.allPosts.map(p => p.getPrice).reduce((a, b) => Math.max(a, b));
} else {
this.getPosts(); if (this.priceMax >= this.postMaxPrice || this.priceMax == 0) {
this.priceMax = this.postMaxPrice;
}
}).catch(error => {
console.log(error);
});
}
priceMinChange(){
if (this.priceMin > this.priceMax) {
this.priceMin = this.priceMax;
}
this.filterCategory();
}
priceMaxChange(){
if (this.priceMax < this.priceMin) {
this.priceMax = this.priceMin;
} }
this.filterCategory();
} }
} }
...@@ -201,10 +201,10 @@ export class PostService { ...@@ -201,10 +201,10 @@ export class PostService {
/** /**
* Get all posts in database by specified category. * Get all posts in database by specified category.
*/ */
getPostsByCategory(categoryId: number): Promise<Array<Post>> { getPostsByCategory(categoryId: number, sort: number, minPrice: number, maxPrice: number): Promise<Array<Post>> {
return new Promise<Array<Post>>( return new Promise<Array<Post>>(
(resolve, reject) => { (resolve, reject) => {
this.get_posts_by_category(categoryId).subscribe((data: any) => { this.get_posts_by_category(categoryId, sort, minPrice, maxPrice).subscribe((data: any) => {
try { try {
let outputPosts = []; let outputPosts = [];
for (let post of data.data) { for (let post of data.data) {
...@@ -229,8 +229,8 @@ export class PostService { ...@@ -229,8 +229,8 @@ export class PostService {
); );
} }
private get_posts_by_category(categoryId: number) { private get_posts_by_category(categoryId: number, sort: number, minPrice: number, maxPrice: number) {
return this.http.get(this.postUrl, {params: {categoryid: String(categoryId)}}); return this.http.get(this.postUrl, {params: {categoryid: String(categoryId), sort: String(sort), min_price: String(minPrice), max_price: String(maxPrice)}});
} }
/** /**
......
...@@ -42,20 +42,63 @@ router.route("/").post(async (request: Request, response: Response) => { ...@@ -42,20 +42,63 @@ router.route("/").post(async (request: Request, response: Response) => {
}); });
/* ============================= READ ============================= */ /* ============================= READ ============================= */
// Get all posts `/api/post/?categoryid=:categoryid&userId=:userId` // Get all posts `/api/post/?categoryid=:categoryid&userId=:userId&sort=:sort`
router.route("/").get(async (request: Request, response: Response) => { router.route("/").get(async (request: Request, response: Response) => {
const { categoryid, userId } = request.query as { [key: string]: string }; const { categoryid, userId, sort, min_price, max_price } = request.query as { [key: string]: string };
try { try {
let input = `SELECT p.id, p.title, p.description, p.price, p.timestamp, p.owner, p.categoryid, p.imageUrl let input = `SELECT p.id, p.title, p.description, p.price, p.timestamp, p.owner, p.categoryid, p.imageUrl
FROM post as p`; FROM post as p`;
if (categoryid || userId) input += ` WHERE `; if (categoryid || userId || min_price || max_price) input += ` WHERE `;
const params = Object.entries({ const params = Object.entries({
categoryId: categoryid, categoryId: categoryid,
owner: userId owner: userId
}).filter((param) => param[1]) }).filter((param) => param[1])
// Add p.categoryId = ? AND p.userId = ? respectively if it is not undefined // Add p.categoryId = ? AND p.userId = ? respectively if it is not undefined
console.log(params);
console.log(categoryid)
if (categoryid == "undefined") {
console.log(params);
params.shift();
}
input += params.map((param) => `p.${param[0]} = ?`).join(" AND ") input += params.map((param) => `p.${param[0]} = ?`).join(" AND ")
console.log(input, params.map((param) => param[1]));
if (min_price) {
if (categoryid || categoryid == "undefined") {
input += ` AND`;
}
input += ` p.price >= ${min_price}`
}
if (max_price) {
input += ` AND p.price <= ${max_price}`
}
console.log("category: " + categoryid);
console.log("min: " + min_price);
console.log("max: " + max_price);
if (sort && sort != "0") {
switch(sort){
case "1":
input += " ORDER BY p.price ASC"
break;
case "2":
input += " ORDER BY p.price DESC"
break;
case "3":
input += " ORDER BY p.title ASC"
break;
case "4":
input += " ORDER BY p.title DESC"
break;
case "5":
input += " ORDER BY p.timestamp DESC"
break;
case "6":
input += " ORDER BY p.timestamp ASC"
break;
}
}
// console.log(input, params.map((param) => param[1]));
response.status(200).json(await query(input, params.map((param) => param[1]))); response.status(200).json(await query(input, params.map((param) => param[1])));
} catch (error) { } catch (error) {
response.status(400).send("Bad Request"); response.status(400).send("Bad Request");
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment