Issue
I am trying to create a web-page where some elements (forms and buttons) become visible or are being hidden when some other elements (buttons) are clicked.
I try to find a way to manage this, that is re-usable, and easy to maintain.
My current solution is shown below, but I hope someone has a more elegant solution.
The problem with my own solution is that it will become difficult to read when the number of dependencies increase. It will then also require a lot of editing when I add another button and form.
My current solution is to use an observable to manage the state of the forms, like this:
HTML:
<button id="button-A">Show form A, hide button A and B</button>
<button id="button-B">Show form B, hide button A and B</button>
<form id="form-A">
...this form is initially hidden
...some form elements
<button id="cancel-A">Hide form A, show button A and B</button>
</form>
<form id="form-B">
...this form is initially hidden
...some form elements
<button id="cancel-B">Hide form B, show button A and B</button>
</form>
Dart:
import 'dart:html';
import 'package:observe/observe.dart';
final $ = querySelector;
final $$ = querySelectorAll;
Map<String, bool> toBeObserved = {
"showFormA" : false,
"showFormB" : false
};
// make an observable map
ObservableMap observeThis = toObservable(toBeObserved);
// start managing dependencies
main() {
// add click event to buttons
$('#button-A')
..onClick.listen((E) => observeThis["showFormA"] = true);
$('#button-B')
..onClick.listen((E) => observeThis["showFormB"] = true);
// add click events to form buttons
$('#cancel-A')
..onClick.listen((E) {
E.preventDefault();
E.stopPropagation();
observeThis["showFormA"] = false;
});
$('#cancel-B')
..onClick.listen((E) {
E.preventDefault();
E.stopPropagation();
observeThis["showFormB"] = false;
});
// listen for changes
observeThis.changes.listen((L) {
L.where((E) => E.key == 'showFormA').forEach((R) {
$('#form-A').style.display = (R.newValue) ? 'block' : 'none';
$('#button-A').style.display = (R.newValue || observeThis['showFormB']) ? 'none' : 'inline-block';
$('#button-B').style.display = (R.newValue || observeThis['showFormB']) ? 'none' : 'inline-block';
});
L.where((E) => E.key == 'showFormB').forEach((R) {
$('#form-B').style.display = (R.newValue) ? 'block' : 'none';
$('#button-A').style.display = (R.newValue || observeThis['showFormA']) ? 'none' : 'inline-block';
$('#button-B').style.display = (R.newValue || observeThis['showFormA']) ? 'none' : 'inline-block';
});
});
}
Solution
You could use polymer’s template functionality like
<template if="showA">...
This should work without embedding your elements within Polymer elements too.
This discussion provides some information how to use <template>
without Polymer elements.
Using Polymer elements could also be useful.
It all depends on your requirements/preferences.
Angular.dart is also useful for such view manipulation.
If you want to use plain Dart/HMTL I don’t have ideas how to simplify your code.
Answered By – Günter Zöchbauer
Answer Checked By – Mary Flores (FlutterFixes Volunteer)