Skip to content

Instantly share code, notes, and snippets.

@alexspeller
Forked from validkeys/Component Usage
Last active August 29, 2015 14:04
Show Gist options
  • Save alexspeller/2feb14a692252816eea8 to your computer and use it in GitHub Desktop.
Save alexspeller/2feb14a692252816eea8 to your computer and use it in GitHub Desktop.
{{#object-form for=this action="formSubmitted" buttonLabel="Click Me" formClass="narrow"}}
{{form-field for="email"}}
{{form-field for="password" label="Create new password" hint="Minimum 8 characters"}}
{{form-field for="passwordConfirmation" label="Confirm new password"}}
{{/object-form}}
{{#if for.errors.length}}
<div class="alert alert-danger">
<h4>There was a problem</h4>
<ul>
{{#each baseErrors}}
<li>
{{message}}
</li>
{{/each}}
{{#each errors}}
<li>
{{titleize attribute}} {{message}}
</li>
{{/each}}
</ul>
</div>
{{/if}}
<div class="form-group" {{bind-attr class="hasError:has-error"}}>
{{#if label}}
<label {{bind-attr for=fieldId}} class='control-label'>{{label}}</label>
{{/if}}
{{#if template}}
{{yield}}
{{else}}
{{#if isTextArea}}
{{textarea value=value id=fieldId}}
{{else}}
{{input type=type value=value id=fieldId class="form-control" placeholder=placeholder}}
{{/if}}
{{/if}}
{{#if errors.length}}
<span class="help-block">
{{errors}}
</span>
{{/if}}
{{#if hint}}
<span class="help-block">{{hint}}</span>
{{/if}}
</div>
{{error-messages for=for}}
<form {{action "submit" on="submit"}} {{bind-attr class=formClass}}>
{{yield}}
{{#unless noButton}}
<div class="form-group">
<p>
<button type='submit' class='btn-block btn-primary'>{{buttonLabel}}</button>
</p>
</div>
{{/unless}}
</form>
App.ErrorMessagesComponent = Em.Component.extend
errors: Em.computed.filter 'for.errors.content', (error) ->
error.attribute != 'base'
baseErrors: Em.computed.filter 'for.errors.content', (error) ->
error.attribute is 'base'
App.FormFieldComponent = Em.Component.extend
type: prop 'for', ->
if @get('for').match(/password/)
"password"
else
"text"
label: prop 'for', ->
@get('for').titleize()
fieldId: prop 'object', 'for', ->
"#{Em.guidFor @get('object')}-input-#{@get('for')}"
isTextArea: Em.computed.equal 'type', 'textarea'
object: Em.computed.alias 'parentView.for'
hasError: prop 'object.errors.[]', ->
@get('object.errors').has @get('for')
errors: prop 'object.errors.[]', ->
@get('object.errors').errorsFor(@get('for')).mapBy('message').join(', ')
# dynamically bind the value field to the right field on the object
# needed because the field is provided as a string
# This is just to make the api nicer to use, you could pass in both
# the string and the value into the component to avoid this magic
setupBindings: (->
@binding?.disconnect @ # Disconnect old binding if present
# Create a binding between the value property of the component,
# and the correct field name on the model object.
@binding = Em.Binding.from("object.#{@get 'for'}").to('value')
# Activate the binding
@binding.connect @
).on('init').observes 'for', 'object'
App.ObjectFormComponent = Em.Component.extend
buttonLabel: "Submit"
actions:
submit: ->
@sendAction()
@alexspeller
Copy link
Author

If you have bootstrap css this will automatically look pretty good out of the box ;)

@validkeys
Copy link

wow this looks nice. Great work!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment