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

Support maxlength HTML element for text_field component #204

Open
dennismonsewicz opened this issue Aug 20, 2019 · 0 comments
Open

Support maxlength HTML element for text_field component #204

dennismonsewicz opened this issue Aug 20, 2019 · 0 comments

Comments

@dennismonsewicz
Copy link
Contributor

dennismonsewicz commented Aug 20, 2019

As a developer, who is creating a form with a max length requirement for an input field, I would like the ability to pass in a maxlength attribute when creating a text_field.

Proposed Change

Component Class

require 'voom/presenters/dsl/components/input'

module Voom
  module Presenters
    module DSL
      module Components
        class TextField < Input

          attr_reader :required, :full_width, :password, :auto_complete

          def initialize(**attribs_, &block)
            super(type: :text_field, **attribs_, &block)
            @required = attribs.delete(:required){ false }
            @full_width = attribs.delete(:full_width){ true }
            @password = attribs.delete(:password){ false }
            @maxlength = attribs.delete(:maxlength) { nil }
            @auto_complete = validate_auto_complete(attribs.delete(:auto_complete) { :off })
            label(attribs.delete(:label))if attribs.key?(:label)
            value(attribs.delete(:value))if attribs.key?(:value)
            expand!
          end

          def label(text=nil)
            return @label if locked?
            @label = text
          end

          def icon(icon=nil, **attribs, &block)
            return @icon if locked?
            @icon = Components::Icon.new(parent: self, icon: icon, position: attribs.delete(:position){:right},
                                         **attribs, &block)
          end

          def value(value=nil)
            return @value if locked?
            @value = value
          end

          def pattern(pattern=nil)
            return @pattern if locked?
            @pattern = json_regexp(Regexp.new(pattern))
          end

          def hint(hint=nil)
            return @hint if locked?
            @hint = hint
          end

          def error(error=nil)
            return @error if locked?
            @error = error
          end

          private
          def json_regexp(regexp)
            str = regexp.inspect.
                sub('\\A', '^').
                sub('\\Z', '$').
                sub('\\z', '$').
                sub(/^\//, '').
                sub(/\/[a-z]*$/, '').
                gsub(/\(\?#.+\)/, '').
                gsub(/\(\?-\w+:/, '(').
                gsub(/\s/, '')
            Regexp.new(str).source
          end

          def validate_auto_complete(value)
            case value
            when false, :disabled, 'disabled', 'off', nil
              :off
            when true, :enabled, 'enabled', 'on'
              :on
            else # :on, :off, client-specific values
              value
            end
          end
        end
      end
    end
  end
end

Component HTML

<% if comp
     leading_icon = comp.icon && comp.icon.position.select {|p| eq(p, :left)}.any?
     trailing_icon = comp.icon && comp.icon.position.select {|p| eq(p, :right)}.any?
     auto_complete = comp.auto_complete&.to_sym == :off ? 'extra-off' : comp.auto_complete
%>
  <div id="<%= comp.id %>"
       <% if comp.tag %>data-input-tag="<%= comp.tag %>"<% end %>
       <% if comp.dirtyable %>data-dirtyable<% end %>
       class="v-input v-text-field v-focusable mdc-text-field mdc-text-field--outlined
            <%= 'mdc-text-field--with-leading-icon' if leading_icon %>
            <%= 'mdc-text-field--with-trailing-icon' if trailing_icon %>
            <%= 'mdc-text-field--disabled' if comp.disabled %>
            <%= 'is-invalid is-dirty' if comp.error %>"
       style="<%= 'width:100%' if comp.full_width %>">

    <input id="<%= comp.id %>-input"
           name="<%= comp.name %>"
           type="<%= comp.password ? 'password' : 'text' %>"
           value="<%= comp.value %>"
           class="mdc-text-field__input"
           aria-controls="<%= comp.id %>-input-helper-text"
           <% if comp.disabled %>disabled<% end %>
           <%= 'required' if comp.required %>
           <%= 'invalid' if comp.error %>
           <%= "pattern='#{comp.pattern}'" if comp.pattern %>
           <%= "maxlength='#{comp.maxlength}'" if comp.maxlength %>
           autocomplete="<%= auto_complete %>"
           list="<%= comp.id %>-list"
           <%= erb :"components/event", :locals => {comp: comp, events: comp.events, parent_id:  "#{comp.id}-input"} %>>

    <%= erb :"components/icon", :locals => {comp: comp.icon, class_name: 'mdc-text-field__icon', parent_id: "#{comp.id}-input"} %>

    <div class="mdc-notched-outline">
      <div class="mdc-notched-outline__leading"></div>
      <div class="mdc-notched-outline__notch">
        <label for="<%= comp.id %>-input" class="mdc-floating-label"><%= comp.label %></label>
      </div>
      <div class="mdc-notched-outline__trailing"></div>
    </div>
    <datalist id="<%= comp.id %>-list">
    </datalist>
  </div>
  <% if comp.error || comp.hint %>
    <p id="<%= comp.id %>-input-helper-text" class="mdc-text-field-helper-text mdc-text-field-helper-text--persistent mdc-text-field-helper-text--validation-msg" aria-hidden="true">
      <%= comp.error || comp.hint %>
    </p>
  <% end %>
  <%= erb :"components/tooltip", :locals => {comp: comp.tooltip, parent_id: comp.id} %>
<% end %>
@dennismonsewicz dennismonsewicz changed the title Support max_length HTML element for text_field component Support maxlength HTML element for text_field component Aug 20, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant