260 lines
11 KiB
JavaScript
260 lines
11 KiB
JavaScript
/* WP Multi Formular – Frontend JS v2.0 */
|
||
(function($){
|
||
'use strict';
|
||
|
||
$(document).ready(function(){
|
||
$('.wmf-form').each(function(){ WMF_Form.init($(this)); });
|
||
});
|
||
|
||
var WMF_Form = {
|
||
|
||
init: function($form){
|
||
this.initConditional($form);
|
||
this.initMultiStep($form);
|
||
this.initRating($form);
|
||
this.initSignature($form);
|
||
this.initRange($form);
|
||
this.initCharCount($form);
|
||
this.initLiveValidation($form);
|
||
this.initSubmit($form);
|
||
},
|
||
|
||
/* BEDINGTE LOGIK */
|
||
initConditional: function($form){
|
||
var self = this;
|
||
var $fields = $form.find('[data-condition="1"]');
|
||
if(!$fields.length) return;
|
||
|
||
function evalAll(){
|
||
$fields.each(function(){
|
||
var $field = $(this);
|
||
var action = $field.data('condition-action') || 'show';
|
||
var match = $field.data('condition-match') || 'all';
|
||
var rules = $field.data('condition-rules');
|
||
if(typeof rules === 'string'){ try{ rules=JSON.parse(rules); }catch(e){ rules=[]; } }
|
||
if(!rules||!rules.length) return;
|
||
|
||
var results = $.map(rules, function(rule){
|
||
if(!rule.field) return true;
|
||
var $t = $form.find('[name="wmf_fields['+rule.field+']"],[name="wmf_fields['+rule.field+'][]"]');
|
||
var val = '';
|
||
if($t.is('[type=checkbox]')){ var c=[]; $t.filter(':checked').each(function(){ c.push($(this).val()); }); val=c; }
|
||
else if($t.is('[type=radio]')){ val=$t.filter(':checked').val()||''; }
|
||
else { val=$t.val()||''; }
|
||
switch(rule.operator){
|
||
case '=': return Array.isArray(val)?val.indexOf(rule.value)!==-1:val===rule.value;
|
||
case '!=': return Array.isArray(val)?val.indexOf(rule.value)===-1:val!==rule.value;
|
||
case 'contains': return (Array.isArray(val)?val.join(','):val).indexOf(rule.value)!==-1;
|
||
case 'not_empty':return Array.isArray(val)?val.length>0:val.trim()!=='';
|
||
default: return true;
|
||
}
|
||
});
|
||
|
||
var passed = (match==='all') ? results.every(Boolean) : results.some(Boolean);
|
||
var $wrap = $field.closest('.wmf-field-wrap');
|
||
var hide = (action==='show') ? !passed : passed;
|
||
$wrap.toggleClass('wmf-cond-hidden', hide);
|
||
$wrap.find('input,select,textarea').prop('disabled', hide);
|
||
});
|
||
}
|
||
|
||
$form.on('change input','input,select,textarea', evalAll);
|
||
evalAll();
|
||
},
|
||
|
||
/* MULTI STEP */
|
||
initMultiStep: function($form){
|
||
var ms = $form.data('multi-step');
|
||
if(ms!==1&&ms!=='1') return;
|
||
var self = this;
|
||
var $steps = $form.find('.wmf-step');
|
||
var total = $steps.length;
|
||
var current = 0;
|
||
var $prog = $form.closest('.wmf-form-wrap').find('.wmf-progress-bar');
|
||
|
||
function show(idx){
|
||
$steps.hide().eq(idx).show();
|
||
current = idx;
|
||
$prog.find('.wmf-step-indicator').each(function(i){
|
||
$(this).toggleClass('active',i===idx).toggleClass('done',i<idx);
|
||
});
|
||
$('html,body').animate({scrollTop:$form.closest('.wmf-form-wrap').offset().top-60},300);
|
||
}
|
||
|
||
$form.on('click','.wmf-next-step',function(){
|
||
if(!self.validateStep($form.find('.wmf-step').eq(current))) return;
|
||
show(current+1);
|
||
});
|
||
$form.on('click','.wmf-prev-step',function(){ show(current-1); });
|
||
show(0);
|
||
},
|
||
|
||
validateStep: function($step){
|
||
var valid=true, $first=null;
|
||
$step.find('.wmf-field-wrap:not(.wmf-cond-hidden)').each(function(){
|
||
var $w=$( this);
|
||
var $i=$w.find('input:not([type=hidden]),select,textarea').first();
|
||
if(!$i.length) return;
|
||
var r=WMF_Validate.field($i,$w);
|
||
if(r!==true){
|
||
$w.addClass('wmf-has-error');
|
||
$w.find('.wmf-field-error-msg').text(r).show();
|
||
if(!$first) $first=$i;
|
||
valid=false;
|
||
}
|
||
});
|
||
if($first) $first.focus();
|
||
return valid;
|
||
},
|
||
|
||
/* LIVE VALIDIERUNG */
|
||
initLiveValidation: function($form){
|
||
$form.on('blur','input:not([type=hidden]),select,textarea',function(){
|
||
var $w=$(this).closest('.wmf-field-wrap');
|
||
if(!$w.length) return;
|
||
var r=WMF_Validate.field($(this),$w);
|
||
if(r===true){ $w.removeClass('wmf-has-error'); $w.find('.wmf-field-error-msg').hide(); }
|
||
else { $w.addClass('wmf-has-error'); $w.find('.wmf-field-error-msg').text(r).show(); }
|
||
});
|
||
$form.on('input change','input:not([type=hidden]),select,textarea',function(){
|
||
var $w=$(this).closest('.wmf-field-wrap');
|
||
if($w.hasClass('wmf-has-error')){
|
||
if(WMF_Validate.field($(this),$w)===true){ $w.removeClass('wmf-has-error'); $w.find('.wmf-field-error-msg').hide(); }
|
||
}
|
||
});
|
||
},
|
||
|
||
/* SUBMIT */
|
||
initSubmit: function($form){
|
||
$form.on('submit',function(e){
|
||
var valid=true,$first=null;
|
||
$form.find('.wmf-field-wrap:not(.wmf-cond-hidden)').each(function(){
|
||
var $w=$(this),$i=$w.find('input:not([type=hidden]),select,textarea').first();
|
||
if(!$i.length) return;
|
||
var r=WMF_Validate.field($i,$w);
|
||
if(r!==true){
|
||
$w.addClass('wmf-has-error');
|
||
$w.find('.wmf-field-error-msg').text(r).show();
|
||
if(!$first) $first=$i;
|
||
valid=false;
|
||
}
|
||
});
|
||
if(!valid){
|
||
e.preventDefault();
|
||
if($first) $('html,body').animate({scrollTop:$first.closest('.wmf-field-wrap').offset().top-80},300);
|
||
return;
|
||
}
|
||
// Unterschrift
|
||
$form.find('.wmf-signature-canvas').each(function(){
|
||
var $c=$(this);
|
||
if($c.data('drawn')) $c.closest('.wmf-signature-wrap').find('.wmf-signature-data').val(this.toDataURL('image/png'));
|
||
});
|
||
$form.addClass('wmf-loading');
|
||
$form.find('.wmf-submit-button').prop('disabled',true);
|
||
});
|
||
},
|
||
|
||
/* STERNE */
|
||
initRating: function($form){
|
||
$form.on('mouseenter','.wmf-star',function(){
|
||
var v=parseInt($(this).data('value'));
|
||
$(this).closest('.wmf-rating').find('.wmf-star').each(function(){ $(this).toggleClass('hover',parseInt($(this).data('value'))<=v); });
|
||
});
|
||
$form.on('mouseleave','.wmf-rating',function(){ $(this).find('.wmf-star').removeClass('hover'); });
|
||
$form.on('click','.wmf-star',function(){
|
||
var v=$(this).data('value');
|
||
var $r=$(this).closest('.wmf-rating');
|
||
$r.find('.wmf-rating-value').val(v).trigger('change');
|
||
$r.find('.wmf-star').each(function(){ $(this).toggleClass('active',parseInt($(this).data('value'))<=parseInt(v)); });
|
||
});
|
||
},
|
||
|
||
/* UNTERSCHRIFT */
|
||
initSignature: function($form){
|
||
$form.find('.wmf-signature-canvas').each(function(){
|
||
var canvas=this, ctx=canvas.getContext('2d'), drawing=false;
|
||
var dpr=window.devicePixelRatio||1;
|
||
var rect=canvas.getBoundingClientRect();
|
||
canvas.width=rect.width*dpr; canvas.height=rect.height*dpr;
|
||
ctx.scale(dpr,dpr);
|
||
ctx.strokeStyle='#1d2327'; ctx.lineWidth=2; ctx.lineCap='round'; ctx.lineJoin='round';
|
||
|
||
function pos(e){ var r=canvas.getBoundingClientRect(),s=e.touches?e.touches[0]:e; return{x:s.clientX-r.left,y:s.clientY-r.top}; }
|
||
function start(e){ e.preventDefault(); drawing=true; var p=pos(e); ctx.beginPath(); ctx.moveTo(p.x,p.y); }
|
||
function move(e){ e.preventDefault(); if(!drawing)return; var p=pos(e); ctx.lineTo(p.x,p.y); ctx.stroke(); $(canvas).data('drawn',true); }
|
||
function stop(){ drawing=false; }
|
||
|
||
canvas.addEventListener('mousedown',start);
|
||
canvas.addEventListener('mousemove',move);
|
||
canvas.addEventListener('mouseup',stop);
|
||
canvas.addEventListener('mouseleave',stop);
|
||
canvas.addEventListener('touchstart',start,{passive:false});
|
||
canvas.addEventListener('touchmove',move,{passive:false});
|
||
canvas.addEventListener('touchend',stop);
|
||
|
||
$(canvas).closest('.wmf-signature-wrap').find('.wmf-sig-clear').on('click',function(){
|
||
ctx.clearRect(0,0,canvas.width,canvas.height);
|
||
$(canvas).data('drawn',false);
|
||
$(canvas).closest('.wmf-signature-wrap').find('.wmf-signature-data').val('');
|
||
});
|
||
});
|
||
},
|
||
|
||
/* SCHIEBEREGLER */
|
||
initRange: function($form){
|
||
$form.on('input','.wmf-range-input',function(){
|
||
$(this).closest('.wmf-range-wrap').find('.wmf-range-value').text($(this).val());
|
||
});
|
||
},
|
||
|
||
/* ZEICHENZÄHLER */
|
||
initCharCount: function($form){
|
||
$form.find('textarea[maxlength]').each(function(){
|
||
var $ta=$(this), max=parseInt($ta.attr('maxlength'));
|
||
var $c=$ta.closest('.wmf-field').find('.wmf-char-count .wmf-chars-used');
|
||
$ta.on('input',function(){ var l=$(this).val().length; $c.text(l); $c.closest('.wmf-char-count').toggleClass('wmf-over-limit',l>=max); });
|
||
});
|
||
}
|
||
};
|
||
|
||
/* VALIDIERUNG */
|
||
var WMF_Validate = {
|
||
field: function($i,$w){
|
||
var req=$i.prop('required'), type=$i.attr('type')||$i.prop('tagName').toLowerCase(), val=$i.val();
|
||
var i18n=(typeof WMF_Frontend!=='undefined'&&WMF_Frontend.i18n)||{};
|
||
|
||
if(type==='checkbox'){
|
||
var $boxes=$w.find('input[type=checkbox]');
|
||
if($boxes.first().prop('required')&&!$boxes.filter(':checked').length) return i18n.required||'Pflichtfeld.';
|
||
return true;
|
||
}
|
||
if(type==='radio'){
|
||
var $radios=$w.find('input[type=radio]');
|
||
if($radios.first().prop('required')&&!$radios.filter(':checked').length) return i18n.required||'Pflichtfeld.';
|
||
return true;
|
||
}
|
||
if($i.is('select[multiple]')){
|
||
if(req&&(!val||!val.length)) return i18n.required||'Pflichtfeld.';
|
||
return true;
|
||
}
|
||
if(req&&(!val||val.trim()==='')) return i18n.required||'Pflichtfeld.';
|
||
if(!val||val.trim()==='') return true;
|
||
if(type==='email'&&!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(val)) return i18n.email||'Ungültige E-Mail.';
|
||
if(type==='url'){ try{ new URL(val); }catch(e){ return i18n.url||'Ungültige URL.'; } }
|
||
return true;
|
||
}
|
||
};
|
||
|
||
/* SHORTCODE KOPIEREN */
|
||
$(document).on('click','.wmf-sc-copy',function(){
|
||
var t=$(this).text().trim();
|
||
if(navigator.clipboard) navigator.clipboard.writeText(t).then(function(){ WMF_Form.toast && WMF_Form.toast('Shortcode kopiert!'); });
|
||
});
|
||
WMF_Form.toast = function(msg){
|
||
var $t=$('<div class="wmf-toast">'+msg+'</div>').appendTo('body');
|
||
setTimeout(function(){$t.addClass('show');},10);
|
||
setTimeout(function(){$t.removeClass('show');setTimeout(function(){$t.remove();},400);},2500);
|
||
};
|
||
|
||
})(jQuery);
|