forked from miguel456/rbrecruiter
Add Dynamic Form Processing for Custom Forms
This commit is contained in:
parent
4c6a435e34
commit
cf7cc142a7
|
@ -6,5 +6,11 @@ use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
class Application extends Model
|
class Application extends Model
|
||||||
{
|
{
|
||||||
//
|
public $fillable = [
|
||||||
|
|
||||||
|
'applicantUserID',
|
||||||
|
'applicantFormResponseID',
|
||||||
|
'applicantStatus'
|
||||||
|
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,13 @@
|
||||||
|
|
||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Application;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
use App\Response;
|
||||||
use App\Vacancy;
|
use App\Vacancy;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
use Illuminate\Support\Facades\Validator;
|
||||||
|
|
||||||
class ApplicationController extends Controller
|
class ApplicationController extends Controller
|
||||||
{
|
{
|
||||||
|
@ -59,4 +64,66 @@ class ApplicationController extends Controller
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function saveApplicationAnswers(Request $request, $vacancySlug)
|
||||||
|
{
|
||||||
|
$vacancy = Vacancy::with('forms')->where('vacancySlug', $vacancySlug)->get();
|
||||||
|
|
||||||
|
Log::info('Processing new application!');
|
||||||
|
|
||||||
|
$formStructure = json_decode($vacancy->first()->forms->formStructure, true);
|
||||||
|
$responseStructure = [];
|
||||||
|
|
||||||
|
$excludedNames = [
|
||||||
|
'_token',
|
||||||
|
];
|
||||||
|
|
||||||
|
$validator = [];
|
||||||
|
|
||||||
|
foreach($request->all() as $fieldName => $value)
|
||||||
|
{
|
||||||
|
if(!in_array($fieldName, $excludedNames))
|
||||||
|
{
|
||||||
|
$validator[$fieldName] = 'required|string';
|
||||||
|
|
||||||
|
$responseStructure['responses'][$fieldName]['type'] = $formStructure['fields'][$fieldName]['type'] ?? 'Unavailable';
|
||||||
|
$responseStructure['responses'][$fieldName]['title'] = $formStructure['fields'][$fieldName]['title'];
|
||||||
|
$responseStructure['responses'][$fieldName]['response'] = $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Log::info('Built response & validator structure!');
|
||||||
|
|
||||||
|
$validation = Validator::make($request->all(), $validator);
|
||||||
|
|
||||||
|
if (!$validation->fails())
|
||||||
|
{
|
||||||
|
$response = Response::create([
|
||||||
|
'responseFormID' => $vacancy->first()->forms->id,
|
||||||
|
'associatedVacancyID' => $vacancy->first()->id, // Since a form can be used by multiple vacancies, we can only know which specific vacancy this response ties to by using a vacancy ID
|
||||||
|
'responseData' => json_encode($responseStructure)
|
||||||
|
]);
|
||||||
|
|
||||||
|
Log::info('Registered form response for user ' . Auth::user()->name . ' for vacancy ' . $vacancy->first()->vacancyName);
|
||||||
|
|
||||||
|
Application::create([
|
||||||
|
'applicantUserID' => Auth::user()->id,
|
||||||
|
'applicantFormResponseID' => $response->id,
|
||||||
|
'applicationStatus' => 'STAGE_SUBMITTED',
|
||||||
|
]);
|
||||||
|
|
||||||
|
Log::info('Submitted application for user ' . Auth::user()->name . ' with response ID' . $response->id);
|
||||||
|
|
||||||
|
$request->session()->flash('success', 'Thank you for your application! It will be reviewed as soon as possible.');
|
||||||
|
return redirect()->to(route('userPendingApps'));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log::warning('Application form for ' . Auth::user()->name . ' contained errors, resetting!');
|
||||||
|
$request->session()->flash('error', 'There are one or more errors in your application. Please make sure none of your fields are empty, since they are all required.');
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return redirect()->back();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,9 @@ class HomeController extends Controller
|
||||||
*/
|
*/
|
||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
|
// TODO: Relationships for Applications, Users and Responses
|
||||||
|
// Also prevent apps if user already has one in the space of 30d
|
||||||
|
// Display apps in the relevant menus
|
||||||
return view('home')
|
return view('home')
|
||||||
->with('positions', Vacancy::where('vacancyStatus', 'OPEN')->get());
|
->with('positions', Vacancy::where('vacancyStatus', 'OPEN')->get());
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,5 +6,9 @@ use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
class Response extends Model
|
class Response extends Model
|
||||||
{
|
{
|
||||||
//
|
public $fillable = [
|
||||||
|
'responseFormID',
|
||||||
|
'associatedVacancyID',
|
||||||
|
'responseData'
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
class AddVacancyIDToResponses extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::table('responses', function (Blueprint $table) {
|
||||||
|
$table->bigInteger('associatedVacancyID')->unsigned()->after('responseFormID');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::table('responses', function (Blueprint $table) {
|
||||||
|
$table->dropColumn('associatedVacancyID');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,6 +6,24 @@
|
||||||
<h1>My Account / Apply / {{$vacancy->vacancyName}} Application</h1>
|
<h1>My Account / Apply / {{$vacancy->vacancyName}} Application</h1>
|
||||||
@stop
|
@stop
|
||||||
|
|
||||||
|
@section('js')
|
||||||
|
|
||||||
|
@if (session()->has('success'))
|
||||||
|
|
||||||
|
<script>
|
||||||
|
toastr.success("{{session('success')}}")
|
||||||
|
</script>
|
||||||
|
|
||||||
|
@elseif(session()->has('error'))
|
||||||
|
|
||||||
|
<script>
|
||||||
|
toastr.error("{{session('error')}}")
|
||||||
|
</script>
|
||||||
|
|
||||||
|
@endif
|
||||||
|
|
||||||
|
@stop
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
|
|
||||||
<div class="modal fade" tabindex="-1" id="confirm" role="dialog" aria-labelledby="modalConfirmLabel" aria-hidden="true">
|
<div class="modal fade" tabindex="-1" id="confirm" role="dialog" aria-labelledby="modalConfirmLabel" aria-hidden="true">
|
||||||
|
@ -24,7 +42,7 @@
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button type="button" class="btn btn-success"><i class="fas fa-check-double"></i> Accept & Send</button>
|
<button type="button" class="btn btn-success" onclick="document.getElementById('submitApplicationForm').submit()"><i class="fas fa-check-double"></i> Accept & Send</button>
|
||||||
<button type="button" class="btn btn-secondary" data-dismiss="modal">Review</button>
|
<button type="button" class="btn btn-secondary" data-dismiss="modal">Review</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -65,6 +83,8 @@
|
||||||
|
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
|
|
||||||
|
<form action="{{route('saveApplicationForm', ['vacancySlug' => $vacancy->vacancySlug])}}" method="POST" id="submitApplicationForm">
|
||||||
|
@csrf
|
||||||
@foreach($preprocessedForm['fields'] as $fieldName => $field)
|
@foreach($preprocessedForm['fields'] as $fieldName => $field)
|
||||||
|
|
||||||
@switch ($field['type'])
|
@switch ($field['type'])
|
||||||
|
@ -98,6 +118,8 @@
|
||||||
|
|
||||||
@endforeach
|
@endforeach
|
||||||
|
|
||||||
|
</form>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card-footer text-center">
|
<div class="card-footer text-center">
|
||||||
|
|
|
@ -8,6 +8,24 @@
|
||||||
|
|
||||||
@stop
|
@stop
|
||||||
|
|
||||||
|
@section('js')
|
||||||
|
|
||||||
|
@if (session()->has('success'))
|
||||||
|
|
||||||
|
<script>
|
||||||
|
toastr.success("{{session('success')}}")
|
||||||
|
</script>
|
||||||
|
|
||||||
|
@elseif(session()->has('error'))
|
||||||
|
|
||||||
|
<script>
|
||||||
|
toastr.error("{{session('error')}}")
|
||||||
|
</script>
|
||||||
|
|
||||||
|
@endif
|
||||||
|
|
||||||
|
@stop
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
|
|
@ -50,6 +50,9 @@ Route::group(['middleware' => 'auth'], function(){
|
||||||
Route::get('positions/{vacancySlug}', 'ApplicationController@renderApplicationForm')
|
Route::get('positions/{vacancySlug}', 'ApplicationController@renderApplicationForm')
|
||||||
->name('renderApplicationForm');
|
->name('renderApplicationForm');
|
||||||
|
|
||||||
|
Route::post('positions/{vacancySlug}/submit', 'ApplicationController@saveApplicationAnswers')
|
||||||
|
->name('saveApplicationForm');
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
Route::group(['prefix' => '/profile'], function (){
|
Route::group(['prefix' => '/profile'], function (){
|
||||||
|
|
Loading…
Reference in New Issue