diff --git a/src/app/degree-planner/degree-planner.component.html b/src/app/degree-planner/degree-planner.component.html
index 0cb8a39e38844a7d70471e9a731b7b392e40898f..83d91f44622458dd7b8f5362e3efa3d50eec226b 100644
--- a/src/app/degree-planner/degree-planner.component.html
+++ b/src/app/degree-planner/degree-planner.component.html
@@ -3,44 +3,43 @@
 	<mat-sidenav #addMenu position="end" mode="over" [opened]="isCourseSearchOpen$ | async">
 		<mat-toolbar color="primary" class="dialog-toolbar">
 			<span class="dialog-toolbar-title">Course Search</span>
-			<button mat-button class="close-btn" (click)="closeCourseSearch();"><i class="material-icons">clear</i></button>
+			<button mat-button class="close-btn" (click)="closeCourseSearch();"><i class="material-icons">keyboard_arrow_right</i></button>
 		</mat-toolbar>
-	
-		<div [formGroup]='courseSearchForm' class="add-course-form" fxLayout="column" fxLayoutAlign="space-around none" style="padding: 12px 22px;">
+			
+		<form [formGroup]='courseSearchForm' (ngSubmit)="search()" class="add-course-form" fxLayout="column" fxLayoutAlign="space-around none" style="padding: 12px 22px;">
 			<mat-form-field>
-				<input type="text" placeholder="Term" aria-label="Term" matInput [formControl]="" [matAutocomplete]="term">
-				<mat-autocomplete #term="matAutocomplete">
-					<mat-option *ngFor="let term of (coursesData$ | async)" [value]="term[0].termCode | getTermDescription">
-						{{ term[0].termCode | getTermDescription }}
-					</mat-option>
-				</mat-autocomplete>
+				<mat-select placeholder="Term" formControlName="term">
+						<mat-option value="0000" selected>All</mat-option>
+						<mat-option *ngFor="let term of activeTerms$ | async" [value]="term">{{term | getTermDescription}}</mat-option>
+					</mat-select>
 			</mat-form-field>
 
 			<mat-form-field>
-				<input matInput placeholder="Subject" formControlName='coursesInput' required>
-				<!-- <mat-error *ngIf="coursesInput.invalid">Please select an existing Subject or 'All'.</mat-error> -->
+				<mat-select placeholder="Subject" formControlName="subject" required>
+					<mat-option value="all">All</mat-option>
+					<mat-option *ngFor="let subject of (subjects$ | async) | keyvalue" [value]="subject.key">
+						{{subject.value}}
+					</mat-option>
+				</mat-select>
 			</mat-form-field>
 
-			<mat-form-field class="example-full-width">
-				<input matInput placeholder="Keyword, number" value="">
+			<mat-form-field>
+				<div class="search-input-wrapper">
+					<input id="keyword-field" matInput placeholder="Keyword, number" formControlName="search" value="">
+					<button id="search-button" mat-icon-button aria-label="Search" matSuffix style="margin-top: -10px;"><i class="material-icons">search</i></button>
+				</div>
 			</mat-form-field>
+		</form>
 
-			<button mat-button (click)="search()">Search <i class="material-icons">search</i></button>
-
-			<div class="search-results-toolbar mat-typography" fxLayout="row" fxLayoutAlign="space-between center" style="padding: 12px 22px; background-color: #EDF1F3">
-				<h3 style="margin: 0px;">15 results</h3>
-				<span class="mat-button">Reset Search</span>
+		<div *ngIf="hasResults || isLoading">
+			<div class="search-results-toolbar mat-typography" fxLayout="row" fxLayoutAlign="space-between center" style="padding: 12px 22px; background-color: #EDF1F3; min-height: 60px;">
+				<h3 *ngIf="isLoading" style="margin: 0px;">Searching for courses...</h3>
+				<h3 *ngIf="hasResults" style="margin: 0px;">{{queriedCourses.length}} result(s)</h3>
+				<button *ngIf="hasResults" mat-button (click)="resetSearch()">Reset Search</button>
 			</div>
-	
+			<mat-progress-bar mode="indeterminate" *ngIf="isLoading"></mat-progress-bar>
+			
 			<div id="course-search-results" fxLayout="column" fxLayoutAlign="space-around none" style="padding: 12px 22px;">
-				<mat-form-field>
-					<mat-select placeholder="Order by">
-						<mat-option>Relevance</mat-option>
-						<mat-option>Subject</mat-option>
-						<mat-option>Catalog Number</mat-option>
-					</mat-select>
-				</mat-form-field>
-
 				<div
 					cdkDropList
 					id="queried-courses-list"
diff --git a/src/app/degree-planner/degree-planner.component.scss b/src/app/degree-planner/degree-planner.component.scss
index a86efb37cb46f307a6094fc7e17820f1635826a1..191df4e4c51da1ba5f875d99f90561401578276c 100644
--- a/src/app/degree-planner/degree-planner.component.scss
+++ b/src/app/degree-planner/degree-planner.component.scss
@@ -6,10 +6,6 @@ mat-sidenav {
   width: 340px;
 }
 
