Access model in controller-action? - ember.js

I'm editing an object with a form and want to save the changed object from within the controller-action which is bound to the submit-button. I don't want to bind the values directly to the template.
Here's the admin/edit.hbs
<form>
<label>Title
<input name="title" type="text" {{ bind-attr value=title }} />
</label>
<label>Permalink
<input name="permalink" type="text" {{ bind-attr value=permalink }} />
</label>
<label>Post
{{textarea value=body cols="80" rows="12"}}
</label>
<button {{ action 'submitAction' }}>Submit</button>
</form>
This is the controller admin/edit.hbs
import Ember from 'ember';
export default Ember.ObjectController.extend({
actions: {
submitAction: function() {
var newTitle = this.get('title');
// how to access the model here?
}
}
});

Assuming that the model you want is currently the model of your ObjectController, you can do one of two things:
Get the model directly:
submitAction: function() {
var model = this.get('model');
}
Pass it to the handler in the template:
// admin/edit.hbs
<button {{action 'submitAction' model}}>Submit</button>
// admin/edit.js
submitAction: function(model) {
}

In an ObjectController, the model is stored as… model. You can access it like this:
var model = this.get('model');
model.set('title', newTitle);
If you’re not using the features of ObjectController that automatically bind get and set calls to the object, you probably shouldn’t use ObjectController. The code as you have it listed will be setting the title of your model directly from the input field.

Related

data-value attribute in emberjs

I want to add data-value attribute in input element:
{{input type="text" data-value=ec.ec_id value=ec.ecl_subject placeholder=ec.ecl_en_subject name="ecl_subject" class="form-control" }}
But its not visible in browser:
<input id="ember874" class="ember-view ember-text-field form-control" placeholder="Doctor4US: Appointment" type="text" name="ecl_subject">
ADDING DATA ATTRIBUTES
By default, view helpers do not accept data attributes
i.e.
{{input type="text" data-value=ec.ec_id value=ec.ecl_subject name="ecl_subject" }}
Render as
<input id="ember257" class="ember-view ember-text-field" type="text" value="12">
There are two ways to enable support for data attributes. One way
would be to add an attribute binding on the view, e.g. Ember.TextField for the specific attribute:
Ember.TextField.reopen({
attributeBindings: ['data-value']
});
Now the same handlebars code above renders the following HTML:
<input id="ember259" class="ember-view ember-text-field"
type="text" data-value="110" value="12">
You can also automatically bind data attributes on the base view with the following:
Ember.View.reopen({
init: function() {
this._super();
var self = this;
// bind attributes beginning with 'data-'
Em.keys(this).forEach(function(key) {
if (key.substr(0, 5) === 'data-') {
self.get('attributeBindings').pushObject(key);
}
});
}
});
For more detail reffer:https://guides.emberjs.com/v1.10.0/templates/binding-element-attributes/
Ember Input helpers doesn't allow data-attributes. The list of allowed attributes can be found at https://guides.emberjs.com/v2.6.0/templates/input-helpers/
The solution for problem is that you use html tag itself, when you want to place data-attributes like below
<input type="text" data-value="{{ec.ec_id}}" value="{{ec.ecl_subject}}" placeholder="{{ec.ecl_en_subject}}" name="ecl_subject" class="form-control/>

Ember Form Action returns Undefined Input Value

I'm running into a weird issue with Ember.js.
I built out a basic search form like so, with an Ember input field that submits to a form action 'submitSearch':
import Ember from 'ember';
export default Ember.Route.extend({
actions: {
submitSearch: function() {
var searchItem = this.get('searchItem');
this.transitionTo({queryParams: {'q':searchItem}});
}
}
});
<div class="search">
<form {{action "submitSearch" on="submit"}}>
<fieldset>
{{input type="text" class="form-control" value=searchItem}}
<input type="submit" name="submit" id="submit-search" class="btn btn-default" value="Search" />
</fieldset>
</form>
</div>
Any reason why I would be getting a value of 'undefined' when logging out searchItem? I've tried just about everything including creating a model, but I can't get the input to save.
The searchTerm value in your template is referring to your controller's searchTerm property, not a property of your route (by default when referring to a property in your template, it is referring to a property of the corresponding controller).
To get the value in the route, simply do this.get('controller.searchTerm').

Ember.js: conditional input attribute

