forgive me if this question is too silly .I'm studying Ember.js myself and I'm stuck with a problem I need to set a value of the textbox dynamically and I dont know how to do that now I'm using jquery for overcome this error by using $("#results")[0].value = data; and I know its not the right way How can I do the same in Ember,js
my Current code is given below
App = Em.Application.create();
App.BaseCurrency = Em.Object.extend({
id: null,
name: null
});
App.DestCurrency = Em.Object.extend({
id: null,
name: null
});
App.BaseSelector = Em.ArrayController.extend({
content: [
App.BaseCurrency.create({ id: "INR", name:" Indian Rupee (INR)" }),
App.BaseCurrency.create({ id: "USD", name: "US Dollar (USD)" })
]
});
App.baseSelector = App.BaseSelector.create();
App.DestSelector = Em.ArrayController.extend({
content: [
App.DestCurrency.create({ id: "INR", name: " Indian Rupee (INR)" }),
App.DestCurrency.create({ id: "USD", name: "US Dollar (USD)" })
]
});
App.destSelector = App.DestSelector.create();
App.ConvertCurrency = Em.ObjectController.extend({
content: [],
amount:0,
baseCur: null,
destcur: null,
result: 0,
convert: function () {
var amount = this.get('amount');
var from = this.get('baseCur');
var to = this.get('destCur');
$.ajax({
type: "POST",
url: "Home/ConvertCurenncy",
data: "{amount:" + amount + ",from:'" + from + "',to:'" + to + "'}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {
$("#results")[0].value = data;
}
});
}
});
App.convertCurrency = App.ConvertCurrency.create();
and html
<script type="text/x-handlebars">
AMOUNT : {{view Ember.TextField valueBinding="App.convertCurrency.amount"}}
BASE : {{view Ember.Select contentBinding="App.baseSelector" optionLabelPath="content.name" optionValuePath="content.id" valueBinding="App.convertCurrency.baseCur" }}
DEST : {{view Ember.Select contentBinding="App.destSelector" optionLabelPath="content.name" optionValuePath="content.id" valueBinding="App.convertCurrency.destCur" }}
<button id="btnConvert"{{action "convert" target="App.convertCurrency"}}>convert</button>
RESULT :<input type="text" readonly=true id="results" />
</script>
You where almost there, what you might do is to customize a Ember.Texfield, for example:
App.ResultField = Ember.TextField.extend({
type: 'text',
attributeBindings: ['readonly'],
readonly: true
})
and then use it like so:
Result: {{view App.ResultField valueBinding="App.convertCurrency.result"}}
then in your success callback you set App.convertCurrency.result to the received value:
...
success: function (data) {
App.convertCurrency.set('result', data);
}
...
and bindings will take care on updating your textfield's value
Hope it helps.
Related
I have a router that returns data from the data model.
I want to use this data to bind it to a widget in a view.
Model:
myApp.Unit = DS.Model.extend({
active: DS.attr('boolean'),
allowdecimals: DS.attr('boolean'),
name: DS.attr('string'),
count: DS.attr('number'),
});
Router:
myApp.EunitsRoute = Ember.Route.extend({
model: function() {
return this.store.find('unit');
},
setupController: function(controller, model) {
this._super(controller, model);
controller.set('units', model);
},
actions: { ...
In the view I expect an object formated as follows:
[ {"id": 1,"active": true,"allowdecimals": true,"name": "Pint","count": 8},
{"id": 2,"active": true,"allowdecimals": true,"name": "Each","count": 8},
...]
What I am getting now in the view is an object:<DS.RecordArray:ember400>
View:
var source10 = {
datatype: "array",
datafields: [
{ name: 'id' },
{ name: 'name' },
{ name: 'allowdecimals' },
{ name: 'active' },
{ name: 'count' }
],
localdata: controller.get('units')
};
var dataAdapter10 = new $.jqx.dataAdapter(source10);
$("#eunits_grid").jqxGrid({
pageable: true,
theme: 'energyblue',
autorowheight : true,
rowsheight : 50,
pagesize: 10,
source: dataAdapter10,
....
Template:
<script type="text/x-handlebars" data-template-name="eunits">
<div class="col-md-12">
<h3 class="page-header">Edit Units</h3>
{{#if adding}}
{{view AddnewunitView}}
{{/if}}
{{view UnitsView id='eunits_grid'}}
</div>
</script>
Here is the thing I have a form which have multiple checkboxes and they have the same name attribute "classifications[]"
with the code:
<input type="checkbox" name="classification[]" value="Value 1" />
<input type="checkbox" name="classification[]" value="Value 2" />
<input type="checkbox" name="classification[]" value="Value 3" />
this works properly by default it posts "classification[]" like this
[ 0 => "Value 1", 1 => "Value 2"]
but I want this to work in an ember app so I did this (shortened version)
// index.html
{{input type="checkbox" name="classification[]" value="Cell Member" checked=classification}}
App.ApplicationController = Ember.Controller.extend({
var user = this.store.createRecord('user',{
classification: this.get("classification")
})
user.save();
})
App.User = DS.Model.extend({
classification: DS.attr("string")
});
but the only posted classification value is True..
try this
// index.html
{{#for possibleValues}}
<label>{{this.label}}</label>
{{input type="checkbox" value=this.isChecked}}
{{/for}}
<a {{action save}}>save</a>
var possibleValue = [{
label: 'Label for value 1',
isChecked: false,
value: 'Value 1'
},{
label: 'Label for value 2',
isChecked: false,
value: 'Value 2'
},{
label: 'Label for value 3',
isChecked: false,
value: 'Value 3'
}];
App = Ember.Application.create();
App.ApplicationAdapter = DS.RESTAdapter.extend();
App.ApplicationController = Ember.ObjectController.extend({
init: function () {
this._super();
var user = this.store.createRecord('user');
this.set('content', user);
},
actions:{
save: function () {
var user = this.get('content'),
collected = user.get('classifications');
this.set('collected', collected);
user.save();
}
},
//executes when isChecked is changed in one item of possibleValues
collectChecked: function () {
var classifications;
classifications = this.get('possibleValues').filterBy('isChecked', true); //filter checked only
classifications = classifications.mapBy('value'); //map values
this.set('classifications', classifications);
console.log(classifications);
}.observes('possibleValues.#each.isChecked'),
possibleValues: possibleValues
});
App.RawTransform = DS.Transform.extend({
deserialize: function(serialized) {
return serialized;
},
serialize: function(deserialized) {
return deserialized;
}
});
App.User = DS.Model.extend({
classifications: DS.attr('raw')
});
http://jsbin.com/dokiwati/6/edit
new here to ember, and very much trying to learn - and learn where I'm going wrong.
I'm being fed json that looks like this:
"status": "success",
"data": {
"groups": [
{
"id": 2,
"name": "Test1234",
"kind": "Happy",
"parent_group_id": 1,
"children_count": {
"boy": 10,
"girl": 4,
"pets": 2
},
"is_top_level": true
},
The path to get this info would be /api/groups/top.
I have a (what I believe would be) simple app.js:
App = Ember.Application.create();
App.Router.map(function() {
this.route("login", {path: "/"});
this.route("groups");
this.resource('about');
});
App.GroupsRoute = Ember.Route.extend({
model: function() {
return App.Group.find('top');
}
});
App.LoginController = Ember.Controller.extend({
actions: {
login: function(username, password){
jQuery.ajax({
url: "/api/auth",
type: 'post',
data: JSON.stringify( { "username": "user", "password": "pass" } ),
contentType: 'application/json',
dataType: 'json',
async: false,
success: function(result) {
if (result.status === 'success') {
user = result.data.user;
App.User.id = user.id;
App.User.name = user.name;
App.User.isAuthenticated = true;
App.User.displayUnits = "F";
} else {
//debugger;
throw "The! username and/or password you have entered is incorrect, please try again ";
return false;
}
},
error: function(xhr, status, errorOut) {
throw "The? username and/or password you have entered is incorrect, please try again ";
return false;
}
});
if (App.User.isAuthenticated)
this.transitionToRoute('groups');
}}
});
App.RESTAdapter = RL.RESTAdapter.create({
host: 'http://localhost:3000',
namespace: 'api/'
});
App.Client = RL.Client.create({
adapter: App.RESTAdapter
});
App.User = RL.Model.extend({
username: RL.attr('string'),
id: RL.attr('string'),
isAuthenticated: RL.attr('boolean'),
});
App.Group = RL.Model.extend({
id: RL.attr('string'),
name: RL.attr('string'),
kind: RL.attr('string')
});
App.RESTAdapter = RL.RESTAdapter.create({
defaultData: { cookie: "data"}
});
I'm trying to display each "group" in my template. For example {{#each groups}} {{name}} {{/each}}, but no luck - I can see the JSON data in the response in inspector, and no errors - but still, nothing coming trough.
Any help?
Thanks!
Ptep
edit - template:
<script type="text/x-handlebars">
{{outlet}}
</script>
<script type="text/x-handlebars" id="groups">
<h3>Hello,
{{#each groups}}
{{name}}! <br>
{{kind}}, {{id}}
{{/each}}
</h3>
</script>
The array itself would be the context of your template, so you would either use
{{#each}}{{name}}{{/each}}
or
{{#each model}}{{name}}{{/each}}
or
{{#each controller}}{{name}}{{/each}}
or
{{#each item in controller}}{{item.name}}{{/each}}
I am a starter of Ember and I try to use Ember.js(1.0.0.pre) in my app.
I am trying to set title for my Ember.Select's options to show tips when mouseover.
But, I can't find any information about the option's title in API.
Do I have to write a function myself to populate the "title" attribute?
Is there any way like "optionLabelPath" to bind "title" attribute for options?
To achieve this we need to reopen the Ember.SelectOption
here is the fiddle for the following example
MyApp = Ember.Application.create();
Ember.SelectOption.reopen({
attributeBindings: ['title'],
title: function() {
var titlePath = this.getPath('parentView.optionTitlePath');
return this.getPath(titlePath);
}.property('parentView.optionTitlePath')
});
MyApp.selectArray = [{
label: "A",
id: "1",
title: "for Apple"
},
{
label: "B",
id: "2",
title: "for Ball"
}];
Handlebars
<script type="text/x-handlebars" >
{{view Ember.Select
contentBinding="MyApp.selectArray"
optionLabelPath="content.label"
optionValuePath="content.id"
optionClassPath="content.title"
}}
</script>
Here is the simplest I could come up with:
http://jsfiddle.net/aK8JH/1/
Template:
{{view MyApp.Select contentBinding="content"}}
View:
MyApp.Select = Ember.Select.extend({
attributeBindings: ['title'],
title: 'myTitle'
});
Read this: http://emberjs.com/documentation/#toc_attribute-bindings-on-a-view
Below is what I've got after observing source code in Ember:
Ember.SelectOption.reopen({
attributeBindings: ['title'],
init: function() {
this.titlePathDidChange();
this._super();
},
titlePathDidChange: function() {
var titlePath = this.get('parentView.optionTitlePath');
if (!titlePath) { return; }
Ember.defineProperty(this, 'title', Ember.computed(function() {
return this.get(titlePath);
}).property(titlePath));
}.observes('parentView.optionTitlePath')
});
I try to bind value from input select to attribute "selectedValue" in controller.
This is app.js
Food = Ember.Application.create();
Food.appsController = Ember.Object.create({
selectedValue: ""
});
Food.Todo = Ember.Object.extend({
title: null,
value: null
});
Food.FoodController = Ember.ArrayProxy.create({
content: []
});
Food.FoodController.pushObject(Food.Todo.create({title:"a", value:"1"}));
Food.FoodController.pushObject(Food.Todo.create({title:"b", value:"2"}));
Food.FoodController.pushObject(Food.Todo.create({title:"c", value:"3"}));
This is index.html
{{#collection
contentBinding="Todos.todosController"
tagName="select"
itemClassBinding="content.isDone"}}
{{content.title}}
{{/collection}}
Output look like this
<select id="ember180" class="ember-view">
<option id="ember192" class="ember-view">
<script id="metamorph-0-start" type="text/x-placeholder"></script>
a
<script id="metamorph-0-end" type="text/x-placeholder"></script>
</option>
<option id="ember196" class="ember-view">
<script id="metamorph-1-start" type="text/x-placeholder"></script>
b
<script id="metamorph-1-end" type="text/x-placeholder"></script>
</option>
<option id="ember200" class="ember-view">
<script id="metamorph-2-start" type="text/x-placeholder"></script>
c
<script id="metamorph-2-end" type="text/x-placeholder"></script>
</option>
</select>
I have no idea how to add value to option and how to binding selected value back to controller.
Is this possible to do in Emberjs?
Ember now has a built-in Select view.
You can find it in the latest Ember.js build here: http://cloud.github.com/downloads/emberjs/ember.js/ember-latest.js
Here's an example usage:
var App = Ember.Application.create();
App.Person = Ember.Object.extend({
id: null,
firstName: null,
lastName: null,
fullName: function() {
return this.get('firstName') + " " + this.get('lastName');
}.property('firstName', 'lastName').cacheable()
});
App.selectedPersonController = Ember.Object.create({
person: null
});
App.peopleController = Ember.ArrayController.create({
content: [
App.Person.create({id: 1, firstName: 'Yehuda', lastName: 'Katz'}),
App.Person.create({id: 2, firstName: 'Tom', lastName: 'Dale'}),
App.Person.create({id: 3, firstName: 'Peter', lastName: 'Wagenet'}),
App.Person.create({id: 4, firstName: 'Erik', lastName: 'Bryn'})
]
});
Your template would look like:
{{view Ember.Select
contentBinding="App.peopleController"
selectionBinding="App.selectedPersonController.person"
optionLabelPath="content.fullName"
optionValuePath="content.id"}}
Again, here's a jsFiddle example: http://jsfiddle.net/ebryn/zgLCr/
Jumping off from the solution for #pangrantz, this Fiddle example (http://jsfiddle.net/bsyjr/) illustrates some improvements: The Handlebars code is cleaner through the use of tagName. When tagName is set to "select", the child views automatically become "option" elements. See the Ember.CollectionView.CONTAINER_MAP in https://github.com/emberjs/ember.js/blob/master/packages/ember-views/lib/views/collection_view.js to understand why. On the Javascript side, by specifying an itemViewClass, we can add the value attribute to the option element.
<script type="text/x-handlebars" >
{{#collection Food.SelectView tagName="select" contentBinding="Food.foodController"
valueBinding="Food.appsController.selectedValue"}}
{{content.title}}
{{/collection}}
selected: {{view Ember.TextField valueBinding="Food.appsController.selectedValue"}}{{Food.appsController.selectedValue}}
</script>
Food = Ember.Application.create();
Food.SelectView = Ember.CollectionView.extend({
value: null,
itemViewClass: SC.View.extend({
attributeBindings:['value'],
valueBinding: 'content.value'
}),
valueChanged: function(){
this.$().val( this.get('value') );
}.observes('value'),
didInsertElement: function(){
var self = this;
this.$().change(function(){
var val = $('select option:selected').val();
self.set('value', val);
});
}
});
Food.appsController = Ember.Object.create({
selectedValue: ""
});
Food.Todo = Ember.Object.extend({
title: null,
value: null
});
Food.foodController = Ember.ArrayProxy.create({
content: []
});
Food.foodController.pushObject(Food.Todo.create({title:"a", value:"1"}));
Food.foodController.pushObject(Food.Todo.create({title:"b", value:"2"}));
Food.foodController.pushObject(Food.Todo.create({title:"c", value:"3"}));
There is still room for improvement in the event handling, which is not using Ember's event framework, and it would make a lot of sense to use a custom written SelectView that doesn't leverage Handlebars, since IMO, it is dubious how much value Handlebars adds in this case.
Using a custom Ember.View works for me, but I think there is a better solution...
See working example is this fiddle http://jsfiddle.net/pangratz/hcxrJ/
Handlebars:
{{#view Food.SelectView contentBinding="Food.foodController"
valueBinding="Food.appsController.selectedValue"}}
<select>
{{#each content}}
<option {{bindAttr value="value"}} >{{title}}</option>
{{/each}}
</select>
{{/view}}
app.js:
Food = Ember.Application.create();
Food.SelectView = Ember.View.extend({
value: null,
valueChanged: function(){
this.$('select').val( this.get('value') );
}.observes('value'),
didInsertElement: function(){
var self = this;
this.$('select').change(function(){
var val = $('select option:selected').val();
self.set('value', val);
});
}
});
Food.appsController = Ember.Object.create({
selectedValue: ""
});
Food.Todo = Ember.Object.extend({
title: null,
value: null
});
Food.foodController = Ember.ArrayProxy.create({
content: []
});
Food.foodController.pushObject(Food.Todo.create({title:"a", value:"1"}));
Food.foodController.pushObject(Food.Todo.create({title:"b", value:"2"}));
Food.foodController.pushObject(Food.Todo.create({title:"c", value:"3"}));
I'm not sure if this is of use to others, but I've been doing something similar based on the answers here, and have made this SelectView that should work in this context too. It binds to 'change', works out the view that is currently selected and then does something with its content.
Food.SelectView = Ember.CollectionView.extend({
change: function(e) {
var selected = this.$().find(":selected").index();
var content = this.get('childViews')[selected].content;
// Do something with the result
Food.appsController.set('selectedValue', content.title);
}
});
This way you're able to pass around an object rather than the index of the select.