I'm using semantic-ui, which has its own modal functionality built in (see here). Rather than writing all the code to leverage this particular functionality in Aurelia, is there a way to hook into the aurelia-dialog plugin's rendering pipeline so I can use configure the aurelia-dialog plugin to use semantic-ui?
2 Answers
Yes, there is.
Aurelia-dialog provides an abstract Renderer interface, which it uses to interface with a renderer. By default, it'll use the renderer that it provides, but you can override this by configuring the dialog plugin, like so:
import {MyRenderer} from './my-renderer';
aurelia.use.plugin('aurelia-dialog', (config) => {
config.useRenderer(MyRenderer);
});
...where MyRenderer
uses the abstract Renderer interface. In your renderer, you'll need to implement three methods: getDialogContainer
, showDialog
, and hideDialog
.
Some caveats - in your showDialog
function, you will need to create showDialog
and hideDialog
methods and attach them to the dialogController that is passed as an argument. This ensures that your dialogController can programmatically close the dialog.
After you've implemented and registered your renderer, the dialog plugin will then use the UI toolkit you've chosen. Hope this helps.
-
Is this one of the parts that you added to the plugin? – Matthew James Davis Jun 27 '16 at 18:39
-
1@MatthewJamesDavis Yup. It was a little while back, actually - the pull request can be found [here](https://github.com/aurelia/dialog/pull/120). – Jun 27 '16 at 20:10
-
1Can you demonstrate how to implement a renderer in your answer, please? – Matthew James Davis Jun 27 '16 at 20:49
-
1I would also be interested to see a bootstrap renderer, I've looked at the source of the default renderer, but does not seem to actually do any rendering, just the opening/closing? – Tim Bailey Sep 15 '16 at 00:17
This is my solution(in TypeScript) for semantic-ui modals, it does not use aurelia-dialog.
The view (/ui/dialogs/dialog-confirm.html):
<template>
<div class="ui modal small" ref="dialogElement">
<div class="header">${model.headerText}</div>
<div class="content">
<p>${model.messageText}</p>
</div>
<div class="actions">
<div class="ui approve button">${model.confirmText?model.confirmText:'OK'}</div>
<div class="ui cancel button">${model.cancelText?model.cancelText:'Cancel'}</div>
</div>
</div>
</template>
The view-model (/ui/dialogs/dialog-confirm.ts):
export class Dialog {
model;
done;
result;
dialogElement:HTMLElement;
activate(data) {
if( data ){
this.model = data.model;
this.done = data.done;
this.result = false;
}
}
bind(){
$(this.dialogElement)
.modal({
onApprove : ()=>{ this.result = true; },
onDeny : ()=>{ this.result = false; },
onHide : ()=>{ this.done(this.result); }
})
.modal('show');
}
}
The Dialog class (/ui/dialogs/dialog.ts):
import { inject } from 'aurelia-framework';
import { EventAggregator } from 'aurelia-event-aggregator';
@inject(EventAggregator)
export class Dialog {
constructor(private eventAggregator) {
}
show(viewName: string, model) {
return new Promise( (resolve, reject) => {
this.eventAggregator.publish('showDialog', {
viewName: viewName,
model: model,
resolve: resolve
});
});
}
}
... inject EventAggregator into your App class and add this to the attached() hook:
attached() {
this.eventAggregator.subscribe('showDialog', (event) => {
console.assert( !this.dialogData, "Only one dialog can be shown at any time." );
event.done = (result) => {
event.resolve(result);
this.dialogData = null;
}
this.dialogName = event.viewName;
this.dialogData = event;
});
}
... finally add this to your app.html:
<compose if.bind="dialogData" view-model="./ui/dialogs/${dialogName}" model.bind="dialogData" view="./ui/dialogs/${dialogName}.html">
</compose>
Usage, you can give the name of any model-view/view pair as the first argument:
this.dialog.show('dialog-confirm',{
headerText:'Warning!',
messageText:'When you delete stuff - it is lost',
confirmText:'Delete',
cancelText:'I better not...'
}).then( function(result){
console.log( 'The result is: '+result )
});

- 47
- 1
- 6
-
-
Just remove the types ( :HTMLElement ) and update the eventAggregator injection in Dialog and it should work – Angel Popov May 25 '17 at 11:38