Validating grids that contain more than one question
Grids can contain more than one question. In some scripts, whether or not a question must be answered depends on whether the other questions in the grid were answered. For example, in a grid containing questions to do with newspaper readership, respondents who say they read a particular newspaper must also answer the questions to do with frequency and rating, whereas if they do not read a newspaper these questions must be unanswered. This topic shows a function you can use for validating this type of grid.
The questions are defined in the metadata section as follows:
NewspaperList "" define
{
Telegraph, Independent, Times,
Express, Mail, Sun, Mirror
};
RatingList "" define
{
Good, Neutral, Poor,
NoRating "No Rating",
NotApplic "Not Applicable"
};
PaperReview "Please answer the following questions about
the papers you read regularly." loop
{use NewspaperList}
fields (
Frequency "How often do you read this paper?"
style(Control(Type = "DropList")) categorical [0..1]
{
Select "- Select -"
{
Daily "Daily",
OnceAWeek "Up to once a week",
OnceAMonth "Up to once a month",
Less "Less than once a month",
NoAnswer "Not Answered" NA
}
};
LastRead "When (date) did you last read this paper?"
style(Width = "10em") date
codes(
{
NoAnswer "No Answer" NA
}
);
Rating "Rating" categorical [0..1]
{use \\.RatingList} initialanswer({NotApplic});
) expand;
They generate a grid that looks like this:
Grid containing more than one question
The routing section that displays the grid and implements the validation is:
IOM.LayoutTemplate = "Card_Blue_TopAndBottomErrors.htm"
PaperReview[..].LastRead.MustAnswer = False
PaperReview[..].Frequency.MustAnswer = False
PaperReview[..].Rating.MustAnswer = False
PaperReview.Validation.Function = "ValidateGrid"
PaperReview.Ask()
Function ValidateGrid(GridQuestion, IOM, Attempt)
Dim Cat, RowFrequencyError, RowLastReadError
Dim RowRatingError, GridFrequencyError, GridLastReadError
Dim GridRatingError, errString
' Clear any previously set error settings
GridQuestion.Errors.Clear()
errString = ""
GridFrequencyError = 0
GridLastReadError = 0
GridRatingError = 0
'Check rows for errors
For each Cat in GridQuestion.Categories
' Reset row error codes between each row
RowFrequencyError = 0
RowLastReadError = 0
RowRatingError = 0
' If Frequency is answered, must answer LastRead and Rating.
If Not GridQuestion[Cat].Frequency.Response.Value = Null Then
If GridQuestion[Cat].LastRead.Response.Coded.ContainsAll({NoAnswer},True) Then
RowLastReadError = 1
End If
If GridQuestion[Cat].Rating.Response.Value.ContainsAll({NotApplic},True) Then
RowRatingError = 1
End If
' If Frequency is blank, RowLastRead and RowRating should be too.
Else
If Not GridQuestion[Cat].LastRead.Response.Coded.ContainsAll({NoAnswer},True) Then
RowFrequencyError = 1
End If
If Not GridQuestion[Cat].Rating.Response.Value.ContainsAll({NotApplic},True) Then
RowFrequencyError = 1
End If
End If
'Set Grid error codes
If RowFrequencyError = 1 Then
GridFrequencyError = 1
End If
If RowLastReadError = 1 Then
GridLastReadError = 1
End If
If RowRatingError =1 Then
GridRatingError = 1
End If
Next
' Display errors
If GridFrequencyError = 1 or _
GridLastReadError = 1 or _
GridRatingError = 1 Then
ValidateGrid = False
If GridFrequencyError = 1 Then
errString = "LastRead and/or Rating answered but no answer for Frequency."
End If
If GridLastReadError = 1 or GridRatingError = 1 Then
If errString <> "" Then
errString = errString + mr.CrLf
End If
errString = errString + "LastRead and/or Rating is unanswered."
End If
GridQuestion.Errors.AddNew("GridQuestion", Ctext(errString))
Else
ValidateGrid = True
End If
End Function
None of the questions in the grid requires an answer, so the questions' MustAnswer properties are set to False.
Frequency and
LastRead both have
na (no answer) categories that will be selected automatically if the respondent does not answer the question. (See
Allowing respondents not to answer questions for further details about the relationship between MustAnswer and
na categories.)
Rating does not have a “no answer” category but, instead, has “Not Applicable” which is set as the initial (and therefore default) answer and which respondents can select if they want to cancel a previously selected rating. Respondents wanting to cancel a selection from the
Frequency list can simply choose the “Select” category, and dates in
LastRead can be deleted.
The ValidateGrid function checks two things for each newspaper (row) in the grid:
▪If Frequency has an answer, LastRead and Rating must both be answered. If this is not so, the RowLastReadError and/or RowRatingError variables are set to 1 as appropriate.
▪If Frequency does not have an answer, LastRead and Rating must both be unanswered. If this is not so, the RowFrequencyError variable is set to 1.
The function loops through each row of the grid setting the values of the row error variables if errors are found. These variables are reset between each row. At the end of each row, the variables GridFrequencyError, GridLastDateError and GridRatingError are set to 1 if RowFrequencyError, RowLastDateError or RowRatingError are 1 for the current row. The Grid variables are not reset between rows to cater for cases where some rows contains errors while others do not.
When the whole grid has been checked, the function uses the grid error variables to display error messages.
See also