Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: form progress bar #334

Merged
merged 4 commits into from
Mar 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions app/Http/Requests/UserFormRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ public function rules()
'editable_submissions' => 'boolean|nullable',
'editable_submissions_button_text' => 'string|min:1|max:50',
'confetti_on_submission' => 'boolean',
'show_progress_bar' => 'boolean',
'auto_save' => 'boolean',

// Properties
Expand Down
1 change: 1 addition & 0 deletions app/Models/Forms/Form.php
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ class Form extends Model implements CachableAttributes
'editable_submissions',
'editable_submissions_button_text',
'confetti_on_submission',
'show_progress_bar',
'auto_save',

// Security & Privacy
Expand Down
27 changes: 27 additions & 0 deletions client/components/open/forms/OpenForm.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,24 @@
</p>
</div>
<form v-else-if="dataForm" @submit.prevent="">
<template v-if='form.show_progress_bar'>
<div v-if='isIframe' class='mb-4 p-2'>
<div class='w-full h-2 bg-gray-200 dark:bg-gray-600 relative border rounded-full overflow-hidden'>
<div class='h-full transition-all duration-300 rounded-r-full'
:class="{ 'w-0': formProgress === 0 }"
:style="{ width: formProgress + '%', background: form.color }"
/>
</div>
</div>
<div v-else class='fixed top-0 left-0 right-0 z-50'>
<div class='w-full h-[0.2rem] bg-gray-200 dark:bg-gray-600 relative overflow-hidden'>
<div class='h-full transition-all duration-300'
:class="{ 'w-0': formProgress === 0 }"
:style="{ width: formProgress + '%', background: form.color }"
/>
</div>
</div>
Comment on lines +8 to +24
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The implementation of the dynamic progress bar in OpenForm.vue is well-executed, with conditional rendering based on form.show_progress_bar and isIframe. The formProgress computed property correctly calculates the progress percentage, enhancing the user experience by providing visual feedback on form completion status.

However, to improve accessibility for users relying on screen readers, consider adding accessibility attributes such as role="progressbar" and aria-valuenow, aria-valuemin, aria-valuemax to the progress bar elements.

+ <div role="progressbar" aria-valuenow="formProgress" aria-valuemin="0" aria-valuemax="100" class='h-full transition-all duration-300 rounded-r-full'
+      :class="{ 'w-0': formProgress === 0 }"
+      :style="{ width: formProgress + '%', background: form.color }">

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
<template v-if='form.show_progress_bar'>
<div v-if='isIframe' class='mb-4 p-2'>
<div class='w-full h-2 bg-gray-200 dark:bg-gray-600 relative border rounded-full overflow-hidden'>
<div class='h-full transition-all duration-300 rounded-r-full'
:class="{ 'w-0': formProgress === 0 }"
:style="{ width: formProgress + '%', background: form.color }"
/>
</div>
</div>
<div v-else class='fixed top-0 left-0 right-0 z-50'>
<div class='w-full h-[0.2rem] bg-gray-200 dark:bg-gray-600 relative overflow-hidden'>
<div class='h-full transition-all duration-300'
:class="{ 'w-0': formProgress === 0 }"
:style="{ width: formProgress + '%', background: form.color }"
/>
</div>
</div>
<template v-if='form.show_progress_bar'>
<div v-if='isIframe' class='mb-4 p-2'>
<div class='w-full h-2 bg-gray-200 dark:bg-gray-600 relative border rounded-full overflow-hidden'>
<div role="progressbar" aria-valuenow="formProgress" aria-valuemin="0" aria-valuemax="100" class='h-full transition-all duration-300 rounded-r-full'
:class="{ 'w-0': formProgress === 0 }"
:style="{ width: formProgress + '%', background: form.color }">
</div>
</div>
</div>
<div v-else class='fixed top-0 left-0 right-0 z-50'>
<div class='w-full h-[0.2rem] bg-gray-200 dark:bg-gray-600 relative overflow-hidden'>
<div role="progressbar" aria-valuenow="formProgress" aria-valuemin="0" aria-valuemax="100" class='h-full transition-all duration-300'
:class="{ 'w-0': formProgress === 0 }"
:style="{ width: formProgress + '%', background: form.color }">
</div>
</div>
</div>

</template>
<transition name="fade" mode="out-in">
<div :key="currentFieldGroupIndex" class="form-group flex flex-wrap w-full">
<draggable v-model="currentFields"
Expand Down Expand Up @@ -147,6 +165,15 @@ export default {
groups.push(currentGroup)
return groups
},
formProgress () {
const requiredFields = this.fields.filter(field => field.required)
if (requiredFields.length === 0) {
return 100
}
const completedFields = requiredFields.filter(field => ![null, undefined, ''].includes(this.dataFormValue[field.id]))
const progress = (completedFields.length / requiredFields.length) * 100
return Math.round(progress)
},
currentFields: {
get () {
return this.fieldGroups[this.currentFieldGroupIndex]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@
<pro-tag class="ml-1" />
</template>
</toggle-switch-input>
<toggle-switch-input name="show_progress_bar" :form="form" class="mt-4"
label="Show progress bar"
/>
<toggle-switch-input name="uppercase_labels" :form="form" class="mt-4"
label="Uppercase Input Labels"
/>
Expand Down
31 changes: 31 additions & 0 deletions database/migrations/2024_03_12_173732_show_progress_bar.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

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

return new class () extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('forms', function (Blueprint $table) {
$table->boolean('show_progress_bar')->default(false);
});
}

/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('forms', function (Blueprint $table) {
$table->dropColumn('show_progress_bar');
});
}
};
Loading