Skip to content

Instantly share code, notes, and snippets.

@Thanood
Forked from mar9000/app.html
Last active April 3, 2017 19:02
Show Gist options
  • Save Thanood/19da3700c486ed6692fb1c11b00e8ceb to your computer and use it in GitHub Desktop.
Save Thanood/19da3700c486ed6692fb1c11b00e8ceb to your computer and use it in GitHub Desktop.
aurelia-materialize-bridge: i18n for select label
<template>
<!-- The following require is required as a workaround for last version of materializecss. -->
<require from="materialize/dist/css/materialize.css"></require>
<require from="./md-select2"></require>
<!-- i18n support. -->
<br/>
<div>
<h4>i18n support</h4>
<select md-select2="label.two-way: translateMe;" value.two-way="language" change.trigger="updateLanguage()">
<option value="" disabled selected t="selectLanguage">S L</option>
<option value="en_UK">English UK</option>
<option value="en_US">English US</option>
</select>
<md-input md-label="psth" t="[md-label]dialogs.putSomeTextHere" md-value.bind="textValue" md-disabled.bind="disabledValue"></md-input>
<div>${translateMe}</div>
</div>
</template>
import { inject } from 'aurelia-framework';
import {I18N} from 'aurelia-i18n';
@inject(I18N)
export class App {
textValue = '';
translateMe = 'placeholder';
disabledValue = false;
setText() {
this.textValue = 'something';
}
setDisabled() {
this.disabledValue = !this.disabledValue;
}
constructor(i18n) {
this.i18n = i18n;
}
language;
updateLanguage() {
this.setLanguage(this.language);
}
setLanguage(l) {
this.i18n.setLocale(l);
this.translateMe = this.i18n.tr('dialogs.translateMe');
}
}
{
"dialogs" : {
"putSomeTextHere": "put some text here uk",
"translateMe": "translate me uk"
}
}
{
"dialogs" : {
"putSomeTextHere": "put some text here us",
"translateMe": "translate me us"
}
}
<!doctype html>
<html>
<head>
<title>Aurelia</title>
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body aurelia-app="main">
<h1>Loading....</h1>
<script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.6/system.js"></script>
<script src="https://rawgit.com/mar9000/aurelia-materialize-bundles/0.24.0-1_i18n-2/config2.js"></script>
<script>
System.import('aurelia-bootstrapper');
</script>
</body>
</html>
import {inject} from 'aurelia-framework';
import {I18N} from 'aurelia-i18n';
@inject(I18N)
export class Locale {
static LANGUAGES = new Map([
['en_UK', 'English UK'],
['en_US', 'English US']
]);
static INITIAL_LANGUAGE_KEY = 'en_UK';
constructor(i18n) {
this.i18n = i18n;
}
setLanguage(l) {
this.currentLanguageKey = l;
this.currentLanguageName = Locale.LANGUAGES.get(this.currentLanguageKey);
this.i18n.setLocale(l);
}
get languages() {
return Locale.LANGUAGES;
}
}
/*******************************************************************************
* The following two lines enable async/await without using babel's
* "runtime" transformer. Uncomment the lines if you intend to use async/await.
*
* More info here: https://github.com/jdanyow/aurelia-plunker/issues/2
*/
//import regeneratorRuntime from 'babel-runtime/regenerator';
//window.regeneratorRuntime = regeneratorRuntime;
/******************************************************************************/
import 'materialize';
import {I18N} from 'aurelia-i18n';
import Backend from 'i18next-xhr-backend';
import {Locale} from 'locale';
export function configure(aurelia) {
aurelia.use
.standardConfiguration()
.developmentLogging()
.plugin('aurelia-materialize-bridge', bridge => bridge.useAll() )
// Add the aurelia-i18n plugin.
.plugin('aurelia-i18n', (instance) => {
instance.i18next.use(Backend);
return instance.setup({
backend: {
loadPath: './{{lng}}_{{ns}}.json'
},
lng : Locale.INITIAL_LANGUAGE_KEY,
attributes : ['t'],
fallbackLng : Locale.INITIAL_LANGUAGE_KEY,
debug : true
});
});
aurelia.start().then(a => a.setRoot());
}
import {bindable, customAttribute} from 'aurelia-templating';
import {BindingEngine} from 'aurelia-binding';
import {inject} from 'aurelia-dependency-injection';
import {TaskQueue} from 'aurelia-task-queue';
import {getLogger} from 'aurelia-logging';
import {DOM} from 'aurelia-framework';
@inject(Element, BindingEngine, TaskQueue)
@customAttribute('md-select2')
export class MdSelect {
@bindable() disabled = false;
@bindable() enableOptionObserver = false;
@bindable() label = '';
@bindable() showErrortext = true;
_suspendUpdate = false;
subscriptions = [];
input = null;
dropdownMutationObserver = null;
optionsMutationObserver = null;
constructor(element, bindingEngine, taskQueue) {
this.element = element;
this.taskQueue = taskQueue;
this.handleChangeFromViewModel = this.handleChangeFromViewModel.bind(this);
this.handleChangeFromNativeSelect = this.handleChangeFromNativeSelect.bind(this);
this.handleBlur = this.handleBlur.bind(this);
this.log = getLogger('md-select');
this.bindingEngine = bindingEngine;
}
attached() {
this.taskQueue.queueTask(() => {
this.createMaterialSelect(false);
if (this.label) {
let wrapper = $(this.element).parent('.select-wrapper');
let div = $('<div class="input-field"></div>');
let va = this.element.attributes.getNamedItem('validate');
if (va) {
div.attr(va.name, va.label);
}
wrapper.wrap(div);
$(`<label class="md-select-label">${this.label}</label>`).insertAfter(wrapper);
}
});
this.subscriptions.push(this.bindingEngine.propertyObserver(this.element, 'value').subscribe(this.handleChangeFromViewModel));
$(this.element).on('change', this.handleChangeFromNativeSelect);
}
detached() {
$(this.element).off('change', this.handleChangeFromNativeSelect);
this.observeVisibleDropdownContent(false);
this.observeOptions(false);
this.dropdownMutationObserver = null;
$(this.element).material_select('destroy');
this.subscriptions.forEach(sub => sub.dispose());
}
refresh() {
this.taskQueue.queueTask(() => {
this.createMaterialSelect(true);
});
}
labelChanged(newValue) {
this.updateLabel();
}
updateLabel() {
if (this.label) {
const $label = $(this.element).parent('.select-wrapper').siblings('.md-select-label');
$label.text(this.label);
}
}
disabledChanged(newValue) {
this.toggleControl(newValue);
}
showErrortextChanged() {
this.setErrorTextAttribute();
}
setErrorTextAttribute() {
let input = this.element.parentElement.querySelector('input.select-dropdown');
if (!input) return;
this.log.debug('showErrortextChanged: ' + this.showErrortext);
input.setAttribute('data-show-errortext', (this.showErrortext === true || this.showErrortext === 'true'));
}
notifyBindingEngine() {
this.log.debug('selectedOptions changed', arguments);
}
handleChangeFromNativeSelect() {
if (!this._suspendUpdate) {
this.log.debug('handleChangeFromNativeSelect', this.element.value, $(this.element).val());
this._suspendUpdate = true;
//fireEvent(this.element, 'change');
const event = DOM.createCustomEvent('change', {bubbles: true});
this.element.dispatchEvent(event);
this._suspendUpdate = false;
}
}
handleChangeFromViewModel(newValue) {
this.log.debug('handleChangeFromViewModel', newValue, $(this.element).val());
if (!this._suspendUpdate) {
this.createMaterialSelect(false);
}
}
toggleControl(disable) {
let $wrapper = $(this.element).parent('.select-wrapper');
if ($wrapper.length > 0) {
if (disable) {
$('.caret', $wrapper).addClass('disabled');
$('input.select-dropdown', $wrapper).attr('disabled', 'disabled');
$wrapper.attr('disabled', 'disabled');
} else {
$('.caret', $wrapper).removeClass('disabled');
$('input.select-dropdown', $wrapper).attr('disabled', null);
$wrapper.attr('disabled', null);
$('.select-dropdown', $wrapper).dropdown({'hover': false, 'closeOnClick': false});
}
}
}
createMaterialSelect(destroy) {
this.observeVisibleDropdownContent(false);
this.observeOptions(false);
if (destroy) {
$(this.element).material_select('destroy');
}
$(this.element).material_select();
this.toggleControl(this.disabled);
this.observeVisibleDropdownContent(true);
this.observeOptions(true);
this.setErrorTextAttribute();
}
observeVisibleDropdownContent(attach) {
if (attach) {
if (!this.dropdownMutationObserver) {
this.dropdownMutationObserver = DOM.createMutationObserver(mutations => {
let isHidden = false;
for (let mutation of mutations) {
if (window.getComputedStyle(mutation.target).getPropertyValue('display') === 'none') {
isHidden = true;
}
}
if (isHidden) {
this.dropdownMutationObserver.takeRecords();
this.handleBlur();
}
});
}
this.dropdownMutationObserver.observe(this.element.parentElement.querySelector('.dropdown-content'), {
attributes: true,
attributeFilter: ['style']
});
} else {
if (this.dropdownMutationObserver) {
this.dropdownMutationObserver.disconnect();
this.dropdownMutationObserver.takeRecords();
}
}
}
observeOptions(attach) {
if ((this.enableOptionObserver === true || this.enableOptionObserver === 'true')) {
if (attach) {
if (!this.optionsMutationObserver) {
this.optionsMutationObserver = DOM.createMutationObserver(mutations => {
// this.log.debug('observeOptions', mutations);
this.refresh();
});
}
this.optionsMutationObserver.observe(this.element, {
// childList: true,
characterData: true,
subtree: true
});
} else {
if (this.optionsMutationObserver) {
this.optionsMutationObserver.disconnect();
this.optionsMutationObserver.takeRecords();
}
}
}
}
//
// Firefox sometimes fire blur several times in a row
// observable at http://localhost:3000/#/samples/select/
// when enable 'Disable Functionality', open that list and
// then open 'Basic use' list.
// Chrome - ok
// IE 11 - ok
// Edge ?
//
_taskqueueRunning = false;
handleBlur() {
if (this._taskqueueRunning) return;
this._taskqueueRunning = true;
this.taskQueue.queueTask(() => {
this.log.debug('fire blur event');
//fireEvent(this.element, 'blur');
this._taskqueueRunning = false;
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment