Skip to content

Evaluation Survey

A training evaluation survey demonstrating slider fields, conditional follow-up questions, and soft validation.

Requirements

  • Rate multiple aspects on a 1-5 scale (slider)
  • Text feedback for each rating category
  • Conditional follow-up when rating is low
  • Overall recommendation (select)
  • Instructor reference
  • Soft validation for unusual rating patterns

Complete Implementation

dart
import 'package:vyuh_feature_forms/dsl/form_builder.dart';

Form buildEvaluationSurvey({
  required String courseTitle,
  Map<String, dynamic>? initialValues,
}) {
  return FormBuilder(title: 'Training Evaluation')
    .description('Evaluation for: $courseTitle')

    // ── Course and Student ───────────────────────────────
    .text('student_name', title: 'Your Name')
      .required('Name is required')

    .text('student_email', title: 'Email')
      .required()
      .email()


    // ── Content Rating ───────────────────────────────────
    .section('Content Quality', (s) => s
      .slider('content_relevance', title: 'Content Relevance',
        min: 1, max: 5, divisions: 4)
        .help('1 = Not Relevant, 5 = Highly Relevant')

      .slider('content_depth', title: 'Content Depth',
        min: 1, max: 5, divisions: 4)
        .help('1 = Too Shallow, 5 = Excellent Depth')

      .slider('content_clarity', title: 'Content Clarity',
        min: 1, max: 5, divisions: 4)
        .help('1 = Unclear, 5 = Crystal Clear')

      .slider('content_organization', title: 'Organization',
        min: 1, max: 5, divisions: 4)
        .help('1 = Disorganized, 5 = Well Structured')

      .text('content_feedback', title: 'Content Feedback')
        .multiline(3)
        .placeholder('What would you improve about the content?'),
      description: 'Rate the quality and relevance of the training content',
    )

    // ── Instructor Rating ────────────────────────────────
    .section('Instructor Effectiveness', (s) => s
      .slider('instructor_knowledge', title: 'Subject Knowledge',
        min: 1, max: 5, divisions: 4)
        .help('1 = Poor, 5 = Expert')

      .slider('instructor_engagement', title: 'Engagement',
        min: 1, max: 5, divisions: 4)
        .help('1 = Disengaged, 5 = Highly Engaging')

      .slider('instructor_pacing', title: 'Pacing',
        min: 1, max: 5, divisions: 4)
        .help('1 = Too Fast/Slow, 5 = Perfect Pace')

      .slider('instructor_responsiveness', title: 'Responsiveness',
        min: 1, max: 5, divisions: 4)
        .help('1 = Unresponsive, 5 = Very Responsive')

      .text('instructor_feedback', title: 'Instructor Feedback')
        .multiline(3)
        .placeholder('Comments about the instructor'),
      description: 'Rate the instructor\'s teaching effectiveness',
    )

    // ── Logistics Rating ─────────────────────────────────
    .section('Logistics & Environment', (s) => s
      .slider('venue_quality', title: 'Venue/Platform Quality',
        min: 1, max: 5, divisions: 4)

      .slider('materials_quality', title: 'Materials Quality',
        min: 1, max: 5, divisions: 4)

      .slider('schedule_convenience', title: 'Schedule Convenience',
        min: 1, max: 5, divisions: 4)

      .slider('technical_support', title: 'Technical Support',
        min: 1, max: 5, divisions: 4)
        ,
      description: 'Rate the logistics and learning environment',
    )

    // ── Overall Assessment ───────────────────────────────
    .section('Overall Assessment', (s) => s
      .slider('overall_rating', title: 'Overall Satisfaction',
        min: 1, max: 5, divisions: 4)
        .required()
      .select('recommendation', title: 'Would you recommend this course?')
        .option('strongly_yes', title: 'Strongly Recommend')
        .option('yes', title: 'Recommend')
        .option('neutral', title: 'Neutral')
        .option('no', title: 'Would Not Recommend')
        .option('strongly_no', title: 'Strongly Against')
        .required('Please provide a recommendation')
      .text('improvement_suggestions', title: 'Improvement Suggestions')
        .multiline(4)
        .placeholder('How can we make this course better?')
      .text('additional_comments', title: 'Additional Comments')
        .multiline(3),
    )

    .build(initialValues: initialValues);
}

Adding Soft Validation

For unusual rating patterns (e.g., all 1s or all 5s), add soft validation:

dart
SliderField(
  name: 'overall_rating',
  title: 'Overall Satisfaction',
  min: 1,
  max: 5,
  divisions: 4,
  validations: [
    RequiredValidation(errorMessage: 'Please rate overall satisfaction'),
    SoftRangeValidation(
      softMin: 2.0,
      softMax: 4.0,
      warningMessage: 'Extreme ratings are noted for review',
      triggersException: true,
      exceptionSeverity: ExceptionSeverity.low,
    ),
  ],
)

Conditional Follow-up

Show additional detail fields when a rating is low:

dart
// Using constructor-based rules for numeric conditions
SliderField(
  name: 'instructor_knowledge',
  title: 'Subject Knowledge',
  min: 1, max: 5, divisions: 4,
  validations: [],
),
TextField(
  name: 'instructor_concern',
  title: 'Please describe your concerns about instructor knowledge',
  rules: [
    FormFieldRule(
      condition: NumericCondition(
        targetField: 'instructor_knowledge',
        operator: NumericOperator.lessEqual,
        value: 2,
      ),
      action: VisibilityAction(showWhenTrue: true),
    ),
  ],
  validations: [],
),

Processing Results

dart
void processEvaluation(Form form) {
  final values = form.currentValues;

  // Calculate category averages
  final contentRatings = [
    values['content_relevance'] as double? ?? 0,
    values['content_depth'] as double? ?? 0,
    values['content_clarity'] as double? ?? 0,
    values['content_organization'] as double? ?? 0,
  ];
  final contentAvg = contentRatings.reduce((a, b) => a + b) / contentRatings.length;

  final instructorRatings = [
    values['instructor_knowledge'] as double? ?? 0,
    values['instructor_engagement'] as double? ?? 0,
    values['instructor_pacing'] as double? ?? 0,
    values['instructor_responsiveness'] as double? ?? 0,
  ];
  final instructorAvg = instructorRatings.reduce((a, b) => a + b) / instructorRatings.length;

  // Check for soft breaches
  final breaches = form.collectSoftBreaches();

  print('Content Average: ${contentAvg.toStringAsFixed(1)}');
  print('Instructor Average: ${instructorAvg.toStringAsFixed(1)}');
  print('Overall: ${values['overall_rating']}');
  print('Recommendation: ${values['recommendation']}');
  print('Soft breaches: ${breaches.length}');
}

What This Demonstrates

FeatureUsage
Slider fields12 rating sliders with 1-5 scale
Sections4 logical rating categories
Conditional visibilityFollow-up fields for low ratings
Soft validationWarning for extreme ratings
Multiline textFeedback and comments fields
Row layoutSide-by-side sliders through row blocks and row item spans
Select fieldRecommendation dropdown

Next Steps