UNPKG

json-object-editor

Version:

JOE the Json Object Editor | Platform Edition

340 lines (316 loc) 16.3 kB
function FormBuilder(){ var self = this; this.submission = function(data,req){ var fid =data.formid; if(!fid){ return {errors:'no form id',failedat:'submissionhandler'}; } var form = JOE.Cache.findByID('form',fid); var source = req.headers.referer || req.headers.host; var payload = { source:source, //headers:req.headers, data:data, message:'Form Submitted', formname:form.name }; if(!form){ return {errors:'form not found',failedat:'submissionhandler'}; } if(form.save_submission){ var visitorid = (form.visitor_id_field)?data.submission[form.visitor_id_field]:''; var submission_date = (form.submission_date_field)?data.submission[form.submission_date_field]:''; var sub = { data:data.submission, form_name:form.name, source:source, form:fid, submission_date, visitor:visitorid }; sub.joeUpdated = new Date().toISOString(); sub.itemtype = 'submission'; if(form.upsert_submission){ logit(`running upsert ${visitorid} | ${submission_date} `); var submissionExists = $J.search({visitor:visitorid,submission_date,itemtype:'submission'}); if(submissionExists.length){ console.log('submission found',submissionExists); sub._id = submissionExists[0]._id; sub.created = submissionExists[0].created || sub.joeUpdated; JOE.Storage.save(sub,'submission',function(err,data){ if(!err){ logit('submission updated') } },{history:false}); return { message:'successfully updated existing submission', '_id':submissionExists[0]._id }; } } sub.created = sub.joeUpdated; sub._id = cuid(); JOE.Storage.save(sub,'submission',function(err,data){ if(!err){ logit('submission saved') } },{history:false}); } if(form.server_action){ try{ var server_action = eval('('+form.server_action+')'); var tpayload = server_action(data,form,req); payload = tpayload; }catch(e){ return {errors:'plugin error: '+e,failedat:'plugin'}; } } return payload; }, this.default = this.render = function(data,req){ try{ var formid = (req.query.formid||req.query.form||data.formid||data.form); console.log('form:'+formid); var form = JOE.Cache.findByID('form',formid); var form_copy = $c.merge({},form); var hostname = JOE.webconfig.hostname || 'localhost'; delete form_copy.form_preview; form_copy._port = (!JOE.webconfig.https)?JOE.webconfig.port:''; var port =form_copy.port= (!JOE.webconfig.https)?':'+JOE.webconfig.port:''; if(JOE.webconfig.PORT){ form_copy._fulljoepath =JOE.webconfig.joepath; var _joereqpath = form_copy._joereqpath = JOE.webconfig.joepath; if(data.remote && JOE.webconfig.hostname){ _joereqpath=((JOE.webconfig.hostname.indexOf('http')== -1)?'//':'')+JOE.webconfig.hostname+_joereqpath; } var fullhostname = form_copy.fullhostname = ''; console.log(data); console.log(_joereqpath); }else{ var protocol =form_copy.protocol =(JOE.webconfig.https)?'https://':'//'; form_copy._fulljoepath =protocol+hostname+port+JOE.webconfig.joepath; var _joereqpath = form_copy._joereqpath = protocol+hostname+port+JOE.webconfig.joepath; var fullhostname = form_copy.fullhostname = protocol+hostname+port; } //console.log(fullhostname); //console.log('urlparams',req.query); var template = `<meta name="viewport" content="initial-scale=1.0, user-scalable=no" /> <script>var web_dir="${fullhostname}/JsonObjectEditor/"</script> <link rel="stylesheet" href="${_joereqpath}capp/capp.css"/> <script src="${_joereqpath}_joeinclude.js"></script> <script src="${_joereqpath}capp/capp.js"></script>`+ "<script>var __apiport = '"+fullhostname+"'; " +`var JOE = new JsonObjectEditor();_joe.addStylesheet('${_joereqpath}css/form-styles.css');</script>`+ "<form class='joe-form' data-id='${_id}' onsubmit='return __onSubmit(this);'>"; var section_questions,question,input_rendering,required,question_name,fieldname; form.sections.map(function(section,index){ section_questions = form.questions[index] || []; template += `<fieldset id="${section.id}"><section-label>${section.name}</section-label>`; section_questions.map(function(qid){ question = JOE.Cache.findByID('question',qid)||{}; try{ required = question.required; fieldname = question.fieldname || question.name; question_name = `<question-name> ${question.title || question.name}`+((required && '<req-star>*</req-star>' )||'')+'</question-name>'; template +=fillTemplate('<form-question data-name="'+fieldname+'" data-label="${name}" class="'+(required&&'required'||'')+'"><label for="'+fieldname+'"> '+question_name +(question.info && ' <question-info> ${info}</question-info>' || ''),question); input_rendering = ''; switch(question.question_type){ case 'oneline': input_rendering = '<input type="text" name="'+fieldname+'" id="'+fieldname+'">'; break; case 'number': input_rendering = '<input type="number" name="'+fieldname+'" id="'+fieldname+'">'; break; case 'password': input_rendering = '<input type="password" name="'+fieldname+'" id="'+fieldname+'">'; break; case 'textarea': input_rendering = '<textarea name="'+fieldname+'" id="'+fieldname+'"></textarea>'; break; case 'content': var content_eval; try{ content_eval = eval('('+question.content+')'); }catch(e){ content_eval = question.content; } input_rendering = (typeof content_eval == 'function')? content_eval({question:question,form:form}):content_eval; break; case 'select': var opts = question.options||[]; var ds = question.question_dataset; //TODO: get values from question dataset if(ds && ds != "none"){ if(JOE.Data[ds]){ logit('DS '+ds+' found: '+JOE.Data[ds].length); opts = JOE.Data[ds]; if(opts && opts[0] && opts[0].name){ logit('sorting by name'); $c.sortBy(opts,"name"); } }else{ input_rendering =' remote dataset: '+ds; break; } } input_rendering = '<select name="'+fieldname+'" id="'+fieldname+'">'; opts.map(function(opt){ //console.log(opt); let opt_display = (opt.label||opt.name||opt.value); let opt_value = (opt._id||opt.value); if(question.option_template){ opt_display = fillTemplate(question.option_template,opt); } if(question.value_template){ opt_value = fillTemplate(question.value_template,opt); } input_rendering += `<option value="${opt_value}">${opt_display}</option>`; }); input_rendering += '</select>'; break; case 'multiple': var opts = question.options||[]; var ds = question.question_dataset; if(ds && ds != "none"){ if(JOE.Data[ds]){ opts = JOE.Data[ds]; }else{ input_rendering =' remote dataset: '+ds; break; } } opts.map(function(opt){ input_rendering += `<label class="form-checkbox" > <input type="checkbox" name="${fieldname}" value="${(opt.value||opt._id)}" />${(opt.label||opt.name||opt.value)} </label>`; }); break; } template+=input_rendering+'</label></form-question>'; }catch(e){ template +='<div>Error rendering question:'+fieldname+'|'+question._id+'</div>'; } }) template +='</fieldset>'; });//end section fieldsets //add complete template += '<input type="submit" value="'+ (form.form_button_label||'submit')+'" onclick="">'; template += "</form>"; var payload = fillTemplate('<h2 id="formTitle">${name}</h2>'+template,form_copy); if(form.includes){ var i_html = ''; form.includes.map(inc=>{ let include = global.$J.get(inc); switch(include.filetype){ case 'css': i_html +=`<link rel="stylesheet" href="/_include/${inc}"/>`; break; case 'js': i_html +=`<script src="/_include/${inc}"></script>`; break; } }) payload = i_html+payload; } var form_str = '<script>var __form='+JSON.stringify(form_copy)+'</script>'; function __onFormRender(){ //replace ajax-field? } function __onSubmit(formdom){ try{ var $ = $ || jQuery; var user_submission = {}; var required = []; var errors=[]; $(formdom).find('form-question').each(function(){ var name = $(this).data('name'); var label = $(this).data('label'); var req =$(this).hasClass('required'); var dom = $('form *[name=\''+name+'\']'); var val = dom && dom.val(); if(name && dom){ if(dom.length > 1){//checkboxgroup val = []; $("form *[name='"+name+"']:checked") .each(function(){ val.push($(this).val()); }); } user_submission[name] = val; if(req){ if(!user_submission[name] || !user_submission[name] == 'undefined'|| !user_submission[name].length){ errors.push(label+' is required') } required.push(name); } }else{ alert(name+' field not found') } }); if(__form.validate){ try{ var val_func = eval('('+__form.validate+')'); var validates = val_func(user_submission); if(validates !== true){ errors.push(validates || 'error validating form'); } }catch(e){ errors.push('error running form validation: '+e); } } //alert(JSON.stringify(user_submission,' ',' ')); if(errors.length){ alert('submission error:\n '+errors.join('\n ')); return false; } }catch(e){ alert('error:'+e); return false; } var form_submission={ formid:__form._id, submission:user_submission }; var hostname = __form.hostname || location.hostname; $.ajax({ url:__form.fullhostname+'/API/plugin/formBuilder/submission', data:form_submission, dataType:'jsonp', success:function(data){ if(data.errors){ alert(data.errors); return; } var completeAction; try{ completeAction = eval('('+ __form.callback.replace(/\;n/g,';')+')'); }catch(e){ } if(completeAction){ completeAction(data); }else{ alert((typeof data == 'object')?JSON.stringify(data,' ',' '):data); } } }) return false; //check requireds //run form.validate //sendPayload } var additional_functions ='<script>'+ __onSubmit.toString()+'</script>'; if(data.remote){ return {response:payload+form_str+additional_functions,form:form_copy}; } return payload+form_str+additional_functions; }catch(e){ return 'Error rendering form: '+e; } }//end bodycontent return self; } module.exports = new FormBuilder();