Skip to content

Instantly share code, notes, and snippets.

@petmat
Last active May 8, 2017 09:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save petmat/b7a44ce6b73ad547d3342da7c79984eb to your computer and use it in GitHub Desktop.
Save petmat/b7a44ce6b73ad547d3342da7c79984eb to your computer and use it in GitHub Desktop.
Aurelia Demo
<template>
<require from="./contact-list"></require>
<nav class="navbar navbar-default navbar-fixed-top" role="navigation">
<div class="navbar-header">
<a class="navbar-brand" href="#">
<i class="fa fa-user"></i>
<span>Contacts MEYOOW</span>
<span if.bind="1 < 2">I am dog</span>
<span if.bind="1 > 2">I am cat</span>
</a>
</div>
</nav>
<div class="container">
<div class="row">
<contact-list class="col-md-4"></contact-list>
<router-view class="col-md-8"></router-view>
</div>
</div>
</template>
import {inject} from 'aurelia-framework';
import {WebAPI} from './web-api';
@inject(WebAPI)
export class App {
constructor(api) {
this.api = api;
}
configureRouter(config, router){
config.title = 'Contacts';
config.map([
{ route: '', moduleId: 'no-selection', title: 'Select'},
{ route: 'contacts/:id', moduleId: 'contact-detail', name:'contacts' }
]);
this.router = router;
}
}
<template>
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title">Profile</h3>
</div>
<div class="panel-body">
<form role="form" class="form-horizontal">
<div class="form-group">
<label class="col-sm-2 control-label">First Name</label>
<div class="col-sm-10">
<input type="text" placeholder="first name" class="form-control" value.bind="contact.firstName">
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">Last Name</label>
<div class="col-sm-10">
<input type="text" placeholder="last name" class="form-control" value.bind="contact.lastName">
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">Email</label>
<div class="col-sm-10">
<input type="text" placeholder="email" class="form-control" value.bind="contact.email">
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">Phone Number</label>
<div class="col-sm-10">
<input type="text" placeholder="phone number" class="form-control" value.bind="contact.phoneNumber">
</div>
</div>
</form>
</div>
</div>
<div class="button-bar">
<button class="btn btn-success" click.delegate="save()" disabled.bind="!canSave">Save</button>
</div>
</template>
import {inject} from 'aurelia-framework';
import {EventAggregator} from 'aurelia-event-aggregator';
import {WebAPI} from './web-api';
import {ContactUpdated,ContactViewed} from './messages';
import {areEqual} from './utility';
@inject(WebAPI, EventAggregator)
export class ContactDetail {
constructor(api, ea){
this.api = api;
this.ea = ea;
}
activate(params, routeConfig) {
this.routeConfig = routeConfig;
return this.api.getContactDetails(params.id).then(contact => {
this.contact = contact;
this.routeConfig.navModel.setTitle(contact.firstName);
this.originalContact = JSON.parse(JSON.stringify(contact));
this.ea.publish(new ContactViewed(this.contact));
});
}
get canSave() {
return this.contact.firstName && this.contact.lastName && !this.api.isRequesting;
}
save() {
this.api.saveContact(this.contact).then(contact => {
this.contact = contact;
this.routeConfig.navModel.setTitle(contact.firstName);
this.originalContact = JSON.parse(JSON.stringify(contact));
this.ea.publish(new ContactUpdated(this.contact));
});
}
canDeactivate() {
if (!areEqual(this.originalContact, this.contact)){
let result = confirm('You have unsaved changes. Are you sure you wish to leave?');
if(!result) {
this.ea.publish(new ContactViewed(this.contact));
}
return result;
}
return true;
}
}
<template>
<div class="contact-list">
<ul class="list-group">
<li repeat.for="contact of contacts" class="list-group-item ${contact.id === $parent.selectedId ? 'active' : ''}">
<a route-href="route: contacts; params.bind: {id:contact.id}" click.delegate="$parent.select(contact)">
<h4 class="list-group-item-heading">${contact.firstName} ${contact.lastName}</h4>
<p class="list-group-item-text">${contact.email}</p>
</a>
</li>
</ul>
</div>
</template>
import {EventAggregator} from 'aurelia-event-aggregator';
import {WebAPI} from './web-api';
import {ContactUpdated, ContactViewed} from './messages';
import {inject} from 'aurelia-framework';
@inject(WebAPI, EventAggregator)
export class ContactList {
constructor(api, ea) {
this.api = api;
this.contacts = [];
ea.subscribe(ContactViewed, msg => this.select(msg.contact));
ea.subscribe(ContactUpdated, msg => {
let id = msg.contact.id;
let found = this.contacts.find(x => x.id == id);
Object.assign(found, msg.contact);
});
}
created() {
this.api.getContactList().then(contacts => this.contacts = contacts);
}
select(contact) {
this.selectedId = contact.id;
return true;
}
}
<!doctype html>
<html>
<head>
<title>Aurelia</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<link rel="stylesheet" href="styles.css">
</head>
<body aurelia-app>
<h1>Loading...</h1>
<script src="https://cdn.rawgit.com/jdanyow/aurelia-bundle/v1.0.3/jspm_packages/system.js"></script>
<script src="https://cdn.rawgit.com/jdanyow/aurelia-bundle/v1.0.3/config.js"></script>
<script>
System.import('aurelia-bootstrapper');
</script>
</body>
</html>
export class ContactUpdated {
constructor(contact) {
this.contact = contact;
}
}
export class ContactViewed {
constructor(contact) {
this.contact = contact;
}
}
<template>
<div class="no-selection text-center">
<h2>${message}</h2>
</div>
</template>
export class NoSelection {
constructor() {
this.message = "Please Select a Contact.";
}
}
body { padding-top: 70px; }
section {
margin: 0 20px;
}
a:focus {
outline: none;
}
.navbar-nav li.loader {
margin: 12px 24px 0 6px;
}
.no-selection {
margin: 20px;
}
.contact-list {
overflow-y: auto;
border: 1px solid #ddd;
padding: 10px;
}
.panel {
margin: 20px;
}
.button-bar {
right: 0;
left: 0;
bottom: 0;
border-top: 1px solid #ddd;
background: white;
}
.button-bar > button {
float: right;
margin: 20px;
}
li.list-group-item {
list-style: none;
}
li.list-group-item > a {
text-decoration: none;
}
li.list-group-item.active > a {
color: white;
}
export function areEqual(obj1, obj2) {
return Object.keys(obj1).every((key) => obj2.hasOwnProperty(key) && (obj1[key] === obj2[key]));
};
let latency = 200;
let id = 0;
function getId(){
return ++id;
}
let contacts = [
{
id:getId(),
firstName:'John',
lastName:'Tolkien',
email:'tolkien@inklings.com',
phoneNumber:'867-5309'
},
{
id:getId(),
firstName:'Clive',
lastName:'Lewis',
email:'lewis@inklings.com',
phoneNumber:'867-5309'
},
{
id:getId(),
firstName:'Owen',
lastName:'Barfield',
email:'barfield@inklings.com',
phoneNumber:'867-5309'
},
{
id:getId(),
firstName:'Charles',
lastName:'Williams',
email:'williams@inklings.com',
phoneNumber:'867-5309'
},
{
id:getId(),
firstName:'Roger',
lastName:'Green',
email:'green@inklings.com',
phoneNumber:'867-5309'
}
];
export class WebAPI {
isRequesting = false;
getContactList(){
this.isRequesting = true;
return new Promise(resolve => {
setTimeout(() => {
let results = contacts.map(x => { return {
id:x.id,
firstName:x.firstName,
lastName:x.lastName,
email:x.email
}});
resolve(results);
this.isRequesting = false;
}, latency);
});
}
getContactDetails(id){
this.isRequesting = true;
return new Promise(resolve => {
setTimeout(() => {
let found = contacts.filter(x => x.id == id)[0];
resolve(JSON.parse(JSON.stringify(found)));
this.isRequesting = false;
}, latency);
});
}
saveContact(contact){
this.isRequesting = true;
return new Promise(resolve => {
setTimeout(() => {
let instance = JSON.parse(JSON.stringify(contact));
let found = contacts.filter(x => x.id == contact.id)[0];
if(found){
let index = contacts.indexOf(found);
contacts[index] = instance;
}else{
instance.id = getId();
contacts.push(instance);
}
this.isRequesting = false;
resolve(instance);
}, latency);
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment