-
Notifications
You must be signed in to change notification settings - Fork 3.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[#12557] Instructor edit feedback session page: NumberFormatException when inputting decimal numbers into distribute points questions #12558
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @dlimyy, fix looks good! I would suggest shifting the ceil
implementation into the QuestionEditDetailsFormComponent
base class (question-edit-details-form.component.ts
), since it now can be used for 3 different question types. Then, you can delete the 2 functions in the constsum classes, as well as edit the numscale html file to use the ceil
function.
Thank you for reviewing my PR and sorry for the delay in making these changes. I have shifted ceil's implementation to the base class and edited numscale's html file. |
Ready for review |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for taking the time to contribute to TEAMMATES!
Solution definitely works, but I have a little gripe with this. Notice how input validation for this field is handled in two separate ways.
- For decimal point, we round the number only when the model is updated.
- For other non-numeric symbols and letters, we do not allow them to be entered at all.
Though this is but a minor UX inconsistency, I think we can do better. I'm proposing we handle input validation using method 2 as follows.
<input type="number" (keypress)="onPointsInput($event)" />
onPointsInput(event: KeyboardEvent) {
const { key } = event;
const isBackspace = key === "Backspace";
const isDigit = /[0-9]/.test(key);
if (!isBackspace && !isDigit) {
event.preventDefault();
}
}
This will prevent non-numerical characters from being entered in the first place, with the bonus of preventing negative numbers and other potential edge cases we have yet to find as well.
Do let me know your thoughts on this.
...-types/question-edit-details-form/constsum-options-question-edit-details-form.component.html
Show resolved
Hide resolved
<input id="total-points" type="number" class="form-control" min="1" step="1" | ||
[ngModel]="!model.pointsPerOption ? model.points : ''" (ngModelChange)="triggerModelChange('points', $event)" [disabled]="!isEditable || model.pointsPerOption" aria-label="Total Points Input"> | ||
<input id="total-points" type="number" class="form-control" | ||
[ngModel]="!model.pointsPerOption ? model.points : ''" (ngModelChange)="triggerModelChange('points', ceil($event))" [disabled]="!isEditable || model.pointsPerOption" [step]="1" aria-label="Total Points Input"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's remove step property, default value is already 1.
/** | ||
* Rounds up and returns the smallest integer greater than or equal to | ||
* the given number if not null | ||
*/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/** | |
* Rounds up and returns the smallest integer greater than or equal to | |
* the given number if not null | |
*/ | |
/** | |
* Rounds up and returns the smallest integer greater than or equal to | |
* the given number if not null. | |
*/ |
* Rounds up and returns the smallest integer greater than or equal to | ||
* the given number if not null | ||
*/ | ||
ceil(value: number): number { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Strictly speaking, since strict mode is enabled in tsconfig number is a non-nullable type. This should, if possible, be number | null
instead.
Thanks for reviewing my PR and sorry for the delay in response. I agree with you that we should be more consistent in the behaviour of the input validation so I have adopted the (keypress) solution mentioned above. However, I discovered that this solution does not prevent the user from pasting decimals numbers in. To resolve this, I implemented the onPaste method which restricts the content that can be pasted into the fields to be strictly numbers only. List of changes made from previous PR:
|
...components/question-types/question-edit-details-form/question-edit-details-form.component.ts
Outdated
Show resolved
Hide resolved
I have added the tests for onPointsInput to the classes that use this method(since the original class it is implemented in is an abstract class) but currently facing some difficulties in adding the test for the onPasteMethod. When trying to write the test for the method(as shown below), I constantly face the error
I am wondering if anyone knows how to resolve this error. Thanks! |
hi @dlimyy, I've looked into the issue, and I found that A solution I've found to mock a paste event is as follows:
Do try it out and let me know if it works! |
Hi @cedricongjh, thanks for your help and suggestion! I have tested this out on my end but it does not seem to invoke the onPaste method in the process. If I changed |
Ah that's unfortunate, let's leave that untested for now |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @dlimyy, seems like i'm able to enter very large numbers:
Do let me know if you can replicate this on your end and fix it!
Hi @cedricongjh, sorry for the delay in getting back to you! I am also able to replicate this bug on my end so currently I am working on a solution which restricts the length of the number to 9 characters to eliminate the chance of the bug occurring |
I have added my solution which restricts the user from keying in a number that has a length greater than 9 characters. The assignment of |
hey @dlimyy I think it'll be much better if we added the checking for numbers that are too long in the
|
Hi @cedricongjh, thank you for your suggestion. I have initially considered and tried implementing this in onPointsInput but I noticed that this would have a few issues. Firstly, if the user highlights a 9-digit number and types a number over it, the expected behaviour is that the highlighted/selected region is replaced with the number. However, if implemented in onPointsInput, only the last number of the 9 digit number would change rather than the whole highlighted region. Another issue would be that this does not prevent the user from pasting a larger input(Implementing this in the onPaste region with the highlighted region is also quite complicated). As I noted that my previous solution was quite clunky(with the methods implemented in the individual components), I decided to instead abstract it out into the I have also added the tests for the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thank you for the work on this!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @dlimyy, Sorry for the late review! The fix looks good for the 2 distribute points questions. I do have some reservations for the numeric scale question.
I think we still want to cap the inputs, due to the problems big numbers can cause in the backend. But I'm still not too sure what's a good solution. I'll try to come up with one in the next few hours. Feel free to suggest ideas too!
...pes/question-edit-details-form/constsum-options-question-edit-details-form.component.spec.ts
Outdated
Show resolved
Hide resolved
...pes/question-edit-details-form/constsum-options-question-edit-details-form.component.spec.ts
Outdated
Show resolved
Hide resolved
...tion-types/question-edit-details-form/num-scale-question-edit-details-form.component.spec.ts
Outdated
Show resolved
Hide resolved
...uestion-types/question-edit-details-form/num-scale-question-edit-details-form.component.html
Outdated
Show resolved
Hide resolved
Hi @jasonqiu212, thanks for reviewing my PR. For the numerical scale question case, would changing the stepper range to |
Hi @dlimyy, Ah yes, I think that's a valid solution. We can indeed just make use of the existing error message |
Hi @jasonqiu212, I have implemented this solution to fix this bug. I realised I put the min value twice for the num-scale question so I have removed it. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Edit: Sorry, accidentally ticked approved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @dlimyy, I apologize for the excessive back and forth on this PR! Really a big props to you for taking on this tough issue!
I mainly have 1 more suggestion on the increment step input for the numerical scale question. Please let me know what you think or any considerations you may have too!
...components/question-types/question-edit-details-form/question-edit-details-form.component.ts
Outdated
Show resolved
Hide resolved
...components/question-types/question-edit-details-form/question-edit-details-form.component.ts
Outdated
Show resolved
Hide resolved
...uestion-types/question-edit-details-form/num-scale-question-edit-details-form.component.html
Show resolved
Hide resolved
...components/question-types/question-edit-details-form/question-edit-details-form.component.ts
Show resolved
Hide resolved
...tion-types/question-edit-details-form/num-scale-question-edit-details-form.component.spec.ts
Show resolved
Hide resolved
Hi @jasonqiu212, I have added the changes mentioned above. I have also added a new method called |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! Good catch on preventing users from entering e
into float inputs! Great work @dlimyy 👍
Just a note for future reference, custom methods
|
Fixes #12557
Outline of Solution
Similar to the numerical scale question, I made it such that the number inputted will always be an integer so if the user tries keying in a number such as 99.5, it will be rounded up to 100. This helps to prevent this error from occurring and also reduces amount of code which has to be changed to accommodate decimals.
Screen recording of solution
https://github.com/TEAMMATES/teammates/assets/97420966/a311869e-e8e0-40a7-8724-cc568cb9e27d