1

I have the following component template:

<h1>Complexus Vehicle Inventory</h1>

<p *ngIf="!vehicles"><em>No vehicle entries found</em></p>

<div *ngIf="vehicles">
  <form class="form-inline my-2 my-lg-0">
    <input class="form-control mr-sm-2" type="search" placeholder="Search" aria-label="Search" [(ngModel)]="strMakeOrModel" name="search">
    <button class="btn btn-outline-success my-2 my-sm-0" type="submit" (click)="searchVehicle()">Search</button>
  </form>
</div>


<table class="table" *ngIf="vehicles">
    <thead class="thead-dark">
      <tr>
        <th scope="col">Make</th>
        <th scope="col">Model</th>
        <th scope="col">Engine Capacity</th>
        <th scope="col">Cylinder Variant</th>
        <th scope="col">Top Speed</th>
        <th scope="col">Price (R)</th>
        <th scope="col">Cylinder Capacity</th>
        <th scope="col">Air Pressure/second</th>
      </tr>
    </thead>
    <tbody>
      <tr *ngFor="let vehicle of vehicles">
        <td>{{ vehicle.Make }}</td>
        <td>{{ vehicle.Model }}</td>
        <td>{{ vehicle.EngineCapacity }}</td>
        <td>{{ vehicle.CylinderVariant }}</td>
        <td>{{ vehicle.TopSpeed }}</td>
        <td>{{ vehicle.Price }}</td>
        <td>{{ vehicle.IndividualCylinderCapacity }}</td>
        <td>{{ vehicle.AirPressurePerSecond }}</td>
      </tr>
    </tbody>
  </table>

I want to be able to, based on the navigation link clicked in the navigation bar, change the search criteria, that resides in the form. In other words, let's say someone clicked Search by Price, the above component should be updated to incude two text boxes now, serving the price range they would like to search for.

The table layout will stay the same, so this is the re-usable part of the component.

How do you achieve this in Angular 6?

2
  • You achive that by using the Router and router-outlet. You can learn the how-to here angular.io/guide/router Commented May 19, 2018 at 11:39
  • @Cristian This component you see above is injected into the <router-outlet> . Commented May 19, 2018 at 11:46

2 Answers 2

1

You could specify the search criterion with a route parameter. See this stackblitz for a demo.

  1. Add a search parameter to the component route:
{ path: "vehicles/:search", component: VehiclesComponent }
  1. Add the appropriate parameter to each router link:
<a routerLinkActive="active" routerLink="/vehicles/make">Search: make</a> |
<a routerLinkActive="active" routerLink="/vehicles/model">Search: model</a> |
<a routerLinkActive="active" routerLink="/vehicles/price">Search: price</a> |
  1. Retrieve the search criterion from the active route:
import { ActivatedRoute } from '@angular/router';
import { Subscription } from "rxjs";
...

export class VehiclesComponent {
  search: number;
  private subscription: Subscription;

  constructor(private route: ActivatedRoute) { }

  ngOnInit() {
    this.subscription = this.route.params.subscribe(params => {
      this.search= params["search"];
    });
  }

  ngOnDestroy() {
    this.subscription.unsubscribe();
  }
}
  1. Adapt the view to the selected search criterion, for example with an ngSwitch directive:
<form>
  ...
  <ng-container [ngSwitch]="search">
    <div *ngSwitchCase="'make'">
      <div><input type="radio" name="make">Make 1</div>
      <div><input type="radio" name="make">Make 2</div>
      <div><input type="radio" name="make">Make 3</div>
    </div>
    <div *ngSwitchCase="'model'">
      <select>
        <option>Model 1</option>
        <option>Model 2</option>
        <option>Model 3</option>
      </select>
    </div>
    <div *ngSwitchCase="'price'">
      From: <input type="text">
      To: <input type="text">
    </div>
  </ng-container>
  <button>Search</button>
</form>
...
Sign up to request clarification or add additional context in comments.

2 Comments

I was currently busy looking at Child Routing, but your solution seems to be what I am looking for as well.
I would suggest a simple route parameter if you want to handle the search in the same component. Child routes would be appropriate to handle each search criterion in a different sub-component (which sounds like overkill to me).
0

I would make a couple of "templates". Every template would have different input boxes based on different criteria. Let's say you clicked in navigation on "color", then i would display that template with one input box where you can put color name. And then another template for Price, where you would put 2 input boxes for low and high price like you did. Like this:

<div *ngIf="choosed == 'color'">
    <form class="form-inline my-2 my-lg-0">
        <input class="form-control mr-sm-2" type="text" placeholder="Color" 
         aria-label="Color" [(ngModel)]="color" name="color">
        <button class="btn btn-outline-success my-2 my-sm-0" type="submit" 
      (click)="searchVehicle()">Search</button>
    </form>
</div>

<div *ngIf="choosed == 'price'">
    <form class="form-inline my-2 my-lg-0">
        <input class="form-control mr-sm-2" type="text" placeholder="low_price" 
         aria-label="Low Price" [(ngModel)]="low_price" name="low_price">
         <input class="form-control mr-sm-2" type="text" placeholder="high_price" 
         aria-label="High Price" [(ngModel)]="high_price" name="high_price">
        <button class="btn btn-outline-success my-2 my-sm-0" type="submit" 
      (click)="searchVehicle()">Search</button>
    </form>
</div>

And then when you click on navigation bar or some button i would call a method that sets the choosed variable to color or price and template would show itself based on variable content!

Hope it helps!

3 Comments

How do I add these templates, into an existing template??
Thats right ! Its just simple html! No need to complicate things! :)
I am busy looking into child routing in angular, as this seems to be what I require.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.