Last active
August 19, 2017 02:38
-
-
Save jdanyow/a78d15898660218b8438e34dcc31f390 to your computer and use it in GitHub Desktop.
Aurelia Radio Select
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<template> | |
<require from="./radio-select"></require> | |
<style> | |
form > label { | |
display: block; | |
margin-top: 10px; | |
} | |
</style> | |
<form> | |
<label> | |
First Name: | |
<input> | |
</label> | |
<label id="color1"> | |
Color 1: | |
<radio-select items-source.bind="colors" | |
value.bind="color1" | |
aria-labelledby="color1" | |
focus.trigger="logFocus('color1')" | |
blur.trigger="logBlur('color1')" | |
ref="color1RadioSelect"> | |
</radio-select> | |
</label> | |
<label id="color2"> | |
Color 2: | |
<radio-select items-source.bind="colors" | |
value.bind="color2" | |
aria-labelledby="color1" | |
focus.trigger="logFocus('color2')" | |
blur.trigger="logBlur('color2')"> | |
<em css="color: ${item}"> | |
${item} | |
</em> | |
</radio-select> | |
</label> | |
<label> | |
Last Name: | |
<input> | |
</label> | |
</form> | |
<button type="button" click.delegate="color1RadioSelect.focus()">Focus Color 1</button> | |
<button type="button" mouseover.delegate="color1RadioSelect.blur()">Blur Color 1 (on mouse over of this button)</button> | |
</template> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export class App { | |
colors = ['red', 'green', 'blue']; | |
color1 = 'green'; | |
color2 = 'red'; | |
logFocus(event) { | |
console.log('focus', event); | |
} | |
logBlur(event) { | |
console.log('blur', event); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!doctype html> | |
<html> | |
<head> | |
<title>Aurelia</title> | |
<meta name="viewport" content="width=device-width, initial-scale=1"> | |
</head> | |
<body aurelia-app> | |
<h1>Loading...</h1> | |
<script src="https://jdanyow.github.io/rjs-bundle/node_modules/requirejs/require.js"></script> | |
<script src="https://jdanyow.github.io/rjs-bundle/config.js"></script> | |
<script src="https://jdanyow.github.io/rjs-bundle/bundles/aurelia.js"></script> | |
<script src="https://jdanyow.github.io/rjs-bundle/bundles/babel.js"></script> | |
<script> | |
require(['aurelia-bootstrapper']); | |
</script> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import {DOM} from 'aurelia-pal'; | |
import {TaskQueue} from 'aurelia-task-queue'; | |
/** | |
* A component made up of multiple focusable elements. | |
* - exposes focus and blur methods | |
* - normalizes child element focus and blur events and fires focus/blur at the component element level. | |
*/ | |
export class MultiInputComponent { | |
element; | |
focused = false; | |
constructor(element, taskQueue) { | |
this.element = element; | |
this.taskQueue = taskQueue; | |
element.focus = this.focus; | |
element.blur = this.blur; | |
} | |
bind() { | |
this.element.addEventListener('focus', this.handleFocusEvent, true); | |
this.element.addEventListener('blur', this.handleFocusEvent, true); | |
} | |
unbind() { | |
this.element.removeEventListener('focus', this.handleFocusEvent); | |
this.element.removeEventListener('blur', this.handleFocusEvent); | |
} | |
focus = () => { | |
// todo: | |
// - selector needs to handle other types of focusable elements. | |
// - should not attempt to focus hidden or disabled elements. | |
const input = this.element.querySelector('input'); | |
input.focus(); | |
this.syncFocus(); | |
} | |
blur = () => { | |
// todo: selector needs to handle other types of focusable elements | |
const input = this.element.querySelector('input:focus'); | |
if (!input) { | |
return; | |
} | |
input.blur(); | |
this.syncFocus(); | |
} | |
handleFocusEvent = event => { | |
if (!event.isTrusted) { | |
return; | |
} | |
this.taskQueue.queueMicroTask(this.syncFocus); | |
} | |
syncFocus = () => { | |
const focused = this.element.querySelector(':focus'); | |
if (this.focused === focused) { | |
return; | |
} | |
this.focused = focused; | |
this.element.dispatchEvent(DOM.createCustomEvent(focused ? 'focus' : 'blur')); | |
} | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<template> | |
<label repeat.for="item of itemsSource"> | |
<input type="radio" name.one-time="name" model.bind="item" checked.bind="value"> | |
<template replaceable part="item-template">${item}</template> | |
</label> | |
</template> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import {bindable, processContent} from 'aurelia-templating'; | |
import {bindingMode} from 'aurelia-binding'; | |
import {inject} from 'aurelia-dependency-injection'; | |
import {TaskQueue} from 'aurelia-task-queue'; | |
import {makePartReplacementFromContent} from './template-transforms'; | |
import {MultiInputComponent} from './multi-input-component'; | |
let id = 0; | |
@inject(Element, TaskQueue) | |
@processContent(makePartReplacementFromContent) | |
export class RadioSelect extends MultiInputComponent{ | |
@bindable itemsSource = null; | |
@bindable({ defaultBindingMode: bindingMode.twoWay }) value = null; | |
name = `radio-select-${id++}`; | |
constructor(element, taskQueue) { | |
super(element, taskQueue); | |
this.element.setAttribute('role', 'radiogroup'); | |
} | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import {FEATURE} from 'aurelia-pal'; | |
export function makePartReplacementFromContent(viewCompiler, viewResources, element, behaviorInstruction) { | |
const content = element.firstElementChild; | |
if (content) { | |
// create the <template> | |
const template = document.createElement('template'); | |
// support browsers that do not have a real <template> element implementation (IE) | |
FEATURE.ensureHTMLTemplateElement(template); | |
// indicate the part this <template> replaces. | |
template.setAttribute('replace-part', 'item-template'); | |
// replace the element's content with the <template> | |
element.insertBefore(template, content); | |
element.removeChild(content); | |
template.content.appendChild(content); | |
return true; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment