Aknaproff/resources/js/components/ShowForm.vue
2023-09-21 13:45:08 +01:00

512 lines
26 KiB
Vue

<template>
<form id="show_form" v-bind="getCustomAttributes(form_custom_attributes)">
<div class="row">
<template
v-for="(element, index) in formFields">
<div
v-if="!_.includes(['page_break'], element.type)"
:key="index"
:class="[element.col ? element.col : 'col-md-12']"
v-show="togglePageVisibility(element.page_num)">
<fieldGenerator
:element="element"
:settings="settings"
:submitted_data="submitted_data"
@apply_conditions="applyConditions">
</fieldGenerator>
</div>
</template>
</div>
<div class="g-recaptcha" :data-sitekey="settings.recaptcha.site_key" v-if="settings.recaptcha.is_enable"></div>
<div class="row"
:class="[!isCardFormLayout() ? settings.submit.btn_alignment : 'float-right']"
v-show="isSubmitVisible()">
<button v-if="!actionBy.length && settings.is_enabled_draft_submit"
formnovalidate="formnovalidate" type="submit" class="btn m-1 draft_btn"
:class="[settings.submit.btn_size, settings.submit.btn_style == 'default' ? 'btn-warning': 'btn-outline-warning']" name="status" value="incomplete">
<i class="fas " :class="settings.submit.btn_icon" v-if="settings.submit.btn_icon != 'none' && settings.submit.icon_position == 'left'"></i>
{{trans('messages.draft')}}
<i class="fas " :class="settings.submit.btn_icon" v-if="settings.submit.btn_icon != 'none' && settings.submit.icon_position == 'right'"></i>
</button>
<button type="submit" class="btn submit_btn ladda-button m-1" :class="[settings.submit.btn_color, settings.submit.btn_size]" data-style="expand-right" name="status" value="complete">
<i class="fas " :class="settings.submit.btn_icon" v-if="settings.submit.btn_icon != 'none' && settings.submit.icon_position == 'left'"></i>
<span class="btn_text ladda-label"> {{settings.submit.text}} </span>
<i class="fas " :class="settings.submit.btn_icon" v-if="settings.submit.btn_icon != 'none' && settings.submit.icon_position == 'right'"></i>
</button>
</div>
<div class="row" v-if="isCardFormLayout()">
<div class="col-md-12 d-flex justify-content-between">
<button v-show="current_page_number > 0" type="button"
class="btn bg-gradient-primary mr-auto"
@click="changePage('prev')">
<i class="fas fa-arrow-circle-left"></i> {{trans('messages.previous')}}
</button>
<button v-show="current_page_number < page_number" type="button"
class="btn bg-gradient-primary ml-auto" @click="changePage('next')">
{{trans('messages.next')}} <i class="fas fa-arrow-circle-right"></i>
</button>
</div>
</div>
<div class="alert alert-success mt-5 cursor-pointer" role="alert"
v-show="is_available_form_editable_url"
@click="copyLink">
<h4 class="alert-heading cursor-pointer"
v-html="trans('messages.form_editable_url')">
</h4>
<hr>
<span id="form_editable_url" class="cursor-pointer"></span>
<i class="far fa-copy float-right fa-lg cursor-pointer"></i>
</div>
</form>
</template>
<script>
import fieldGenerator from "./FieldGenerator";
export default{
props: ['form', 'actionBy'],
components: {
fieldGenerator
},
data() {
return {
schema: [],
form_parsed: [],
settings:{},
conditional_fields:[],
is_available_form_editable_url: false,
submitted_data:{},
token:'',
form_data_id: '',
form_custom_attributes : [],
formFields:[],
page_number: 0,
current_page_number:0,
is_page_active:'page#0',
};
},
mounted() {
const self = this;
let rules = {};
let messages = {};
self.formFields.forEach(function(field) {
if(!_.isEmpty(field?.allowed_input?.values)) {
let tempRule = {
remote: {
url: "/validate-input-value",
type: "post",
data: {
field: function() {
return JSON.stringify(field);
},
field_value: function() {
return $(`#${field.name}`).val();
}
}
}
}
let tempMsg = {
remote: field?.allowed_input?.error_msg || 'This value is not allowed.'
}
rules = {...rules, ...{[field.name]:tempRule}};
messages = {...messages, ...{[field.name]:tempMsg}};
}
});
var validator = $('#show_form').validate({
ignore: ".note-editor *, .hide",
rules: rules,
messages: messages,
submitHandler: function(form, e) {
e.preventDefault();
var form_data = $('#show_form').serialize();
$("button.submit_btn, button.draft_btn").attr('disabled', 'disabled');
var status = $("input[name=status]").val();
if (status == 'complete') {
$("span.btn_text").text(self.settings.submit.loading_text);
var ladda = Ladda.create(document.querySelector('.ladda-button'));
} else if (status == 'incomplete') {
var ladda = Ladda.create(document.querySelector('.draft_btn'));
}
ladda.start();
if(typeof mpfg_form_submitted === "function"){
var form_array_data = $('#show_form').serializeArray();
mpfg_form_submitted(self.form_parsed.id, form_array_data);
}
let url = '/form-data/' + self.form_parsed.id + '?token=' + self.token + '&form_data_id=' + self.form_data_id;
if (self.actionBy.length && self.actionBy == 'admin') {
url = '/update/'+self.form_parsed.id+'/data/'+self.form_data_id;
}
axios
.post(url, {form_data})
.then(function(response) {
//set token & form data id for form
if (status == 'incomplete') {
self.token = response.data.notification.token;
self.form_data_id = response.data.notification.form_data_id;
}
//remove disabled attr.
$("button.submit_btn, button.draft_btn").removeAttr("disabled");
//set submit text to submit btn
$("span.btn_text").text(self.settings.submit.text);
ladda.stop();
window.onbeforeunload = null;
if (response.data.success == true) {
//if notification action is redirect & status is compelete, redirect user to given url
if ((response.data.notification.post_submit_action === 'redirect') && (status == 'complete')) {
toastr.success(response.data.notification.success_msg);
window.parent.location = response.data.notification.redirect_url;
}
//if submit action is on same page & status is complete, replace url to form view url after 10 sec
if (status == 'complete' && !_.includes(['redirect'], response.data.notification.post_submit_action)) {
$('.card-body').html(response.data.notification.submission_msg);
if (response.data.notification.qr_code_text) {
try {
let qr_option = {
title: self.form_parsed.name,
titleFont: "bold 16px Arial",
titleColor: "#1b294b",
titleBackgroundColor: "#ffffff",
titleHeight: 20,
titleTop: 0,
text: response.data.notification.qr_code_text,
margin: 0,
width: 200,
height: 200,
quietZone: 20,
colorDark: "#1b294b",
colorLight: "#ffffffff",
correctLevel : QRCode.CorrectLevel.L
}
let qr_code = new QRCode(document.getElementById("qrcode"), qr_option);
$('#qrcode').find('canvas').attr('id', 'canvas');
let canvas = document.getElementById('canvas');
$('#download_qrcode').attr('href', canvas.toDataURL());
} catch (error) {
$('#qrcode, #download_qrcode').hide();
}
}
}
//if status is incomplete display form editable url
if (status == 'incomplete') {
toastr.success(response.data.notification.success_msg);
if (response.data.notification.form_editable_url) {
self.is_available_form_editable_url = true;
$('span#form_editable_url').text(response.data.notification.form_editable_url);
} else {
location.reload();
}
}
} else {
toastr.error(response.data.msg);
}
})
.catch(function(error) {
toastr.error(error);
});
}
});
//show aleart before page reloading
var form_obj = $('form#show_form');
var orig_forn_data = form_obj.serialize();
window.onbeforeunload = function() {
if($('form#show_form').length == 1){
if (form_obj.serialize() != orig_forn_data) {
return 'Are you sure?';
}
}
}
},
created() {
this.form_parsed = JSON.parse(this.form);
this.schema = this.form_parsed.schema.form;
this.settings = this.form_parsed.schema.settings;
this.conditional_fields = this.form_parsed.schema.conditional_fields;
this.form_custom_attributes = this.form_parsed.schema.form_attributes;
if (!_.isEmpty(this.form_parsed.data)) {
this.submitted_data = this.form_parsed.data[0].data;
this.token = this.form_parsed.data[0].token;
this.form_data_id = this.form_parsed.data[0].id;
}
this.getUrlParameters();
this.customizeFieldsArrayForLayout();
this.$eventBus.$on('callApplyConditions', (data) => {
this.applyConditions();
});
//if page break enabled, set layout 'card_form'
if (
this.form_parsed.schema.contains_page_break &&
this.form_parsed.schema.contains_page_break
) {
this.settings.layout = 'card_form';
}
},
beforeDestroy() {
this.$eventBus.$off('callApplyConditions');
},
methods: {
applyConditions(){
var schema = this.schema;
var is_condition_satisfied = true;
_.forEach(this.conditional_fields, function(conditional_field) {
_.forEach(conditional_field.conditions, function(element) {
if (!_.isNull(element.condition)) {
//find element as condition is present & if present check its type and find it value
var index = schema.findIndex(field => field.name === element.condition);
var form_element_value = '';
var logical_operator = element?.logical_operator || 'AND';
if (schema[index].type === 'radio') {
form_element_value = $('input[name='+element.condition+']:checked').val();
} else if (schema[index].type === 'checkbox') {
var checked_value = [];
$('input[name='+'"'+element.condition+'[]"'+']:checked').each(function() {
checked_value.push($(this).val());
});
if (_.includes(checked_value, element.value)) {
form_element_value = element.value;
}
} else if (schema[index].type === 'dropdown' && schema[index].multiselect) {
var selected_value = $('select[name='+'"'+element.condition+'[]"'+']').val();
if (_.includes(selected_value, element.value)) {
form_element_value = element.value;
}
} else if(schema[index].type === 'calendar') {
form_element_value = $('input[name='+element.condition+']').val();
} else if(schema[index].type === 'terms_and_condition') {
form_element_value = $('input[name='+element.condition+']').is(':checked') ? 'true' : 'false';
} else if(schema[index].type === 'switch') {
form_element_value = $('input[name='+element.condition+']').is(':checked') ? '1' : '0';
} else {
form_element_value = document.getElementById(element.condition).value;
}
//check if condition_satisfied or not
if(logical_operator == 'AND') {
if (element.operator == '==') {
if (form_element_value == element.value) {
is_condition_satisfied = true && is_condition_satisfied;
} else {
is_condition_satisfied = false;
}
} else if (element.operator == '!=') {
if (form_element_value != element.value) {
is_condition_satisfied = true && is_condition_satisfied;
} else {
is_condition_satisfied = false;
}
} else if (element.operator == 'empty') {
if (form_element_value.length == 0) {
is_condition_satisfied = true && is_condition_satisfied;
} else {
is_condition_satisfied = false;
}
} else if (element.operator == 'not_empty') {
if (form_element_value.length > 0) {
is_condition_satisfied = true && is_condition_satisfied;
} else {
is_condition_satisfied = false;
}
}
} else {
if (element.operator == '==') {
is_condition_satisfied = (form_element_value == element.value) || is_condition_satisfied;
} else if (element.operator == '!=') {
is_condition_satisfied = (form_element_value != element.value) || is_condition_satisfied;
} else if (element.operator == 'empty') {
is_condition_satisfied = (form_element_value.length == 0) || is_condition_satisfied;
} else if (element.operator == 'not_empty') {
is_condition_satisfied = (form_element_value.length > 0) || is_condition_satisfied;
}
}
}
});
//check if element is exist or not in schema
var index = schema.findIndex(element => element.name === conditional_field.element);
var action = conditional_field.action;
//if element exist then toggle conditional class
if (index !== -1) {
if (is_condition_satisfied) {
schema[index].conditional_class = conditional_field.action;
} else {
action = (conditional_field.action === 'show') ? 'hide' : 'show';
schema[index].conditional_class = (conditional_field.action === 'show') ? 'hide' : 'show'
}
is_condition_satisfied = true;
if(action == 'hide') {
if(schema[index]['type'] == 'radio') {
$(`input[name="${schema[index]['name']}"]`).prop('checked',false).trigger("change");
} else if(schema[index]['type'] == 'checkbox') {
$(`input[name="${schema[index]['name']}"]:checkbox`).prop('checked',false).trigger("change");
} else if(schema[index].type === 'dropdown' && schema[index].multiselect) {
$(`select[name="${schema[index]['name']}"]`).val('').trigger("change");
} else if(schema[index].type === 'terms_and_condition' || schema[index].type === 'switch') {
$(`input[name="${schema[index]['name']}"]`).prop('checked',false).trigger("change");
} else {
$(`input[name="${schema[index]['name']}"]`).val('').trigger("change");
}
}
}
});
},
getUrlParameters(){
const self = this;
let url = window.location.href;
let parameters = url.split('?')[1];
if (
!_.isEmpty(parameters) &&
_.isEmpty(self.submitted_data)
) {
let query_string = new URLSearchParams(parameters);
let data = {};
//convert query string to key value object
for (let parameter_pair of query_string.entries()) {
data[parameter_pair[0]] = parameter_pair[1];
}
self.submitted_data = data;
}
},
customizeFieldsArrayForLayout(){
const self = this;
let tempArrayEls = [];
if (!_.isEmpty(self.schema)) {
let maxIndex = self.schema.length - 1;
_.forEach(self.schema, function(element, index){
element['page_num'] = `page#${self.page_number}`;
tempArrayEls.push(element);
let nextEl = self.schema[index+1];//find next field
//increase page num if page break exists & not consecutive page break
if (
_.includes(['page_break'], element.type) &&
index > 0 //remove first index page break
&& nextEl &&
!_.includes(['page_break'], nextEl.type)
) {
self.page_number += 1;
}
//if layout is card.. & does not contain page break, insert one
if(
_.includes(['card_form'], self.settings.layout) &&
!self.form_parsed.schema.contains_page_break &&
(index < maxIndex)
) {
self.page_number += 1;
}
});
}
self.formFields = tempArrayEls;
},
isSubmitVisible() {
const self = this;
let is_visible = true;
if (self.isCardFormLayout() && (self.current_page_number < self.page_number)) {
is_visible = false;
}
return is_visible;
},
isCardFormLayout() {
const self = this;
if (
self.settings.layout &&
_.includes(['card_form'], self.settings.layout)
) {
return true
}
return false;
},
togglePageVisibility(page_num) {
const self = this;
if (!self.isCardFormLayout()) return true;
if (self.isCardFormLayout() && _.includes([self.is_page_active],page_num)) return true;
return false;
},
changePage(move) {
const self = this;
if (move == 'next') {
//validate fields before proceeding
let pageEles = self.formFields
.filter((el) => el.page_num == `page#${self.current_page_number}`);
let is_page_valid = true; //default true
for(let el of pageEles){
if (!_.includes(['page_break'], el.type)) {
is_page_valid = self.validateElement(el);
if(!is_page_valid) break;
}
}
//if page's field validated, move to next page
if (
is_page_valid &&
(self.current_page_number < self.page_number)
) {
self.current_page_number += 1;
self.is_page_active = `page#${self.current_page_number}`;
}
} else if (move == 'prev') {
if (self.current_page_number != 0) {
self.current_page_number -= 1;
self.is_page_active = `page#${self.current_page_number}`;
}
}
},
validateElement(element) {
const self = this;
let element_name = element.name;
let is_element_valid = true;
if (
_.includes(['checkbox', 'file_upload'], element.type) ||
(element.type == 'dropdown' && element.multiselect === true)
) {
element_name = element_name + '[]';
}
if (
!_.includes(['heading', 'hr', 'html_text'], element.type) &&
$('[name="' + element_name + '"]').rules()
) {
is_element_valid = $('[name="' + element_name + '"]').valid();
}
return is_element_valid;
},
copyLink(){
const self = this;
let textarea = document.createElement('textarea');
textarea.innerHTML = $("#form_editable_url").text();
document.body.appendChild(textarea);
textarea.select();
textarea.setSelectionRange(0, 99999);
document.execCommand("copy");
document.body.removeChild(textarea);
Swal.fire(self.trans('messages.link_copied'));
}
}
}
</script>