问题
I have an Alfresco Share client-side Form in a registration scenario and I want to validate if the chosen username is taken.
Can I add a Alfresco forms validator in a synchronous way?
So far my form goes something like this:
this.widgets.saveForm = new Alfresco.forms.Form(this.id + "-form");
this.widgets.saveForm.addValidation(Dom.get(this.id + "-username"), this.validateUsername, me, "blur", this.msg("validation-hint.username-taken"));
But this.validateUsername needs to make an Alfresco.util.Ajax.request to a repo-side web service which checks availability for the chosen username. So basically, by the time the response is here, my original validateUsername method is long-finished, returning false (likely).
My progress so far is to disable the submit button (that is why I am passing "me" to the validation handler), and have success/failure callbacks enable it if the username is fine.
What would be a decent way to make a synchronous validator?
A side question would be if there is a better way to set the scope of the validation handler to "this", as opposed to passing me (this one works too, this is just to make sure I am not missing a better way).
回答1:
This is a snippet of the create-site form. It does the same and checks if the shortname is already present and shows an error if it's taken.
createSiteForm.doBeforeFormSubmit =
{
fn: function()
{
var formEl = Dom.get(this.id + "-form");
formEl.attributes.action.nodeValue = Alfresco.constants.URL_SERVICECONTEXT + "modules/create-site";
this.widgets.okButton.set("disabled", true);
this.widgets.cancelButton.set("disabled", true);
// Site access
var siteVisibility = "PUBLIC";
if (this.widgets.isPublic.checked)
{
if (this.widgets.isModerated.checked)
{
siteVisibility = "MODERATED";
}
}
else
{
siteVisibility = "PRIVATE";
}
this.widgets.siteVisibility.value = siteVisibility;
this.widgets.panel.hide();
this.widgets.feedbackMessage = Alfresco.util.PopupManager.displayMessage(
{
text: Alfresco.util.message("message.creating", this.name),
spanClass: "wait",
displayTime: 0
});
},
obj: null,
scope: this
};
// Submit as an ajax submit (not leave the page), in json format
createSiteForm.setAJAXSubmit(true,
{
successCallback:
{
fn: this.onCreateSiteSuccess,
scope: this
},
failureCallback:
{
fn: this.onCreateSiteFailure,
scope: this
}
});
So this is the client side JavaScript file create-site.js which does the ajax call just before the submit.
回答2:
My workaround solution is this:
Add a custom validation to the form, and pass the "var me = this" for the validator function to get the scope.
this.widgets.saveForm.addValidation(Dom.get(this.id + "-username"), this.validateUsername, me, "blur", this.msg("validation-hint.username-taken"));
Add a validation handler function which will a. disable the submit button and set the "checking" CSS class to the appropriate form for the user to have feedback. Code snip:
validateUsername: function Reg_validateUsername(el, me) { var val = this.fieldId.value; var username = trim(val); me.widgets.registerButton.set("disabled", true); Dom.addClass(me.id + "-username-img", "checking"); Dom.removeClass(me.id + "-username-img", "hidden"); Alfresco.util.Ajax.request({ url: "/alfresco/service/slingshot/register/username-available?username=" + username , method: "GET" , successCallback: { fn: me.onUsernameAvailable , scope: me } , failureCallback: { fn: me.onUsernameTaken , scope: me } });
Write a backend webscript username-available.get that will return success only if the username is free (and valid, even though I have another validator for that).
onUsernameAvailable will set the submit button to enabled again and run validation again (because of other fields) and change the CSS class to "valid".
onUsernameTaken will set the CSS class to "taken".
That's how I ended up doing this.
来源:https://stackoverflow.com/questions/14294604/alfresco-share-client-side-synchronous-form-validation