diff --git a/app/helpers/profile_helper.rb b/app/helpers/profile_helper.rb index 34627e4e5..333971607 100644 --- a/app/helpers/profile_helper.rb +++ b/app/helpers/profile_helper.rb @@ -15,4 +15,13 @@ module ProfileHelper { github: urls["GitHub"], twitter: urls["Twitter"], facebook: urls["Facebook"] }.compact end + + def character_count_denominator(field_type) + case field_type + when "text_field" + "100" + when "text_area" + "200" + end + end end diff --git a/app/javascript/packs/userProfileSettings.js b/app/javascript/packs/userProfileSettings.js new file mode 100644 index 000000000..8013fd49e --- /dev/null +++ b/app/javascript/packs/userProfileSettings.js @@ -0,0 +1,32 @@ +const userFieldIds = ['user[name]', 'user[email]', 'user[username]']; +const profileFieldIds = Array.from( + document.querySelectorAll('[id^="profile["]'), +).map((node) => node.id); +const allFieldIds = [...userFieldIds, ...profileFieldIds]; + +export function fieldCharacterLimits() { + window.addEventListener('load', () => { + allFieldIds.forEach((field_id) => { + const field = document.getElementById(field_id); + const fieldValueLength = field.value.length; + const fieldCharacterSpan = document.getElementById( + field.dataset.characterSpanId, + ); + fieldCharacterSpan.innerHTML = fieldValueLength; + }); + + document + .getElementById('user-profile-form') + .addEventListener('keyup', (event) => { + if (!event.target.dataset.characterSpanId) { + return; + } + + document.getElementById( + event.target.dataset.characterSpanId, + ).innerHTML = event.target.value.length; + }); + }); +} + +fieldCharacterLimits(); diff --git a/app/views/users/_profile.html.erb b/app/views/users/_profile.html.erb index 9ea4bf46e..14976e153 100644 --- a/app/views/users/_profile.html.erb +++ b/app/views/users/_profile.html.erb @@ -1,20 +1,40 @@ -<%= javascript_packs_with_chunks_tag "colorPreview", "validateFileInputs", "stickySaveFooter", defer: true %> +<%= javascript_packs_with_chunks_tag "colorPreview", "stickySaveFooter", "userProfileSettings", "validateFileInputs", defer: true %> <%= render "users/additional_authentication" %> -<%= form_with(url: profile_path(@user.profile_id), method: "put", html: { class: "sticky-footer-form" }) do |f| %> +<%= form_with(url: profile_path(@user.profile_id), method: "put", html: { class: "sticky-footer-form", id: "user-profile-form" }) do |f| %>

User

<%= f.label :name, for: "user[name]", class: "crayons-field__label" %> - <%= f.text_field "user[name]", maxlength: 30, class: "crayons-textfield", placeholder: "John Doe", value: @user.name %> + <%= f.text_field "user[name]", + maxlength: 30, + class: "crayons-textfield", + placeholder: "John Doe", + value: @user.name, + aria: { describedby: "name-description" }, + data: { character_span_id: "name-characters" } %> +
+ Available characters used: + /30 +
<%= f.label :email, for: "user[email]", class: "crayons-field__label" %> - <%= f.text_field "user[email]", class: "crayons-textfield", placeholder: "john.doe@example.com", value: @user.email %> + <%= f.text_field "user[email]", + maxlength: 50, + class: "crayons-textfield", + placeholder: "john.doe@example.com", + value: @user.email, + aria: { describedby: "email-description" }, + data: { character_span_id: "email-characters" } %> +
+ Available characters used: + /50 +
@@ -24,7 +44,17 @@
<%= f.label :username, for: "user[username]", class: "crayons-field__label" %> - <%= f.text_field "user[username]", maxlength: 30, class: "crayons-textfield", placeholder: "johndoe", value: @user.username %> + <%= f.text_field "user[username]", + maxlength: 30, + class: "crayons-textfield", + placeholder: "johndoe", + value: @user.username, + aria: { describedby: "username-description" }, + data: { character_span_id: "username-characters" } %> +
+ Available characters used: + /30 +
@@ -51,9 +81,16 @@ <%= t("views.users.profile_fields.website.label") %> <%= f.url_field "profile[website_url]", + maxlength: 100, value: profile.website_url, placeholder: "https://yoursite.com", - class: "crayons-textfield js-color-field" %> + class: "crayons-textfield", + aria: { describedby: "url-description" }, + data: { character_span_id: "url-characters" } %> +
+ Available characters used: + /100 +
@@ -61,9 +98,16 @@ <%= t("views.users.profile_fields.location.label") %> <%= f.text_field "profile[location]", + maxlength: 100, value: profile.location, placeholder: t("views.users.profile_fields.location.placeholder"), - class: "crayons-textfield js-color-field" %> + class: "crayons-textfield", + aria: { describedby: "location-description" }, + data: { character_span_id: "location-characters" } %> +
+ Available characters used: + /100 +
@@ -71,9 +115,16 @@ <%= t("views.users.profile_fields.bio.label") %> <%= f.text_area "profile[summary]", + maxlength: 200, value: profile.summary, placeholder: t("views.users.profile_fields.bio.placeholder"), - class: "crayons-textfield js-color-field" %> + class: "crayons-textfield", + aria: { describedby: "summary-description" }, + data: { character_span_id: "summary-characters" } %> +
+ Available characters used: + /200 +
@@ -103,7 +154,13 @@ "profile[#{field.attribute_name}]", value: profile.public_send(field.attribute_name), placeholder: field["placeholder_text"], + aria: { describedby: "#{field.attribute_name}-description" }, + data: { character_span_id: "#{field.attribute_name}-characters" }, class: "crayons-textfield") %> +
+ Available characters used: + /<%= character_count_denominator(field["input_type"]) %> +
<% end %> <% if field.description.present? %>

<%= field.description %>

diff --git a/spec/helpers/profile_helper_spec.rb b/spec/helpers/profile_helper_spec.rb index 6d45b9d63..74c28d493 100644 --- a/spec/helpers/profile_helper_spec.rb +++ b/spec/helpers/profile_helper_spec.rb @@ -68,4 +68,14 @@ describe ProfileHelper do end end end + + describe "character_count_denominator" do + it "returns '100' when the field_type is 'text_field'" do + expect(helper.character_count_denominator("text_field")).to eq("100") + end + + it "returns '200' when the field_type is 'text_area'" do + expect(helper.character_count_denominator("text_area")).to eq("200") + end + end end