UNPKG

react-native-surveys

Version:

Build your own forms, surveys and polls for your React Native apps.

294 lines (253 loc) 6.76 kB
import React from "react"; import { Platform } from "react-native"; import Description from "./Description"; import Open from "./Open"; import SingleSelection from "./SingleSelection"; import MultiSelection from "./MultiSelection"; import NumberScale from "./NumberScale"; import Stars from "./Stars"; import Contact from "./Contact"; import FilesUploadWeb from "./FilesUpload/Web"; import FilesUploadMobile from "./FilesUpload/Mobile"; import Date from "./Date"; export function clearFormValues(form) { const pages = form.pages || []; pages.forEach(page => { const blocks = page.blocks || []; blocks.forEach(block => clearBlock(block)); }); } export function clearBlock(block) { if (Array.isArray(block.value)) { if (block.value[0] && (block.value[0].type || block.value[0].question)) { block.value.forEach(field => { if (field.value) { field.value = ""; } }); } else { if (block.value.length > 0) { block.value = []; } } } else { if (block.value) { block.value = ""; } if (block.files) { delete block.files; } if (block.time) { delete block.time; } if (block.timezone) { delete block.timezone; } } } export function getTypeLabel(type) { switch (type) { case "contact": return "Contact Form"; case "files": return "File Upload"; case "date": return "Date Picker"; case "open": return "Open-ended"; case "number-scale": return "Net Promoter Score"; case "single-selection": return "Single-selection"; case "stars": return "Stars Rating"; case "multi-selection": return "Multiple-selection"; case "description": return "Description"; default: return type; } } export const returnQuestionNumber = (blockIndex, pageIndex, pages) => { let questionNumber = blockIndex + 1; for (let i = 0; i < pageIndex; i++) { questionNumber += pages[i].blocks.length; } return questionNumber; }; export const returnFormData = form => { const pages = form.pages || []; let formData = {}; pages.forEach(page => { const blocks = page.blocks || []; blocks.forEach(block => { if (block.type === "contact") { const fields = block.value || []; fields.forEach(field => { const { value } = returnBlockValue(field); if (!value) return; formData[field.question] = value; }); return; } const { value } = returnBlockValue(block); if (!value) return; formData[block.question] = value; }); }); if (form.extraData) { Object.keys(form.extraData).forEach(key => { if (typeof form.extraData[key] !== "string") { console.error(`${key} has invalid data format. Should be string.`); return; } formData[key] = form.extraData[key]; }); } return formData; }; export function returnBlockValue(block) { if (Array.isArray(block.value)) { if (block.value[0] && (block.value[0].type || block.value[0].question)) { let canSend = true; block.value.forEach(field => { if (field.isRequired && !field.value) { canSend = false; } }); return { value: block.value .filter(field => field.value) .map(f => "\n" + f.question + ": " + f.value) .join(", "), hasValue: block.value.filter(field => field.value).length > 0, canSend }; } else { block.value = block.value.filter(value => value); return { canSend: block.isRequired ? block.value.length > 0 : true, hasValue: block.value.length > 0, value: block.value.join(", ") }; } } return { canSend: block.isRequired ? block.value : true, hasValue: block.value, value: block.value }; } export function returnPageCompletionStatus(page) { const blocks = page.blocks || []; let isCompleted = true; let hasValues = false; blocks.forEach(block => { const { canSend, hasValue } = returnBlockValue(block); if (!hasValues && hasValue) { hasValues = true; } if (!canSend) { isCompleted = false; } }); return { isCompleted, hasValues }; } export function returnQuestionsCount(pages = []) { let count = 0; pages.forEach(page => { if (page.blocks) { page.blocks.forEach(block => { if (block.type === "contact") { const fields = block.value || []; count += fields.length; return; } count += 1; }); } }); return count; } export function getDefaultBadge(badge, type) { if (badge) return badge; switch (type) { case "contact": return "FILL IN FIELDS BELOW"; case "files": return "DROP FILES IN THE BOX BELOW"; case "date": return "SELECT DATE"; case "open": return "WRITE IN THE BOX BELOW"; case "number-scale": return "PICK NUMBER"; case "single-selection": return "SELECT ONE"; case "stars": return "TAP STARS TO RATE"; case "multi-selection": return "SELECT ONE OR MORE"; default: return ""; } } export function renderBlocks({ page, form, isPreview, currentPageIndex, onFocus, onBlur }) { const pages = form.pages || []; const allBlocks = []; pages.forEach(page => allBlocks.push(...page.blocks)); const pageBlocks = page.blocks || []; return pageBlocks.map((block, blockIndex) => { block.badge = getDefaultBadge(block.badge, block.type); const props = { form, block, page, isPreview, currentPageIndex, blockIndex, allBlocks, onFocus, onBlur, key: block.type + currentPageIndex + "block" + blockIndex }; return renderBlock(block.type, props); }); } export const renderBlock = (type, props) => { switch (type) { case "description": return React.createElement(Description, props); case "number-scale": return React.createElement(NumberScale, props); case "stars": return React.createElement(Stars, props); case "contact": return React.createElement(Contact, props); case "open": return React.createElement(Open, props); case "single-selection": return React.createElement(SingleSelection, props); case "multi-selection": return React.createElement(MultiSelection, props); case "date": return React.createElement(Date, props); case "files": return Platform.OS === "web" ? React.createElement(FilesUploadWeb, props) : React.createElement(FilesUploadMobile, props); default: return null; } };