I'm trying to make a generic, reusable dialog that we can use for basic data entry on simple objects -- phone, email, etc.
In general, I have a helper class that opens the dialog, a generic dialog using aurelia-dialog, and then a vm that gets composed into the generic dialog for the body that includes all the form editing code.
The problem I'm having is that the buttons are in the footer which is part of the dialog vm, but the validation and dirty indicator exist in the vm that composes the body. I want to disable/enable the Save button (in the footer) based on the indicators in the body vm.
Dialog Helper:
import {DialogService} from 'aurelia-dialog'
import {EditDialog} from 'app/resources/dialogs/edit-dialog'
export class DialogHelper {
static inject = [DialogService]
constructor(dialogService){
this.dialogService = dialogService
}
edit(title, view, item, showDelete){
return this.dialogService.open({
viewModel: EditDialog,
model: {view: view,
item: item,
title: title,
showDelete: showDelete } })
}
}
Calling Code:
let email = {emailAddress: "123@gmail.com", emailType: "Personal"}
this.dialogHelper.edit("Email",'./pages/email-dialog',email,false)
EditDialog.js
import {DialogController} from 'aurelia-dialog'
export class EditDialog {
static inject = [DialogController]
showDelete = false
constructor(dialogController){
this.dialogController = dialogController
}
activate(options){
this.options = options
}
EditDialog.html
<template>
<ai-dialog>
<ai-dialog-header style="display:flex; justify-content:space-between">
<span>Add/Edit ${options.title}</span><i style="cursor:pointer" class="fa fa-close" click.delegate="dialogController.cancel()"></i>
</ai-dialog-header>
<ai-dialog-body>
<compose view-model.bind="options.view" model.bind="options.item" ></compose>
</ai-dialog-body>
<ai-dialog-footer style="display:flex;justify-content:space-between;">
<span>
<!--Should have an if.bind here but not sure how since vm composed above knows details -->
<button click.delegate="dialogController.ok({type:'save'})">Save</button>
<button click.delegate="dialogController.cancel()">Cancel</button>
</span>
<button if.bind="options.showDelete" click.delegate="dialogController.ok({type:'delete'})"><i class="fa fa-trash"></i></button>
</ai-dialog-footer>
</ai-dialog>
</template>
email-dialog.js
import {ValidationRules, ValidationController} from 'aurelia-validation'
import {computedFrom,NewInstance} from 'aurelia-framework'
export class EmailDialog {
static inject = [NewInstance.of(ValidationController)]
email = null
constructor(validationController){
this.validationController = validationController
this.rule = ValidationRules.ensure(i => i.emailAddress)
.required()
.email()
.ensure(i => i.emailType)
.required()
.rules
}
activate(item){
this.original = item
this.email = JSON.parse(JSON.stringify(item))
}
@computedFrom('email.emailAddress', 'email.emailType')
get canSave() {
for(var prop in this.original){
if(this.email[prop] != this.original[prop])
return false
}
return true
}
}
Do I have to use EventAggregator to pass messages to the parent or is there a better way to handle this through some kind of binding? (Or is there just a better way to approach this problem all together?)
Thanks for your help!