提交 99b11d0d 编写于 作者: K Kohsuke Kawaguchi

added UI sample fo contextual form field validation

上级 17317bb4
package jenkins.plugins.ui_samples;
import hudson.Extension;
import hudson.RelativePath;
import hudson.model.AbstractDescribableImpl;
import hudson.model.Descriptor;
import hudson.util.FormValidation;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.QueryParameter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* How to access values of the nearby input fields when you do form field validation.
*
* @author Kohsuke Kawaguchi
*/
@Extension
public class FormFieldValidationWithContext extends UISample {
private List<State> states = new ArrayList<State>(Arrays.asList(
new State("California",new City("Sacramento"), Arrays.asList(new City("San Francisco"),new City("Los Angeles"))),
new State("New York",new City("New York"), Arrays.asList(new City("Albany"),new City("Ithaca")))
));
public FormFieldValidationWithContext() {
}
@DataBoundConstructor
public FormFieldValidationWithContext(List<State> states) {
this.states = states;
}
@Override
public String getDescription() {
return "How to access values of the nearby input fields when you do form field validation";
}
public List<State> getStates() {
return states;
}
@Override
public List<SourceFile> getSourceFiles() {
List<SourceFile> r = super.getSourceFiles();
r.add(new SourceFile("City/config.groovy"));
r.add(new SourceFile("State/config.groovy"));
return r;
}
public static class State extends AbstractDescribableImpl<State> {
/*
I'm lazy and just exposing fields as opposed to getter/setter.
Jenkins doesn't care and works correctly either way.
*/
public String name;
public City capital;
public List<City> cities;
@DataBoundConstructor
public State(String name, City capital, List<City> cities) {
this.name = name;
this.capital = capital;
this.cities = cities;
}
@Extension
public static class DescriptorImpl extends Descriptor<State> {
@Override
public String getDisplayName() {
return "";
}
public FormValidation doCheckName(@QueryParameter String value,
@RelativePath("capital") @QueryParameter String name) {
/*
@RelativePath("capital") @QueryParameter
... is short for
@RelativePath("capital") @QueryParameter("name")
... and thus can be thought of "capital/name"
so this matches the current city name entered as the capital of this state
*/
return FormValidation.ok("Are you sure " + name + " is a capital of " + value + "?");
}
}
}
public static class City extends AbstractDescribableImpl<City> {
public String name;
@DataBoundConstructor
public City(String name) {
this.name = name;
}
@Extension
public static class DescriptorImpl extends Descriptor<City> {
@Override
public String getDisplayName() {
return "";
}
public FormValidation doCheckName(@QueryParameter String value,
@RelativePath("..") @QueryParameter String name) {
/*
@RelativePath("..") @QueryParameter
... is short for
@RelativePath("..") @QueryParameter("name")
... and thus can be thought of "../name"
in the UI, fields for city is wrapped inside those of state, so "../name" binds
to the name field in the state.
*/
if (name==null || value==null || value.contains(name)) return FormValidation.ok();
return FormValidation.warning("City name doesn't contain "+name);
}
}
}
@Extension
public static class DescriptorImpl extends UISampleDescriptor {
}
}
package jenkins.plugins.ui_samples.FormFieldValidationWithContext.City;
def f = namespace(lib.FormTagLib)
f.entry(title:"City Name", field:"name") {
f.textbox()
}
package jenkins.plugins.ui_samples.FormFieldValidationWithContext.State;
def f = namespace(lib.FormTagLib)
f.entry(title:"State Name", field:"name") {
f.textbox()
}
f.nested {
table {
f.section(title:"Capital city") {
f.property(field:"capital")
}
f.entry(title:"Other cities") {
f.repeatableProperty(field:"cities")
}
}
}
package jenkins.plugins.ui_samples.FormFieldValidationWithContext;
import lib.JenkinsTagLib
import lib.FormTagLib
def f=namespace(FormTagLib.class)
t=namespace(JenkinsTagLib.class)
namespace("/lib/samples").sample(title:_("Context-sensitive form validation")) {
p {
raw(_("blurb.context"))
raw(_("blurb.otheruse"))
raw(_("blurb.contrived"))
}
f.form {
f.entry(title:"States") {
f.repeatableProperty(field:"states")
}
}
}
blurb.context=\
Form field validation can access values of the nearby input controls, which is useful for performing \
complex context sensitive form validation.
blurb.otheruse=\
The same technique can be also used for auto-completion, populating combobox/listbox, and so on.
blurb.contrived=\
The example below is bit contrived, but all the input elements are named 'name' (for city name and state name), \
and we use <code>@RelativePath</code> so that the validation of the state name refers to the capital name, \
and the validation of the city name refers to the state name.
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册