-#degree-plan-wrapper {
-  // margin-right: 0 !important;
-}
-
 #menu-toggle-btn {
   position: absolute;
   right: 0px;
@@ -52,3 +48,10 @@ mat-sidenav {
     padding: 12px;
   }
 }
+
+// Course search
+.search-input-wrapper {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+}
diff --git a/src/app/degree-planner/degree-planner.component.ts b/src/app/degree-planner/degree-planner.component.ts
index 1050db439dfde6a6979dcb343db3e0a57be43a8b..56f961e6e8ee159111e5122caea48c1b1091abc3 100644
--- a/src/app/degree-planner/degree-planner.component.ts
+++ b/src/app/degree-planner/degree-planner.component.ts
@@ -41,6 +41,8 @@ import {
   hasLoadedDegreePlan,
   getDropZones,
   isCourseSearchOpen,
+  getSubjects,
+  getActiveTerms,
 } from '@app/degree-planner/store/selectors';
 
 // Actions
@@ -77,9 +79,15 @@ export class DegreePlannerComponent implements OnInit {
   public allDegreePlans$: Observable<DegreePlan[]>;
   public firstActiveTermCode$: Observable<string | undefined>;
   public termsByYear$: Observable<Year[]>;
+  public isCourseSearchOpen$: Observable<boolean>;
+  public subjects$: Observable<object>;
+  public activeTerms$: Observable<string[]>;
+
+  // Search variables
   public queriedCourses: Course[];
+  public hasResults: boolean;
+  public isLoading: boolean;
   public courseSearchForm: FormGroup;
-  public isCourseSearchOpen$: Observable<boolean>;
 
   constructor(
     private store: Store<GlobalState>,
@@ -103,8 +111,20 @@ export class DegreePlannerComponent implements OnInit {
     this.termsByYear$ = this.store.pipe(select(getAllVisibleTermsByYear));
     this.dropZones$ = this.store.pipe(select(getDropZones));
 
+    // State attributes needed to create the search form
+    this.subjects$ = this.store.pipe(select(getSubjects));
+    this.activeTerms$ = this.store.pipe(select(getActiveTerms));
+
+    // Internal values used to manage loading state
+    this.queriedCourses = [];
+    this.hasResults = false;
+    this.isLoading = false;
+
+    // Deafults for the search form
     this.courseSearchForm = this.fb.group({
-      coursesInput: null,
+      term: '0000',
+      subject: 'all',
+      search: '',
     });
 
     this.isCourseSearchOpen$ = this.store.pipe(select(isCourseSearchOpen));
@@ -225,13 +245,30 @@ export class DegreePlannerComponent implements OnInit {
   }
 
   public search() {
-    // console.log('here');
-    // console.log(this.coursesForm.value.subjectCode);
+    // Get the form field values
+    const { search, term, subject } = this.courseSearchForm.value;
+
+    // Set the internal UI state
+    this.isLoading = true;
+    this.hasResults = false;
+    this.queriedCourses = [];
+
+    // Hit the search API
     this.api
-      .searchCourses('test', 'test')
+      .searchCourses({
+        subjectCode: subject,
+        searchText: search,
+        termCode: term === '' ? '0000' : term,
+      })
       .toPromise()
       .then(res => {
-        console.log(res.hits);
+        // TODO add error handeling
+
+        // Update the internal state
+        this.hasResults = true;
+        this.isLoading = false;
+
+        // Map out the results and update the course object to match the needed structure
         this.queriedCourses = res.hits.map(course => {
           return {
             ...course,
@@ -242,6 +279,16 @@ export class DegreePlannerComponent implements OnInit {
       })
       .catch(console.log);
   }
+
+  public resetSearch() {
+    // Reset the internal state and form values
+    this.queriedCourses = [];
+    this.hasResults = false;
+    this.courseSearchForm.setValue({
+      subject: 'all',
+      search: '',
+    });
+  }
 }
 
 const isntUndefined = <T>(anything: T | undefined): anything is T => {
diff --git a/src/app/degree-planner/services/api.service.ts b/src/app/degree-planner/services/api.service.ts
index dbd233f272c0768de5fbda31a1660d9ad9da3274..63a681a57b3fa57d402929db133d115c359ea523 100644
--- a/src/app/degree-planner/services/api.service.ts
+++ b/src/app/degree-planner/services/api.service.ts
@@ -4,7 +4,7 @@ import { Injectable } from '@angular/core';
 import { HttpClient, HttpHeaders } from '@angular/common/http';
 import { Location } from '@angular/common';
 import { Observable } from 'rxjs';
-import { map } from 'rxjs/operators';
+import { map, filter } from 'rxjs/operators';
 
 // Services
 import { ConfigService } from '@app/core/config.service';
@@ -106,7 +106,11 @@ export class DegreePlannerApiService {
     return this.http.post('/api/search/v1/autocomplete', data, HTTP_OPTIONS);
   }
 
-  public searchCourses(search: string, subjectCode: string): Observable<any> {
+  public searchCourses(config: {
+    subjectCode: string;
+    searchText?: string;
+    termCode?: string;
+  }): Observable<any> {
     // const data = {
     //   filters: [
     //     { term: { 'subject.subjectCode': '266' } },
@@ -128,43 +132,44 @@ export class DegreePlannerApiService {
     //   sortOrder: 'SCORE',
     // };
 
-    // Used to search all terms
-    const data = {
-      filters: [{ term: { 'subject.subjectCode': '266' } }],
-      page: 1,
-      pageSize: 10,
-      queryString: 'Programming',
-      selectedTerm: '0000',
-      sortOrder: 'SCORE',
-    };
+    const { subjectCode, termCode, searchText } = config;
 
-    // Used to search a specific term
-    const test = {
-      selectedTerm: '1194',
-      queryString: 'programing',
+    const payload: any = {
+      selectedTerm: termCode,
+      queryString: searchText === '' ? '*' : searchText,
 
       // Filters are use to build the elastic search query
-      filters: [
-        { term: { 'subject.subjectCode': '266' } },
-        {
-          has_child: {
-            type: 'enrollmentPackage',
-            query: {
-              // We want to make sure we search for ALL classes regardless of status
-              match: {
-                'packageEnrollmentStatus.status': 'OPEN WAITLISTED CLOSED',
-              },
-            },
-          },
-        },
-      ],
+      filters: [],
 
       // These options control how much data we get back
       page: 1,
-      pageSize: 20,
+      pageSize: 25,
+      sortOrder: 'SCORE',
     };
 
-    return this.http.post('/api/search/v1', data, HTTP_OPTIONS);
+    // If we have a specific subject code, add a fitler for it
+    if (subjectCode !== 'all') {
+      payload.filters.push({ term: { 'subject.subjectCode': subjectCode } });
+    }
+
+    // 0000 is used to search all courses
+    // Any other term code we can assuem is an active term
+    if (termCode !== '0000') {
+      // Used to search a specific term
+      payload.filters.push({
+        has_child: {
+          type: 'enrollmentPackage',
+          query: {
+            // We want to make sure we search for ALL classes regardless of status
+            match: {
+              'packageEnrollmentStatus.status': 'OPEN WAITLISTED CLOSED',
+            },
+          },
+        },
+      });
+    }
+
+    return this.http.post('/api/search/v1', payload, HTTP_OPTIONS);
   }
 
   public addCourse(
diff --git a/src/app/degree-planner/store/selectors.ts b/src/app/degree-planner/store/selectors.ts
index 15c890d4ff495cd52de71f0bf8d2dcf763605ca1..01ce5daa0c87da0c427975d502d2c6863ae387ef 100644
--- a/src/app/degree-planner/store/selectors.ts
+++ b/src/app/degree-planner/store/selectors.ts
@@ -69,6 +69,8 @@ export const getDropableTerms = createSelector(
 export const getAllVisibleTermsByYear = createSelector(
   getDegreePlannerState,
   state => {
+    console.log('getting visible terms');
+
     const unqiueYears = state.visibleTerms
       .map(term => term.termCode.slice(0, 3))
       .filter(year => year.match(/^\d{3}/))
@@ -117,6 +119,20 @@ export const isCourseSearchOpen = createSelector(
   },
 );
 
+export const getSubjects = createSelector(
+  getDegreePlannerState,
+  (state: DegreePlannerState) => {
+    return state.subjects;
+  },
+);
+
+export const getActiveTerms = createSelector(
+  getDegreePlannerState,
+  (state: DegreePlannerState) => {
+    return state.activeTermCodes;
+  },
+);
+
 export const isPastTerm = (termCode: string) =>
   createSelector(
     getDegreePlannerState,
diff --git a/src/app/shared/shared.module.ts b/src/app/shared/shared.module.ts
index bbe21af1e478ee527f97482b237bf9cecbba0bb0..648ca93bd4f2b8872afe12a1e7b464ed6d949990 100644
--- a/src/app/shared/shared.module.ts
+++ b/src/app/shared/shared.module.ts
@@ -16,6 +16,7 @@ import { MatDialogModule } from '@angular/material/dialog';
 import { MatInputModule } from '@angular/material/input';
 import { MatTooltipModule } from '@angular/material/tooltip';
 import { MatSnackBarModule } from '@angular/material/snack-bar';
+import { MatProgressBarModule } from '@angular/material/progress-bar';
 
 import { GetTermDescriptionPipe } from './pipes/get-term-description.pipe';
 import { AcademicYearStatePipe } from './pipes/academic-year-state.pipe';
@@ -45,6 +46,7 @@ const modules = [
   MatAutocompleteModule,
   MatFormFieldModule,
   MatSnackBarModule,
+  MatProgressBarModule,
 ];
 const pipes = [
   GetTermDescriptionPipe,