I am writing a simple form with Dojo. This is my very first “real” use of Dojo in terms of actually doing something…
Basically:
1) When the widget is shown, onShow, it tries to pre-load the values the form should have
2) When the user submits, the values are saved using the same store
The “problem” here is that I am trying to make a 1000% failsafe application. For example, if the store doesn’t work (and therefore settings cannot be retrieved), I would like to application to try again after 3 seconds — or, well, when the user clicks on a link.
So, what I am doing now is place all of the “fetching” functionality into a function, loadUp(). If there is a problem, I will run loadUp() again (from the error callback in the promise) AND I should also disable the form — something like turning it grey, and now allowing input).
So, questions:
1) Is this a sane way of doing things?
2) How would you go, about greying out the form?
I realise that I am talking about the Workspace settings here. So, what will really happen is that the “get” will be done at the very beginning of the whole process. However, I will reuse this for pretty much every form…
Here is the code:
var SettingsGeneral = declare('hotplate.bd.SettingsGeneral', [ ContentPane, _WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin ], {
templateString: '' +
'<div>' +
' <form data-dojo-type="dijit.form.Form" data-dojo-attach-point="form" method="POST"> ' +
' <input id="${id}_WorkspaceLongName" data-dojo-type="dijit/form/ValidationTextBox" name="longName" data-dojo-props="" />' +
' <input id="${id}_WorkspaceTag" data-dojo-type="dijit/form/ValidationTextBox" name="tag" data-dojo-props="" />' +
' <input class="formSubmit" type="submit" data-dojo-attach-point="button" data-dojo-type="hotplate.hotDojoWidgets.BusyButton" label="Create!" />' +
' </form>' +
'</div>',
onShow: function(){
this.inherited(arguments);
// This returns a working store
var workspaceSettings = stores('workspaceSettings', { workspaceIdCall: vars['hotDojoAppContainer']['workspaceId'] } );
function loadUp(){
// The server will return the settings for this particular workspace
workspaceSettings.get('').then(
function(res){
// All good...
// Assign all of the received values to matching fields
// TODO: Turn this into a function
that.form._descendants.forEach(function( widget ) {
console.log(widget);
if( typeof( res.data[ widget.name ] ) !== 'undefined'){
widget.set('value', res.data[ widget.name] );
}
});
},
function(err){
// Error: try this again in 3 seconds, hopefully it will work. It would actually be better having a
// link to click for the user
console.log("Something went wrong. The form needs to be disabled (turned grey?) and the connection should be retried");
setTimeout(loadUp, 3000);
}
);
};
loadUp();
// Submit form
this.form.onSubmit = ds.defaultSubmit(this.form, this.button, function(){
console.log("PRESSED!");
that.button.cancel();
console.log(workspaceSettings);
// Use the same data store to save the settings...
});
}
});
Here is what I did:
STEP 1: I added a mixin to my class:
_OverlayMixin, and setonOverlayClickto re-show the widget. I also runthis.set( 'overlayed', true ); this.set( 'overlayClickable', false );as soon asshow()is called, and thenthat.set( 'overlayed', false );(If things worked OK) orthat.set('overlayClickable', true ); (if things don’t go well).STEP 2: Actually wrote the _OverlayMixin class
The code follows. The
_OverlayMixinclass is really simple, self-contained. It needs prettifying — right now it’s just a gray thing over the widget. If the overlay is clickable, it will have a class set — so it might have an icon for retrying. I like what I did, because it’s very dojo-ish, and it’s just so simple to read. Also, this way the widget can be “restarted” easily by the user if things go wrong.Here is the code… starting from my simple widget:
The mixin: