File: D:/HostingSpaces/SBogers10/hours.komma.pro/wwwroot/js/app.js.map
{"version":3,"sources":["jquery.form-validator.js"],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"app.js","sourcesContent":["(function (root, factory) {\n if (typeof define === 'function' && define.amd) {\n // AMD. Register as an anonymous module unless amdModuleId is set\n define([\"jquery\"], function (a0) {\n return (factory(a0));\n });\n } else if (typeof module === 'object' && module.exports) {\n // Node. Does not work with strict CommonJS, but\n // only CommonJS-like environments that support module.exports,\n // like Node.\n module.exports = factory(require(\"jquery\"));\n } else {\n factory(root[\"jQuery\"]);\n }\n}(this, function (jQuery) {\n\n/** File generated by Grunt -- do not modify\n * JQUERY-FORM-VALIDATOR\n *\n * @version 2.3.77\n * @website http://formvalidator.net/\n * @author Victor Jonsson, http://victorjonsson.se\n * @license MIT\n */\n/**\n */\n(function ($, window, undefined) {\n\n var disableFormSubmit = function () {\n return false;\n },\n lastFormEvent = null,\n HaltManager = {\n numHalted: 0,\n haltValidation: function($form) {\n this.numHalted++;\n $.formUtils.haltValidation = true;\n $form\n .unbind('submit', disableFormSubmit)\n .bind('submit', disableFormSubmit)\n .find('*[type=\"submit\"]')\n .addClass('disabled')\n .attr('disabled', 'disabled');\n },\n unHaltValidation: function($form) {\n this.numHalted--;\n if (this.numHalted === 0) {\n $.formUtils.haltValidation = false;\n $form\n .unbind('submit', disableFormSubmit)\n .find('*[type=\"submit\"]')\n .removeClass('disabled')\n .removeAttr('disabled', 'disabled');\n }\n }\n };\n\n function AsyncValidation($form, $input) {\n this.$form = $form;\n this.$input = $input;\n this.reset();\n $input.on('change paste', this.reset.bind(this));\n }\n\n AsyncValidation.prototype.reset = function() {\n this.haltedFormValidation = false;\n this.hasRun = false;\n this.isRunning = false;\n this.result = undefined;\n };\n\n AsyncValidation.prototype.run = function(eventContext, callback) {\n if (eventContext === 'keyup') {\n return null;\n } else if (this.isRunning) {\n lastFormEvent = eventContext;\n if (!this.haltedFormValidation) {\n HaltManager.haltValidation();\n this.haltedFormValidation = true;\n }\n return null; // Waiting for result\n } else if(this.hasRun) {\n //this.$input.one('keyup change paste', this.reset.bind(this));\n return this.result;\n } else {\n lastFormEvent = eventContext;\n HaltManager.haltValidation(this.$form);\n this.haltedFormValidation = true;\n this.isRunning = true;\n this.$input\n .attr('disabled', 'disabled')\n .addClass('async-validation');\n this.$form.addClass('async-validation');\n\n callback(function(result) {\n this.done(result);\n }.bind(this));\n\n return null;\n }\n };\n\n AsyncValidation.prototype.done = function(result) {\n this.result = result;\n this.hasRun = true;\n this.isRunning = false;\n this.$input\n .removeAttr('disabled')\n .removeClass('async-validation');\n this.$form.removeClass('async-validation');\n if (this.haltedFormValidation) {\n HaltManager.unHaltValidation(this.$form);\n if (lastFormEvent === 'submit') {\n this.$form.trigger('submit');\n } else {\n this.$input.trigger('validation.revalidate');\n }\n }\n };\n\n AsyncValidation.loadInstance = function(validatorName, $input, $form) {\n // Return async validator attached to this input element\n // or create a new async validator and attach it to the input\n var asyncValidation,\n input = $input.get(0);\n\n if (!input.asyncValidators) {\n input.asyncValidators = {};\n }\n\n if (input.asyncValidators[validatorName]) {\n asyncValidation = input.asyncValidators[validatorName];\n } else {\n asyncValidation = new AsyncValidation($form, $input);\n input.asyncValidators[validatorName] = asyncValidation;\n }\n\n return asyncValidation;\n };\n\n $.formUtils = $.extend($.formUtils || {}, {\n\n /**\n * @deprecated\n * @param validatorName\n * @param $input\n * @param $form\n */\n asyncValidation: function(validatorName, $input, $form) {\n // @todo: Remove when moving up to version 3.0\n this.warn('Use of deprecated function $.formUtils.asyncValidation, use $.formUtils.addAsyncValidator() instead');\n return AsyncValidation.loadInstance(validatorName, $input, $form);\n },\n\n /**\n * @param {Object} asyncValidator\n */\n addAsyncValidator: function (asyncValidator) {\n var validator = $.extend({}, asyncValidator),\n originalValidatorFunc = validator.validatorFunction;\n validator.async = true;\n validator.validatorFunction = function (value, $el, config, language, $form, eventContext) {\n var asyncValidation = AsyncValidation.loadInstance(this.name, $el, $form);\n return asyncValidation.run(eventContext, function(done) {\n originalValidatorFunc.apply(validator, [\n done, value, $el, config, language, $form, eventContext\n ]);\n });\n };\n this.addValidator(validator);\n }\n });\n\n // Tag elements having async validators\n $(window).bind('validatorsLoaded formValidationSetup', function (evt, $form) {\n if (!$form) {\n $form = $('form');\n }\n $form.find('[data-validation]').each(function () {\n var $input = $(this);\n $input.valAttr('async', false);\n $.each($.split($input.attr('data-validation')), function (i, validatorName) {\n var validator = $.formUtils.validators['validate_'+validatorName];\n if (validator && validator.async) {\n $input.valAttr('async', 'yes');\n }\n });\n });\n });\n\n})(jQuery, window);\n\n/**\n * Deprecated functions and attributes\n * @todo: Remove in release of 3.0\n */\n(function ($, undefined) {\n\n 'use strict';\n\n /**\n * @deprecated\n * @param language\n * @param conf\n */\n $.fn.validateForm = function (language, conf) {\n $.formUtils.warn('Use of deprecated function $.validateForm, use $.isValid instead');\n return this.isValid(language, conf, true);\n };\n\n $(window)\n .on('formValidationPluginInit', function(evt, config) {\n convertDeprecatedLangCodeToISO6391(config);\n addSupportForCustomErrorMessageCallback(config);\n addSupportForElementReferenceInPositionParam(config);\n })\n .on('validatorsLoaded formValidationSetup', function(evt, $form) {\n if( !$form ) {\n $form = $('form');\n }\n addSupportForValidationDependingOnCheckedInput($form);\n });\n\n\n function addSupportForCustomErrorMessageCallback(config) {\n if (config &&\n config.errorMessagePosition === 'custom' &&\n typeof config.errorMessageCustom === 'function') {\n\n $.formUtils.warn('Use of deprecated function errorMessageCustom, use config.submitErrorMessageCallback instead');\n\n config.submitErrorMessageCallback = function($form, errorMessages) {\n config.errorMessageCustom(\n $form,\n config.language.errorTitle,\n errorMessages,\n config\n );\n };\n }\n }\n\n function addSupportForElementReferenceInPositionParam(config) {\n if (config.errorMessagePosition && typeof config.errorMessagePosition === 'object') {\n $.formUtils.warn('Deprecated use of config parameter errorMessagePosition, use config.submitErrorMessageCallback instead');\n var $errorMessageContainer = config.errorMessagePosition;\n config.errorMessagePosition = 'top';\n config.submitErrorMessageCallback = function() {\n return $errorMessageContainer;\n };\n }\n }\n\n function addSupportForValidationDependingOnCheckedInput($form) {\n var $inputsDependingOnCheckedInputs = $form.find('[data-validation-if-checked]');\n if ($inputsDependingOnCheckedInputs.length) {\n $.formUtils.warn(\n 'Detected use of attribute \"data-validation-if-checked\" which is '+\n 'deprecated. Use \"data-validation-depends-on\" provided by module \"logic\"'\n );\n }\n\n $inputsDependingOnCheckedInputs\n .on('beforeValidation', function() {\n\n var $elem = $(this),\n nameOfDependingInput = $elem.valAttr('if-checked');\n\n // Set the boolean telling us that the validation depends\n // on another input being checked\n var $dependingInput = $('input[name=\"' + nameOfDependingInput + '\"]', $form),\n dependingInputIsChecked = $dependingInput.is(':checked'),\n valueOfDependingInput = ($.formUtils.getValue($dependingInput) || '').toString(),\n requiredValueOfDependingInput = $elem.valAttr('if-checked-value');\n\n if (!dependingInputIsChecked || !(\n !requiredValueOfDependingInput ||\n requiredValueOfDependingInput === valueOfDependingInput\n )) {\n $elem.valAttr('skipped', true);\n }\n\n });\n }\n\n function convertDeprecatedLangCodeToISO6391(config) {\n var deprecatedLangCodes = {\n se: 'sv',\n cz: 'cs',\n dk: 'da'\n };\n\n if (config.lang in deprecatedLangCodes) {\n var newLangCode = deprecatedLangCodes[config.lang];\n $.formUtils.warn(\n 'Deprecated use of lang code \"'+config.lang+'\" use \"'+newLangCode+'\" instead'\n );\n config.lang = newLangCode;\n }\n }\n\n})(jQuery);\n\n/**\n * Utility methods used for displaying error messages (attached to $.formUtils)\n */\n(function ($) {\n\n 'use strict';\n\n var dialogs = {\n\n resolveErrorMessage: function($elem, validator, validatorName, conf, language) {\n var errorMsgAttr = conf.validationErrorMsgAttribute + '-' + validatorName.replace('validate_', ''),\n validationErrorMsg = $elem.attr(errorMsgAttr);\n\n if (!validationErrorMsg) {\n validationErrorMsg = $elem.attr(conf.validationErrorMsgAttribute);\n if (!validationErrorMsg) {\n if (typeof validator.errorMessageKey !== 'function') {\n validationErrorMsg = language[validator.errorMessageKey];\n }\n else {\n validationErrorMsg = language[validator.errorMessageKey(conf)];\n }\n if (!validationErrorMsg) {\n validationErrorMsg = validator.errorMessage;\n }\n }\n }\n return validationErrorMsg;\n },\n getParentContainer: function ($elem) {\n if ($elem.valAttr('error-msg-container')) {\n return $($elem.valAttr('error-msg-container'));\n } else {\n var $parent = $elem.parent();\n if($elem.attr('type') === 'checkbox' && $elem.closest('.checkbox').length) {\n $parent = $elem.closest('.checkbox').parent();\n } else if($elem.attr('type') === 'radio' && $elem.closest('.radio').length) {\n $parent = $elem.closest('.radio').parent();\n }\n if($parent.closest('.input-group').length) {\n $parent = $parent.closest('.input-group').parent();\n }\n return $parent;\n }\n },\n applyInputErrorStyling: function ($input, conf) {\n $input\n .addClass(conf.errorElementClass)\n .removeClass(conf.successElementClass);\n\n this.getParentContainer($input)\n .addClass(conf.inputParentClassOnError)\n .removeClass(conf.inputParentClassOnSuccess);\n\n if (conf.borderColorOnError !== '') {\n $input.css('border-color', conf.borderColorOnError);\n }\n },\n applyInputSuccessStyling: function($input, conf) {\n $input.addClass(conf.successElementClass);\n this.getParentContainer($input)\n .addClass(conf.inputParentClassOnSuccess);\n },\n removeInputStylingAndMessage: function($input, conf) {\n\n // Reset input css\n $input\n .removeClass(conf.successElementClass)\n .removeClass(conf.errorElementClass)\n .css('border-color', '');\n\n var $parentContainer = dialogs.getParentContainer($input);\n\n // Reset parent css\n $parentContainer\n .removeClass(conf.inputParentClassOnError)\n .removeClass(conf.inputParentClassOnSuccess);\n\n // Remove possible error message\n if (typeof conf.inlineErrorMessageCallback === 'function') {\n var $errorMessage = conf.inlineErrorMessageCallback($input, false, conf);\n if ($errorMessage) {\n $errorMessage.html('');\n }\n } else {\n $parentContainer\n .find('.' + conf.errorMessageClass)\n .remove();\n }\n\n },\n removeAllMessagesAndStyling: function($form, conf) {\n\n // Remove error messages in top of form\n if (typeof conf.submitErrorMessageCallback === 'function') {\n var $errorMessagesInTopOfForm = conf.submitErrorMessageCallback($form, false, conf);\n if ($errorMessagesInTopOfForm) {\n $errorMessagesInTopOfForm.html('');\n }\n } else {\n $form.find('.' + conf.errorMessageClass + '.alert').remove();\n }\n\n // Remove input css/messages\n $form.find('.' + conf.errorElementClass + ',.' + conf.successElementClass).each(function() {\n dialogs.removeInputStylingAndMessage($(this), conf);\n });\n },\n setInlineMessage: function ($input, errorMsg, conf) {\n\n this.applyInputErrorStyling($input, conf);\n\n var custom = document.getElementById($input.attr('name') + '_err_msg'),\n $messageContainer = false,\n setErrorMessage = function ($elem) {\n $.formUtils.$win.trigger('validationErrorDisplay', [$input, $elem]);\n $elem.html(errorMsg);\n },\n addErrorToMessageContainer = function() {\n var $found = false;\n $messageContainer.find('.' + conf.errorMessageClass).each(function () {\n if (this.inputReferer === $input[0]) {\n $found = $(this);\n return false;\n }\n });\n if ($found) {\n if (!errorMsg) {\n $found.remove();\n } else {\n setErrorMessage($found);\n }\n } else if(errorMsg !== '') {\n $message = $('<div class=\"' + conf.errorMessageClass + ' alert\"></div>');\n setErrorMessage($message);\n $message[0].inputReferer = $input[0];\n $messageContainer.prepend($message);\n }\n },\n $message;\n\n if (custom) {\n // Todo: remove in 3.0\n $.formUtils.warn('Using deprecated element reference ' + custom.id);\n $messageContainer = $(custom);\n addErrorToMessageContainer();\n } else if (typeof conf.inlineErrorMessageCallback === 'function') {\n $messageContainer = conf.inlineErrorMessageCallback($input, errorMsg, conf);\n if (!$messageContainer) {\n // Error display taken care of by inlineErrorMessageCallback\n return;\n }\n addErrorToMessageContainer();\n } else {\n var $parent = this.getParentContainer($input);\n $message = $parent.find('.' + conf.errorMessageClass + '.help-block');\n if ($message.length === 0) {\n $message = $('<span></span>').addClass('help-block').addClass(conf.errorMessageClass);\n $message.appendTo($parent);\n }\n setErrorMessage($message);\n }\n },\n setMessageInTopOfForm: function ($form, errorMessages, conf, lang) {\n var view = '<div class=\"{errorMessageClass} alert alert-danger\">'+\n '<strong>{errorTitle}</strong>'+\n '<ul>{fields}</ul>'+\n '</div>',\n $container = false;\n\n if (typeof conf.submitErrorMessageCallback === 'function') {\n $container = conf.submitErrorMessageCallback($form, errorMessages, conf);\n if (!$container) {\n // message display taken care of by callback\n return;\n }\n }\n\n var viewParams = {\n errorTitle: lang.errorTitle,\n fields: '',\n errorMessageClass: conf.errorMessageClass\n };\n\n $.each(errorMessages, function (i, msg) {\n viewParams.fields += '<li>'+msg+'</li>';\n });\n\n $.each(viewParams, function(param, value) {\n view = view.replace('{'+param+'}', value);\n });\n\n if ($container) {\n $container.html(view);\n } else {\n $form.children().eq(0).before($(view));\n }\n }\n };\n\n $.formUtils = $.extend($.formUtils || {}, {\n dialogs: dialogs\n });\n\n})(jQuery);\n\n/**\n * File declaring all methods if this plugin which is applied to $.fn.\n */\n(function($, window, undefined) {\n\n 'use strict';\n\n var _helpers = 0;\n\n\n /**\n * Assigns validateInputOnBlur function to elements blur event\n *\n * @param {Object} language Optional, will override $.formUtils.LANG\n * @param {Object} conf Optional, will override the default settings\n * @return {jQuery}\n */\n $.fn.validateOnBlur = function (language, conf) {\n var $form = this,\n $elems = this.find('*[data-validation]');\n\n $elems.each(function(){\n var $this = $(this);\n if ($this.is('[type=radio]')){\n var $additionals = $form.find('[type=radio][name=\"' + $this.attr('name') + '\"]');\n $additionals.bind('blur.validation', function(){\n $this.validateInputOnBlur(language, conf, true, 'blur');\n });\n if (conf.validateCheckboxRadioOnClick) {\n $additionals.bind('click.validation', function () {\n $this.validateInputOnBlur(language, conf, true, 'click');\n });\n }\n }\n });\n\n $elems.bind('blur.validation', function () {\n $(this).validateInputOnBlur(language, conf, true, 'blur');\n });\n\n if (conf.validateCheckboxRadioOnClick) {\n // bind click event to validate on click for radio & checkboxes for nice UX\n this.find('input[type=checkbox][data-validation],input[type=radio][data-validation]')\n .bind('click.validation', function () {\n $(this).validateInputOnBlur(language, conf, true, 'click');\n });\n }\n\n return this;\n };\n\n /*\n * Assigns validateInputOnBlur function to elements custom event\n * @param {Object} language Optional, will override $.formUtils.LANG\n * @param {Object} settings Optional, will override the default settings\n * * @return {jQuery}\n */\n $.fn.validateOnEvent = function (language, config) {\n var $elements = this[0].nodeName === 'FORM' ? this.find('*[data-validation-event]') : this;\n $elements\n .each(function () {\n var $el = $(this),\n etype = $el.valAttr('event');\n if (etype) {\n $el\n .unbind(etype + '.validation')\n .bind(etype + '.validation', function (evt) {\n if( (evt || {}).keyCode !== 9 ) {\n $(this).validateInputOnBlur(language, config, true, etype);\n }\n });\n }\n });\n return this;\n };\n\n /**\n * fade in help message when input gains focus\n * fade out when input loses focus\n * <input data-help=\"The info that I want to display for the user when input is focused\" ... />\n *\n * @param {String} attrName - Optional, default is data-help\n * @return {jQuery}\n */\n $.fn.showHelpOnFocus = function (attrName) {\n if (!attrName) {\n attrName = 'data-validation-help';\n }\n\n // Add help text listeners\n this.find('textarea,input').each(function () {\n var $elem = $(this),\n className = 'jquery_form_help_' + (++_helpers),\n help = $elem.attr(attrName);\n\n // Reset\n $elem\n .removeClass('has-help-text')\n .unbind('focus.help')\n .unbind('blur.help');\n\n if (help) {\n $elem\n .addClass('has-help-txt')\n .bind('focus.help', function () {\n var $help = $elem.parent().find('.' + className);\n if ($help.length === 0) {\n $help = $('<span />')\n .addClass(className)\n .addClass('help')\n .addClass('help-block') // twitter bs\n .text(help)\n .hide();\n\n $elem.after($help);\n }\n $help.fadeIn();\n })\n .bind('blur.help', function () {\n $(this)\n .parent()\n .find('.' + className)\n .fadeOut('slow');\n });\n }\n });\n\n return this;\n };\n\n /**\n * @param {Function} cb\n * @param {Object} [conf]\n * @param {Object} [lang]\n */\n $.fn.validate = function(cb, conf, lang) {\n var language = $.extend({}, $.formUtils.LANG, lang || {});\n this.each(function() {\n var $elem = $(this),\n closestFormElem = $elem.closest('form').get(0) || {},\n formDefaultConfig = closestFormElem.validationConfig || $.formUtils.defaultConfig();\n\n $elem.one('validation', function(evt, isValid) {\n if ( typeof cb === 'function' ) {\n cb(isValid, this, evt);\n }\n });\n\n $elem.validateInputOnBlur(\n language,\n $.extend({}, formDefaultConfig, conf || {}),\n true\n );\n });\n };\n\n /**\n * Tells whether or not validation of this input will have to postpone the form submit ()\n * @returns {Boolean}\n */\n $.fn.willPostponeValidation = function() {\n return (this.valAttr('suggestion-nr') ||\n this.valAttr('postpone') ||\n this.hasClass('hasDatepicker')) &&\n !window.postponedValidation;\n };\n\n /**\n * Validate single input when it loses focus\n * shows error message in a span element\n * that is appended to the parent element\n *\n * @param {Object} [language] Optional, will override $.formUtils.LANG\n * @param {Object} [conf] Optional, will override the default settings\n * @param {Boolean} attachKeyupEvent Optional\n * @param {String} eventContext\n * @return {jQuery}\n */\n $.fn.validateInputOnBlur = function (language, conf, attachKeyupEvent, eventContext) {\n\n $.formUtils.eventType = eventContext;\n\n if ( this.willPostponeValidation() ) {\n // This validation has to be postponed\n var _self = this,\n postponeTime = this.valAttr('postpone') || 200;\n\n window.postponedValidation = function () {\n _self.validateInputOnBlur(language, conf, attachKeyupEvent, eventContext);\n window.postponedValidation = false;\n };\n\n setTimeout(function () {\n if (window.postponedValidation) {\n window.postponedValidation();\n }\n }, postponeTime);\n\n return this;\n }\n\n language = $.extend({}, $.formUtils.LANG, language || {});\n $.formUtils.dialogs.removeInputStylingAndMessage(this, conf);\n\n var $elem = this,\n $form = $elem.closest('form'),\n result = $.formUtils.validateInput(\n $elem,\n language,\n conf,\n $form,\n eventContext\n );\n\n var reValidate = function() {\n $elem.validateInputOnBlur(language, conf, false, 'blur.revalidated');\n };\n\n if (eventContext === 'blur') {\n $elem\n .unbind('validation.revalidate', reValidate)\n .one('validation.revalidate', reValidate);\n }\n\n if (attachKeyupEvent) {\n $elem.removeKeyUpValidation();\n }\n\n if (result.shouldChangeDisplay) {\n if (result.isValid) {\n $.formUtils.dialogs.applyInputSuccessStyling($elem, conf);\n } else {\n $.formUtils.dialogs.setInlineMessage($elem, result.errorMsg, conf);\n }\n }\n\n if (!result.isValid && attachKeyupEvent) {\n $elem.validateOnKeyUp(language, conf);\n }\n\n return this;\n };\n\n /**\n * Validate element on keyup-event\n */\n $.fn.validateOnKeyUp = function(language, conf) {\n this.each(function() {\n var $input = $(this);\n if (!$input.valAttr('has-keyup-event')) {\n $input\n .valAttr('has-keyup-event', 'true')\n .bind('keyup.validation', function (evt) {\n if( evt.keyCode !== 9 ) {\n $input.validateInputOnBlur(language, conf, false, 'keyup');\n }\n });\n }\n });\n return this;\n };\n\n /**\n * Remove validation on keyup\n */\n $.fn.removeKeyUpValidation = function() {\n this.each(function() {\n $(this)\n .valAttr('has-keyup-event', false)\n .unbind('keyup.validation');\n });\n return this;\n };\n\n /**\n * Short hand for fetching/adding/removing element attributes\n * prefixed with 'data-validation-'\n *\n * @param {String} name\n * @param {String|Boolean} [val]\n * @return {String|undefined|jQuery}\n * @protected\n */\n $.fn.valAttr = function (name, val) {\n if (val === undefined) {\n return this.attr('data-validation-' + name);\n } else if (val === false || val === null) {\n return this.removeAttr('data-validation-' + name);\n } else {\n name = ((name.length > 0) ? '-' + name : '');\n return this.attr('data-validation' + name, val);\n }\n };\n\n /**\n * Function that validates all inputs in active form\n *\n * @param {Object} [language]\n * @param {Object} [conf]\n * @param {Boolean} [displayError] Defaults to true\n */\n $.fn.isValid = function (language, conf, displayError) {\n\n if ($.formUtils.isLoadingModules) {\n var $self = this;\n setTimeout(function () {\n $self.isValid(language, conf, displayError);\n }, 200);\n return null;\n }\n\n conf = $.extend({}, $.formUtils.defaultConfig(), conf || {});\n language = $.extend({}, $.formUtils.LANG, language || {});\n displayError = displayError !== false;\n\n if ($.formUtils.errorDisplayPreventedWhenHalted) {\n // isValid() was called programmatically with argument displayError set\n // to false when the validation was halted by any of the validators\n delete $.formUtils.errorDisplayPreventedWhenHalted;\n displayError = false;\n }\n\n /**\n * Adds message to error message stack if not already in the message stack\n *\n * @param {String} mess\n * @para {jQuery} $elem\n */\n var addErrorMessage = function (mess, $elem) {\n if ($.inArray(mess, errorMessages) < 0) {\n errorMessages.push(mess);\n }\n errorInputs.push($elem);\n $elem.valAttr('current-error', mess);\n if (displayError) {\n $.formUtils.dialogs.applyInputErrorStyling($elem, conf);\n }\n },\n\n /** Holds inputs (of type checkox or radio) already validated, to prevent recheck of mulitple checkboxes & radios */\n checkedInputs = [],\n\n /** Error messages for this validation */\n errorMessages = [],\n\n /** Input elements which value was not valid */\n errorInputs = [],\n\n /** Form instance */\n $form = this,\n\n /**\n * Tells whether or not to validate element with this name and of this type\n *\n * @param {String} name\n * @param {String} type\n * @return {Boolean}\n */\n ignoreInput = function (name, type) {\n if (type === 'submit' || type === 'button' || type === 'reset') {\n return true;\n }\n return $.inArray(name, conf.ignore || []) > -1;\n };\n\n // Reset style and remove error class\n if (displayError) {\n $.formUtils.dialogs.removeAllMessagesAndStyling($form, conf);\n }\n\n // Validate element values\n $form.find('input,textarea,select').filter(':not([type=\"submit\"],[type=\"button\"])').each(function () {\n var $elem = $(this),\n elementType = $elem.attr('type'),\n isCheckboxOrRadioBtn = elementType === 'radio' || elementType === 'checkbox',\n elementName = $elem.attr('name');\n\n if (!ignoreInput(elementName, elementType) && (!isCheckboxOrRadioBtn || $.inArray(elementName, checkedInputs) < 0)) {\n\n if (isCheckboxOrRadioBtn) {\n checkedInputs.push(elementName);\n }\n\n var result = $.formUtils.validateInput(\n $elem,\n language,\n conf,\n $form,\n 'submit'\n );\n\n if (!result.isValid) {\n addErrorMessage(result.errorMsg, $elem);\n } else if (result.isValid && result.shouldChangeDisplay) {\n $elem.valAttr('current-error', false);\n $.formUtils.dialogs.applyInputSuccessStyling($elem, conf);\n }\n }\n\n });\n\n // Run validation callback\n if (typeof conf.onValidate === 'function') {\n var errors = conf.onValidate($form);\n if ($.isArray(errors)) {\n $.each(errors, function (i, err) {\n addErrorMessage(err.message, err.element);\n });\n }\n else if (errors && errors.element && errors.message) {\n addErrorMessage(errors.message, errors.element);\n }\n }\n\n // Reset form validation flag\n $.formUtils.isValidatingEntireForm = false;\n\n // Validation failed\n if (errorInputs.length > 0) {\n if (displayError) {\n if (conf.errorMessagePosition === 'top') {\n $.formUtils.dialogs.setMessageInTopOfForm($form, errorMessages, conf, language);\n } else {\n $.each(errorInputs, function (i, $input) {\n $.formUtils.dialogs.setInlineMessage($input, $input.valAttr('current-error'), conf);\n });\n }\n if (conf.scrollToTopOnError) {\n $.formUtils.$win.scrollTop($form.offset().top - 20);\n }\n }\n }\n\n if (!displayError && $.formUtils.haltValidation) {\n $.formUtils.errorDisplayPreventedWhenHalted = true;\n }\n\n return errorInputs.length === 0 && !$.formUtils.haltValidation;\n };\n\n /**\n * Plugin for displaying input length restriction\n */\n $.fn.restrictLength = function (maxLengthElement) {\n new $.formUtils.lengthRestriction(this, maxLengthElement);\n return this;\n };\n\n /**\n * Add suggestion dropdown to inputs having data-suggestions with a comma\n * separated string with suggestions\n * @param {Array} [settings]\n * @returns {jQuery}\n */\n $.fn.addSuggestions = function (settings) {\n var sugs = false;\n this.find('input').each(function () {\n var $field = $(this);\n\n sugs = $.split($field.attr('data-suggestions'));\n\n if (sugs.length > 0 && !$field.hasClass('has-suggestions')) {\n $.formUtils.suggest($field, sugs, settings);\n $field.addClass('has-suggestions');\n }\n });\n return this;\n };\n\n\n})(jQuery, window);\n\n/**\n * Utility methods used for handling loading of modules (attached to $.formUtils)\n */\n(function($) {\n\n 'use strict';\n\n $.formUtils = $.extend($.formUtils || {}, {\n\n /**\n * @var {Boolean}\n */\n isLoadingModules: false,\n\n /**\n * @var {Object}\n */\n loadedModules: {},\n\n /**\n * @param {String} name\n */\n registerLoadedModule: function (name) {\n this.loadedModules[$.trim(name).toLowerCase()] = true;\n },\n\n /**\n * @param {String} name\n * @return {Boolean}\n */\n hasLoadedModule: function (name) {\n return $.trim(name).toLowerCase() in this.loadedModules;\n },\n\n /**\n * @example\n * $.formUtils.loadModules('date, security.dev');\n *\n * Will load the scripts date.js and security.dev.js from the\n * directory where this script resides. If you want to load\n * the modules from another directory you can use the\n * path argument.\n *\n * The script will be cached by the browser unless the module\n * name ends with .dev\n *\n * @param {String} modules - Comma separated string with module file names (no directory nor file extension)\n * @param {String} [path] - Path where the module files are located if their not in the same directory as the core modules\n * @param {function} [callback] - Callback invoked when all modules are loaded\n */\n loadModules: function (modules, path, callback) {\n\n if ($.formUtils.isLoadingModules) {\n setTimeout(function () {\n $.formUtils.loadModules(modules, path, callback);\n }, 100);\n return;\n }\n\n var loadModuleScripts = function (modules, path) {\n\n var moduleList = $.split(modules),\n numModules = moduleList.length,\n moduleLoadedCallback = function () {\n numModules--;\n if (numModules === 0) {\n $.formUtils.isLoadingModules = false;\n if (typeof callback === 'function') {\n callback();\n }\n }\n };\n\n if (numModules > 0) {\n $.formUtils.isLoadingModules = true;\n }\n\n var cacheSuffix = '?_=' + ( new Date().getTime() ),\n appendToElement = document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0];\n\n $.each(moduleList, function (i, modName) {\n modName = $.trim(modName);\n if (modName.length === 0 || $.formUtils.hasLoadedModule(modName)) {\n moduleLoadedCallback();\n } else {\n var scriptUrl = path + modName + (modName.slice(-3) === '.js' ? '' : '.js'),\n script = document.createElement('SCRIPT');\n\n if (typeof define === 'function' && define.amd) {\n require([scriptUrl + ( scriptUrl.slice(-7) === '.dev.js' ? cacheSuffix : '' )], moduleLoadedCallback);\n } else {\n // Load the script\n script.type = 'text/javascript';\n script.onload = moduleLoadedCallback;\n script.src = scriptUrl + ( scriptUrl.slice(-7) === '.dev.js' ? cacheSuffix : '' );\n script.onerror = function() {\n $.formUtils.warn('Unable to load form validation module '+scriptUrl, true);\n moduleLoadedCallback();\n };\n script.onreadystatechange = function () {\n // IE 7 fix\n if (this.readyState === 'complete' || this.readyState === 'loaded') {\n moduleLoadedCallback();\n // Handle memory leak in IE\n this.onload = null;\n this.onreadystatechange = null;\n }\n };\n appendToElement.appendChild(script);\n }\n }\n });\n };\n\n if (path) {\n loadModuleScripts(modules, path);\n } else {\n var findScriptPathAndLoadModules = function () {\n var foundPath = false;\n $('script[src*=\"form-validator\"]').each(function () {\n var isScriptFromPluginNodeModulesDirectory = this.src.split('form-validator')[1].split('node_modules').length > 1;\n if (!isScriptFromPluginNodeModulesDirectory) {\n foundPath = this.src.substr(0, this.src.lastIndexOf('/')) + '/';\n if (foundPath === '/') {\n foundPath = '';\n }\n return false;\n }\n });\n\n if (foundPath !== false) {\n loadModuleScripts(modules, foundPath);\n return true;\n }\n return false;\n };\n\n if (!findScriptPathAndLoadModules()) {\n $(function () {\n var hasLoadedModuleScripts = findScriptPathAndLoadModules();\n if (!hasLoadedModuleScripts) {\n // The modules may have been inserted via a minified script\n if (typeof callback === 'function') {\n callback();\n }\n }\n });\n }\n }\n }\n\n });\n\n})(jQuery);\n\n/**\n * Setup function for the plugin\n */\n(function ($) {\n\n 'use strict';\n\n\n /**\n * A bit smarter split function\n * delimiter can be space, comma, dash or pipe\n * @param {String} val\n * @param {Function|String} [callback]\n * @param {Boolean} [allowSpaceAsDelimiter]\n * @returns {Array|void}\n */\n $.split = function (val, callback, allowSpaceAsDelimiter) {\n // default to true\n allowSpaceAsDelimiter = allowSpaceAsDelimiter === undefined || allowSpaceAsDelimiter === true;\n var pattern = '[,|'+(allowSpaceAsDelimiter ? '\\\\s':'')+'-]\\\\s*',\n regex = new RegExp(pattern, 'g');\n if (typeof callback !== 'function') {\n // return array\n if (!val) {\n return [];\n }\n var values = [];\n $.each(val.split(callback ? callback : regex),\n function (i, str) {\n str = $.trim(str);\n if (str.length) {\n values.push(str);\n }\n }\n );\n return values;\n } else if (val) {\n // exec callback func on each\n $.each(val.split(regex),\n function (i, str) {\n str = $.trim(str);\n if (str.length) {\n return callback(str, i);\n }\n }\n );\n }\n };\n\n /**\n * Short hand function that makes the validation setup require less code\n * @param conf\n */\n $.validate = function (conf) {\n\n var defaultConf = $.extend($.formUtils.defaultConfig(), {\n form: 'form',\n validateOnEvent: false,\n validateOnBlur: true,\n validateCheckboxRadioOnClick: true,\n showHelpOnFocus: true,\n addSuggestions: true,\n modules: '',\n onModulesLoaded: null,\n language: false,\n onSuccess: false,\n onError: false,\n onElementValidate: false\n });\n\n conf = $.extend(defaultConf, conf || {});\n\n $(window).trigger('formValidationPluginInit', [conf]);\n\n if( conf.lang && conf.lang !== 'en' ) {\n var langModule = 'lang/'+conf.lang+'.js';\n conf.modules += conf.modules.length ? ','+langModule : langModule;\n }\n\n // Add validation to forms\n $(conf.form).each(function (i, form) {\n\n // Make a reference to the config for this form\n form.validationConfig = conf;\n\n // Trigger jQuery event that we're about to setup validation\n var $form = $(form);\n $form.trigger('formValidationSetup', [$form, conf]);\n\n // Remove classes and event handlers that might have been\n // added by a previous call to $.validate\n $form.find('.has-help-txt')\n .unbind('focus.validation')\n .unbind('blur.validation');\n\n $form\n .removeClass('has-validation-callback')\n .unbind('submit.validation')\n .unbind('reset.validation')\n .find('input[data-validation],textarea[data-validation]')\n .unbind('blur.validation');\n\n // Validate when submitted\n $form.bind('submit.validation', function (evt) {\n\n var $form = $(this),\n stop = function() {\n evt.stopImmediatePropagation();\n return false;\n };\n\n if ($.formUtils.haltValidation) {\n // pressing several times on submit button while validation is halted\n return stop();\n }\n\n if ($.formUtils.isLoadingModules) {\n setTimeout(function () {\n $form.trigger('submit.validation');\n }, 200);\n return stop();\n }\n\n var valid = $form.isValid(conf.language, conf);\n if ($.formUtils.haltValidation) {\n // Validation got halted by one of the validators\n return stop();\n } else {\n if (valid && typeof conf.onSuccess === 'function') {\n var callbackResponse = conf.onSuccess($form);\n if (callbackResponse === false) {\n return stop();\n }\n } else if (!valid && typeof conf.onError === 'function') {\n conf.onError($form);\n return stop();\n } else {\n return valid ? true : stop();\n }\n }\n })\n .bind('reset.validation', function () {\n $.formUtils.dialogs.removeAllMessagesAndStyling($form, conf);\n })\n .addClass('has-validation-callback');\n\n if (conf.showHelpOnFocus) {\n $form.showHelpOnFocus();\n }\n if (conf.addSuggestions) {\n $form.addSuggestions();\n }\n if (conf.validateOnBlur) {\n $form.validateOnBlur(conf.language, conf);\n $form.bind('html5ValidationAttrsFound', function () {\n $form.validateOnBlur(conf.language, conf);\n });\n }\n if (conf.validateOnEvent) {\n $form.validateOnEvent(conf.language, conf);\n }\n });\n\n if (conf.modules !== '') {\n $.formUtils.loadModules(conf.modules, null, function() {\n if (typeof conf.onModulesLoaded === 'function') {\n conf.onModulesLoaded();\n }\n var $form = typeof conf.form === 'string' ? $(conf.form) : conf.form;\n $.formUtils.$win.trigger('validatorsLoaded', [$form, conf]);\n });\n }\n };\n\n})(jQuery);\n\n/**\n * Utility methods and properties attached to $.formUtils\n */\n(function($, window) {\n\n 'use strict';\n\n var $win = $(window);\n\n $.formUtils = $.extend($.formUtils || {}, {\n\n $win: $win,\n\n /**\n * Default config for $(...).isValid();\n */\n defaultConfig: function () {\n return {\n ignore: [], // Names of inputs not to be validated even though `validationRuleAttribute` containing the validation rules tells us to\n errorElementClass: 'error', // Class that will be put on elements which value is invalid\n successElementClass: 'valid', // Class that will be put on elements that has been validated with success\n borderColorOnError: '#b94a48', // Border color of elements which value is invalid, empty string to not change border color\n errorMessageClass: 'form-error', // class name of div containing error messages when validation fails\n validationRuleAttribute: 'data-validation', // name of the attribute holding the validation rules\n validationErrorMsgAttribute: 'data-validation-error-msg', // define custom err msg inline with element\n errorMessagePosition: 'inline', // Can be either \"top\" or \"inline\"\n errorMessageTemplate: {\n container: '<div class=\"{errorMessageClass} alert alert-danger\">{messages}</div>',\n messages: '<strong>{errorTitle}</strong><ul>{fields}</ul>',\n field: '<li>{msg}</li>'\n },\n scrollToTopOnError: true,\n dateFormat: 'yyyy-mm-dd',\n addValidClassOnAll: false, // whether or not to apply class=\"valid\" even if the input wasn't validated\n decimalSeparator: '.',\n inputParentClassOnError: 'has-error', // twitter-bootstrap default class name\n inputParentClassOnSuccess: 'has-success', // twitter-bootstrap default class name\n validateHiddenInputs: false, // whether or not hidden inputs should be validated\n inlineErrorMessageCallback: false,\n submitErrorMessageCallback: false\n };\n },\n\n /**\n * Available validators\n */\n validators: {},\n\n /**\n * Events triggered by form validator\n */\n _events: {load: [], valid: [], invalid: []},\n\n /**\n * Setting this property to true during validation will\n * stop further validation from taking place and form will\n * not be sent\n */\n haltValidation: false,\n\n /**\n * Function for adding a validator\n * @see $.formUtils.addAsyncValidator (async.js)\n * @param {Object} validator\n */\n addValidator: function (validator) {\n // prefix with \"validate_\" for backward compatibility reasons\n var name = validator.name.indexOf('validate_') === 0 ? validator.name : 'validate_' + validator.name;\n if (validator.validateOnKeyUp === undefined) {\n validator.validateOnKeyUp = true;\n }\n this.validators[name] = validator;\n },\n\n /**\n * Warn user via the console if available\n */\n warn: function(msg, fallbackOnAlert) {\n if( 'console' in window ) {\n if( typeof window.console.warn === 'function' ) {\n window.console.warn(msg);\n } else if( typeof window.console.log === 'function' ) {\n window.console.log(msg);\n }\n } else if (fallbackOnAlert) {\n // This is for some old IE version...\n alert(msg);\n }\n },\n\n /**\n * Same as input $.fn.val() but also supporting input of typ radio or checkbox\n * @example\n *\n * $.formUtils.getValue('.myRadioButtons', $('#some-form'));\n * $.formUtils.getValue($('#some-form').find('.check-boxes'));\n *\n * @param query\n * @param $parent\n * @returns {String|Boolean}\n */\n getValue: function(query, $parent) {\n var $inputs = $parent ? $parent.find(query) : query;\n if ($inputs.length > 0 ) {\n var type = $inputs.eq(0).attr('type');\n if (type === 'radio' || type === 'checkbox') {\n return $inputs.filter(':checked').val() || '';\n } else {\n return $inputs.val() || '';\n }\n }\n return false;\n },\n\n /**\n * Validate the value of given element according to the validation rules\n * found in the attribute data-validation. Will return an object representing\n * a validation result, having the props shouldChangeDisplay, isValid and errorMsg\n * @param {jQuery} $elem\n * @param {Object} language ($.formUtils.LANG)\n * @param {Object} conf\n * @param {jQuery} $form\n * @param {String} [eventContext]\n * @return {Object}\n */\n validateInput: function ($elem, language, conf, $form, eventContext) {\n\n conf = conf || $.formUtils.defaultConfig();\n language = language || $.formUtils.LANG;\n\n if (!$form.length) {\n $form = $elem.parent();\n }\n\n var value = this.getValue($elem);\n\n $elem\n .valAttr('skipped', false)\n .one('beforeValidation', function() {\n // Skip input because its hidden or disabled\n // Doing this in a callback makes it possible for others to prevent the default\n // behaviour by binding to the same event and call evt.stopImmediatePropagation()\n if ($elem.attr('disabled') || (!$elem.is(':visible') && !conf.validateHiddenInputs)) {\n $elem.valAttr('skipped', 1);\n }\n })\n .trigger('beforeValidation', [value, language, conf]);\n\n var inputIsOptional = $elem.valAttr('optional') === 'true',\n skipBecauseItsEmpty = !value && inputIsOptional,\n validationRules = $elem.attr(conf.validationRuleAttribute),\n isValid = true,\n errorMsg = '',\n result = {isValid: true, shouldChangeDisplay:true, errorMsg:''};\n\n // For input type=\"number\", browsers attempt to parse the entered value into a number.\n // If the input is not numeric, browsers handle the situation differently:\n // Chrome 48 simply disallows non-numeric input; FF 44 clears out the input box on blur;\n // Safari 5 parses the entered string to find a leading number.\n // If the input fails browser validation, the browser sets the input value equal to an empty string.\n // Therefore, we cannot distinguish (apart from hacks) between an empty input type=\"text\" and one with a\n // value that can't be parsed by the browser.\n\n if (!validationRules || skipBecauseItsEmpty || $elem.valAttr('skipped')) {\n result.shouldChangeDisplay = conf.addValidClassOnAll;\n return result;\n }\n\n // Filter out specified characters\n var ignore = $elem.valAttr('ignore');\n if (ignore) {\n $.each(ignore.split(''), function(i, character) {\n value = value.replace(new RegExp('\\\\'+character, 'g'), '');\n });\n }\n\n $.split(validationRules, function (rule) {\n\n if (rule.indexOf('validate_') !== 0) {\n rule = 'validate_' + rule;\n }\n\n var validator = $.formUtils.validators[rule];\n\n if (validator) {\n\n // special change of element for checkbox_group rule\n if (rule === 'validate_checkbox_group') {\n // set element to first in group, so error msg attr doesn't need to be set on all elements in group\n $elem = $form.find('[name=\"' + $elem.attr('name') + '\"]:eq(0)');\n }\n\n if (eventContext !== 'keyup' || validator.validateOnKeyUp) {\n // A validator can prevent itself from getting triggered on keyup\n isValid = validator.validatorFunction(value, $elem, conf, language, $form, eventContext);\n }\n\n if (!isValid) {\n if (conf.validateOnBlur) {\n $elem.validateOnKeyUp(language, conf);\n }\n errorMsg = $.formUtils.dialogs.resolveErrorMessage($elem, validator, rule, conf, language);\n return false; // break iteration\n }\n\n } else {\n\n // todo: Add some validator lookup function and tell immediately which module is missing\n throw new Error('Using undefined validator \"' + rule +\n '\". Maybe you have forgotten to load the module that \"' + rule +'\" belongs to?');\n\n }\n\n });\n\n\n if (isValid === false) {\n $elem.trigger('validation', false);\n result.errorMsg = errorMsg;\n result.isValid = false;\n result.shouldChangeDisplay = true;\n } else if (isValid === null) {\n // A validatorFunction returning null means that it's not able to validate\n // the input at this time. Most probably some async stuff need to gets finished\n // first and then the validator will re-trigger the validation.\n result.shouldChangeDisplay = false;\n } else {\n $elem.trigger('validation', true);\n result.shouldChangeDisplay = true;\n }\n\n // Run element validation callback\n if (typeof conf.onElementValidate === 'function' && errorMsg !== null) {\n conf.onElementValidate(result.isValid, $elem, $form, errorMsg);\n }\n\n $elem.trigger('afterValidation', [result, eventContext]);\n\n return result;\n },\n\n /**\n * Is it a correct date according to given dateFormat. Will return false if not, otherwise\n * an array 0=>year 1=>month 2=>day\n *\n * @param {String} val\n * @param {String} dateFormat\n * @param {Boolean} [addMissingLeadingZeros]\n * @return {Array}|{Boolean}\n */\n parseDate: function (val, dateFormat, addMissingLeadingZeros) {\n var divider = dateFormat.replace(/[a-zA-Z]/gi, '').substring(0, 1),\n regexp = '^',\n formatParts = dateFormat.split(divider || null),\n matches, day, month, year;\n\n $.each(formatParts, function (i, part) {\n regexp += (i > 0 ? '\\\\' + divider : '') + '(\\\\d{' + part.length + '})';\n });\n\n regexp += '$';\n\n if (addMissingLeadingZeros) {\n var newValueParts = [];\n $.each(val.split(divider), function(i, part) {\n if(part.length === 1) {\n part = '0'+part;\n }\n newValueParts.push(part);\n });\n val = newValueParts.join(divider);\n }\n\n matches = val.match(new RegExp(regexp));\n if (matches === null) {\n return false;\n }\n\n var findDateUnit = function (unit, formatParts, matches) {\n for (var i = 0; i < formatParts.length; i++) {\n if (formatParts[i].substring(0, 1) === unit) {\n return $.formUtils.parseDateInt(matches[i + 1]);\n }\n }\n return -1;\n };\n\n month = findDateUnit('m', formatParts, matches);\n day = findDateUnit('d', formatParts, matches);\n year = findDateUnit('y', formatParts, matches);\n\n if ((month === 2 && day > 28 && (year % 4 !== 0 || year % 100 === 0 && year % 400 !== 0)) ||\n (month === 2 && day > 29 && (year % 4 === 0 || year % 100 !== 0 && year % 400 === 0)) ||\n month > 12 || month === 0) {\n return false;\n }\n if ((this.isShortMonth(month) && day > 30) || (!this.isShortMonth(month) && day > 31) || day === 0) {\n return false;\n }\n\n return [year, month, day];\n },\n\n /**\n * skum fix. är talet 05 eller lägre ger parseInt rätt int annars får man 0 när man kör parseInt?\n *\n * @param {String} val\n * @return {Number}\n */\n parseDateInt: function (val) {\n if (val.indexOf('0') === 0) {\n val = val.replace('0', '');\n }\n return parseInt(val, 10);\n },\n\n /**\n * Has month only 30 days?\n *\n * @param {Number} m\n * @return {Boolean}\n */\n isShortMonth: function (m) {\n return (m % 2 === 0 && m < 7) || (m % 2 !== 0 && m > 7);\n },\n\n /**\n * Restrict input length\n *\n * @param {jQuery} $inputElement Jquery Html object\n * @param {jQuery} $maxLengthElement jQuery Html Object\n * @return void\n */\n lengthRestriction: function ($inputElement, $maxLengthElement) {\n // read maxChars from counter display initial text value\n var maxChars = parseInt($maxLengthElement.text(), 10),\n charsLeft = 0,\n\n // internal function does the counting and sets display value\n countCharacters = function () {\n var numChars = $inputElement.val().length;\n if (numChars > maxChars) {\n // get current scroll bar position\n var currScrollTopPos = $inputElement.scrollTop();\n // trim value to max length\n $inputElement.val($inputElement.val().substring(0, maxChars));\n $inputElement.scrollTop(currScrollTopPos);\n }\n charsLeft = maxChars - numChars;\n if (charsLeft < 0) {\n charsLeft = 0;\n }\n\n // set counter text\n $maxLengthElement.text(charsLeft);\n };\n\n // bind events to this element\n // setTimeout is needed, cut or paste fires before val is available\n $($inputElement).bind('keydown keyup keypress focus blur', countCharacters)\n .bind('cut paste', function () {\n setTimeout(countCharacters, 100);\n });\n\n // count chars on pageload, if there are prefilled input-values\n $(document).bind('ready', countCharacters);\n },\n\n /**\n * Test numeric against allowed range\n *\n * @param $value int\n * @param $rangeAllowed str; (1-2, min1, max2, 10)\n * @return array\n */\n numericRangeCheck: function (value, rangeAllowed) {\n // split by dash\n var range = $.split(rangeAllowed),\n // min or max\n minmax = parseInt(rangeAllowed.substr(3), 10);\n\n if( range.length === 1 && rangeAllowed.indexOf('min') === -1 && rangeAllowed.indexOf('max') === -1 ) {\n range = [rangeAllowed, rangeAllowed]; // only a number, checking agains an exact number of characters\n }\n\n // range ?\n if (range.length === 2 && (value < parseInt(range[0], 10) || value > parseInt(range[1], 10) )) {\n return [ 'out', range[0], range[1] ];\n } // value is out of range\n else if (rangeAllowed.indexOf('min') === 0 && (value < minmax )) // min\n {\n return ['min', minmax];\n } // value is below min\n else if (rangeAllowed.indexOf('max') === 0 && (value > minmax )) // max\n {\n return ['max', minmax];\n } // value is above max\n // since no other returns executed, value is in allowed range\n return [ 'ok' ];\n },\n\n\n _numSuggestionElements: 0,\n _selectedSuggestion: null,\n _previousTypedVal: null,\n\n /**\n * Utility function that can be used to create plugins that gives\n * suggestions when inputs is typed into\n * @param {jQuery} $elem\n * @param {Array} suggestions\n * @param {Object} settings - Optional\n * @return {jQuery}\n */\n suggest: function ($elem, suggestions, settings) {\n var conf = {\n css: {\n maxHeight: '150px',\n background: '#FFF',\n lineHeight: '150%',\n textDecoration: 'underline',\n overflowX: 'hidden',\n overflowY: 'auto',\n border: '#CCC solid 1px',\n borderTop: 'none',\n cursor: 'pointer'\n },\n activeSuggestionCSS: {\n background: '#E9E9E9'\n }\n },\n setSuggsetionPosition = function ($suggestionContainer, $input) {\n var offset = $input.offset();\n $suggestionContainer.css({\n width: $input.outerWidth(),\n left: offset.left + 'px',\n top: (offset.top + $input.outerHeight()) + 'px'\n });\n };\n\n if (settings) {\n $.extend(conf, settings);\n }\n\n conf.css.position = 'absolute';\n conf.css['z-index'] = 9999;\n $elem.attr('autocomplete', 'off');\n\n if (this._numSuggestionElements === 0) {\n // Re-position suggestion container if window size changes\n $win.bind('resize', function () {\n $('.jquery-form-suggestions').each(function () {\n var $container = $(this),\n suggestID = $container.attr('data-suggest-container');\n setSuggsetionPosition($container, $('.suggestions-' + suggestID).eq(0));\n });\n });\n }\n\n this._numSuggestionElements++;\n\n var onSelectSuggestion = function ($el) {\n var suggestionId = $el.valAttr('suggestion-nr');\n $.formUtils._selectedSuggestion = null;\n $.formUtils._previousTypedVal = null;\n $('.jquery-form-suggestion-' + suggestionId).fadeOut('fast');\n };\n\n $elem\n .data('suggestions', suggestions)\n .valAttr('suggestion-nr', this._numSuggestionElements)\n .unbind('focus.suggest')\n .bind('focus.suggest', function () {\n $(this).trigger('keyup');\n $.formUtils._selectedSuggestion = null;\n })\n .unbind('keyup.suggest')\n .bind('keyup.suggest', function () {\n var $input = $(this),\n foundSuggestions = [],\n val = $.trim($input.val()).toLocaleLowerCase();\n\n if (val === $.formUtils._previousTypedVal) {\n return;\n }\n else {\n $.formUtils._previousTypedVal = val;\n }\n\n var hasTypedSuggestion = false,\n suggestionId = $input.valAttr('suggestion-nr'),\n $suggestionContainer = $('.jquery-form-suggestion-' + suggestionId);\n\n $suggestionContainer.scrollTop(0);\n\n // Find the right suggestions\n if (val !== '') {\n var findPartial = val.length > 2;\n $.each($input.data('suggestions'), function (i, suggestion) {\n var lowerCaseVal = suggestion.toLocaleLowerCase();\n if (lowerCaseVal === val) {\n foundSuggestions.push('<strong>' + suggestion + '</strong>');\n hasTypedSuggestion = true;\n return false;\n } else if (lowerCaseVal.indexOf(val) === 0 || (findPartial && lowerCaseVal.indexOf(val) > -1)) {\n foundSuggestions.push(suggestion.replace(new RegExp(val, 'gi'), '<strong>$&</strong>'));\n }\n });\n }\n\n // Hide suggestion container\n if (hasTypedSuggestion || (foundSuggestions.length === 0 && $suggestionContainer.length > 0)) {\n $suggestionContainer.hide();\n }\n\n // Create suggestion container if not already exists\n else if (foundSuggestions.length > 0 && $suggestionContainer.length === 0) {\n $suggestionContainer = $('<div></div>').css(conf.css).appendTo('body');\n $elem.addClass('suggestions-' + suggestionId);\n $suggestionContainer\n .attr('data-suggest-container', suggestionId)\n .addClass('jquery-form-suggestions')\n .addClass('jquery-form-suggestion-' + suggestionId);\n }\n\n // Show hidden container\n else if (foundSuggestions.length > 0 && !$suggestionContainer.is(':visible')) {\n $suggestionContainer.show();\n }\n\n // add suggestions\n if (foundSuggestions.length > 0 && val.length !== foundSuggestions[0].length) {\n\n // put container in place every time, just in case\n setSuggsetionPosition($suggestionContainer, $input);\n\n // Add suggestions HTML to container\n $suggestionContainer.html('');\n $.each(foundSuggestions, function (i, text) {\n $('<div></div>')\n .append(text)\n .css({\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n padding: '5px'\n })\n .addClass('form-suggest-element')\n .appendTo($suggestionContainer)\n .click(function () {\n $input.focus();\n $input.val($(this).text());\n $input.trigger('change');\n onSelectSuggestion($input);\n });\n });\n }\n })\n .unbind('keydown.validation')\n .bind('keydown.validation', function (e) {\n var code = (e.keyCode ? e.keyCode : e.which),\n suggestionId,\n $suggestionContainer,\n $input = $(this);\n\n if (code === 13 && $.formUtils._selectedSuggestion !== null) {\n suggestionId = $input.valAttr('suggestion-nr');\n $suggestionContainer = $('.jquery-form-suggestion-' + suggestionId);\n if ($suggestionContainer.length > 0) {\n var newText = $suggestionContainer.find('div').eq($.formUtils._selectedSuggestion).text();\n $input.val(newText);\n $input.trigger('change');\n onSelectSuggestion($input);\n e.preventDefault();\n }\n }\n else {\n suggestionId = $input.valAttr('suggestion-nr');\n $suggestionContainer = $('.jquery-form-suggestion-' + suggestionId);\n var $suggestions = $suggestionContainer.children();\n if ($suggestions.length > 0 && $.inArray(code, [38, 40]) > -1) {\n if (code === 38) { // key up\n if ($.formUtils._selectedSuggestion === null) {\n $.formUtils._selectedSuggestion = $suggestions.length - 1;\n }\n else{\n $.formUtils._selectedSuggestion--;\n }\n if ($.formUtils._selectedSuggestion < 0) {\n $.formUtils._selectedSuggestion = $suggestions.length - 1;\n }\n }\n else if (code === 40) { // key down\n if ($.formUtils._selectedSuggestion === null) {\n $.formUtils._selectedSuggestion = 0;\n }\n else {\n $.formUtils._selectedSuggestion++;\n }\n if ($.formUtils._selectedSuggestion > ($suggestions.length - 1)) {\n $.formUtils._selectedSuggestion = 0;\n }\n }\n\n // Scroll in suggestion window\n var containerInnerHeight = $suggestionContainer.innerHeight(),\n containerScrollTop = $suggestionContainer.scrollTop(),\n suggestionHeight = $suggestionContainer.children().eq(0).outerHeight(),\n activeSuggestionPosY = suggestionHeight * ($.formUtils._selectedSuggestion);\n\n if (activeSuggestionPosY < containerScrollTop || activeSuggestionPosY > (containerScrollTop + containerInnerHeight)) {\n $suggestionContainer.scrollTop(activeSuggestionPosY);\n }\n\n $suggestions\n .removeClass('active-suggestion')\n .css('background', 'none')\n .eq($.formUtils._selectedSuggestion)\n .addClass('active-suggestion')\n .css(conf.activeSuggestionCSS);\n\n e.preventDefault();\n return false;\n }\n }\n })\n .unbind('blur.suggest')\n .bind('blur.suggest', function () {\n onSelectSuggestion($(this));\n });\n\n return $elem;\n },\n\n /**\n * Error dialogs\n *\n * @var {Object}\n */\n LANG: {\n errorTitle: 'Form submission failed!',\n requiredField: 'This is a required field',\n requiredFields: 'You have not answered all required fields',\n badTime: 'You have not given a correct time',\n badEmail: 'You have not given a correct e-mail address',\n badTelephone: 'You have not given a correct phone number',\n badSecurityAnswer: 'You have not given a correct answer to the security question',\n badDate: 'You have not given a correct date',\n lengthBadStart: 'The input value must be between ',\n lengthBadEnd: ' characters',\n lengthTooLongStart: 'The input value is longer than ',\n lengthTooShortStart: 'The input value is shorter than ',\n notConfirmed: 'Input values could not be confirmed',\n badDomain: 'Incorrect domain value',\n badUrl: 'The input value is not a correct URL',\n badCustomVal: 'The input value is incorrect',\n andSpaces: ' and spaces ',\n badInt: 'The input value was not a correct number',\n badSecurityNumber: 'Your social security number was incorrect',\n badUKVatAnswer: 'Incorrect UK VAT Number',\n badUKNin: 'Incorrect UK NIN',\n badUKUtr: 'Incorrect UK UTR Number',\n badStrength: 'The password isn\\'t strong enough',\n badNumberOfSelectedOptionsStart: 'You have to choose at least ',\n badNumberOfSelectedOptionsEnd: ' answers',\n badAlphaNumeric: 'The input value can only contain alphanumeric characters ',\n badAlphaNumericExtra: ' and ',\n wrongFileSize: 'The file you are trying to upload is too large (max %s)',\n wrongFileType: 'Only files of type %s is allowed',\n groupCheckedRangeStart: 'Please choose between ',\n groupCheckedTooFewStart: 'Please choose at least ',\n groupCheckedTooManyStart: 'Please choose a maximum of ',\n groupCheckedEnd: ' item(s)',\n badCreditCard: 'The credit card number is not correct',\n badCVV: 'The CVV number was not correct',\n wrongFileDim : 'Incorrect image dimensions,',\n imageTooTall : 'the image can not be taller than',\n imageTooWide : 'the image can not be wider than',\n imageTooSmall : 'the image was too small',\n min : 'min',\n max : 'max',\n imageRatioNotAccepted : 'Image ratio is not be accepted',\n badBrazilTelephoneAnswer: 'The phone number entered is invalid',\n badBrazilCEPAnswer: 'The CEP entered is invalid',\n badBrazilCPFAnswer: 'The CPF entered is invalid',\n badPlPesel: 'The PESEL entered is invalid',\n badPlNip: 'The NIP entered is invalid',\n badPlRegon: 'The REGON entered is invalid',\n badreCaptcha: 'Please confirm that you are not a bot',\n passwordComplexityStart: 'Password must contain at least ',\n passwordComplexitySeparator: ', ',\n passwordComplexityUppercaseInfo: ' uppercase letter(s)',\n passwordComplexityLowercaseInfo: ' lowercase letter(s)',\n passwordComplexitySpecialCharsInfo: ' special character(s)',\n passwordComplexityNumericCharsInfo: ' numeric character(s)',\n passwordComplexityEnd: '.'\n }\n });\n\n})(jQuery, window);\n\n/**\n * File declaring all default validators.\n */\n(function($) {\n\n /*\n * Validate email\n */\n $.formUtils.addValidator({\n name: 'email',\n validatorFunction: function (email) {\n\n var emailParts = email.toLowerCase().split('@'),\n localPart = emailParts[0],\n domain = emailParts[1];\n\n if (localPart && domain) {\n\n if( localPart.indexOf('\"') === 0 ) {\n var len = localPart.length;\n localPart = localPart.replace(/\\\"/g, '');\n if( localPart.length !== (len-2) ) {\n return false; // It was not allowed to have more than two apostrophes\n }\n }\n\n return $.formUtils.validators.validate_domain.validatorFunction(emailParts[1]) &&\n localPart.indexOf('.') !== 0 &&\n localPart.substring(localPart.length-1, localPart.length) !== '.' &&\n localPart.indexOf('..') === -1 &&\n !(/[^\\w\\+\\.\\-\\#\\-\\_\\~\\!\\$\\&\\'\\(\\)\\*\\+\\,\\;\\=\\:]/.test(localPart));\n }\n\n return false;\n },\n errorMessage: '',\n errorMessageKey: 'badEmail'\n });\n\n /*\n * Validate domain name\n */\n $.formUtils.addValidator({\n name: 'domain',\n validatorFunction: function (val) {\n return val.length > 0 &&\n val.length <= 253 && // Including sub domains\n !(/[^a-zA-Z0-9]/.test(val.slice(-2))) && !(/[^a-zA-Z0-9]/.test(val.substr(0, 1))) && !(/[^a-zA-Z0-9\\.\\-]/.test(val)) &&\n val.split('..').length === 1 &&\n val.split('.').length > 1;\n },\n errorMessage: '',\n errorMessageKey: 'badDomain'\n });\n\n /*\n * Validate required\n */\n $.formUtils.addValidator({\n name: 'required',\n validatorFunction: function (val, $el, config, language, $form) {\n switch ($el.attr('type')) {\n case 'checkbox':\n return $el.is(':checked');\n case 'radio':\n return $form.find('input[name=\"' + $el.attr('name') + '\"]').filter(':checked').length > 0;\n default:\n return $.trim(val) !== '';\n }\n },\n errorMessage: '',\n errorMessageKey: function(config) {\n if (config.errorMessagePosition === 'top' || typeof config.errorMessagePosition === 'function') {\n return 'requiredFields';\n }\n else {\n return 'requiredField';\n }\n }\n });\n\n /*\n * Validate length range\n */\n $.formUtils.addValidator({\n name: 'length',\n validatorFunction: function (val, $el, conf, lang) {\n var lengthAllowed = $el.valAttr('length'),\n type = $el.attr('type');\n\n if (lengthAllowed === undefined) {\n alert('Please add attribute \"data-validation-length\" to ' + $el[0].nodeName + ' named ' + $el.attr('name'));\n return true;\n }\n\n // check if length is above min, below max or within range.\n var len = type === 'file' && $el.get(0).files !== undefined ? $el.get(0).files.length : val.length,\n lengthCheckResults = $.formUtils.numericRangeCheck(len, lengthAllowed),\n checkResult;\n\n switch (lengthCheckResults[0]) { // outside of allowed range\n case 'out':\n this.errorMessage = lang.lengthBadStart + lengthAllowed + lang.lengthBadEnd;\n checkResult = false;\n break;\n // too short\n case 'min':\n this.errorMessage = lang.lengthTooShortStart + lengthCheckResults[1] + lang.lengthBadEnd;\n checkResult = false;\n break;\n // too long\n case 'max':\n this.errorMessage = lang.lengthTooLongStart + lengthCheckResults[1] + lang.lengthBadEnd;\n checkResult = false;\n break;\n // ok\n default:\n checkResult = true;\n }\n\n return checkResult;\n },\n errorMessage: '',\n errorMessageKey: ''\n });\n\n /*\n * Validate url\n */\n $.formUtils.addValidator({\n name: 'url',\n validatorFunction: function (url) {\n // written by Scott Gonzalez: http://projects.scottsplayground.com/iri/\n // - Victor Jonsson added support for arrays in the url ?arg[]=sdfsdf\n // - General improvements made by Stéphane Moureau <https://github.com/TraderStf>\n\n var urlFilter = /^(https?|ftp):\\/\\/((((\\w|-|\\.|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:)*@)?(((\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5]))|((([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])(\\w|-|\\.|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.)+(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])(\\w|-|\\.|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.?)(:\\d*)?)(\\/(((\\w|-|\\.|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:|@)+(\\/((\\w|-|\\.|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:|@)*)*)?)?(\\?((([a-z]|\\d|\\[|\\]|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:|@)|[\\uE000-\\uF8FF]|\\/|\\?)*)?(\\#(((\\w|-|\\.|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:|@)|\\/|\\?)*)?$/i;\n if (urlFilter.test(url)) {\n var domain = url.split('://')[1],\n domainSlashPos = domain.indexOf('/');\n\n if (domainSlashPos > -1) {\n domain = domain.substr(0, domainSlashPos);\n }\n\n return $.formUtils.validators.validate_domain.validatorFunction(domain); // todo: add support for IP-addresses\n }\n return false;\n },\n errorMessage: '',\n errorMessageKey: 'badUrl'\n });\n\n /*\n * Validate number (floating or integer)\n */\n $.formUtils.addValidator({\n name: 'number',\n validatorFunction: function (val, $el, conf) {\n if (val !== '') {\n var allowing = $el.valAttr('allowing') || '',\n decimalSeparator = $el.valAttr('decimal-separator') || conf.decimalSeparator,\n allowsRange = false,\n begin, end,\n steps = $el.valAttr('step') || '',\n allowsSteps = false,\n sanitize = $el.attr('data-sanitize') || '',\n isFormattedWithNumeral = sanitize.match(/(^|[\\s])numberFormat([\\s]|$)/i);\n\n if (isFormattedWithNumeral) {\n if (!window.numeral) {\n throw new ReferenceError('The data-sanitize value numberFormat cannot be used without the numeral' +\n ' library. Please see Data Validation in http://www.formvalidator.net for more information.');\n }\n //Unformat input first, then convert back to String\n if (val.length) {\n val = String(numeral().unformat(val));\n }\n }\n\n if (allowing.indexOf('number') === -1) {\n allowing += ',number';\n }\n\n if (allowing.indexOf('negative') === -1 && val.indexOf('-') === 0) {\n return false;\n }\n\n if (allowing.indexOf('range') > -1) {\n begin = parseFloat(allowing.substring(allowing.indexOf('[') + 1, allowing.indexOf(';')));\n end = parseFloat(allowing.substring(allowing.indexOf(';') + 1, allowing.indexOf(']')));\n allowsRange = true;\n }\n\n if (steps !== '') {\n allowsSteps = true;\n }\n\n if (decimalSeparator === ',') {\n if (val.indexOf('.') > -1) {\n return false;\n }\n // Fix for checking range with floats using ,\n val = val.replace(',', '.');\n }\n if (val.replace(/[0-9-]/g, '') === '' && (!allowsRange || (val >= begin && val <= end)) && (!allowsSteps || (val % steps === 0))) {\n return true;\n }\n\n if (allowing.indexOf('float') > -1 && val.match(new RegExp('^([0-9-]+)\\\\.([0-9]+)$')) !== null && (!allowsRange || (val >= begin && val <= end)) && (!allowsSteps || (val % steps === 0))) {\n return true;\n }\n }\n return false;\n },\n errorMessage: '',\n errorMessageKey: 'badInt'\n });\n\n /*\n * Validate alpha numeric\n */\n $.formUtils.addValidator({\n name: 'alphanumeric',\n validatorFunction: function (val, $el, conf, language) {\n var patternStart = '^([a-zA-Z0-9',\n patternEnd = ']+)$',\n additionalChars = $el.valAttr('allowing'),\n pattern = '',\n hasSpaces = false;\n\n if (additionalChars) {\n pattern = patternStart + additionalChars + patternEnd;\n var extra = additionalChars.replace(/\\\\/g, '');\n if (extra.indexOf(' ') > -1) {\n hasSpaces = true;\n extra = extra.replace(' ', '');\n extra += language.andSpaces || $.formUtils.LANG.andSpaces;\n }\n\n if(language.badAlphaNumericAndExtraAndSpaces && language.badAlphaNumericAndExtra) {\n if(hasSpaces) {\n this.errorMessage = language.badAlphaNumericAndExtraAndSpaces + extra; \n } else {\n this.errorMessage = language.badAlphaNumericAndExtra + extra + language.badAlphaNumericExtra; \n }\n } else {\n this.errorMessage = language.badAlphaNumeric + language.badAlphaNumericExtra + extra;\n }\n } else {\n pattern = patternStart + patternEnd;\n this.errorMessage = language.badAlphaNumeric;\n }\n\n return new RegExp(pattern).test(val);\n },\n errorMessage: '',\n errorMessageKey: ''\n });\n\n /*\n * Validate against regexp\n */\n $.formUtils.addValidator({\n name: 'custom',\n validatorFunction: function (val, $el) {\n var regexp = new RegExp($el.valAttr('regexp'));\n return regexp.test(val);\n },\n errorMessage: '',\n errorMessageKey: 'badCustomVal'\n });\n\n /*\n * Validate date\n */\n $.formUtils.addValidator({\n name: 'date',\n validatorFunction: function (date, $el, conf) {\n var dateFormat = $el.valAttr('format') || conf.dateFormat || 'yyyy-mm-dd',\n addMissingLeadingZeros = $el.valAttr('require-leading-zero') === 'false';\n return $.formUtils.parseDate(date, dateFormat, addMissingLeadingZeros) !== false;\n },\n errorMessage: '',\n errorMessageKey: 'badDate'\n });\n\n\n /*\n * Validate group of checkboxes, validate qty required is checked\n * written by Steve Wasiura : http://stevewasiura.waztech.com\n * element attrs\n * data-validation=\"checkbox_group\"\n * data-validation-qty=\"1-2\" // min 1 max 2\n * data-validation-error-msg=\"chose min 1, max of 2 checkboxes\"\n */\n $.formUtils.addValidator({\n name: 'checkbox_group',\n validatorFunction: function (val, $el, conf, lang, $form) {\n // preset return var\n var isValid = true,\n // get name of element. since it is a checkbox group, all checkboxes will have same name\n elname = $el.attr('name'),\n // get checkboxes and count the checked ones\n $checkBoxes = $('input[type=checkbox][name^=\"' + elname + '\"]', $form),\n checkedCount = $checkBoxes.filter(':checked').length,\n // get el attr that specs qty required / allowed\n qtyAllowed = $el.valAttr('qty');\n\n if (qtyAllowed === undefined) {\n var elementType = $el.get(0).nodeName;\n alert('Attribute \"data-validation-qty\" is missing from ' + elementType + ' named ' + $el.attr('name'));\n }\n\n // call Utility function to check if count is above min, below max, within range etc.\n var qtyCheckResults = $.formUtils.numericRangeCheck(checkedCount, qtyAllowed);\n\n // results will be array, [0]=result str, [1]=qty int\n switch (qtyCheckResults[0]) {\n // outside allowed range\n case 'out':\n this.errorMessage = lang.groupCheckedRangeStart + qtyAllowed + lang.groupCheckedEnd;\n isValid = false;\n break;\n // below min qty\n case 'min':\n this.errorMessage = lang.groupCheckedTooFewStart + qtyCheckResults[1] + (lang.groupCheckedTooFewEnd || lang.groupCheckedEnd);\n isValid = false;\n break;\n // above max qty\n case 'max':\n this.errorMessage = lang.groupCheckedTooManyStart + qtyCheckResults[1] + (lang.groupCheckedTooManyEnd || lang.groupCheckedEnd);\n isValid = false;\n break;\n // ok\n default:\n isValid = true;\n }\n\n if( !isValid ) {\n var _triggerOnBlur = function() {\n $checkBoxes.unbind('click', _triggerOnBlur);\n $checkBoxes.filter('*[data-validation]').validateInputOnBlur(lang, conf, false, 'blur');\n };\n $checkBoxes.bind('click', _triggerOnBlur);\n }\n\n return isValid;\n }\n // errorMessage : '', // set above in switch statement\n // errorMessageKey: '' // not used\n });\n\n})(jQuery);\n\n\n}));\n"]}