<!-- Language app, first go -->
<!DOCTYPE html>
<html>
<head>
<script data-require="angular.js@*" data-semver="1.2.0-rc3-nonmin" src="http://code.angularjs.org/1.2.0-rc.3/angular.js"></script>
<link rel="stylesheet" href="style.css" />
<script>
var app = angular.module('sm', []);
</script>
<script src="filters.js"></script>
<script src="providers.js"></script>
<script src="directives.js"></script>
</head>
<body>
<div ng-app="sm">
<languages></languages>
</div>
</body>
</html>
// Code goes here
var app = angular.module('sm', []);
app.filter('forceFalse', function(){
return function(input, prop){
angular.forEach(input, function(i){
i[prop] = false;
});
return input;
}
});
app.filter('forceTrue', function(){
return function(input, prop){
angular.forEach(input, function(i){
i[prop] = true;
});
return input;
}
});
app.factory('Languages', function() {
return {
model:[{
name: 'English',
isAssigned: false,
fluencies: [{
label: 'Converational',
fluent: false
}, {
label: 'Read Write',
fluent: false
}, {
label: 'Totally Fluent',
fluent: false
}]
},
{
name: 'Spanish',
isAssigned: true,
fluencies: [{
label: 'Converational',
fluent: true
}, {
label: 'Read Write',
fluent: true
}, {
label: 'Totally Fluent',
fluent: false
}]
},
{
name: 'Russian',
isAssigned: false,
fluencies: [{
label: 'Converational',
fluent: false
}, {
label: 'Read Write',
fluent: false
}, {
label: 'Totally Fluent',
fluent: false
}]
}
]};
});
app.directive('controlPanel', function(){
return {
restrict:' E',
transclude: true,
replace: true,
require: '^languages',
template: '<div class="control-panel"><div ng-transclude></div></div>',
link: function(scope, element, attr, languagesCtrl){
scope.languagesCtrl = languagesCtrl;
}
}
});
app.directive('controlButton', function(){
return {
restrict:' E',
transclude: true,
replace: true,
//requires: '^languages',
template: '<a class="control-button" ng-transclude></a>',
link: function(scope, element, attr){
}
}
});
app.directive('languages', ['Languages',
function(langs) {
return {
restrict: 'E',
scope: {
}, //isolate scope
replace: true,
link: function(scope, element, attr) {
scope.model = {};
scope.model.languages = langs.model;
console.log(scope.model);
},
template: '<div>'+
'<control-panel>'+
'<control-button><div ng-click="assign(model.languages)">Assign</div></control-button>'+
'<control-button><div ng-click="unassign(model.languages)">Unassign</div></control-button>'+
'</control-panel>'+
'<div class="assigned">' +
'<language ng-repeat="lang in model.languages|filter:{isAssigned:true}" model="lang"></language>' +
'</div>' +
'<div class="unassigned">' +
'<language ng-repeat="lang in model.languages|filter:{isAssigned:false}" model="lang"></language>' +
'</div>'+
'</div>',
controller: function($scope, $filter) {
this.reportModel = function() {
console.log($scope.model.languages);
}
$scope.assign = function(selectedLangs){
selectedLangs = $filter('forceFalse')(selectedLangs, 'isSelected');
selectedLangs = $filter('forceTrue')(selectedLangs, 'isAssigned');
}
$scope.unassign = function(selectedLangs){
selectedLangs = $filter('forceFalse')(selectedLangs, 'isAssigned');
selectedLangs = $filter('forceFalse')(selectedLangs, 'isSelected');
}
//save method for prod, should be generic save factory call
}
}
}]);
app.directive('language', function() {
return {
restrict: 'E',
scope: {
model: '='
}, //isolate scope
replace: true,
require: '^languages',
template: '<div class="lang {{selectedClass(state.isSelected)}}">' +
'<a href="#" ng-click="toggleProp(state, \'isSelected\')" class="right-button">Select</a>'+
'<a href="#" ng-click="toggleProp(model, \'isAssigned\')" class="right-button">Assign</a>'+
'<div class="name" ng-bind="model.name"></div>' +
//'<div syle="clear:both;"></div>'+
'<div class="fluencies">' +
'<div ng-repeat="fluency in model.fluencies">' +
'<fluency model="fluency"></fluency>' +
'</div>' +
'</div>' +
'</div>',
link: function(scope, element, attr, languagesCtrl) {
scope.languagesCtrl = languagesCtrl;
scope.state = {isSelected: false};
//console.log(scope.model);
},
controller: function($scope) {
$scope.assignedClass = function(flag){
return flag ? 'assigned':'unassigned';
}
$scope.selectedClass = function(flag){
return flag ? 'selected':'';
}
$scope.toggleProp = function(o,p){
console.log(p);
o[p] = !o[p];
$scope.languagesCtrl.reportModel();
}
}
}
}
);
app.directive('fluency', function() {
return {
restrict: 'E',
scope: {
model: '='
},
require: '^languages',
replace: true,
template: '<div>' +
'<input type="checkbox" ng-model="model.fluent" ng-click="toggle(model, \'fluent\')" />' +
'{{model.label}}' +
'</div>',
link: function(scope, element, attr, languagesCtrl) {
scope.languagesCtrl = languagesCtrl;
},
controller: function($scope) {
$scope.toggleProp = function(o,p) {
o[p] = !o[p];
$scope.languagesCtrl.reportModel();
}
}
}
});
/* Styles go here */
.selected{
background-color:ghostwhite;
}
.assigned{
float:right;
width:48%;
margin:1%;
}
.assigned div.lang{
margin:0 0 10px 0;
border:1px solid blue;
}
.unassigned{
float:left;
width:48%;
margin:1%;
}
.unassigned div.lang{
margin:0 0 10px 0;
border:1px solid green;
}
.control-panel{
margin:1%;
border:1px solid #000;
padding:1%;
}
.control-panel a:hover{
background:#cceeff;
}
.control-panel a{
display:inline-block;
margin:0 1%;
cursor:pointer;
}
.right-button{
float:right;
display:block;
margin:10px;
}
.name{
margin:10px;
font-weight:bold;
}
.fluencies{
margin:10px;
}
app.filter('forceFalse', function(){
return function(input, prop){
angular.forEach(input, function(i){
i[prop] = false;
});
return input;
}
});
app.filter('forceTrue', function(){
return function(input, prop){
angular.forEach(input, function(i){
i[prop] = true;
});
return input;
}
});
app.factory('Languages', function() {
return {
model:[{
name: 'English',
isAssigned: false,
fluencies: [{
label: 'Converational',
fluent: false
}, {
label: 'Read Write',
fluent: false
}, {
label: 'Totally Fluent',
fluent: false
}]
},
{
name: 'Spanish',
isAssigned: true,
fluencies: [{
label: 'Converational',
fluent: true
}, {
label: 'Read Write',
fluent: true
}, {
label: 'Totally Fluent',
fluent: false
}]
},
{
name: 'Russian',
isAssigned: false,
fluencies: [{
label: 'Converational',
fluent: false
}, {
label: 'Read Write',
fluent: false
}, {
label: 'Totally Fluent',
fluent: false
}]
}
]};
});
app.directive('controlPanel', function(){
return {
restrict:' E',
transclude: true,
replace: true,
require: '^languages',
template: '<div class="control-panel"><div ng-transclude></div></div>',
link: function(scope, element, attr, languagesCtrl){
scope.languagesCtrl = languagesCtrl;
}
}
});
app.directive('controlButton', function(){
return {
restrict:' E',
transclude: true,
replace: true,
//requires: '^languages',
template: '<a class="control-button" ng-transclude></a>',
link: function(scope, element, attr){
}
}
});
app.directive('languages', ['Languages',
function(langs) {
return {
restrict: 'E',
scope: {
}, //isolate scope
replace: true,
link: function(scope, element, attr) {
scope.model = {};
scope.model.languages = langs.model;
console.log(scope.model);
},
template: '<div>'+
'<control-panel>'+
'<control-button><div ng-click="assign(model.languages)">Assign</div></control-button>'+
'<control-button><div ng-click="unassign(model.languages)">Unassign</div></control-button>'+
'</control-panel>'+
'<div class="assigned">' +
'<language ng-repeat="lang in model.languages|filter:{isAssigned:true}" model="lang"></language>' +
'</div>' +
'<div class="unassigned">' +
'<language ng-repeat="lang in model.languages|filter:{isAssigned:false}" model="lang"></language>' +
'</div>'+
'</div>',
controller: function($scope, $filter) {
this.reportModel = function() {
console.log($scope.model.languages);
}
$scope.assign = function(selectedLangs){
selectedLangs = $filter('forceFalse')(selectedLangs, 'isSelected');
selectedLangs = $filter('forceTrue')(selectedLangs, 'isAssigned');
}
$scope.unassign = function(selectedLangs){
selectedLangs = $filter('forceFalse')(selectedLangs, 'isAssigned');
selectedLangs = $filter('forceFalse')(selectedLangs, 'isSelected');
}
//save method for prod, should be generic save factory call
}
}
}]);
app.directive('language', function() {
return {
restrict: 'E',
scope: {
model: '='
}, //isolate scope
replace: true,
require: '^languages',
template: '<div class="lang {{selectedClass(state.isSelected)}}">' +
'<a href="#" ng-click="toggleProp(state, \'isSelected\')" class="right-button">Select</a>'+
'<a href="#" ng-click="toggleProp(model, \'isAssigned\')" class="right-button">Assign</a>'+
'<div class="name" ng-bind="model.name"></div>' +
//'<div syle="clear:both;"></div>'+
'<div class="fluencies">' +
'<div ng-repeat="fluency in model.fluencies">' +
'<fluency model="fluency"></fluency>' +
'</div>' +
'</div>' +
'</div>',
link: function(scope, element, attr, languagesCtrl) {
scope.languagesCtrl = languagesCtrl;
scope.state = {isSelected: false};
//console.log(scope.model);
},
controller: function($scope) {
$scope.assignedClass = function(flag){
return flag ? 'assigned':'unassigned';
}
$scope.selectedClass = function(flag){
return flag ? 'selected':'';
}
$scope.toggleProp = function(o,p){
console.log(p);
o[p] = !o[p];
$scope.languagesCtrl.reportModel();
}
}
}
}
);
app.directive('fluency', function() {
return {
restrict: 'E',
scope: {
model: '='
},
require: '^languages',
replace: true,
template: '<div>' +
'<input type="checkbox" ng-model="model.fluent" ng-click="toggle(model, \'fluent\')" />' +
'{{model.label}}' +
'</div>',
link: function(scope, element, attr, languagesCtrl) {
scope.languagesCtrl = languagesCtrl;
},
controller: function($scope) {
$scope.toggleProp = function(o,p) {
o[p] = !o[p];
$scope.languagesCtrl.reportModel();
}
}
}
});