Skip to content

Commit

Permalink
Add basic Live Search functionality with AJAX.
Browse files Browse the repository at this point in the history
User can now have suggestions from a search box (input element).

To Do:
Have ability to search multiple types of data. Currently, only student
data could be retrieved. Maybe tinker a little with the JS function and
HTML elements to achive that.
  • Loading branch information
hanisirfan committed Dec 26, 2020
1 parent 8804cd1 commit c167fbc
Show file tree
Hide file tree
Showing 23 changed files with 31,493 additions and 19 deletions.
25 changes: 20 additions & 5 deletions app/Http/Controllers/Classroom/ClassroomController.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,24 @@

class ClassroomController extends Controller
{
public $systemSettings;
/***************************************************************************
* Controller Constuctor
* Most of the properties included here is used by any of the methods below.
**************************************************************************/
protected $systemSettings;
protected $currentUserUsername;
protected $apiToken;
public function __construct()
{
$this->systemSettings = SystemSetting::find(1);
$this->middleware(function ($request, $next) {
$this->currentUserUsername = 'admin';
$this->apiToken = User::where('username', $this->currentUserUsername)->select('api_token')->first();
return $next($request);
});
}
/***************************************************************************/

/**
* Handling Views
*/
Expand All @@ -35,14 +48,15 @@ public function classroom(){
}
}
public function view($classroomID){
$students = ClassroomStudent::where('classrooms_id', $classroomID)->with('user')->get();
if(Classroom::where('id', $classroomID)->count() < 1){
abort(404, 'Tiada kelas dijumpai');
}elseif(Gate::allows('authCoordinator', $classroomID) || Gate::allows('authAdmin') || Gate::allows('authSuperAdmin')){
return view('dashboard.user.classroom.view')->with(['settings' => $this->systemSettings, 'page' => 'Maklumat Kelas']);
return view('dashboard.user.classroom.view')->with(['settings' => $this->systemSettings, 'page' => 'Maklumat Kelas', 'students' => $students]);
}elseif(!empty(ClassroomStudent::where('users_username', Auth::user()->username)->first()->classroom)){
$classroomStudentID = ClassroomStudent::where('users_username', Auth::user()->username)->first()->classroom->id;
if($classroomStudentID == $classroomID){
return view('dashboard.user.classroom.view')->with(['settings' => $this->systemSettings, 'page' => 'Maklumat Kelas']);
return view('dashboard.user.classroom.view')->with(['settings' => $this->systemSettings, 'page' => 'Maklumat Kelas', 'students' => $students]);
}else{
abort(403, 'Anda tiada akses paga laman ini');
}
Expand All @@ -56,7 +70,8 @@ public function student($classroomID){
if(Classroom::where('id', $classroomID)->count() < 1){
abort(404, 'Tiada kelas dijumpai');
}elseif(Gate::allows('authCoordinator', $classroomID) || Gate::allows('authAdmin') || Gate::allows('authSuperAdmin')){
return view('dashboard.user.classroom.view')->with(['settings' => $this->systemSettings, 'page' => 'Maklumat Kelas']);
$students = ClassroomStudent::where('classrooms_id', $classroomID)->with('user')->get();
return view('dashboard.user.classroom.student')->with(['settings' => $this->systemSettings, 'apiToken' => $this->apiToken, 'page' => 'Pelajar Kelas', 'students' => $students]);
}else{
abort(403, 'Anda tiada akses paga laman ini');
}
Expand All @@ -65,7 +80,7 @@ public function update($classroomID){
if(Classroom::where('id', $classroomID)->count() < 1){
abort(404, 'Tiada kelas dijumpai');
}elseif(Gate::allows('authCoordinator', $classroomID) || Gate::allows('authAdmin') || Gate::allows('authSuperAdmin')){
return view('dashboard.user.classroom.view')->with(['settings' => $this->systemSettings, 'page' => 'Maklumat Kelas']);
return view('dashboard.user.classroom.update')->with(['settings' => $this->systemSettings, 'page' => 'Maklumat Kelas']);
}else{
abort(403, 'Anda tiada akses paga laman ini');
}
Expand Down
16 changes: 15 additions & 1 deletion app/Http/Controllers/Exam/ExamController.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,29 @@

use App\Http\Controllers\Controller;
use App\Models\SystemSetting;
use App\Models\User;
use Illuminate\Http\Request;

class ExamController extends Controller
{
public $systemSettings;
/***************************************************************************
* Controller Constuctor
* Most of the properties included here is used by any of the methods below.
**************************************************************************/
protected $systemSettings;
protected $currentUserUsername;
protected $apiToken;
public function __construct()
{
$this->systemSettings = SystemSetting::find(1);
$this->middleware(function ($request, $next) {
$this->currentUserUsername = 'admin';
$this->apiToken = User::where('username', $this->currentUserUsername)->select('api_token')->first();
return $next($request);
});
}
/***************************************************************************/

public function exam(){
return view('dashboard.exam.exam')->with(['settings' => $this->systemSettings,'page' => 'Penilaian']);
}
Expand Down
68 changes: 68 additions & 0 deletions app/Http/Controllers/LiveSearch/LiveSearchController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<?php

namespace App\Http\Controllers\LiveSearch;

use App\Http\Controllers\Controller;
use App\Models\Classroom;
use App\Models\ClassroomStudent;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Foundation\Http\FormRequest;

class LiveSearchController extends Controller
{
//Note: Improve the API by adding authentication
public function search(Request $request){
if(isset($request->data) & isset($request->searchFor)){
/**
* Token fetched from request header. The token is store in the HTML meta tag then passed to the
* request header. This token is fetched from the
*/
$headerToken = $request->header('API-TOKEN');
/**
* Check for API token in database
*/
$tokenCount = User::where('api_token', $headerToken)->count();
/**
* Check if there's specified token in database.
*/
if($tokenCount > 0){
if(!empty($request->data)){
if($request->searchFor == 'user'){
$response = User::where('username', 'LIKE', "%{$request->data}%")
->orWhere('fullname', 'LIKE', "%{$request->data}%")
->orWhere('email', 'LIKE', "%{$request->data}%")
->select('username', 'fullname', 'email')->get();
header('Content-Type: application/json');
return response()->json($response);
}
if($request->searchFor == 'student'){
// Only user with the student role is retrieved
$response = User::select('username', 'fullname', 'email')
->where('role', 'student')
->where('username', 'LIKE', "%{$request->data}%")
->where('fullname', 'LIKE', "%{$request->data}%")
->where('email', 'LIKE', "%{$request->data}%")->get();
header('Content-Type: application/json');
return response()->json($response);
}
if($request->searchFor == 'classroom'){
$response = Classroom::where('id', 'LIKE', "%{$request->data}%")
->orWhere('programs_code', 'LIKE', "%{$request->data}%")
->orWhere('admission_year', 'LIKE', "%{$request->data}%")
->orWhere('study_year', 'LIKE', "%{$request->data}%")
->orWhere('study_levels_code', 'LIKE', "%{$request->data}%")
->select('id', 'programs_code', 'admission_year', 'study_year', 'study_levels_code')->get();
header('Content-Type: application/json');
return response()->json($response);
}
}else{
$error = ['Error: Query is empty!'];
return response()->json($error);
}
}

}
}
}
22 changes: 21 additions & 1 deletion app/Http/Controllers/User/UserController.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,29 @@
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;
use App\Models\User;

class UserController extends Controller
{
public $systemSettings;
/***************************************************************************
* Controller Constuctor
* Most of the properties included here is used by any of the methods below.
**************************************************************************/
protected $systemSettings;
protected $currentUserUsername;
protected $apiToken;
public function __construct()
{
$this->systemSettings = SystemSetting::find(1);
$this->middleware(function ($request, $next) {
$this->currentUserUsername = 'admin';
$this->apiToken = User::where('username', $this->currentUserUsername)->select('api_token')->first();
return $next($request);
});
}
/***************************************************************************/

public function login(Request $request){
$username = strtolower($request->username);
if(User::where('username', '=', $username)->count() > 0){
Expand All @@ -31,6 +45,9 @@ public function login(Request $request){
'ip_address' => $request->ip(),
'user_agent' => $request->server('HTTP_USER_AGENT')
]);
$user = User::find($username);
$user->api_token = Str::random(60);
$user->save();
return redirect()->intended('dashboard');
}else{
return back()->withErrors([
Expand All @@ -44,6 +61,9 @@ public function login(Request $request){
}
}
public function logout(Request $request){
$user = User::find(Auth::user()->username);
$user->api_token = null;
$user->save();
Auth::logout();
$request->session()->invalidate();
$request->session()->regenerateToken();
Expand Down
14 changes: 13 additions & 1 deletion app/Http/Controllers/User/UserProfileController.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,23 @@

class UserProfileController extends Controller
{
public $systemSettings;
/***************************************************************************
* Controller Constuctor
* Most of the properties included here is used by any of the methods below.
**************************************************************************/
protected $systemSettings;
protected $currentUserUsername;
protected $apiToken;
public function __construct()
{
$this->systemSettings = SystemSetting::find(1);
$this->middleware(function ($request, $next) {
$this->currentUserUsername = 'admin';
$this->apiToken = User::where('username', $this->currentUserUsername)->select('api_token')->first();
return $next($request);
});
}
/***************************************************************************/

/**
* Handling Views
Expand Down
3 changes: 3 additions & 0 deletions app/Models/ClassroomCoordinator.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ class ClassroomCoordinator extends Model
'classrooms_id'
];
// Relationships
public function user(){
return $this->belongsTo(User::class, 'users_username');
}
public function classroom(){
return $this->belongsTo(Classroom::class, 'classrooms_id');
}
Expand Down
3 changes: 3 additions & 0 deletions app/Models/ClassroomStudent.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ class ClassroomStudent extends Model
'classrooms_id'
];
// Relationships
public function user(){
return $this->belongsTo(User::class, 'users_username');
}
public function classroom(){
return $this->belongsTo(Classroom::class, 'classrooms_id');
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class AddsApiTokenToUsersTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('users', function (Blueprint $table) {
$table->string('api_token', 60)->unique()->nullable();
});
}

/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('users', function (Blueprint $table) {
$table->dropColumn(['api_token']);
});
}
}
11,586 changes: 11,585 additions & 1 deletion public/css/app.css

Large diffs are not rendered by default.

19,464 changes: 19,462 additions & 2 deletions public/js/app.js

Large diffs are not rendered by default.

0 comments on commit c167fbc

Please sign in to comment.