In Ember's input helper, how can I show/hide attributes based on a condition? For example, let's say I want to show required="required" if isEditable is true and disabled="disabled" otherwise. Currently I have something like this:
{{#if isEditable}}
{{input value=model.name required="required"}}
{{else}}
{{input value=model.name disabled="disabled"}}
{{/if}}
...but it would be nice if I bind the attributes somehow instead.
{{ input type='text' required=required disabled=disabled }} works just fine
Working example here
There are a whole bunch of attributes that you can bind directly and required and disabled are among the pack. See here
Note #blackmind is correct that if you were to do this from scratch, you would need to do some work. Fortunately though, TextSupport already does the work for you... :) See here
From the EmberJS site
By default, view helpers do not accept data attributes. For example
{{#link-to "photos" data-toggle="dropdown"}}Photos{{/link-to}}
{{input type="text" data-toggle="tooltip" data-placement="bottom" title="Name"}}
renders the following HTML:
<a id="ember239" class="ember-view" href="#/photos">Photos</a>
<input id="ember257" class="ember-view ember-text-field" type="text" title="Name">
There are two ways to enable support for data attributes. One way would be to add an attribute binding on the view, e.g. Ember.LinkView or Ember.TextField for the specific attribute:
Ember.LinkView.reopen({
attributeBindings: ['data-toggle']
});
Ember.TextField.reopen({
attributeBindings: ['data-toggle', 'data-placement']
});
Now the same handlebars code above renders the following HTML:
<a id="ember240" class="ember-view" href="#/photos" data-toggle="dropdown">Photos</a>
<input id="ember259" class="ember-view ember-text-field"
type="text" data-toggle="tooltip" data-placement="bottom" title="Name">
Or you can reopen the view
Ember.View.reopen({
init: function() {
this._super();
var self = this;
// bind attributes beginning with 'data-'
Em.keys(this).forEach(function(key) {
if (key.substr(0, 5) === 'data-') {
self.get('attributeBindings').pushObject(key);
}
});
}
});
I typically do the following
<input type="checkbox" {{bind-attr disabled=isAdministrator}}>

Ember - displaying model value in form field

I have a user settings form like so:
<script type="text/x-handlebars" data-template-name="settings">
<form class="form-horizontal user-form" {{action "update" on="submit"}}>
<div>
<label>First Name</label>
{{input type="text" value=firstName placeholder="First Name"}}
{{error.firstName}}
</div>
<div>
<label>Last Name</label>
{{input type="text" value=lastName placeholder="Last Name"}}
{{error.lastName}}
</div>
<div>
<label>Email Address *</label>
{{input type="text" value=email placeholder="Email Address"}}
{{error.email}}
</div>
</form>
</script>
In my route for this page, I define the model:
App.SettingsRoute = Ember.Route.extend({
model: function() {
return this.store.find('user', 1);
}
});
If things are left like this, the form will automatically populate with the values retrieved from the model. However, if I add a controller:
App.SettingsController = Ember.Controller.extend({
actions: {
update: function() {
// Do something
}
}
});
...They won't. So how do I use my model in conjunction with this controller to set the properties?
The way you defined your controller was as a regular Ember.Controller and not an Ember.ObjectController so the controller is not proxying the model. If you modify it to be like this:
App.SettingsController = Ember.ObjectController.extend({
actions: {
update: function() {
// Do something
}
}
});
Then it should still automatically populate with the values from the model.

Adding a new object to an ArrayController

I am attempting to create a basic CRUD setup for managing 'User' objects in Ember. I think I have my models and routes in order. I'm struggling with managing:
A) The proper controller setup for the (all) users page. I think that I should be creating an ArrayController, but it seems to work fine automatically. Does my Ember App know to make an array of individual 'user' objects? if so, how?
B) Passing data from InputFields. If you click 'Add User' in my example, I have made a form to create a user. When you click 'create', I'm not sure how to get the textField values, nor do I understand what to do with those values once I have them. How would I update my controller?
Again, here a jsbin of my code. Any guidance would be greatly appreciated.
Regarding A):
I assume you refer to the following route of your App. This model function returns an Array. Therefore Ember knows that it should use an ArrayController to render your UsersRoute.
App.UsersIndexRoute = Ember.Route.extend({
model: function() {
return App.User.find();
}
});
Regarding B): I have updated your code -> http://jsbin.com/ozilam/15/edit
I needed to update some of your names (controller and view) to match the naming conventions of Ember.
With Ember you do not have to use forms and manually read those values. Instead you create a new records, when you enter your Route:
App.UsersNewRoute = Ember.Route.extend({
setupController : function(controller){
controller.set("content", App.User.createRecord({}));
}
});
Inside your View you are binding on the properties of your record. As you see i also updated your button with an action helper.
<script type="text/x-handlebars" data-template-name="users/new">
<div class="row">
<div class="six columns">
<h3>New User Information</h3>
<form>
<label>First Name</label>
{{view Ember.TextField valueBinding='name_first'}}<br />
<label>Last Name</label>
{{view Ember.TextField valueBinding='name_last'}}<br />
<label>Email Address</label>
{{view Ember.TextField valueBinding='email_address'}}<br />
<label>SSN</label>
{{view Ember.TextField valueBinding='ssn'}}<br />
<button {{action create target="view"}} class="button">Create</button>
{{#linkTo users}}Cancel{{/linkTo}}
</form>
</div>
</div>
</script>
As those changes in the form get automatically propagated to your controller, you can just access the object in the controller:
App.UsersNewView = Ember.View.extend({
didInsertElement: function() {
this.$('input:first').focus();
},
create: function(){
console.log('view submitted');
var newUser = this.get("controller.content");
console.log(newUser.get("name_first"));
console.log(newUser.get("name_last"));
// HOW DO I PROCESS THIS FORM
}
});
Note: As i am writing this i am realizing that it would be probably better, if you would handle this event in your Controller instead of the View, since its an data modification task.