Difference between revisions of "MediaWiki:Form.rythm"

From BITPlan Wiki
Jump to navigation Jump to search
Line 48: Line 48:
 
     addField(new TextField("captcha",captcha.task,captcha.task_de,"question-sign",1));
 
     addField(new TextField("captcha",captcha.task,captcha.task_de,"question-sign",1));
 
     addField(new HiddenField("expected",""+captcha.expected));
 
     addField(new HiddenField("expected",""+captcha.expected));
     SelectField robotField=new SelectField("whatami","What am i?","Was bin ich?","Mensch","Human","book",0);
+
     SelectField robotField=new SelectField("whatami","What am i?","Was bin ich?","Human","Mensch","book",0);
 
     String [] robots_en={"Human","Robot"};
 
     String [] robots_en={"Human","Robot"};
 
     String [] robots_de={"Mensch","Roboter"};
 
     String [] robots_de={"Mensch","Roboter"};
Line 72: Line 72:
 
   }
 
   }
  
 +
  // check whether the form is complete
 +
  // and the captcha has been entered
 
   public boolean isComplete() {
 
   public boolean isComplete() {
 
       if (!submitted)
 
       if (!submitted)
Line 78: Line 80:
 
       Field captchaField=getField("captcha");
 
       Field captchaField=getField("captcha");
 
       Field expectedField=getField("expected");
 
       Field expectedField=getField("expected");
 +
      // check that captcha and expected Field are ok.
 
       if (captchaField!=null && expectedField!=null) {
 
       if (captchaField!=null && expectedField!=null) {
 
         String captchaValue=captchaField.value;
 
         String captchaValue=captchaField.value;
 
         String expectedValue=expectedField.value;
 
         String expectedValue=expectedField.value;
 
         result=captchaValue!=null && expectedValue!=null && !expectedValue.isEmpty() && expectedValue.equals(captchaValue);
 
         result=captchaValue!=null && expectedValue!=null && !expectedValue.isEmpty() && expectedValue.equals(captchaValue);
 +
      }
 +
      Field robotField=getField("robot");
 +
      if (robotField!=null) {
 +
        String robotValue=robotField.value;
 +
        boolean noRobot=robotValue.equals("Human") || robotValue.equals("Mensch");
 +
        result=result && noRobot;
 
       }
 
       }
 
       return result;
 
       return result;
Line 266: Line 275:
 
     @("}"),
 
     @("}"),
 
     notEmpty: @("{")
 
     notEmpty: @("{")
         message: '@(de?"Bitte "+field.label_de+" eingeben":"Please supply "+field.label_en)'
+
         message: '@(de?"Bitte "+field.label_de+" eingeben":"Please enter "+field.label_en)'
 
       @("}")
 
       @("}")
 
     @("}")
 
     @("}")

Revision as of 12:15, 16 July 2018

Links

Rythm template source

@// Rythm template for Bootstrap form handling with validation
@import org.simplejavamail.email.Email
@import org.simplejavamail.email.EmailBuilder
@import org.simplejavamail.mailer.Mailer
@import com.bitplan.mail.SimpleMail
@import javax.ws.rs.core.MultivaluedMap
@import com.bitplan.smw.PropertyMap
@import com.bitplan.wikifrontend.PostService
@// field definitions
@def static {
 //a form with fields
 class Form {
   boolean debug=false;
   Captcha captcha;
   boolean de; // true if things are to be displayed in german
   Map<String,Field> fieldMap=new LinkedHashMap<String,Field>();
   MultivaluedMap<String, String> formParams;
   String title;
   String title_de;

   String success;
   String success_de;

   String subject="Contact Form Request";

   String submit="Send";
   String submit_de="Absenden";

   String task;
   String id="contact_form";

   boolean submitted=false;
   
   public Form(boolean de,PostService postService,String postToken,Field[] fields) {
     this.de=de;
     for (Field field:fields) {
       this.addField(field);
     }
     captcha=new Captcha();
     task=de?captcha.task_de:captcha.task;
     addField(new TextField("captcha",captcha.task,captcha.task_de,"question-sign",1));
     addField(new HiddenField("expected",""+captcha.expected));
     SelectField robotField=new SelectField("whatami","What am i?","Was bin ich?","Human","Mensch","book",0);
     String [] robots_en={"Human","Robot"};
     String [] robots_de={"Mensch","Roboter"};
     if (de) {
       robotField.addSelections(robots_de);
     } else {
       robotField.addSelections(robots_en);
     }
     this.addField(robotField);
     if (postService!=null) {
       addField(new HiddenField("postToken",postService.getPostToken()));
       fromPost(postService,postToken);
     }
   }

   // true if the form has never been submitted yet
   public boolean isNew() {
     return !submitted;
   }

   public String getTask() {
     return task;
   }

   // check whether the form is complete
   // and the captcha has been entered
   public boolean isComplete() {
      if (!submitted)
        return false;
      boolean result=false;
      Field captchaField=getField("captcha");
      Field expectedField=getField("expected");
      // check that captcha and expected Field are ok.
      if (captchaField!=null && expectedField!=null) {
        String captchaValue=captchaField.value;
        String expectedValue=expectedField.value;
        result=captchaValue!=null && expectedValue!=null && !expectedValue.isEmpty() && expectedValue.equals(captchaValue);
      }
      Field robotField=getField("robot");
      if (robotField!=null) {
        String robotValue=robotField.value;
        boolean noRobot=robotValue.equals("Human") || robotValue.equals("Mensch");
        result=result && noRobot;
      }
      return result;
   }

   public String asMail() { 
     String mail="";
     for (Field field:getFields()) {
       mail+=String.format("%s=%s\n",field.name,field.value);
     }
     return mail;
   }

   // constructor
   public void fromPost(PostService postService,String postToken) {
     if (postToken!=null) {
        formParams=postService.getPostData(postToken);
        if (formParams!=null) {
          submitted=true;
          for (Field field:getFields()) {
            field.value=formParams.getFirst(field.name);
          }
        }
     }
   }

   public void setTitle(String title, String title_de) {
     this.title=title;
     this.title_de=title_de;    
   }

   public void setSubmit(String submit, String submit_de) {
     this.submit=submit;
     this.submit_de=submit_de;    
   }

   public void setSuccess(String success, String success_de) {
     this.success=success;
     this.success_de=success_de;    
   }

   public void setSubject(String subject) {
     this.subject=subject;
   }
   
   public Collection<Field> getFields() {
     return fieldMap.values();
   }
   
   public void addField(Field field) {
     fieldMap.put(field.name,field);
   }
   
   public Field getField(String fieldName) {
     Field field=fieldMap.get(fieldName);
     return field;
   }
 }
 class SelectField extends Field {
   List<String> selections=new ArrayList<String>();
   public void addSelection(String selection) {
     selections.add(selection);
   }

   public void addSelections(String[] pSelections) {
     selections.addAll(Arrays.asList(pSelections));
   }

   public SelectField(String name,String label_en, String label_de, String placeholder_en,String placeholder_de, String icon, int min) {
     super(name,label_en,label_de,placeholder_en,placeholder_de,icon,min);
   }
   public SelectField(String name,String label_en, String label_de, String icon, int min) {
     super(name,label_en,label_de,label_en,label_de,icon,min);
   }
 }

 class HiddenField extends Field {
   public HiddenField(String name,String value) {
     super(name,name,name,"flash",0);
     super.hidden=true;
     super.value=value;
   }
 }
 class TextAreaField extends Field {
  public TextAreaField(String name,String label_en, String label_de, String placeholder_en,String placeholder_de, String icon, int min) {
     super(name,label_en,label_de,placeholder_en,placeholder_de,icon,min);
   }
   public TextAreaField(String name,String label_en, String label_de, String icon, int min) {
     super(name,label_en,label_de,label_en,label_de,icon,min);
   }
 }
 class TextField extends Field {
   public TextField(String name,String label_en, String label_de, String placeholder_en,String placeholder_de, String icon, int min) {
     super(name,label_en,label_de,placeholder_en,placeholder_de,icon,min);
   }
   public TextField(String name,String label_en, String label_de, String icon, int min) {
     super(name,label_en,label_de,label_en,label_de,icon,min);
   }
 }

 // a field
 class Field {
    boolean hidden=false;
    String id;
    String name;
    String label_en;
    String label_de; 
    String labelClass="";

    String placeholder_en;
    String placeholder_de;
    String icon;
    String value;
    int min;

    public Field(String name,String label_en, String label_de, String placeholder_en,String placeholder_de, String icon, int min) {
       this.name=name;
       this.id=name;
       this.label_en=label_en;
       this.label_de=label_de;
       this.placeholder_de=placeholder_de;
       this.placeholder_en=placeholder_en;
       this.icon=icon;
       this.min=min;
    }

    public Field(String name,String label_en, String label_de, String icon, int min) {
      this(name,label_en,label_de,label_en,label_de,icon,min);
    }

 }

 class Captcha {
   int expected;
   String task;
   String task_de;

   public Captcha() {
     int a1=(int)(Math.random() * 10 + 1);
     int a2=(int)(Math.random() * 10 + 1);
     expected=a1+a2;
     task_de="Was ist "+a1+"+"+a2+"?";
     task="What is "+a1+"+"+a2+"?";
   }
 } // Captcha
}
@// optional debugging of form
@def formDebug(Form form) {
@if (form.formParams!=null && form.debug) {
<pre>
  @for(String key : form.formParams.keySet()){
@(key)=@(form.formParams.getFirst(key))
  }
</pre>
}
}
@//optional feedback
@def feedback(Form form) {
<pre>
  @for(String key : form.formParams.keySet()){
@{
  Field field=form.getField(key);
}
@if (!field.hidden) {
@(key)=@(form.formParams.getFirst(key))
}
  }
</pre>
}
@// display an alert
@def alert(String alertType,String icon, String message) {
    <div class="row">
      <div class="col-md-12">
         <div class="alert alert-@(alertType)"><strong><span class="glyphicon glyphicon-@(icon)"></span> @(message)</strong></div>
      </div>
    </div>
}
@// add a bootstrap field validation
@def fieldvalidate(boolean de,Field field) {
@(field.name): @("{")
   validators:  @("{")
     stringLength: @("{")
        min: @(field.min),
     @("}"),
     notEmpty: @("{")
        message: '@(de?"Bitte "+field.label_de+" eingeben":"Please enter "+field.label_en)'
       @("}")
     @("}")
   @("}")
}
@// add a form field
@def field(boolean de,Field pField) {
  @if (pField instanceof HiddenField) {
    @hiddenField(de,(HiddenField) pField)
  } 
  @if (pField instanceof TextField) {
    @textField(de,(TextField)pField)
  }
  @if (pField instanceof TextAreaField) {
    @textAreaField(de,(TextAreaField)pField)
  }
  @if (pField instanceof SelectField) {
    @selectField(de,(SelectField)pField)
  }
}
@// add a hidden form field
@def hiddenField(boolean de,HiddenField field) {
  <!-- Hidden input -->
        <input type="hidden" name="@(field.name)" id="@(field.id)" value="@(field.value)" >
}
@// add a textarea form field
@def textAreaField(boolean de,TextAreaField field) {
    <!-- TextArea input-->
@preField(de,field)
             <textarea name="@(field.name)" id="@(field.id)" placeholder="@(de?field.placeholder_de:field.placeholder_en)" class="form-control">@(field.value)</textarea>
@postField(field)
}
@// add a text form field
@def textField(boolean de,TextField field) {
    <!-- Text input-->
@preField(de,field)
             <input type="text" name="@(field.name)" id="@(field.id)" placeholder="@(de?field.placeholder_de:field.placeholder_en)" class="form-control" value="@(field.value)" >
@postField(field)
}
@// add a select form field
@def selectField(boolean de,SelectField field) {
    <!-- Select input-->
@preField(de,field)
             <select name="@(field.name)" id="@(field.id)" class="form-control selectpicker" >
             <option value=" " >@(de?"Bitte "+field.label_de+" wählen":"Please select "+field.label_en)</option>
            @for(String option:field.selections) {
@{ String selected=option.equals(field.value)?"selected":"";}
             <option @(selected)>@(option)</option>
            }
          </select>
@postField(field)
}
@// open a form-group for a field
@def preField(boolean de,Field field) {
        <div class="form-group">
          <label class="col-md-3 control-label @field.labelClass">@(de?field.label_de:field.label_en)</label>  
          <div class="col-md-6 inputGroupContainer">
            <div class="input-group">
              <span class="input-group-addon"><i class="glyphicon glyphicon-@(field.icon)"></i></span>
}
@// close a form-group for a field
@def postField(Field field) {
            </div>
          </div>
        </div>
}
@// formvalidation
@def formvalidate(Form form) {
  <style>
#success_message{ display: none;}
  </style>
  <script>
 $(document).ready(function() @("{")
    $('#contact_form').bootstrapValidator(@("{")
      // To use feedback icons, ensure that you use Bootstrap v3.1.0 or later
      feedbackIcons: @("{")
        valid: 'glyphicon glyphicon-ok',
        invalid: 'glyphicon glyphicon-remove',
        validating: 'glyphicon glyphicon-refresh'
      @("}"),
      fields: @("{")
@{ String delim="";}
@for (Field field:form.getFields()) {
@if (!field.hidden) {
@(delim)@(fieldvalidate(form.de,field))
@{ delim=",";}
}
}
    @("}")
  @("}"))
  .on('success.form.bv', function(e) @("{")
    $('#success_message').slideDown(@("{") opacity: "show" @("}"), "slow") // Do something ...
    $('#contact_form').data('bootstrapValidator').resetForm();

    // Prevent form submission
    e.preventDefault();
  @("}"));
 @("}"));
  </script>
}
@// show form content
@def showFormContent(Form form){
   <form class="rounded form-horizontal" action=" " method="post"  id="@(form.id)">
      <fieldset>
        <!-- Form Name -->
        <legend>@(form.de?form.title_de:form.title)</legend>
@for (Field field:form.getFields()) {
@field(form.de,field)
}
        <!-- Success message -->
        <div class="alert alert-success" role="alert" id="success_message">Success <i class="glyphicon glyphicon-thumbs-up"></i> @(form.de?form.success_de:form.success)</div>
        <!-- Button -->
        <div class="form-group">
          <label class="col-md-4 control-label"></label>
          <div class="col-md-4">
            <button type="submit">@(form.de?form.submit_de:form.submit)<span class="glyphicon glyphicon-send"></span></button>
          </div>
        </div>
      </fieldset>
    </form>
}
@// show form 
@def showform(Form form){
@if (form.isNew()) {
  @showFormContent(form)
} else if (form.isComplete()) {
  @{ 
       String msg=form.de?"Entschuldigen Sie bitte - es ist ein Problem aufgetreten. Bitte nehmen Sie über einen anderen Weg laut Impressum Kontakt mit uns auf!!":"Sorry - there is a problem please contact us via a different channel as per our imprint!";
       String alertType="danger";
       String icon="alert";
       try {
         Mailer mailer=SimpleMail.getMailer();
         if (mailer!=null) {
            Email email=new EmailBuilder()
            .from("BITPlan WebMaster","webmaster@bitplan.com")
            .to("info@bitplan.com")
            .subject(form.subject)
            .text(form.asMail())
            .build();
            mailer.sendMail(email);
            msg=form.de?"Vielen Dank - Ihre Nachricht wurde gesendet":"Thank you - your message was sent";
            alertType="success";
            icon="send";
         }
       } catch (Throwable th) {
         msg="Exception "+th.getClass().getName()+":"+th.getMessage();
       }
    } 
    @alert(alertType,icon,msg) 
    @feedback(form)
  } else {
      @showFormContent(form)
      @{ 
        String msg_de="Bitte geben Sie das richtige Ergebnis für die Aufgabe "+form.getTask()+" ein";
        String msg_en="Please enter the correct result for the task "+form.getTask(); 
        String msg=form.de?msg_de:msg_en; 
      }
      @alert("danger","alert",msg)
  }
}