diff --git a/assets/javascripts/discourse/components/wizard-custom-field.js.es6 b/assets/javascripts/discourse/components/wizard-custom-field.js.es6 index b17464d4..97f003df 100644 --- a/assets/javascripts/discourse/components/wizard-custom-field.js.es6 +++ b/assets/javascripts/discourse/components/wizard-custom-field.js.es6 @@ -21,7 +21,7 @@ export default Component.extend(UndoChanges, { showPrefill: or('isText', 'isCategory', 'isTag', 'isGroup', 'isDropdown'), showContent: or('isCategory', 'isTag', 'isGroup', 'isDropdown'), showLimit: or('isCategory', 'isTag'), - showLengthControls: or('isText', 'isTextarea', 'isComposer'), + isTextType: or('isText', 'isTextarea', 'isComposer'), categoryPropertyTypes: selectKitContent(['id', 'slug']), showAdvanced: alias('field.type'), messageUrl: 'https://thepavilion.io/t/2809', diff --git a/assets/javascripts/discourse/templates/components/wizard-custom-field.hbs b/assets/javascripts/discourse/templates/components/wizard-custom-field.hbs index 2792fdc5..563ab716 100644 --- a/assets/javascripts/discourse/templates/components/wizard-custom-field.hbs +++ b/assets/javascripts/discourse/templates/components/wizard-custom-field.hbs @@ -70,7 +70,7 @@ url=messageUrl component='field'}} -{{#if showLengthControls}} +{{#if isTextType}}
@@ -98,6 +98,19 @@ class="small"}}
+ +
+
+ +
+ +
+ {{i18n 'admin.wizard.field.char_counter_placeholder'}} + {{input + type="checkbox" + checked=field.char_counter}} +
+
{{/if}} {{#if isUpload}} diff --git a/assets/javascripts/wizard/helpers/char-counter.js.es6 b/assets/javascripts/wizard/helpers/char-counter.js.es6 new file mode 100644 index 00000000..c27c0818 --- /dev/null +++ b/assets/javascripts/wizard/helpers/char-counter.js.es6 @@ -0,0 +1,15 @@ +import { registerUnbound } from "discourse-common/lib/helpers"; +import I18n from "I18n"; + +export default registerUnbound("char-counter", function(body, maxLength) { + let bodyLength = body ? body.length : 0; + let finalString; + + if (maxLength) { + finalString = `
${bodyLength} / ${I18n.t('wizard.x_characters', { count: parseInt(maxLength) })}
`; + } else { + finalString = `
${I18n.t('wizard.x_characters', { count: parseInt(bodyLength) })}
`; + } + + return new Handlebars.SafeString(finalString); +}); diff --git a/assets/javascripts/wizard/initializers/custom-wizard-field.js.es6 b/assets/javascripts/wizard/initializers/custom-wizard-field.js.es6 index 75327413..efeaaefd 100644 --- a/assets/javascripts/wizard/initializers/custom-wizard-field.js.es6 +++ b/assets/javascripts/wizard/initializers/custom-wizard-field.js.es6 @@ -1,4 +1,5 @@ import { dasherize } from "@ember/string"; +import discourseComputed from "discourse-common/utils/decorators"; export default { name: "custom-wizard-field", @@ -15,6 +16,11 @@ export default { FieldComponent.reopen({ classNameBindings: ["field.id"], + @discourseComputed("field.type") + textType(fieldType) { + return ['text', 'textarea'].includes(fieldType); + }, + cookedDescription: function () { return cook(this.get("field.description")); }.property("field.description"), diff --git a/assets/javascripts/wizard/templates/components/wizard-field-composer.hbs b/assets/javascripts/wizard/templates/components/wizard-field-composer.hbs index 1fe2bde6..3160d9fb 100644 --- a/assets/javascripts/wizard/templates/components/wizard-field-composer.hbs +++ b/assets/javascripts/wizard/templates/components/wizard-field-composer.hbs @@ -7,6 +7,12 @@ togglePreview=(action "togglePreview") afterRefresh=(action "afterRefresh")}} +
\ No newline at end of file + + +{{#if field.char_counter}} + {{char-counter field.value field.max_length}} +{{/if}} +
diff --git a/assets/javascripts/wizard/templates/components/wizard-field.hbs b/assets/javascripts/wizard/templates/components/wizard-field.hbs index c8c785b0..5f524e92 100644 --- a/assets/javascripts/wizard/templates/components/wizard-field.hbs +++ b/assets/javascripts/wizard/templates/components/wizard-field.hbs @@ -16,6 +16,12 @@ {{/if}} +{{#if field.char_counter}} + {{#if textType}} + {{char-counter field.value field.max_length}} + {{/if}} +{{/if}} + {{#if field.errorDescription}}
{{{field.errorDescription}}}
{{/if}} diff --git a/assets/stylesheets/wizard/custom/base.scss b/assets/stylesheets/wizard/custom/base.scss index 1e4023d5..c9f3b120 100644 --- a/assets/stylesheets/wizard/custom/base.scss +++ b/assets/stylesheets/wizard/custom/base.scss @@ -80,3 +80,6 @@ textarea { } } +.body-length { + text-align: right; +} diff --git a/assets/stylesheets/wizard/custom/composer.scss b/assets/stylesheets/wizard/custom/composer.scss index c360e76a..d747bfcb 100644 --- a/assets/stylesheets/wizard/custom/composer.scss +++ b/assets/stylesheets/wizard/custom/composer.scss @@ -50,10 +50,6 @@ display: none; } -.custom-wizard .wizard-field-composer .toggle-preview { - margin-top: 20px; -} - .d-editor-textarea-wrapper, .d-editor-preview-wrapper { background-color: var(--secondary); @@ -230,3 +226,10 @@ bottom: -40px; right: 0; } + +.bottom-bar { + display: flex; + justify-content:space-between; + margin-top: 20px; + align-items: center; +} diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index be138d48..28304120 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -166,6 +166,8 @@ en: min_length_placeholder: "Minimum length in characters" max_length: "Max Length" max_length_placeholder: "Maximum length in characters" + char_counter: "Character Counter" + char_counter_placeholder: "Display Character Counter" file_types: "File Types" limit: "Limit" property: "Property" @@ -469,6 +471,9 @@ en: requires_login: "You need to be logged in to access this wizard." reset: "Reset this wizard." step_not_permitted: "You're not permitted to view this step." + x_characters: + one: "%{count} Character" + other: "%{count} Characters" wizard_composer: show_preview: "Preview Post" diff --git a/controllers/custom_wizard/admin/wizard.rb b/controllers/custom_wizard/admin/wizard.rb index a9a01035..9859f115 100644 --- a/controllers/custom_wizard/admin/wizard.rb +++ b/controllers/custom_wizard/admin/wizard.rb @@ -98,6 +98,7 @@ class CustomWizard::AdminWizardController < CustomWizard::AdminController :type, :min_length, :max_length, + :char_counter, :file_types, :format, :limit, diff --git a/extensions/wizard_field.rb b/extensions/wizard_field.rb index 5b532071..5b73c6a3 100644 --- a/extensions/wizard_field.rb +++ b/extensions/wizard_field.rb @@ -6,6 +6,7 @@ module CustomWizardFieldExtension :key, :min_length, :max_length, + :char_counter, :file_types, :format, :limit, @@ -21,6 +22,7 @@ module CustomWizardFieldExtension @key = attrs[:key] @min_length = attrs[:min_length] @max_length = attrs[:max_length] + @char_counter = attrs[:char_counter] @file_types = attrs[:file_types] @format = attrs[:format] @limit = attrs[:limit] diff --git a/lib/custom_wizard/builder.rb b/lib/custom_wizard/builder.rb index 1259be58..996b0737 100644 --- a/lib/custom_wizard/builder.rb +++ b/lib/custom_wizard/builder.rb @@ -160,6 +160,7 @@ class CustomWizard::Builder params[:key] = field_template['key'] if field_template['key'] params[:min_length] = field_template['min_length'] if field_template['min_length'] params[:max_length] = field_template['max_length'] if field_template['max_length'] + params[:char_counter] = field_template['char_counter'] if field_template['char_counter'] params[:value] = prefill_field(field_template, step_template) if !build_opts[:reset] && (submission = @wizard.current_submission) diff --git a/lib/custom_wizard/field.rb b/lib/custom_wizard/field.rb index 53a8b5da..0c19b321 100644 --- a/lib/custom_wizard/field.rb +++ b/lib/custom_wizard/field.rb @@ -4,16 +4,19 @@ class CustomWizard::Field text: { min_length: nil, max_length: nil, - prefill: nil + prefill: nil, + char_counter: nil }, textarea: { min_length: nil, max_length: nil, - prefill: nil + prefill: nil, + char_counter: nil }, composer: { min_length: nil, max_length: nil, + char_counter: nil }, text_only: {}, date: { diff --git a/serializers/custom_wizard/wizard_field_serializer.rb b/serializers/custom_wizard/wizard_field_serializer.rb index 82034bd8..805b0a88 100644 --- a/serializers/custom_wizard/wizard_field_serializer.rb +++ b/serializers/custom_wizard/wizard_field_serializer.rb @@ -8,6 +8,8 @@ class CustomWizard::FieldSerializer < ::WizardFieldSerializer :limit, :property, :content, + :max_length, + :char_counter, :number def label @@ -55,7 +57,15 @@ class CustomWizard::FieldSerializer < ::WizardFieldSerializer def include_choices? object.choices.present? end - + + def max_length + object.max_length + end + + def char_counter + object.char_counter + end + def number object.number end