Madeyedexter
Madeyedexter

Reputation: 1193

AJAX validation fails for all form data

I am using ajax jquery validation.

https://code.google.com/p/struts2-jquery/wiki/Validation

In my struts.xml, i have

<action name="createChannel" class="channel.ChannelAction" method="createChannel">
<interceptor-ref name="jsonValidationWorkflowStack"/>
<result  name="success">createSuccess.jsp</result>
<result  name="input">createChannel.jsp</result>
</action>

In JSP page i have:

<s:form method="get" action="createChannel" >
<s:textfield name="channelName" label="Channel Name" />
<s:textfield name="channelBand" label="Channel Band"/>
<s:textfield name="vcFrequency" label="Video Carrier Frequency"/>
<s:textfield name="acFrequency" label="Audio Carrier Frequency"/>
<s:select name="chargeType" label="Charge Type" list="{'PrePaid','PostPaid'}"/>
<s:select name="transmissionType" label="Transmission Type" list="{'HD','Standard'}"/>
<s:textfield name="channelCharge" label="Channel Charge"/>
<sj:submit value="Submit" button="true" validate="true" targets="result"  />
</s:form>
<div id="result">Result:</div>

I have model class Channel with annotation validations as:

public class Channel {
    private int channelId;
    private String channelName;
    private String channelBand;
    private double vcFrequency;
    private double acFrequency;
    private String chargeType; //PrePaid or PostPaid
    private String transmissionType; //HD or Standard
    private double channelCharge;

    private Set<ChannelPackage> channelPackage;

    public Channel(){
        channelPackage=new HashSet<>();
    }

    public int getChannelId() {
        return channelId;
    }

    public void setChannelId(int channelId) {
        this.channelId = channelId;
    }

    @RequiredStringValidator(trim=true,type=ValidatorType.FIELD,message="Please enter valid channel name")
    public String getChannelName() {
        return channelName;
    }

    public void setChannelName(String channelName) {
        this.channelName = channelName;
    }
    @RequiredStringValidator(trim=true,type=ValidatorType.FIELD,message="Please enter valid channel band")
    public String getChannelBand() {
        return channelBand;
    }

    public void setChannelBand(String channelBand) {
        this.channelBand = channelBand;
    }
    @DoubleRangeFieldValidator(type = ValidatorType.SIMPLE,fieldName = "vcFrequency",minInclusive = "40",maxInclusive = "225",message = "The scale must be between ${minInclusive} and ${maxInclusive} (exclusive)")
    public double getVcFrequency() {
        return vcFrequency;
    }

    public void setVcFrequency(double vcFrequency) {
        this.vcFrequency = vcFrequency;
    }
    @DoubleRangeFieldValidator(type = ValidatorType.SIMPLE,fieldName = "acFrequency",minInclusive = "45",maxInclusive = "230",message = "The scale must be between ${minInclusive} and ${maxInclusive} (exclusive)")
    public double getAcFrequency() {
        return acFrequency;
    }

    public void setAcFrequency(double acFrequency) {
        this.acFrequency = acFrequency;
    }

    public String getChargeType() {
        return chargeType;
    }

    public void setChargeType(String chargeType) {
        this.chargeType = chargeType;
    }


    public String getTransmissionType() {
        return transmissionType;
    }

    public void setTransmissionType(String transmissionType) {
        this.transmissionType = transmissionType;
    }
    @DoubleRangeFieldValidator(type = ValidatorType.SIMPLE,fieldName = "channelCharge",minExclusive = "20.5",maxExclusive = "78.5",message = "The scale must be between ${minExclusive} and ${maxExclusive} (exclusive)")
    public double getChannelCharge() {
        return channelCharge;
    }

    public void setChannelCharge(double channelCharge) {
        this.channelCharge = channelCharge;
    }


    public Set<ChannelPackage> getChannelPackage() {
        return channelPackage;
    }

    public void setChannelPackage(Set<ChannelPackage> channelPackage) {
        this.channelPackage = channelPackage;
    }

    public String toString(){
        return channelId+": "+channelName;
    }

}

My action class implements the Model Driven Interface. My Problem is:

Here is a screenshot after submission:

Please help me get this right.

enter image description here

Upvotes: 1

Views: 205

Answers (1)

Andrea Ligios
Andrea Ligios

Reputation: 50203

So many questions in a single one... BTW, here we go:

1. Even if I submit the form with correct data, my form shows error messages.

This is due to the Interceptor Stack you are using:

<interceptor-ref name="jsonValidationWorkflowStack"/>

that is defined as

<interceptor-stack name="jsonValidationWorkflowStack">
    <interceptor-ref name="basicStack"/>
    <interceptor-ref name="validation">
        <param name="excludeMethods">input,back,cancel</param>
    </interceptor-ref>
    <interceptor-ref name="jsonValidation"/>
    <interceptor-ref name="workflow"/>
</interceptor-stack>

and basicStack is

<interceptor-stack name="basicStack">
    <interceptor-ref name="exception"/>
    <interceptor-ref name="servletConfig"/>
    <interceptor-ref name="prepare"/>
    <interceptor-ref name="checkbox"/>
    <interceptor-ref name="params"/>
    <interceptor-ref name="conversionError"/>
</interceptor-stack>

As you can see, no ModelDriven Interceptor is involved here. If you want to keep using ModelDriven, you need to:

  • add ModelDriven Interceptor, and
  • ensure it runs before the Validation Interceptor, otherwise the parameters you are sending will not be (yet) set on the model when the validation will be performed. Read this answer to understand exactly what I mean.

This should be enough:

<action name="createChannel" class="channel.ChannelAction" method="createChannel">
    <interceptor-ref name="modelDriven"/>
    <interceptor-ref name="jsonValidationWorkflowStack"/>
    <result  name="success">createSuccess.jsp</result>
    <result  name="input">createChannel.jsp</result>
</action>

2. Along with the error messages, The input result returned is shown in the result div. Which means I have two forms on jsp page after clicking submit button.

This is obvious, your design is like that, how is it supposed to change automagically in case of INPUT ? You need to rethink your design. For example, you can target the form you are in, something like:

<div id="result">
    <s:form method="get" action="createChannel" >
        <s:textfield name="channelName" label="Channel Name" />
        <s:textfield name="channelBand" label="Channel Band"/>
        <s:textfield name="vcFrequency" label="Video Carrier Frequency"/>
        <s:textfield name="acFrequency" label="Audio Carrier Frequency"/>
        <s:select name="chargeType" label="Charge Type" list="{'PrePaid','PostPaid'}"/>
        <s:select name="transmissionType" label="Transmission Type" list="{'HD','Standard'}"/>
        <s:textfield name="channelCharge" label="Channel Charge"/>
        <sj:submit value="Submit" button="true" validate="true" targets="result"  />
    </s:form>
</div>

Then both in case of INPUT and SUCCESS, you return a message, the form and the fields repopulated. It would be better to create a JSP snippet to be used in the original page too with <s:include/>, to follow DRY.

Upvotes: 2

Related Questions