371 lines
No EOL
12 KiB
HTML
371 lines
No EOL
12 KiB
HTML
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<title>Croodle</title>
|
|
</head>
|
|
<body>
|
|
<!--
|
|
TEMPLATES
|
|
-->
|
|
|
|
<!-- application template -->
|
|
<script type="text/x-handlebars">
|
|
<div class="main">
|
|
<h1>Croodle</h1>
|
|
{{outlet}}
|
|
</div>
|
|
</script>
|
|
|
|
<!-- poll template -->
|
|
<script type="text/x-handlebars" id="poll">
|
|
<h2>title</h2>
|
|
<p>{{title}}</p>
|
|
|
|
<h2>description</h2>
|
|
<p>{{description}}</p>
|
|
|
|
<h2>type</h2>
|
|
<p>{{type}}</p>
|
|
|
|
<h2>options and user</h2>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<td>user</td>
|
|
{{#each option in options}}
|
|
<td>{{option.title}}</td>
|
|
{{/each}}
|
|
<td> </td>
|
|
</tr>
|
|
</thead>
|
|
|
|
<tbody>
|
|
{{#each user in users}}
|
|
<tr>
|
|
<td>{{user.name}}</td>
|
|
{{#each selection in selections}}
|
|
<td>{{selection.value}}</td>
|
|
{{/each}}
|
|
<td> </td>
|
|
</tr>
|
|
{{/each}}
|
|
|
|
<tr class='newUser'>
|
|
<td>{{input value=newUserName}}</td>
|
|
{{#each option in options}}
|
|
<td>{{input class="newUserSelection" data-option=option.id}}</td>
|
|
{{/each}}
|
|
<td><button {{action "save"}}> ok </button></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
|
|
<h2>creationDate</h2>
|
|
<p>{{creationDate}}</p>
|
|
</script>
|
|
|
|
<!-- create templates -->
|
|
<script type="text/x-handlebars" id="create">
|
|
{{outlet}}
|
|
</script>
|
|
|
|
<script type="text/x-handlebars" id="create/index">
|
|
<p>
|
|
type:<br/>
|
|
{{view Ember.Select
|
|
contentBinding="App.Types"
|
|
optionValuePath="content.id"
|
|
optionLabelPath="content.label"
|
|
valueBinding="type"}}
|
|
</p>
|
|
<p><button {{action "save"}}> ok </button></p>
|
|
</script>
|
|
|
|
<script type="text/x-handlebars" id="create/meta">
|
|
<p>title:<br/>{{input value=title}}</p>
|
|
<p>description:<br/>{{input value=description}}</p>
|
|
<p><button {{action "save"}}> ok </button></p>
|
|
</script>
|
|
|
|
<script type="text/x-handlebars" id="create/options">
|
|
<p>options<br/>
|
|
{{#each option in options}}
|
|
{{option.title}}<br/>
|
|
{{/each}}
|
|
</p>
|
|
<p>{{input value=newOptionTitle}} <button {{action "addOption"}}> add option </button></p>
|
|
<p><button {{action "save"}}> ok </button></p>
|
|
</script>
|
|
|
|
<script type="text/x-handlebars" id="create/settings">
|
|
<p>settings</p>
|
|
<p><button {{action "save"}}> ok </button></p>
|
|
</script>
|
|
|
|
<!-- DEPEDENCIES -->
|
|
<script src="lib/jquery-2.0.3.js"></script>
|
|
<script src="lib/handlebars-v1.2.0.js"></script>
|
|
<script src="lib/ember.js"></script>
|
|
<script src="lib/ember-data.js"></script>
|
|
|
|
<!-- EMBER APP CODE -->
|
|
<script type="text/javascript">
|
|
// app initialization
|
|
window.App = Ember.Application.create({
|
|
LOG_TRANSITIONS: true
|
|
});
|
|
|
|
// adapter initialization
|
|
App.ApplicationAdapter = DS.RESTAdapter.extend({
|
|
// set namespace to api.php in same subdirectory
|
|
namespace: 'api.php?'
|
|
});
|
|
|
|
// adding support for attribut data-option-id to input fields
|
|
Ember.TextField.reopen({
|
|
attributeBindings: ['data-option']
|
|
});
|
|
|
|
/*
|
|
* models
|
|
*/
|
|
|
|
// poll model
|
|
App.Poll = DS.Model.extend({
|
|
title : DS.attr('string'),
|
|
description : DS.attr('string', {defaultValue: ''}),
|
|
type : DS.attr('string'),
|
|
options : DS.hasMany('option', {async: true}),
|
|
users : DS.hasMany('user', {async: true}),
|
|
creationDate : DS.attr('date')
|
|
});
|
|
|
|
// option model
|
|
// used by poll model
|
|
App.Option = DS.Model.extend({
|
|
poll : DS.belongsTo('poll', {async: true}),
|
|
title : DS.attr('string')
|
|
});
|
|
|
|
// user model
|
|
// used by poll model
|
|
App.User = DS.Model.extend({
|
|
poll : DS.belongsTo('poll', {async: true}),
|
|
name : DS.attr('string'),
|
|
selections : DS.hasMany('selection', {async: true}),
|
|
creationDate : DS.attr('date')
|
|
});
|
|
|
|
// selection model
|
|
// used by user model
|
|
App.Selection = DS.Model.extend({
|
|
// option : DS.belongsTo('option'),
|
|
user : DS.belongsTo('user', {async: true}),
|
|
value : DS.attr('string')
|
|
});
|
|
|
|
App.Types = [
|
|
Ember.Object.create({
|
|
id : "FindADate",
|
|
label : "Find a date"
|
|
}),
|
|
Ember.Object.create({
|
|
id : "MakeAPoll",
|
|
label : "Make a poll"
|
|
})
|
|
];
|
|
|
|
/*
|
|
* routes
|
|
*/
|
|
|
|
// defining routes of app
|
|
App.Router.map(function(){
|
|
this.route('poll', { path: '/poll/:poll_id' });
|
|
this.resource('create', function(){
|
|
this.route('meta');
|
|
this.route('options');
|
|
this.route('settings');
|
|
});
|
|
});
|
|
|
|
App.CreateRoute = Ember.Route.extend({
|
|
model: function(){
|
|
return this.store.createRecord('poll', {
|
|
creationDate : new Date()
|
|
});
|
|
}
|
|
});
|
|
|
|
App.CreateIndexRoute = Ember.Route.extend({
|
|
model: function(){
|
|
return this.modelFor('create');
|
|
}
|
|
});
|
|
|
|
App.CreateMetaRoute = Ember.Route.extend({
|
|
model: function(){
|
|
return this.modelFor('create');
|
|
},
|
|
|
|
// redirect to create/index if type is not set
|
|
afterModel: function(create){
|
|
if (create.get('type') === undefined) {
|
|
this.transitionTo('create.index');
|
|
}
|
|
}
|
|
});
|
|
|
|
App.CreateOptionsRoute = Ember.Route.extend({
|
|
model: function(){
|
|
return this.modelFor('create');
|
|
},
|
|
|
|
// redirect to create/meta if title is not set
|
|
afterModel: function(create){
|
|
if (create.get('title') === undefined) {
|
|
this.transitionTo('create.meta');
|
|
}
|
|
}
|
|
});
|
|
|
|
App.CreateSettingsRoute = Ember.Route.extend({
|
|
model: function(){
|
|
return this.modelFor('create');
|
|
},
|
|
|
|
// redirect to create/options if less then two options are defined
|
|
afterModel: function(create){
|
|
if (create.get('options.length') < 2) {
|
|
this.transitionTo('create.options');
|
|
}
|
|
}
|
|
});
|
|
|
|
/*
|
|
* controller
|
|
*/
|
|
App.CreateIndexController = Ember.ObjectController.extend({
|
|
actions: {
|
|
save: function(){
|
|
// redirect to CreateMeta
|
|
this.transitionToRoute('create.meta');
|
|
}
|
|
}
|
|
});
|
|
|
|
App.CreateMetaController = Ember.ObjectController.extend({
|
|
actions: {
|
|
save: function(){
|
|
// redirect to CreateOptions
|
|
this.transitionToRoute('create.options');
|
|
}
|
|
}
|
|
});
|
|
|
|
App.CreateOptionsController = Ember.ObjectController.extend({
|
|
actions: {
|
|
addOption: function(){
|
|
// create new option
|
|
var newOptionId = this.get('model.options.length') + 1,
|
|
newOption = this.store.createRecord('option', {
|
|
id : newOptionId,
|
|
title : this.get('newOptionTitle')
|
|
});
|
|
|
|
// assign it to poll
|
|
this.get('model.options').pushObject(newOption);
|
|
|
|
// clear newOptionTitle input field
|
|
this.set('newOptionTitle', '');
|
|
},
|
|
|
|
save: function(){
|
|
// redirect to CreateSettings
|
|
this.transitionToRoute('create.settings');
|
|
}
|
|
}
|
|
});
|
|
|
|
App.CreateSettingsController = Ember.ObjectController.extend({
|
|
actions: {
|
|
save: function(){
|
|
// save poll
|
|
var self = this;
|
|
this.get('model').save().then(function(){
|
|
// redirect to new poll
|
|
self.transitionToRoute('poll', self.get('model') );
|
|
});
|
|
}
|
|
}
|
|
});
|
|
|
|
App.PollController = Ember.ObjectController.extend({
|
|
actions: {
|
|
save: function(){
|
|
// create new user record in store
|
|
var newUser = this.store.createRecord('user', {
|
|
name : this.get('newUserName'),
|
|
creationDate : new Date()
|
|
});
|
|
|
|
// create new selection record in store and assign it to the new user
|
|
var self = this,
|
|
newSelections = [];
|
|
$('.newUserSelection').each(function(){
|
|
// generate a new selection id
|
|
var newSelectionId = function(){
|
|
// ToDo: check if id already exists
|
|
return newId = Math.floor(Math.random()*(100000)+1);
|
|
};
|
|
|
|
// create new selection record in store
|
|
var newSelection = self.store.createRecord('selection', {
|
|
id : newSelectionId(),
|
|
value : $(this).val()
|
|
});
|
|
|
|
// store new selections in an array
|
|
newSelections.push(newSelection);
|
|
});
|
|
|
|
newUser.get('selections').then(function(selections){
|
|
// map over all new selections and assign them to user
|
|
var selections = selections;
|
|
$.each(newSelections, function(){
|
|
selections.pushObject(this);
|
|
});
|
|
|
|
// save new user
|
|
newUser.save().then(function(){
|
|
self.get('model.users').then(function(users){
|
|
// assign new user to poll
|
|
users.pushObject(newUser);
|
|
|
|
// update poll
|
|
self.get('model').save();
|
|
});
|
|
});
|
|
});
|
|
}
|
|
}
|
|
});
|
|
|
|
/*
|
|
* views
|
|
*/
|
|
App.PollSerializer = DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {
|
|
attrs: {
|
|
options: {embedded: 'always'}
|
|
}
|
|
});
|
|
|
|
App.UserSerializer = DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {
|
|
attrs: {
|
|
selections: {embedded: 'always'}
|
|
}
|
|
});
|
|
</script>
|
|
</body>
|
|
</html> |