Skip to content

Commit fe6c780

Browse files
authored
Merge pull request #3117 from ccnmtl/template-form-refactor
More Template graph form refactor
2 parents ac15492 + 8154208 commit fe6c780

File tree

2 files changed

+66
-97
lines changed

2 files changed

+66
-97
lines changed

media/js/src/editors/TemplateGraphEditor.jsx

Lines changed: 53 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -3,110 +3,77 @@ import PropTypes from 'prop-types';
33
import { MathJaxProvider, MathJaxFormula } from 'mathjax3-react';
44
import { create, all } from 'mathjs';
55

6-
import EditableControl from '../form-components/EditableControl.jsx';
6+
import {handleFormUpdate} from '../utils.js';
77

88

99
const math = create(all, {});
1010

1111

1212
export default class TemplateGraphEditor extends React.Component {
13+
/**
14+
* checkFormula()
15+
*
16+
* Check that the given expression (as a string) is a valid
17+
* expression with the x scope.
18+
*
19+
* Returns a boolean, true if valid.
20+
*/
1321
checkFormula(expression) {
1422
try {
1523
math.evaluate(expression, { x: 1 });
16-
return false;
17-
} catch (e) {
1824
return true;
25+
} catch (e) {
26+
return false;
1927
}
2028
}
2129

22-
render() {
23-
return (
24-
<>
25-
<div className="d-flex flex-column">
26-
<div className="row">
27-
<div className="col d-flex">
28-
<label
29-
className="form-check-label me-2 flex-shrink-1 d-flex align-self-center"
30-
htmlFor="gExpression">
31-
<MathJaxProvider>
32-
<MathJaxFormula formula="$$y = $$" />
33-
</MathJaxProvider>
34-
</label>
35-
<EditableControl
36-
id="gExpression"
37-
name="Expression"
38-
className="w-100"
39-
value={this.props.gExpression}
40-
valueEditable={true}
41-
onBlur={true}
42-
isInstructor={this.props.isInstructor}
43-
disabled={this.props.disabled}
44-
updateGraph={this.props.updateGraph} />
45-
{
46-
this.checkFormula(this.props.gExpression) &&
47-
<p className='text-danger mt-2'>Formula Error</p>
48-
}
49-
</div>
50-
</div>
51-
</div>
52-
53-
<div className="d-flex flex-column mt-2">
54-
<div className="row">
55-
<div className="col d-flex">
56-
<label
57-
className="form-check-label me-2 flex-shrink-1 d-flex align-self-center"
58-
htmlFor="gExpression2">
59-
<MathJaxProvider>
60-
<MathJaxFormula formula="$$y = $$" />
61-
</MathJaxProvider>
30+
renderExpressionInput(index=1, value) {
31+
let name = 'Expression';
32+
if (index > 1) {
33+
name = `Expression${index}`;
34+
}
6235

63-
</label>
64-
<EditableControl
65-
id="gExpression2"
66-
name="Expression 2"
67-
className="w-100"
68-
value={this.props.gExpression2}
69-
valueEditable={true}
70-
onBlur={true}
71-
isInstructor={this.props.isInstructor}
72-
disabled={this.props.disabled}
73-
updateGraph={this.props.updateGraph} />
74-
{
75-
this.checkFormula(this.props.gExpression2) &&
76-
<p className='text-danger mt-2'>Formula Error</p>
77-
}
78-
</div>
79-
</div>
80-
</div>
36+
const isInvalid = !this.checkFormula(value);
37+
let invalidClass = '';
38+
if (isInvalid) {
39+
invalidClass = 'is-invalid';
40+
}
8141

82-
<div className="d-flex flex-column mt-2">
83-
<div className="row">
84-
<div className="col d-flex">
85-
<label
86-
className="form-check-label me-2 flex-shrink-1 d-flex align-self-center"
87-
htmlFor="gExpression3">
88-
<MathJaxProvider>
89-
<MathJaxFormula formula="$$y = $$" />
90-
</MathJaxProvider>
42+
return (
43+
<div className="d-flex flex-column mb-2">
44+
<div className="row">
45+
<label className="w-100" htmlFor={`g${name}`}>
46+
{`Expression ${index}`}
47+
</label>
48+
<div className="col d-flex">
9149

92-
</label>
93-
<EditableControl
94-
id="gExpression3"
95-
name="Expression 3"
96-
className="w-100"
97-
value={this.props.gExpression3}
98-
valueEditable={true}
99-
onBlur={true}
100-
isInstructor={this.props.isInstructor}
101-
disabled={this.props.disabled}
102-
updateGraph={this.props.updateGraph} />
103-
{
104-
this.checkFormula(this.props.gExpression3) &&
105-
<p className='text-danger mt-2'>Formula Error</p>
106-
}
107-
</div>
50+
<label
51+
className="form-check-label me-2 flex-shrink-1 d-flex align-self-center"
52+
htmlFor={`g${name}`}>
53+
<MathJaxProvider>
54+
<MathJaxFormula formula="$$y = $$" />
55+
</MathJaxProvider>
56+
</label>
57+
<input
58+
type="text"
59+
className={`form-control ${invalidClass}`}
60+
id={`g${name}`}
61+
name={name}
62+
defaultValue={value}
63+
onBlur={handleFormUpdate.bind(this)}
64+
disabled={this.props.disabled} />
10865
</div>
10966
</div>
67+
</div>
68+
);
69+
}
70+
71+
render() {
72+
return (
73+
<>
74+
{this.renderExpressionInput(1, this.props.gExpression)}
75+
{this.renderExpressionInput(2, this.props.gExpression2)}
76+
{this.renderExpressionInput(3, this.props.gExpression3)}
11077
</>
11178
);
11279
}
@@ -115,7 +82,6 @@ export default class TemplateGraphEditor extends React.Component {
11582
TemplateGraphEditor.propTypes = {
11683
gType: PropTypes.number,
11784
updateGraph: PropTypes.func.isRequired,
118-
isInstructor: PropTypes.bool.isRequired,
11985
disabled: PropTypes.bool,
12086

12187
gExpression: PropTypes.string,

media/js/src/form-components/EditableControl.jsx

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,25 +12,25 @@ import {handleFormUpdate} from '../utils.js';
1212
export default class EditableControl extends React.Component {
1313

1414
render() {
15+
const commonAttrs = {
16+
name: this.props.id,
17+
className: `form-control ${this.props.inputClass}`,
18+
type: 'text',
19+
maxLength: this.props.maxLength || 60,
20+
disabled: this.props.disabled,
21+
};
22+
1523
let input = (
1624
<input
17-
name={this.props.id}
18-
className="form-control"
19-
type="text"
20-
maxLength={this.props.maxLength || 60}
21-
disabled={this.props.disabled}
25+
{...commonAttrs}
2226
value={this.props.value}
2327
onChange={handleFormUpdate.bind(this)} />
2428
);
2529

2630
if (this.props.onBlur) {
2731
input = (
2832
<input
29-
name={this.props.id}
30-
className="form-control"
31-
type="text"
32-
maxLength={this.props.maxLength || 60}
33-
disabled={this.props.disabled}
33+
{...commonAttrs}
3434
defaultValue={this.props.value}
3535
onBlur={handleFormUpdate.bind(this)} />
3636
);
@@ -64,6 +64,9 @@ EditableControl.propTypes = {
6464
// Custom classes for the parent element of this component.
6565
className: PropTypes.string,
6666

67+
// Custom classes for the input element of this component.
68+
inputClass: PropTypes.string,
69+
6770
onBlur: PropTypes.bool,
6871
disabled: PropTypes.bool,
6972
maxLength: PropTypes.number

0 commit comments

Comments
 (0)