Emerson / ember-form-master-2000

A simple form builder for Ember built as an Ember-CLI addon.
MIT License
40 stars 18 forks source link

support bootstrap horizontal form #37

Open jelhan opened 8 years ago

jelhan commented 8 years ago

Introduces inputWrapperClass, an element which wraps input fields, errors and help texts. This is needed for columns in bootstrap horizontal from.

Example usage:

// routes/application.js
import Ember from 'ember';

export default Ember.Route.extend({
  beforeModel() {
    this.set('inputWrapperClass', 'col-sm-10');
    this.set('labelClass', 'col-sm-2');
    this.set('formClass', 'form-horizontal');
  },
  fmConfig: Ember.inject.service('fm-config')
});

You will have a bootstrap horizontal form.

Column offset are not handeled automatically for fields without a label (fm-checkbox, fm-submit) or if label property is empty. As this seems to be to much bootstrap specific for this general form-builder libary.

Together with https://github.com/Emerson/ember-form-master-2000/pull/36 we could make a nice horizontal bootstrap form like this one: http://getbootstrap.com/css/#forms-horizontal

{{#fm-form}}
  {{fm-field label='Email'}}
  {{fm-field label='Password'}}
  {{fm-checkbox label='Remember me' inputWrapperClass='col-sm-10 col-sm-offset-2'}}
  {{#fm-submit inputWrapperClass='col-sm-10 col-sm-offset-2'}}
     Sign in
  {{/fm-submit}}
{{/fm-form}}

Of course you should have service configuration set like above.

g-cassie commented 8 years ago

I think that this is pretty custom behaviour which can easily be added by extending the component and using a custom template.

// horizontal-field.js
import FmField from  'ember-form-master-2000/components/fm-field';
import layout from '../templates/components/fm-field';
export default FmField.extend({
  layout: layout
});
// horizontal-field.hbs
{{#if label}}
  <label for="{{forAttribute}}" class="{{labelClass}}">{{{label}}}</label>
{{/if}}

<div class="horizontal-classes">
{{#if isBasicInput}}
  {{fm-input
    type=type
    value=value
    classNameBindings='errorClass inputClass'
    maxlength=maxlength
    placeholder=placeholder}}
{{/if}}

{{#if isSelect}}
  {{fm-select
    content=content
    optionValuePath=optionValuePath
    optionLabelPath=optionLabelPath
    prompt=prompt
    value=value
    action=(action 'selectAction')
  }}
{{/if}}

{{#if isTextarea}}
  {{fm-textarea
    value=value
    classNameBindings='errorClass textareaClass'
    placeholder=placeholder
    rows=rows
    cols=cols
    maxlength=maxlength
    spellcheck=spellcheck
    disabled=disabled
  }}
{{/if}}

{{#if errors}}
  {{fm-errortext errors=errors}}
{{/if}}

{{#if helptext}}
  {{fm-helptext helptext=helptext}}
{{/if}}
</div>

If we could do something to make this extension process easier - like making it so you do not have to copy as much template from the default form-master template I think that would be a better way to proceed.

jelhan commented 8 years ago

@g-cassie It's of course also possible by overrides and reopen. This was the way I had this one implemented before. But I think a wrapper around these elements is required by many form markup that's why I introduced it as a PR. Also this addon is configured to work with bootstrap as default. But if you come to a decision not to include this one, it's also fine for me.

jelhan commented 8 years ago

Rebased after #36 was merged.

jelhan commented 8 years ago

Rebased after #38 was merged.

g-cassie commented 8 years ago

@jelhan

How about the following API?

{{fm-field
   fieldLayout='bs-horizontal'
   ...
}}

Then we can provide some predefined layouts.

// ember-form-master-2000/templates/field-layouts/bs-horizontal.hbs
{{#if label}}
  <label for="{{forAttribute}}" class="{{labelClass}}">{{{label}}}</label>
{{/if}}

<div class="horizontal-classes">
{{component widgetName
   value=(mut value)
   widgetAttrs=widgetAttrs
}}

{{#if errors}}
  {{fm-errortext errors=errors}}
{{/if}}

{{#if helptext}}
  {{fm-helptext helptext=helptext}}
{{/if}}
</div>
jelhan commented 8 years ago

Thanks for digging into this.

I'm not quite sure about the api. Default template and horizontal template would be very similar for my case - just two lines would be different. If bootstrap grid columns should be supported, there would be some more changes but template specific parameters would be needed. Feels like the api would not solve the DRY issue but make fm-field much more complex. Extending fm-field seems to be a cleaner solution. Perhaps it's all about splitting up default field template so that it would be easier to customize?

Also it's a little bit confusing that basic inputs, textarea and select using fm-field while radio groups, submit and checkboxes aren't. So to at a wrapper class around input fields (as neeeded here) you have to customize 4 components. It's also a source of inconsistency as introduced by 53f3430a8ef10101edbcb3e83e8a49455145d508.

g-cassie commented 8 years ago

I would like to refactor so that we have a concept of a "widget". A widget is a generic term for input, textarea, select, radio group, jquery datepicker etc. It should be extensible so you can make any widget you want and still get standard label, error and help text from the fm-field class. If we had this refactor in place, I think it would be trivial to add new layouts and a lot less DRY than my example above. Also I think we could have layouts for popular css frameworks available in the form-master repo so in most cases it would be zero work.

In terms of making this "widget" class, I think we really need the hash helper introduced in Ember 2.3. So the api would look something like this:

{{fm-field
   fieldLayout='bs-horizontal'
   widgetName='my-autocomplete-input'
   widgetParams=(hash 
      my-autocomplete-choices=someArray
      my-autocomplete-labelField='name'
      my-autocomplete-valueField='id'
  )
  label='Country'
  value=(mut country)
}} 

So I agree the layout option above is not ideal now, but I think if we unified all the field types so there is less repetition in the code base it could have a nice syntax and be very extensible.

jelhan commented 8 years ago

That widget api looks really good. @g-cassie thanks for your work on that! Let me know if I could help you.

Emerson commented 8 years ago

Love the API as well as the notion of an extensible widget. Just need to wrap my mind around the new params and mut syntax.