Ember Data Mockjax
HTML
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery-mockjax/1.5.2/jquery.mockjax.js"></script>
<script src="http://ember.alexspeller.com/handlebars-1.0.0.js"></script>
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css">
<script src="http://ember.alexspeller.com/canary/shas/5c30be4fe354b57a9241be6cd14f0b3fae977c0e/ember.js"></script>
<script src="http://ember.alexspeller.com/canary/shas/45d196b2907ae0ddca2ffc2b50ce84fbc0e275c6/ember-data.js"></script>
<script type="text/x-handlebars">
<div class="container">
<h2>Create User</h2>
{{#object-form for=this action="updateUser" buttonLabel="Save"}}
{{form-field for="name"}}
{{form-field for="email"}}
{{form-field for="password"}}
{{form-field for="passwordConfirmation"}}
{{#form-field for="notes"}}
{{textarea class="form-control" value=notes}}
{{/form-field}}
{{/object-form}}
</div>
</script>
<script type="text/x-handlebars" data-template-name="components/form-field">
<div class="form-group">
<label {{bind-attr for=label}}>{{label}}</label>
{{#if template}}
{{yield}}
{{else}}
{{input type=type value=value id=label class="form-control"}}
{{/if}}
</div>
</script>
<script type="text/x-handlebars" data-template-name="components/object-form">
<form {{action "submit" on="submit"}}>
{{yield}}
<div class="form-group">
<button type='submit' class='btn btn-block btn-primary'>{{buttonLabel}}</button>
</div>
</form>
</script>
CoffeeScript
window.App = Em.Application.create()
# The object form component wraps:
App.ObjectFormComponent = Em.Component.extend
buttonLabel: "Submit"
actions:
submit: ->
@sendAction()
App.FormFieldComponent = Em.Component.extend
type: (->
if @get('for').match(/password/)
"password"
else
"text"
).property 'for'
label: (->
# this turns camelCased words into Title case
@get('for').underscore().replace(/_/g, " ").capitalize()
).property 'for'
fieldId: (->
"#{Em.guidFor @get('object')}-input-#{@get('for')}"
).property 'object', 'for'
# The form-field component must be wrapped in an {{object-form}}
# component, which is passed the object that the form represents
object: Em.computed.alias 'parentView.for'
# 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.
# So by setting up these bindings, you can write in your template:
# {{form-field for="email"}}
# instead of
# {{form-field label="email" value=email}}
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'
# Ensure the bindings are cleaned up when the component is removed
tearDownBindings: (->
@binding?.disconnect @
).on 'willDestroyElement'
App.ApplicationAdapter = DS.ActiveModelAdapter.extend()
App.ApplicationRoute = Em.Route.extend
model: ->
@store.createRecord 'user'
actions:
updateUser: ->
alert "Updating user #{@currentModel.get 'name'}"
App.User = DS.Model.extend
name: ...