diff --git a/client/src/app/instance/search-multiple/components/index.ts b/client/src/app/instance/search-multiple/components/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..d3d2236e97cafc070d1bb437ecdb3eab47a23913
--- /dev/null
+++ b/client/src/app/instance/search-multiple/components/index.ts
@@ -0,0 +1,7 @@
+import { ProgressBarMultipleComponent } from './progress-bar-multiple.component';
+import { SummaryMultipleComponent } from './summary-multiple.component';
+
+export const dummiesComponents = [
+    ProgressBarMultipleComponent,
+    SummaryMultipleComponent
+];
diff --git a/client/src/app/instance/search-multiple/components/progress-bar-multiple.component.html b/client/src/app/instance/search-multiple/components/progress-bar-multiple.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..0dc2981b5b256bdb93776d72088d166970c1ce90
--- /dev/null
+++ b/client/src/app/instance/search-multiple/components/progress-bar-multiple.component.html
@@ -0,0 +1,58 @@
+<div class="row text-center">
+    <div class="col">
+        <h1>Search around a position in multiple datasets</h1>
+        <p class="text-muted">Fill RA & DEC position, select datasets and display the result.</p>
+    </div>
+</div>
+<div class="progress-navigation">
+    <div class="progress progress-with-circle">
+        <div class="progress-bar" role="progressbar" aria-valuenow="1" aria-valuemin="1" aria-valuemax="4"
+            [ngClass]="getStepClass()"></div>
+    </div>
+    <ul class="nav nav-pills">
+        <li class="nav-item checked" [ngClass]="{'active': currentStep === 'position'}">
+            <a *ngIf="!noSelectedDatasets" class="nav-link" routerLink="/search-multiple/position" [queryParams]="queryParams" data-toggle="tab">
+                <div class="icon-circle">
+                    <span class="fas fa-drafting-compass"></span>
+                </div>
+                Position
+            </a>
+            <a *ngIf="noSelectedDatasets" class="nav-link disabled" data-toggle="tab">
+                <div class="icon-circle">
+                    <span class="fas fa-drafting-compass"></span>
+                </div>
+                Position
+            </a>
+        </li>
+
+        <li class="nav-item" [ngClass]="{'active': currentStep === 'datasets', 'checked': datasetsStepChecked}">
+            <a *ngIf="isValidConeSearch" class="nav-link" routerLink="/search-multiple/datasets" [queryParams]="queryParams" data-toggle="tab">
+                <div class="icon-circle">
+                    <span class="fas fa-book"></span>
+                </div>
+                Datasets
+            </a>
+            <a *ngIf="!isValidConeSearch" class="nav-link disabled" data-toggle="tab">
+                <div class="icon-circle">
+                    <span class="fas fa-book"></span>
+                </div>
+                Datasets
+            </a>
+        </li>
+
+        <li class="nav-item" [ngClass]="{'active': currentStep === 'result', 'checked': resultStepChecked}">
+            <a *ngIf="isValidConeSearch && !noSelectedDatasets" class="nav-link" routerLink="/search-multiple/result" [queryParams]="queryParams" data-toggle="tab">
+                <div class="icon-circle">
+                    <span class="fas fa-table"></span>
+                </div>
+                Result
+            </a>
+            <a *ngIf="!isValidConeSearch || noSelectedDatasets" class="nav-link disabled" data-toggle="tab">
+                <div class="icon-circle">
+                    <span class="fas fa-table"></span>
+                </div>
+                Result
+            </a>
+        </li>
+    </ul>
+</div>
diff --git a/client/src/app/instance/search-multiple/components/progress-bar-multiple.component.scss b/client/src/app/instance/search-multiple/components/progress-bar-multiple.component.scss
new file mode 100644
index 0000000000000000000000000000000000000000..0a42a748bbc5a7bef5571be4cbd2b9011a183dd3
--- /dev/null
+++ b/client/src/app/instance/search-multiple/components/progress-bar-multiple.component.scss
@@ -0,0 +1,120 @@
+/**
+ * This file is part of Anis Client.
+ *
+ * @copyright Laboratoire d'Astrophysique de Marseille / CNRS
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+.progress-navigation {
+    position: relative;
+    height: 125px;
+    margin-top: 15px;
+}
+
+.progress-with-circle {
+    position: relative;
+    top: 40px;
+    z-index: 50;
+    height: 4px;
+}
+
+.progress-bar {
+    box-shadow: none;
+    -webkit-transition: width .3s ease;
+    -o-transition: width .3s ease;
+    transition: width .3s ease;
+    background-color: #7AC29A;
+}
+
+.nav-pills {
+    background-color: #F3F2EE;
+    position: absolute;
+    width: 100%;
+    height: 4px;
+    top: 40px;
+    text-align: center;
+}
+
+.nav-pills li a {
+    padding: 0;
+    max-width: 78px;
+    margin: 0 auto;
+    color: rgba(0, 0, 0, 0.2);
+    border-radius: 50%;
+    position: relative;
+    top: -32px;
+    z-index: 100;
+}
+
+.icon-circle {
+    font-size: 20px;
+    border: 3px solid #E9ECEF;
+    text-align: center;
+    border-radius: 50%;
+    color: rgba(0, 0, 0, 0.2);
+    font-weight: 600;
+    width: 70px;
+    height: 70px;
+    background-color: #FFFFFF;
+    margin: 0 auto;
+    position: relative;
+    top: -2px;
+}
+
+.nav-item {
+    width: 33%;
+}
+
+.nav-item.checked .icon-circle {
+    border-color: #7AC29A;
+    color: #7AC29A;
+}
+
+.nav-item.checked a {
+    color: #7AC29A !important;
+}
+
+.nav-item.active a {
+    color: #7AC29A !important;
+    background-color: transparent;
+}
+
+.nav-item.active .icon-circle {
+    color: white !important;
+    border-color: #7AC29A;
+    background-color: #7AC29A;
+}
+
+.nav-link.disabled {
+    cursor: not-allowed;
+}
+
+.icon-circle svg {
+    position: absolute;
+    z-index: 1;
+    left: 22px;
+    right: 0;
+    top: 23px;
+}
+
+.positionStep {
+    width: 15%;
+}
+
+.datasetsStep {
+    width: 48%;
+}
+
+.resultStep {
+    width: 100%;
+}
+
+.btn-clear-form span {
+    display: none;
+}
+
+.btn-clear-form:hover span {
+    display: inline;
+}
diff --git a/client/src/app/instance/search-multiple/components/progress-bar-multiple.component.ts b/client/src/app/instance/search-multiple/components/progress-bar-multiple.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..6060716bc9c61bc29538aad279def19199421fca
--- /dev/null
+++ b/client/src/app/instance/search-multiple/components/progress-bar-multiple.component.ts
@@ -0,0 +1,50 @@
+/**
+ * This file is part of Anis Client.
+ *
+ * @copyright Laboratoire d'Astrophysique de Marseille / CNRS
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+import { Component, Input, ChangeDetectionStrategy } from '@angular/core';
+
+import { SearchMultipleQueryParams } from '../store/model';
+
+@Component({
+    selector: 'app-progress-bar-multiple',
+    templateUrl: 'progress-bar-multiple.component.html',
+    styleUrls: ['progress-bar-multiple.component.scss'],
+    changeDetection: ChangeDetectionStrategy.OnPush
+})
+/**
+ * @class
+ * @classdesc Search multiple progress bar component.
+ */
+export class ProgressBarMultipleComponent {
+    @Input() currentStep: string;
+    @Input() positionStepChecked: boolean;
+    @Input() datasetsStepChecked: boolean;
+    @Input() resultStepChecked: boolean;
+    @Input() isValidConeSearch: boolean;
+    @Input() noSelectedDatasets: boolean;
+    @Input() queryParams: SearchMultipleQueryParams;
+
+    /**
+     * Returns step class that match to the current step.
+     *
+     * @return string
+     */
+    getStepClass(): string {
+        switch (this.currentStep) {
+            case 'position':
+                return 'positionStep';
+            case 'datasets':
+                return 'datasetsStep';
+            case 'result':
+                return 'resultStep';
+            default:
+                return 'positionStep';
+        }
+    }
+}
diff --git a/client/src/app/instance/search-multiple/components/summary-multiple.component.html b/client/src/app/instance/search-multiple/components/summary-multiple.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..b59975fcc35adbfeb473f86d44849b9e64e33d99
--- /dev/null
+++ b/client/src/app/instance/search-multiple/components/summary-multiple.component.html
@@ -0,0 +1,63 @@
+<div class="border rounded">
+    <p class="lead text-center border-bottom bg-light py-3">Search summary</p>
+
+    <!-- Position -->
+    <p class="text-center font-italic">
+        Position
+    </p>
+    <span *ngIf="isValidConeSearch" class="pl-5">
+        Cone search:
+        <ul class="ml-3 pl-5 list-unstyled">
+            <li>RA = {{ coneSearch.ra }}°</li>
+            <li>DEC = {{ coneSearch.dec }}°</li>
+            <li>radius = {{ coneSearch.radius }} arcsecond</li>
+        </ul>
+    </span>
+    <p *ngIf="!isValidConeSearch" class="pl-5 text-danger font-weight-bold">
+        Not valid position!
+    </p>
+    <hr>
+
+    <!-- Dataset List -->
+    <p class="text-center font-italic">
+        Datasets
+    </p>
+    <span *ngIf="datasetSearchMetaIsLoading" class="row justify-content-center mt-5">
+        <span class="fas fa-circle-notch fa-spin fa-3x"></span>
+        <span class="sr-only">Loading...</span>
+    </span>
+    <div *ngIf="datasetSearchMetaIsLoaded">
+        <p *ngIf="noSelectedDatasets" class="pl-5 text-danger font-weight-bold">
+            At least 1 dataset required!
+        </p>
+        <div *ngIf="!noSelectedDatasets">
+            <!-- Accordion Dataset families -->
+            <accordion [isAnimated]="true">
+                <accordion-group *ngFor="let datasetFamily of getDatasetFamilyList()" #ag panelClass="abstract-accordion" [isOpen]="accordionFamilyIsOpen" class="pl-5">
+                    <button class="btn btn-link btn-block clearfix pb-1 text-primary" accordion-heading>
+                        <div class="pull-left float-left">
+                            {{ datasetFamily.label }}
+                            &nbsp;
+                            <span *ngIf="ag.isOpen">
+                                <span class="fas fa-chevron-up"></span>
+                            </span>
+                            <span *ngIf="!ag.isOpen">
+                                <span class="fas fa-chevron-down"></span>
+                            </span>
+                        </div>
+                    </button>
+
+                    <!-- Selected Datasets -->
+                    <ul *ngIf="getSelectedDatasetsByFamily(datasetFamily.id).length > 0; else noDataset" class="mb-0 pl-4 list-unstyled">
+                        <li *ngFor="let dataset of getSelectedDatasetsByFamily(datasetFamily.id)" class="pb-1">
+                            {{ dataset.label }}
+                        </li>
+                    </ul>
+                    <ng-template #noDataset>
+                        <p class="mb-1 pl-4">No selected dataset</p>
+                    </ng-template>
+                </accordion-group>
+            </accordion>
+        </div>
+    </div>
+</div>
diff --git a/client/src/app/instance/search-multiple/components/summary-multiple.component.scss b/client/src/app/instance/search-multiple/components/summary-multiple.component.scss
new file mode 100644
index 0000000000000000000000000000000000000000..c837d14e1ce994aeb0857803139aaad3fd7f8d6d
--- /dev/null
+++ b/client/src/app/instance/search-multiple/components/summary-multiple.component.scss
@@ -0,0 +1,12 @@
+/**
+ * This file is part of Anis Client.
+ *
+ * @copyright Laboratoire d'Astrophysique de Marseille / CNRS
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+li>span {
+    cursor: pointer;
+}
diff --git a/client/src/app/instance/search-multiple/components/summary-multiple.component.ts b/client/src/app/instance/search-multiple/components/summary-multiple.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..fabeefdf1432fd19b947df1cf1b6442328326102
--- /dev/null
+++ b/client/src/app/instance/search-multiple/components/summary-multiple.component.ts
@@ -0,0 +1,70 @@
+/**
+ * This file is part of Anis Client.
+ *
+ * @copyright Laboratoire d'Astrophysique de Marseille / CNRS
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
+
+import { SearchMultipleQueryParams } from '../store/model';
+import { Dataset, Family } from '../../metamodel/model';
+import { ConeSearch } from '../../shared/cone-search/store/model';
+import { sortByDisplay } from '../../shared/utils';
+
+@Component({
+    selector: 'app-summary-multiple',
+    templateUrl: 'summary-multiple.component.html',
+    styleUrls: ['summary-multiple.component.scss'],
+    changeDetection: ChangeDetectionStrategy.OnPush,
+})
+/**
+ * @class
+ * @classdesc Search multiple summary component.
+ */
+export class SummaryMultipleComponent {
+    @Input() currentStep: string;
+    @Input() isValidConeSearch: boolean;
+    @Input() coneSearch: ConeSearch;
+    @Input() datasetSearchMetaIsLoading: boolean;
+    @Input() datasetSearchMetaIsLoaded: boolean;
+    @Input() datasetFamilyList: Family[];
+    @Input() datasetList: Dataset[];
+    @Input() selectedDatasets: string[];
+    @Input() noSelectedDatasets: boolean;
+    @Input() queryParams: SearchMultipleQueryParams;
+
+    accordionFamilyIsOpen = true;
+
+    /**
+     * Returns dataset families sorted by display, that contains datasets with cone search enabled.
+     *
+     * @return Family[]
+     */
+    getDatasetFamilyList(): Family[] {
+        const familiesId: number[] = [];
+        this.datasetList.forEach(d => {
+            if (!familiesId.includes(d.id_dataset_family)) {
+                familiesId.push(d.id_dataset_family);
+            }
+        });
+        return this.datasetFamilyList
+            .filter(f => familiesId.includes(f.id))
+            .sort(sortByDisplay);
+    }
+
+    /**
+     * Returns dataset list for the given dataset family ID.
+     *
+     * @param  {number} familyId - The family ID.
+     *
+     * @return Dataset[]
+     */
+    getSelectedDatasetsByFamily(familyId: number): Dataset[] {
+        return this.datasetList
+            .filter(d => d.id_dataset_family === familyId)
+            .filter(d => this.selectedDatasets.includes(d.name));
+    }
+}
diff --git a/client/src/app/instance/search-multiple/containers/datasets.component.html b/client/src/app/instance/search-multiple/containers/datasets.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..4f05f1ef84dc7fad2f709f7e183b055fc0a23c7f
--- /dev/null
+++ b/client/src/app/instance/search-multiple/containers/datasets.component.html
@@ -0,0 +1,61 @@
+<div class="row mt-4">
+    <div class="col-12 col-md-8 col-lg-9">
+        <div class="border rounded my-2">
+            <p class="border-bottom bg-light text-primary mb-0 py-4 pl-4">Datasets</p>
+            <div class="px-3">
+                <div *ngIf="datasetSearchMetaIsLoading | async" class="text-center my-5">
+                    <span class="fas fa-circle-notch fa-spin fa-3x"></span>
+                    <span class="sr-only">Loading...</span>
+                </div>
+                    <app-dataset-list *ngIf="datasetSearchMetaIsLoaded | async"
+                        [surveyList]="surveyList | async"
+                        [datasetFamilyList]="datasetFamilyList | async"
+                        [datasetList]="datasetList | async"
+                        [selectedDatasets]="selectedDatasets | async"
+                        (updateSelectedDatasets)="updateSelectedDatasets($event)">
+                    </app-dataset-list>
+            </div>
+        </div>
+    </div>
+    <div class="col-12 col-md-4 col-lg-3 pt-2">
+        <app-summary-multiple
+            [currentStep]="currentStep | async"
+            [isValidConeSearch]="isValidConeSearch | async"
+            [coneSearch]="coneSearch | async"
+            [datasetSearchMetaIsLoading]="datasetSearchMetaIsLoading | async"
+            [datasetSearchMetaIsLoaded]="datasetSearchMetaIsLoaded | async"
+            [datasetFamilyList]="datasetFamilyList | async"
+            [datasetList]="datasetList | async"
+            [selectedDatasets]="selectedDatasets | async"
+            [noSelectedDatasets]="noSelectedDatasets | async"
+            [queryParams]="queryParams | async">
+        </app-summary-multiple>
+    </div>
+</div>
+
+<div class="row mt-5 justify-content-between">
+    <div class="col">
+        <button *ngIf="noSelectedDatasets | async" class="btn btn-outline-secondary disabled not-allowed" title="At least one dataset required!">
+            <span class="fas fa-arrow-left"></span> Previous
+        </button>
+        <a *ngIf="!(noSelectedDatasets | async)"
+           routerLink="/search-multiple/position"
+           [queryParams]="queryParams | async"
+           (click)="checkStep()"
+           class="btn btn-outline-secondary">
+            <span class="fas fa-arrow-left"></span> Previous
+        </a>
+    </div>
+    <div class="col col-auto">
+        <button *ngIf="noSelectedDatasets | async" class="btn btn-outline-primary disabled not-allowed" title="At least one dataset required!">
+            Next <span class="fas fa-arrow-right"></span>
+        </button>
+        <a *ngIf="!(noSelectedDatasets | async)"
+           routerLink="/search-multiple/result"
+           [queryParams]="queryParams | async"
+           (click)="checkStep()"
+           class="btn btn-outline-primary">
+            Next <span class="fas fa-arrow-right"></span>
+        </a>
+    </div>
+</div>
diff --git a/client/src/app/instance/search-multiple/containers/datasets.component.ts b/client/src/app/instance/search-multiple/containers/datasets.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..4ffa2ea0d66e9310ed037ce72a78957bc759582a
--- /dev/null
+++ b/client/src/app/instance/search-multiple/containers/datasets.component.ts
@@ -0,0 +1,98 @@
+/**
+ * This file is part of Anis Client.
+ *
+ * @copyright Laboratoire d'Astrophysique de Marseille / CNRS
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+import { Component, OnInit } from '@angular/core';
+
+import { Store } from '@ngrx/store';
+import { Observable } from 'rxjs';
+
+import * as fromSearchMultiple from '../store/search-multiple.reducer';
+import * as searchMultipleActions from '../store/search-multiple.action';
+import * as searchMultipleSelector from '../store/search-multiple.selector';
+import { SearchMultipleQueryParams } from '../store/model';
+import * as fromMetamodel from '../../metamodel/reducers';
+import * as datasetActions from '../../metamodel/action/dataset.action';
+import { Dataset, Family, Survey } from '../../metamodel/model';
+import * as metamodelSelector from '../../metamodel/selectors';
+import * as coneSearchSelector from '../../shared/cone-search/store/cone-search.selector';
+import { ConeSearch } from '../../shared/cone-search/store/model';
+import { ScrollTopService } from '../../shared/service/sroll-top.service';
+
+/**
+ * Interface for store state.
+ *
+ * @interface StoreState
+ */
+interface StoreState {
+    searchMultiple: fromSearchMultiple.State;
+    metamodel: fromMetamodel.State;
+}
+
+@Component({
+    selector: 'app-datasets',
+    templateUrl: 'datasets.component.html'
+})
+/**
+ * @class
+ * @classdesc Search multiple datasets container.
+ *
+ * @implements OnInit
+ */
+export class DatasetsComponent implements OnInit {
+    public datasetSearchMetaIsLoading: Observable<boolean>;
+    public datasetSearchMetaIsLoaded: Observable<boolean>;
+    public currentStep: Observable<string>;
+    public surveyList: Observable<Survey[]>;
+    public datasetFamilyList: Observable<Family[]>;
+    public datasetList: Observable<Dataset[]>;
+    public isValidConeSearch: Observable<boolean>;
+    public coneSearch: Observable<ConeSearch>;
+    public selectedDatasets: Observable<string[]>;
+    public noSelectedDatasets: Observable<boolean>;
+    public queryParams: Observable<SearchMultipleQueryParams>;
+
+    constructor(private store: Store<StoreState>, private scrollTopService: ScrollTopService) {
+        this.datasetSearchMetaIsLoading = store.select(metamodelSelector.getDatasetSearchMetaIsLoading);
+        this.datasetSearchMetaIsLoaded = store.select(metamodelSelector.getDatasetSearchMetaIsLoaded);
+        this.currentStep = store.select(searchMultipleSelector.getCurrentStep);
+        this.surveyList = store.select(metamodelSelector.getSurveyList);
+        this.datasetFamilyList = store.select(metamodelSelector.getDatasetFamilyList);
+        this.datasetList = store.select(metamodelSelector.getDatasetWithConeSearchList);
+        this.isValidConeSearch = this.store.select(coneSearchSelector.getIsValidConeSearch);
+        this.selectedDatasets = this.store.select(searchMultipleSelector.getSelectedDatasets);
+        this.noSelectedDatasets = this.store.select(searchMultipleSelector.getNoSelectedDatasets);
+        this.coneSearch = this.store.select(coneSearchSelector.getConeSearch);
+        this.queryParams = this.store.select(searchMultipleSelector.getQueryParams);
+    }
+
+    ngOnInit() {
+        // Create a micro task that is processed after the current synchronous code
+        // This micro task prevent the expression has changed after view init error
+        Promise.resolve(null).then(() => this.store.dispatch(new searchMultipleActions.InitSearchByUrlAction()));
+        Promise.resolve(null).then(() => this.store.dispatch(new searchMultipleActions.ChangeStepAction('datasets')));
+        this.store.dispatch(new datasetActions.LoadDatasetSearchMetaAction());
+        this.scrollTopService.setScrollTop();
+    }
+
+    /**
+     * Dispatches action to check datasets step.
+     */
+    checkStep(): void {
+        this.store.dispatch(new searchMultipleActions.DatasetsCheckedAction());
+    }
+
+    /**
+     * Dispatches action to update dataset list selection with the given updated selected dataset name list.
+     *
+     * @param  {string[]} selectedDatasets - The updated dataset name list.
+     */
+    updateSelectedDatasets(selectedDatasets: string[]): void {
+        this.store.dispatch(new searchMultipleActions.UpdateSelectedDatasetsAction(selectedDatasets));
+    }
+}
diff --git a/client/src/app/instance/search-multiple/containers/position.component.html b/client/src/app/instance/search-multiple/containers/position.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..b9124abb6a7577dfe418c6f0ecb6d70aac85ea6e
--- /dev/null
+++ b/client/src/app/instance/search-multiple/containers/position.component.html
@@ -0,0 +1,42 @@
+<div class="row mt-4">
+    <div class="col-12 col-md-8 col-lg-9">
+        <div class="border rounded my-2">
+            <p class="border-bottom bg-light text-primary mb-0 py-4 pl-4">Cone Search</p>
+            <div class="p-4">
+                <app-cone-search></app-cone-search>
+                <div class=" pt-3 text-center">
+                    <button class="btn btn-outline-secondary" (click)="resetConeSearch()">Reset cone search</button>
+                </div>
+            </div>
+        </div>
+    </div>
+    <div class="col-12 col-md-4 col-lg-3 pt-2">
+        <app-summary-multiple
+            [currentStep]="currentStep | async"
+            [isValidConeSearch]="isValidConeSearch | async"
+            [coneSearch]="coneSearch | async"
+            [datasetSearchMetaIsLoading]="datasetSearchMetaIsLoading | async"
+            [datasetSearchMetaIsLoaded]="datasetSearchMetaIsLoaded | async"
+            [datasetFamilyList]="datasetFamilyList | async"
+            [datasetList]="datasetList | async"
+            [selectedDatasets]="selectedDatasets | async"
+            [noSelectedDatasets]="noSelectedDatasets | async"
+            [queryParams]="queryParams | async">
+        </app-summary-multiple>
+    </div>
+</div>
+
+<div class="row mt-5 justify-content-end">
+    <div class="col col-auto">
+        <button *ngIf="!(isValidConeSearch | async)" class="btn btn-outline-primary disabled not-allowed" title="Not valid position!">
+            Next <span class="fas fa-arrow-right"></span>
+        </button>
+        <a *ngIf="isValidConeSearch | async"
+           routerLink="/search-multiple/datasets"
+           [queryParams]="queryParams | async"
+           (click)="checkStep()"
+           class="btn btn-outline-primary">
+            Next <span class="fas fa-arrow-right"></span>
+        </a>
+    </div>
+</div>
diff --git a/client/src/app/instance/search-multiple/containers/position.component.scss b/client/src/app/instance/search-multiple/containers/position.component.scss
new file mode 100644
index 0000000000000000000000000000000000000000..b2357fc44b2ff0cb28e86578b3aaaa8bd2ba221a
--- /dev/null
+++ b/client/src/app/instance/search-multiple/containers/position.component.scss
@@ -0,0 +1,12 @@
+/**
+ * This file is part of Anis Client.
+ *
+ * @copyright Laboratoire d'Astrophysique de Marseille / CNRS
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+.disabled {
+    cursor: not-allowed;
+}
diff --git a/client/src/app/instance/search-multiple/containers/position.component.ts b/client/src/app/instance/search-multiple/containers/position.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..f5541c63c2884260e065fc6d3c883426efb25b41
--- /dev/null
+++ b/client/src/app/instance/search-multiple/containers/position.component.ts
@@ -0,0 +1,96 @@
+/**
+ * This file is part of Anis Client.
+ *
+ * @copyright Laboratoire d'Astrophysique de Marseille / CNRS
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+import { Component, OnInit } from '@angular/core';
+
+import { Store } from '@ngrx/store';
+import { Observable } from 'rxjs';
+
+import * as fromSearchMultiple from '../store/search-multiple.reducer';
+import * as searchMultipleActions from '../store/search-multiple.action';
+import * as searchMultipleSelector from '../store/search-multiple.selector';
+import { SearchMultipleQueryParams } from '../store/model';
+import * as datasetActions from '../../metamodel/action/dataset.action';
+import * as fromMetamodel from '../../metamodel/reducers';
+import * as metamodelSelector from '../../metamodel/selectors';
+import { Dataset, Family } from '../../metamodel/model';
+import * as coneSearchActions from '../../shared/cone-search/store/cone-search.action';
+import * as coneSearchSelector from '../../shared/cone-search/store/cone-search.selector';
+import { ConeSearch } from '../../shared/cone-search/store/model';
+import { ScrollTopService } from '../../shared/service/sroll-top.service';
+
+/**
+ * Interface for store state.
+ *
+ * @interface StoreState
+ */
+interface StoreState {
+    searchMultiple: fromSearchMultiple.State;
+    metamodel: fromMetamodel.State;
+}
+
+@Component({
+    selector: 'app-position',
+    templateUrl: 'position.component.html',
+    styleUrls: ['position.component.scss']
+})
+/**
+ * @class
+ * @classdesc Search multiple position container.
+ *
+ * @implements OnInit
+ */
+export class PositionComponent implements OnInit {
+    public datasetSearchMetaIsLoading: Observable<boolean>;
+    public datasetSearchMetaIsLoaded: Observable<boolean>;
+    public currentStep: Observable<string>;
+    public isValidConeSearch: Observable<boolean>;
+    public coneSearch: Observable<ConeSearch>;
+    public datasetFamilyList: Observable<Family[]>;
+    public datasetList: Observable<Dataset[]>;
+    public selectedDatasets: Observable<string[]>;
+    public noSelectedDatasets: Observable<boolean>;
+    public queryParams: Observable<SearchMultipleQueryParams>;
+
+    constructor(private store: Store<StoreState>, private scrollTopService: ScrollTopService) {
+        this.datasetSearchMetaIsLoading = store.select(metamodelSelector.getDatasetSearchMetaIsLoading);
+        this.datasetSearchMetaIsLoaded = store.select(metamodelSelector.getDatasetSearchMetaIsLoaded);
+        this.currentStep = store.select(searchMultipleSelector.getCurrentStep);
+        this.isValidConeSearch = this.store.select(coneSearchSelector.getIsValidConeSearch);
+        this.coneSearch = this.store.select(coneSearchSelector.getConeSearch);
+        this.datasetFamilyList = store.select(metamodelSelector.getDatasetFamilyList);
+        this.datasetList = store.select(metamodelSelector.getDatasetWithConeSearchList);
+        this.selectedDatasets = store.select(searchMultipleSelector.getSelectedDatasets);
+        this.noSelectedDatasets = store.select(searchMultipleSelector.getNoSelectedDatasets);
+        this.queryParams = this.store.select(searchMultipleSelector.getQueryParams);
+    }
+
+    ngOnInit() {
+        // Create a micro task that is processed after the current synchronous code
+        // This micro task prevent the expression has changed after view init error
+        Promise.resolve(null).then(() => this.store.dispatch(new searchMultipleActions.InitSearchByUrlAction()));
+        Promise.resolve(null).then(() => this.store.dispatch(new searchMultipleActions.ChangeStepAction('position')));
+        this.store.dispatch(new datasetActions.LoadDatasetSearchMetaAction());
+        this.scrollTopService.setScrollTop();
+    }
+
+    /**
+     * Dispatches action to check position step.
+     */
+    checkStep(): void {
+        this.store.dispatch(new searchMultipleActions.PositionCheckedAction());
+    }
+
+    /**
+     * Dispatches action to reset cone search.
+     */
+    resetConeSearch(): void {
+        this.store.dispatch(new coneSearchActions.DeleteConeSearchAction());
+    }
+}
diff --git a/client/src/app/instance/search-multiple/containers/result-multiple.component.html b/client/src/app/instance/search-multiple/containers/result-multiple.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..f1d2d75d3ff6eaf0f17ed33584af25108b69c868
--- /dev/null
+++ b/client/src/app/instance/search-multiple/containers/result-multiple.component.html
@@ -0,0 +1,39 @@
+<div class="row mt-4">
+    <div class="col-12">
+        <app-overview
+            [datasetSearchMetaIsLoaded]="datasetSearchMetaIsLoaded | async"
+            [coneSearch]="coneSearch | async"
+            [datasetFamilyList]="datasetFamilyList | async"
+            [datasetList]="datasetList | async"
+            [selectedDatasets]="selectedDatasets | async"
+            [queryParams]="queryParams | async"
+            [datasetsCountIsLoaded]="datasetsCountIsLoaded | async"
+            [datasetsCount]="datasetsCount | async"
+            (getDatasetCount)="getDatasetsCount()">
+        </app-overview>
+        <app-datasets-result
+            [datasetsCountIsLoaded]="datasetsCountIsLoaded | async"
+            [datasetFamilyList]="datasetFamilyList | async"
+            [datasetList]="datasetList | async"
+            [coneSearch]="coneSearch | async"
+            [selectedDatasets]="selectedDatasets | async"
+            [datasetsCount]="datasetsCount | async"
+            [datasetsWithAttributeList]="datasetsWithAttributeList | async"
+            [allAttributeList]="allAttributeList | async"
+            [datasetsWithData]="datasetsWithData | async"
+            [allData]="allData | async"
+            [selectedData]="selectedData | async"
+            (retrieveMeta)="retrieveMeta($event)"
+            (retrieveData)="retrieveData($event)"
+            (updateSelectedData)="updateSelectedData($event)">
+        </app-datasets-result>
+    </div>
+</div>
+<div *ngIf="(datasetSearchMetaIsLoaded | async) && (datasetsCountIsLoaded | async)" class="row mt-5 justify-content-between">
+    <div class="col">
+        <a routerLink="/search-multiple/datasets" [queryParams]="queryParams | async"
+            class="btn btn-outline-secondary">
+            <span class="fas fa-arrow-left"></span> Previous
+        </a>
+    </div>
+</div>
diff --git a/client/src/app/instance/search-multiple/containers/result-multiple.component.ts b/client/src/app/instance/search-multiple/containers/result-multiple.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..64b5ed34853a6e95a67995bcd8ff36b808ccc136
--- /dev/null
+++ b/client/src/app/instance/search-multiple/containers/result-multiple.component.ts
@@ -0,0 +1,142 @@
+/**
+ * This file is part of Anis Client.
+ *
+ * @copyright Laboratoire d'Astrophysique de Marseille / CNRS
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+import { Component, OnInit, OnDestroy } from '@angular/core';
+
+import { Store } from '@ngrx/store';
+import { Dictionary } from '@ngrx/entity';
+import { Observable } from 'rxjs';
+
+import * as fromSearchMultiple from '../store/search-multiple.reducer';
+import * as searchMultipleActions from '../store/search-multiple.action';
+import * as searchMultipleSelector from '../store/search-multiple.selector';
+import { DataByDataset, DatasetCount, SearchMultipleQueryParams } from '../store/model';
+import * as fromMetamodel from '../../metamodel/reducers';
+import * as datasetActions from '../../metamodel/action/dataset.action';
+import * as attributeActions from '../../metamodel/action/attribute.action';
+import * as metamodelSelector from '../../metamodel/selectors';
+import { AttributesByDataset, Dataset, Family } from '../../metamodel/model';
+import * as coneSearchSelector from '../../shared/cone-search/store/cone-search.selector';
+import { ConeSearch } from '../../shared/cone-search/store/model';
+import { Pagination } from '../../shared/datatable/model';
+import { ScrollTopService } from '../../shared/service/sroll-top.service';
+
+/**
+ * Interface for store state.
+ *
+ * @interface StoreState
+ */
+interface StoreState {
+    searchMultiple: fromSearchMultiple.State;
+    metamodel: fromMetamodel.State;
+}
+
+@Component({
+    selector: 'app-result-multiple',
+    templateUrl: 'result-multiple.component.html'
+})
+/**
+ * @class
+ * @classdesc Search multiple result container.
+ *
+ * @implements OnInit
+ * @implements OnDestroy
+ */
+export class ResultMultipleComponent implements OnInit, OnDestroy {
+    public datasetSearchMetaIsLoading: Observable<boolean>;
+    public datasetSearchMetaIsLoaded: Observable<boolean>;
+    public datasetFamilyList: Observable<Family[]>;
+    public datasetList: Observable<Dataset[]>;
+    public currentStep: Observable<string>;
+    public coneSearch: Observable<ConeSearch>;
+    public selectedDatasets: Observable<string[]>;
+    public queryParams: Observable<SearchMultipleQueryParams>;
+    public datasetsCountIsLoading: Observable<boolean>;
+    public datasetsCountIsLoaded: Observable<boolean>;
+    public datasetsCount: Observable<DatasetCount[]>;
+    public datasetsWithAttributeList: Observable<string[] | number[]>;
+    public allAttributeList: Observable<Dictionary<AttributesByDataset>>;
+    public data: Observable<{ dname: string, data: any[]}[]>;
+    public datasetsWithData: Observable<string[] | number[]>;
+    public allData: Observable<Dictionary<DataByDataset>>;
+    public selectedData: Observable<{ dname: string, data: (number | string)[] }[]>;
+
+    constructor(private store: Store<StoreState>, private scrollTopService: ScrollTopService) {
+        this.datasetSearchMetaIsLoading = store.select(metamodelSelector.getDatasetSearchMetaIsLoading);
+        this.datasetSearchMetaIsLoaded = store.select(metamodelSelector.getDatasetSearchMetaIsLoaded);
+        this.currentStep = store.select(searchMultipleSelector.getCurrentStep);
+        this.datasetFamilyList = store.select(metamodelSelector.getDatasetFamilyList);
+        this.datasetList = store.select(metamodelSelector.getDatasetList);
+        this.coneSearch = this.store.select(coneSearchSelector.getConeSearch);
+        this.selectedDatasets = this.store.select(searchMultipleSelector.getSelectedDatasets);
+        this.queryParams = this.store.select(searchMultipleSelector.getQueryParams);
+        this.datasetsCountIsLoading = this.store.select(searchMultipleSelector.getDatasetsCountIsLoading);
+        this.datasetsCountIsLoaded = this.store.select(searchMultipleSelector.getDatasetsCountIsLoaded);
+        this.datasetsCount = this.store.select(searchMultipleSelector.getDatasetsCount);
+        this.datasetsWithAttributeList = this.store.select(metamodelSelector.getDatasetsWithAttributeList);
+        this.allAttributeList = this.store.select(metamodelSelector.getAllAttributeList);
+        this.datasetsWithData = this.store.select(searchMultipleSelector.getDatasetsWithData);
+        this.allData = this.store.select(searchMultipleSelector.getAllData);
+        this.selectedData = this.store.select(searchMultipleSelector.getSelectedData);
+    }
+
+    ngOnInit() {
+        // Create a micro task that is processed after the current synchronous code
+        // This micro task prevent the expression has changed after view init error
+        Promise.resolve(null).then(() => this.store.dispatch(new searchMultipleActions.ChangeStepAction('result')));
+        Promise.resolve(null).then(() => this.store.dispatch(new searchMultipleActions.InitSearchByUrlAction()));
+        this.store.dispatch(new datasetActions.LoadDatasetSearchMetaAction());
+        this.scrollTopService.setScrollTop();
+    }
+
+    /**
+     * Dispatches action to retrieve dataset result number.
+     */
+    getDatasetsCount(): void {
+        this.store.dispatch(new searchMultipleActions.RetrieveDatasetsCountAction());
+    }
+
+    /**
+     * Dispatches action to retrieve metadata of a given dataset name.
+     *
+     * @param  {string} dname - The dataset name.
+     */
+    retrieveMeta(dname: string): void {
+        this.store.dispatch(new attributeActions.LoadAttributeListAction(dname));
+    }
+
+    /**
+     * Dispatches action to retrieve data with the given pagination parameters.
+     *
+     * @param  {Pagination} params - The pagination parameters.
+     */
+    retrieveData(params: Pagination): void {
+        this.store.dispatch(new searchMultipleActions.RetrieveDataAction(params));
+    }
+
+    /**
+     * Dispatches action to update data selection with the given updated selected data.
+     *
+     * @param  {{ dname: string, data: (string | number)[] }[]} data - The updated selected data.
+     */
+    updateSelectedData(data: { dname: string, data: (string | number)[] }[]): void {
+        this.store.dispatch(new searchMultipleActions.UpdateSelectedDataAction(data));
+    }
+
+    // executeProcess(typeProcess: string): void {
+    //     this.store.dispatch(new searchActions.ExecuteProcessAction(typeProcess));
+    // }
+
+    /**
+     * Dispatches action to destroy search multiple results.
+     */
+    ngOnDestroy() {
+        this.store.dispatch(new searchMultipleActions.DestroyResultsAction());
+    }
+}
diff --git a/client/src/app/instance/search-multiple/search-multiple-routing.module.ts b/client/src/app/instance/search-multiple/search-multiple-routing.module.ts
index 4438a68664b0e8e931aabab371af2a8841fc845f..3f84f0f1080a2920ace0b1cf211ab6551b92cc24 100644
--- a/client/src/app/instance/search-multiple/search-multiple-routing.module.ts
+++ b/client/src/app/instance/search-multiple/search-multiple-routing.module.ts
@@ -10,10 +10,16 @@
 import { NgModule } from '@angular/core';
 import { Routes, RouterModule } from '@angular/router';
 
-//import { SearchMultipleComponent } from './search-multiple.component';
+import { SearchMultipleComponent } from './search-multiple.component';
+import { PositionComponent } from './containers/position.component';
 
 const routes: Routes = [
-    //{ path: '', component: SearchMultipleComponent }
+    {
+        path: '', component: SearchMultipleComponent, children: [
+            { path: '', redirectTo: 'position', pathMatch: 'full' },
+            { path: 'dataset', component: PositionComponent }
+        ]
+    }
 ];
 
 @NgModule({
@@ -23,5 +29,6 @@ const routes: Routes = [
 export class SearchMultipleRoutingModule { }
 
 export const routedComponents = [
-    //SearchMultipleComponent
+    SearchMultipleComponent,
+    PositionComponent
 ];
diff --git a/client/src/app/instance/search-multiple/search-multiple.component.html b/client/src/app/instance/search-multiple/search-multiple.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..c3301e3f07d79acf1e1cdcb4ff68816611727dc5
--- /dev/null
+++ b/client/src/app/instance/search-multiple/search-multiple.component.html
@@ -0,0 +1,12 @@
+<div class="mx-1 mx-sm-5 px-1 px-sm-5">
+    <app-progress-bar-multiple
+        [currentStep]="currentStep | async"
+        [positionStepChecked]="positionStepChecked | async"
+        [datasetsStepChecked]="datasetsStepChecked | async"
+        [resultStepChecked]="resultStepChecked | async"
+        [isValidConeSearch]="isValidConeSearch | async"
+        [noSelectedDatasets]="noSelectedDatasets | async"
+        [queryParams]="queryParams | async">
+    </app-progress-bar-multiple>
+    <router-outlet></router-outlet>
+</div>
diff --git a/client/src/app/instance/search-multiple/search-multiple.component.ts b/client/src/app/instance/search-multiple/search-multiple.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..e5d5e1b9a3da95de2a64b194ffbae12c2c9c1fe0
--- /dev/null
+++ b/client/src/app/instance/search-multiple/search-multiple.component.ts
@@ -0,0 +1,53 @@
+/**
+ * This file is part of Anis Client.
+ *
+ * @copyright Laboratoire d'Astrophysique de Marseille / CNRS
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+import { Component, } from '@angular/core';
+
+import { Store } from '@ngrx/store';
+import { Observable } from 'rxjs';
+
+import { SearchMultipleQueryParams } from '../store/models';
+import { Instance } from 'src/app/metamodel/models';
+
+import * as searchMultipleReducer from '../store/search-multiple.reducer';
+import * as searchMultipleSelector from '../store/search-multiple.selector';
+import * as searchActions from '../../search/store/search.action';
+import * as coneSearchSelector from '../../shared/cone-search/store/cone-search.selector';
+import * as coneSearchActions from '../../shared/cone-search/store/cone-search.action';
+
+@Component({
+    selector: 'app-search-multiple',
+    templateUrl: 'search-multiple.component.html'
+})
+/**
+ * @class
+ * @classdesc Search multiple container.
+ */
+export class SearchMultipleComponent {
+    public instance: Observable<Instance>;
+    public currentStep: Observable<string>;
+    public positionStepChecked: Observable<boolean>;
+    public datasetsStepChecked: Observable<boolean>;
+    public resultStepChecked: Observable<boolean>;
+    public isValidConeSearch: Observable<boolean>;
+    public noSelectedDatasets: Observable<boolean>;
+    public queryParams: Observable<SearchMultipleQueryParams>;
+
+    constructor(private store: Store<searchMultipleReducer.State>) {
+        this.currentStep = store.select(searchMultipleSelector.getCurrentStep);
+        this.positionStepChecked = store.select(searchMultipleSelector.getPositionStepChecked);
+        this.datasetsStepChecked = store.select(searchMultipleSelector.getDatasetsStepChecked);
+        this.resultStepChecked = store.select(searchMultipleSelector.getResultStepChecked);
+        this.isValidConeSearch = store.select(coneSearchSelector.getIsValidConeSearch);
+        this.noSelectedDatasets = store.select(searchMultipleSelector.getNoSelectedDatasets);
+        this.queryParams = store.select(searchMultipleSelector.getQueryParams);
+        this.store.dispatch(new searchActions.ResetSearchAction());
+        this.store.dispatch(new coneSearchActions.DeleteConeSearchAction());
+    }
+}
diff --git a/client/src/app/instance/search-multiple/search-multiple.module.ts b/client/src/app/instance/search-multiple/search-multiple.module.ts
index 6368aaf5ac0eed7e0f4be27e5839c470efd21e25..f309487d7a04e1e064c428c6a1303379f093d57d 100644
--- a/client/src/app/instance/search-multiple/search-multiple.module.ts
+++ b/client/src/app/instance/search-multiple/search-multiple.module.ts
@@ -10,13 +10,19 @@
 import { NgModule } from '@angular/core';
 
 import { SharedModule } from 'src/app/shared/shared.module';
+import { SharedSearchModule } from '../shared-search/shared-search.module';
 import { SearchMultipleRoutingModule, routedComponents } from './search-multiple-routing.module';
+import { dummiesComponents } from './components';
 
 @NgModule({
     imports: [
         SharedModule,
+        SharedSearchModule,
         SearchMultipleRoutingModule
     ],
-    declarations: [routedComponents]
+    declarations: [
+        routedComponents,
+        dummiesComponents
+    ]
 })
 export class SearchMultipleModule { }
diff --git a/client/src/app/instance/store/actions/search-multiple.actions.ts b/client/src/app/instance/store/actions/search-multiple.actions.ts
new file mode 100644
index 0000000000000000000000000000000000000000..b28b0ac2741474bb276bf0b6cde90f82bf8b4498
--- /dev/null
+++ b/client/src/app/instance/store/actions/search-multiple.actions.ts
@@ -0,0 +1,11 @@
+/**
+ * This file is part of Anis Client.
+ *
+ * @copyright Laboratoire d'Astrophysique de Marseille / CNRS
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+import { createAction, props } from '@ngrx/store';
+
diff --git a/client/src/app/instance/store/models/index.ts b/client/src/app/instance/store/models/index.ts
index c471d6929ad3c505f8a5a9386d3d6f716d49e750..0f5c77df814cb0308a6169302d0c82e9f01a43f7 100644
--- a/client/src/app/instance/store/models/index.ts
+++ b/client/src/app/instance/store/models/index.ts
@@ -1,5 +1,6 @@
 export * from './criterion.model';
 export * from './search-query-params.model';
+export * from './search-multiple-query-params.model';
 export * from './criterion';
 export * from './pagination.model';
 export * from './cone-search.model';
diff --git a/client/src/app/instance/store/models/search-multiple-query-params.model.ts b/client/src/app/instance/store/models/search-multiple-query-params.model.ts
new file mode 100644
index 0000000000000000000000000000000000000000..9e4cd67b1047b0288bf8fcfabe5c895f41a1713a
--- /dev/null
+++ b/client/src/app/instance/store/models/search-multiple-query-params.model.ts
@@ -0,0 +1,18 @@
+/**
+ * This file is part of Anis Client.
+ *
+ * @copyright Laboratoire d'Astrophysique de Marseille / CNRS
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Interface for search multiple query parameters.
+ *
+ * @interface SearchMultipleQueryParams
+ */
+export interface SearchMultipleQueryParams {
+    cs?: string;
+    d?: string;
+}