Skip to content

Commit

Permalink
feat: Add regex validation on form message inputs (chatwoot#2317)
Browse files Browse the repository at this point in the history

Co-authored-by: Nithin David Thomas <[email protected]>
Co-authored-by: Sojan <[email protected]>
  • Loading branch information
3 people authored Jun 8, 2021
1 parent 0a087c9 commit 67ce6f5
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 14 deletions.
3 changes: 3 additions & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ Metrics/BlockLength:
- '**/routes.rb'
- 'config/environments/*'
- db/schema.rb
Metrics/ModuleLength:
Exclude:
- lib/woot_message_seeder.rb
Rails/ApplicationController:
Exclude:
- 'app/controllers/api/v1/widget/messages_controller.rb'
Expand Down
61 changes: 58 additions & 3 deletions app/javascript/shared/components/ChatForm.vue
Original file line number Diff line number Diff line change
@@ -1,11 +1,32 @@
<template>
<div class="form chat-bubble agent">
<form @submit.prevent="onSubmit">
<div v-for="item in items" :key="item.key" class="form-block">
<div
v-for="item in items"
:key="item.key"
class="form-block"
:class="{
'has-submitted': hasSubmitted,
}"
>
<label>{{ item.label }}</label>
<input
v-if="item.type === 'email' || item.type === 'text'"
v-if="item.type === 'email'"
v-model="formValues[item.name]"
:type="item.type"
:pattern="item.regex"
:title="item.title"
:required="item.required && 'required'"
:name="item.name"
:placeholder="item.placeholder"
:disabled="!!submittedValues.length"
/>
<input
v-else-if="item.type === 'text'"
v-model="formValues[item.name]"
:required="item.required && 'required'"
:pattern="item.pattern"
:title="item.title"
:type="item.type"
:name="item.name"
:placeholder="item.placeholder"
Expand All @@ -14,13 +35,16 @@
<textarea
v-else-if="item.type === 'text_area'"
v-model="formValues[item.name]"
:required="item.required && 'required'"
:title="item.title"
:name="item.name"
:placeholder="item.placeholder"
:disabled="!!submittedValues.length"
/>
<select
v-else-if="item.type === 'select'"
v-model="formValues[item.name]"
:required="item.required && 'required'"
>
<option
v-for="option in item.options"
Expand All @@ -30,13 +54,16 @@
{{ option.label }}
</option>
</select>
<span class="error-message">
{{ item.pattern_error || $t('CHAT_FORM.INVALID.FIELD') }}
</span>
</div>
<button
v-if="!submittedValues.length"
class="button block"
type="submit"
:disabled="!isFormValid"
:style="{ background: widgetColor, borderColor: widgetColor }"
@click="onSubmitClick"
>
{{ buttonLabel || $t('COMPONENTS.FORM_BUBBLE.SUBMIT') }}
</button>
Expand Down Expand Up @@ -64,6 +91,7 @@ export default {
data() {
return {
formValues: {},
hasSubmitted: false,
};
},
computed: {
Expand All @@ -84,6 +112,9 @@ export default {
}
},
methods: {
onSubmitClick() {
this.hasSubmitted = true;
},
onSubmit() {
if (!this.isFormValid) {
return;
Expand Down Expand Up @@ -171,5 +202,29 @@ export default {
.button {
font-size: $font-size-default;
}
.error-message {
display: none;
margin-top: $space-smaller;
color: $color-error;
}
.has-submitted {
input:invalid {
border: 1px solid $color-error;
}
input:invalid + .error-message {
display: block;
}
textarea:invalid {
border: 1px solid $color-error;
}
textarea:invalid + .error-message {
display: block;
}
}
}
</style>
7 changes: 6 additions & 1 deletion app/javascript/widget/i18n/locale/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,5 +51,10 @@
}
}
},
"FILE_SIZE_LIMIT": "File exceeds the {MAXIMUM_FILE_UPLOAD_SIZE} attachment limit"
"FILE_SIZE_LIMIT": "File exceeds the {MAXIMUM_FILE_UPLOAD_SIZE} attachment limit",
"CHAT_FORM": {
"INVALID": {
"FIELD": "Invalid field"
}
}
}
2 changes: 1 addition & 1 deletion app/models/concerns/content_attribute_validator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ class ContentAttributeValidator < ActiveModel::Validator
ALLOWED_SELECT_ITEM_KEYS = [:title, :value].freeze
ALLOWED_CARD_ITEM_KEYS = [:title, :description, :media_url, :actions].freeze
ALLOWED_CARD_ITEM_ACTION_KEYS = [:text, :type, :payload, :uri].freeze
ALLOWED_FORM_ITEM_KEYS = [:type, :placeholder, :label, :name, :options, :default].freeze
ALLOWED_FORM_ITEM_KEYS = [:type, :placeholder, :label, :name, :options, :default, :required, :pattern, :title, :pattern_error].freeze
ALLOWED_ARTICLE_KEYS = [:title, :description, :link].freeze

def validate(record)
Expand Down
25 changes: 16 additions & 9 deletions lib/woot_message_seeder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -74,18 +74,25 @@ def self.create_sample_form_message(conversation)
message_type: :template,
content_type: 'form',
content: 'form',
content_attributes: {
items: [
{ name: 'email', placeholder: 'Please enter your email', type: 'email', label: 'Email' },
{ name: 'text_area', placeholder: 'Please enter text', type: 'text_area', label: 'Large Text' },
{ name: 'text', placeholder: 'Please enter text', type: 'text', label: 'text', default: 'defaut value' },
{ name: 'select', label: 'Select Option', type: 'select', options: [{ label: '🌯 Burito', value: 'Burito' },
{ label: '🍝 Pasta', value: 'Pasta' }] }
]
}
content_attributes: sample_form
)
end

def self.sample_form
{
"items": [
{ "name": 'email', "placeholder": 'Please enter your email', "type": 'email', "label": 'Email', "required": 'required',
"pattern_error": 'Please fill this field', "pattern": '^[^\s@]+@[^\s@]+\.[^\s@]+$' },
{ "name": 'text_area', "placeholder": 'Please enter text', "type": 'text_area', "label": 'Large Text', "required": 'required',
"pattern_error": 'Please fill this field' },
{ "name": 'text', "placeholder": 'Please enter text', "type": 'text', "label": 'text', "default": 'defaut value', "required": 'required',
"pattern": '^[a-zA-Z ]*$', "pattern_error": 'Only alphabets are allowed' },
{ "name": 'select', "label": 'Select Option', "type": 'select', "options": [{ "label": '🌯 Burito', "value": 'Burito' },
{ "label": '🍝 Pasta', "value": 'Pasta' }] }
]
}
end

def self.create_sample_articles_message(conversation)
Message.create!(
account: conversation.account,
Expand Down

0 comments on commit 67ce6f5

Please sign in to comment.