Ugo Cei wrote:

I didn't try the sample, since it's 1AM and I'm going to bed, but just by looking at the code, I have a couple of observations:

XForm.sendView(view, uri) // Sends "view" to the presentation pipeline and waits for the form to be submitted (and automatically resends it if validation fails)

Sometimes, the validation you can perform with Schematron is not enough. In my application, I have a form for user registration and, besides checking that the username is present, email address is valid and passwords match, I need to check that the username is not already registered. To do this, I need to query the database and, if a duplicate is found, create a new violation object and attach it to the form. How can I do that if the validation logic is hidden inside XForm.sendView?

OK. The attached should allow you to also perform validation in JavaScript. XForm.sendView() now looks like this

XForm.sendView(view, uri, validator);

where the (optional) "validator" parameter is a JavaScript function that will be invoked after the form is populated. XForm now also supports a method to add violations

XForm.addViolation(xpath, message); // both parameters are strings

which you can use to report violations.

Here's an example with the feedback wizard:

// XML Form Feedback Wizard Application

importPackage(Packages.org.apache.cocoon.samples.xmlform);

function feedbackWizard(xform) {
var bean = new UserBean();
xform.setModel(bean);
xform.sendView("userIdentity", "wizard/userIdentity.xml");
print("handling user identity");
xform.sendView("deployment",
"wizard/deployment.xml",
function() {
print("I can also do validation in JavaScript")
if (bean.publish) {
xform.addViolation("/publish", "Sorry, I won't let you publish ");
}
});
print("handling deployment");
xform.sendView("system", "wizard/system.xml");
print("handling system");
xform.sendView("confirm", "wizard/confirm.xml");
print("handling confirm");
xform.finish("end", "wizard/end.xml");
print("done");
}

function XForm(id, validatorNS, validatorDoc) {
    cocoon.createSession();
    this.id = id;
    this.lastContinuation = null;
    XForm.forms[id] = this;
    this.validatorNS = validatorNS;
    this.validatorDoc = validatorDoc;
}

XForm.forms = {}

XForm.prototype.setModel = function(model) {
    this.form = 
        new Packages.org.apache.cocoon.components.xmlform.Form(this.id, 
                                                               model);
    this.form.setAutoValidate(false);
    if (this.validatorNS != undefined && this.validatorDoc != undefined) {
        this.setValidator(this.validatorNS, this.validatorDoc);
    }
}

XForm.prototype.start = function(lastCont, timeToLive) {
    var k = new Continuation();
    var kont = new WebContinuation(cocoon, k, 
                                   lastCont, timeToLive);
    return kont;
} 

XForm.prototype.addViolation = function(xpath, message) {
    var violation = 
       new Packages.org.apache.cocoon.components.validation.Violation();
    violation.path = xpath;
    violation.message = message;
    var list = new java.util.LinkedList();
    list.add(violation);
    this.form.addViolations(list);
}

XForm.prototype._sendView = function(uri, lastCont, timeToLive) {
  var k = new Continuation();
  var kont = new WebContinuation(cocoon, k, lastCont, timeToLive);
  cocoon.forwardTo("cocoon://" + cocoon.environment.getURIPrefix() + uri,
                   null, kont);
  this.lastContinuation = kont;
  suicide();
}

XForm.prototype.sendView = function(phase, uri, validator) {
    var lastCont = this.lastContinuation;
    this.form.clearViolations();
    while (true) {
        var k = this.start(lastCont);
        this.form.save(cocoon.environment.objectModel, "request");
        try {
            print("sending view: " + phase);
            this._sendView(uri, k);
        } catch (e) {
            e.printStackTrace();
        }
        print("return from continuation: "+this);
        this.form.populate(cocoon.environment.objectModel);
        this.form.validate(phase);
        print("populated form: and validated...");
        if (this.form.violationsAsSortedSet != null) {
            print(this.form.violationsAsSortedSet.size() + " violations");
        }
        if (validator != undefined) {
            validator();
        }
        if (this.form.violationsAsSortedSet == null ||
            this.form.violationsAsSortedSet.size() == 0) {
            break;
        }
        print(this.form.violationsAsSortedSet.size() + " violations");
    }
}

XForm.prototype.setValidator = function(schNS, schDoc) {
    // if validator params are not specified, then
    // there is no validation by default
    if (schNS == null || schDoc == null ) return null;
    var resolver = cocoon.environment;
    var schemaSrc = resolver.resolveURI( schDoc );
    try {
        var is = 
Packages.org.apache.cocoon.components.source.SourceUtil.getInputSource(schemaSrc);
        var schf = 
Packages.org.apache.cocoon.components.validation.SchemaFactory.lookup ( schNS );
        var sch = schf.compileSchema ( is );
        this.form.setValidator(sch.newValidator());
    } finally {
        resolver.release(schemaSrc);
    }
}

XForm.prototype.finish = function(phase, uri) {
    this.form.save(cocoon.environment.objectModel, "request");
    cocoon.forwardTo("cocoon://" + cocoon.environment.getURIPrefix() + uri,
                     null, null);
    delete XForm.forms[this.id]; // delete myself
}

function xmlForm(application, id, validator_ns, validator_doc, scope) {
    var enum_ = cocoon.request.parameterNames;
    var command = undefined;
    while (enum_.hasMoreElements ()) {
        var paramName = enum_.nextElement();
        // search for the command
        if 
(paramName.startsWith(Packages.org.apache.cocoon.Constants.ACTION_PARAM_PREFIX)) {
            command =
                
paramName.substring(Packages.org.apache.cocoon.Constants.ACTION_PARAM_PREFIX.length(), 
paramName.length());
            break;
        }
    }
    // command encodes the continuation id for "back" or "next" actions
    print("command="+command);
    if (command != undefined) {
        var xform = XForm.forms[id];
        if (xform == undefined) {
            return this[application](new XForm(id, validator_ns, validator_doc));
        }
        // invoke a continuation 
        var continuationsMgr =
            
cocoon.componentManager.lookup(Packages.org.apache.cocoon.components.flow.ContinuationsManager.ROLE);
        var wk = continuationsMgr.lookupWebContinuation(command);
        cocoon.componentManager.release(continuationsMgr);
        if (wk != null) {
            print(paramName + "="+cocoon.request.getParameter(paramName));
            var jswk = wk.userObject;
            try {
                xform.form.clearViolations();
                jswk.continuation(jswk);
            } catch (e) {
                e.printStackTrace();
            }
        }
    } 
    // Just start a new instance of the application
    this[application](new XForm(id, validator_ns, validator_doc));
}


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, email: [EMAIL PROTECTED]

Reply via email to