Implement some placeholder logic for signup forms in admin

This commit is contained in:
Jan Tuomi
2019-03-13 16:45:52 +02:00
parent f0ca49f71f
commit c2163a858b
3 changed files with 89 additions and 9 deletions
@@ -12,9 +12,24 @@ export interface SignupQuestionsWidgetState {}
interface Question {
id: string;
name: string;
type: string;
options: string[];
}
interface InputProps {
index: number;
value: string | string[];
questions: Question[];
type: string;
}
const types = [
"text",
"radiobutton",
];
class SignupQuestionError extends Error {}
class SignupQuestionsWidget extends React.Component<SignupQuestionsWidgetProps, SignupQuestionsWidgetState> {
onValueChange = (questions: Question[]) => {
const { onChange } = this.props;
@@ -23,11 +38,13 @@ class SignupQuestionsWidget extends React.Component<SignupQuestionsWidgetProps,
}
handleNewRowClick = (questions) => () => {
const newQuestions = questions.concat([{
const newRow: Question = {
id: shortid.generate(),
name: `Question #${questions.length + 1}`,
options: [],
}]);
type: "text",
};
const newQuestions: Question[] = questions.concat([newRow]);
this.onValueChange(newQuestions);
}
@@ -38,12 +55,75 @@ class SignupQuestionsWidget extends React.Component<SignupQuestionsWidgetProps,
this.onValueChange(questions);
}
renderQuestions = (questions: Question[]) => {
return questions.map((q, index) => (
<div key={q.id} className="signup-questions-widget-row">
<input type="text" value={ q.name } onChange={this.handleNameInputChange(questions, index)} />
</div>
handleTypeChange = (questions: Question[], index: number) => (event) => {
const val = event.target.value;
questions[index].type = val;
this.onValueChange(questions);
}
handleRadiobuttonOptionsChange = (questions: Question[], index: number) => (event) => {
const val = event.target.value;
const lst = val.split(",").map(p => p.trimLeft());
questions[index].options = lst;
this.onValueChange(questions);
}
renderTextWidget = ({ questions, value, index }: InputProps) => (
<input type="text" value={value} onChange={this.handleNameInputChange(questions, index)} />
)
renderOptionsWidgetByType = (props: InputProps) => {
const { type, value, questions, index } = props;
if (!types.includes(type)) {
throw new SignupQuestionError(`Qquestion widget type "${type}" not in types array.`);
}
if (type === "text") {
return null;
}
else if (type === "radiobutton") {
const lst = value as string[];
const joinedValue = lst.join(",");
return <input
type="text"
placeholder="Yes,no,maybe"
value={joinedValue}
onChange={this.handleRadiobuttonOptionsChange(questions, index)} />;
}
throw new SignupQuestionError(`Unrecognized question widget type "${type}"`);
}
renderTypeSelectWidget = (props: InputProps) => {
const { questions, index, type } = props;
const options = types.map(t => (
<option key={t} value={t}>{t}</option>
));
return (
<select onChange={this.handleTypeChange(questions, index)} value={type} name="type">
{ options }
</select>
);
}
renderQuestions = (questions: Question[]) => {
return questions.map((q, index) => {
const nameWidgetProps = { value: q.name, type: "text", questions, index };
const nameWidget = this.renderTextWidget(nameWidgetProps);
const optionsWidgetProps = { value: q.options, type: q.type, questions, index };
const optionsWidget = this.renderOptionsWidgetByType(optionsWidgetProps);
const typeSelectWidget = this.renderTypeSelectWidget(optionsWidgetProps);
return (
<div key={q.id} className="signup-questions-widget-row">
{ nameWidget }
{ typeSelectWidget }
{ optionsWidget }
</div>
);
});
}
render() {
@@ -4,7 +4,7 @@ import "./SignupCreatePage.scss";
import { isAuthenticated } from "../../auth";
import Form from "react-jsonschema-form";
import { Tag, getTags } from "../../models/Tag";
import { createForm, getForm, updateForm, deserializeForm } from "../../models/SignupForm";
import { createForm, getForm, updateForm } from "../../models/SignupForm";
import DatetimeWidget from "../../components/DatetimeWidget";
import SignupQuestionsWidget from "../../components/SignupQuestionsWidget";
+1 -1
View File
@@ -6,7 +6,7 @@
"module": "commonjs",
"target": "es5",
"jsx": "react",
"lib": ["es5", "es6", "dom"],
"lib": ["es5", "es6", "es7", "dom"],
"experimentalDecorators": true,
"types": [
"node"