Skip to content
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

JS Cleanup #198

Draft
wants to merge 10 commits into
base: development
Choose a base branch
from
Draft

JS Cleanup #198

wants to merge 10 commits into from

Conversation

nienna73
Copy link
Contributor

@nienna73 nienna73 commented May 17, 2021

What's in this PR:

  • removed all onclick attributes on buttons and links
  • added event listeners in place of all onclick attributes
  • moved all JS to its own file

What still needs doing:

  • tests! Lots of the functionality that relies on JS isn't covered in the tests

Notes:
This branch was originally created to solve this issue, where a single quotation mark in a phrase would prevent a user from editing it:

single-quote-issue.mov

Copy link
Member

@eddieantonio eddieantonio left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! I have tonnes of suggestions for how to embetter the JS, but that's better done in a pairing sesh than endless GH comments, haha. Feel free to reach out if you have any questions :)

EDIT: I do not understand the sprinkling of async on all of the event handlers when none of them use the await keyword or need to return a Promise. Is there a reason for these to be async?

<div class="menu__none rec-wrong-word" data-rec-id={{ recording.id }}>
<form id="{{ recording.id }}-wrong-word" method="POST" action="/api/save_wrong_word/{{ recording.id }}">
<input type="hidden" name="csrfmiddlewaretoken" value="{{ csrf_token }}">
<input type="hidden" name="referrer" value="{{ request.build_absolute_uri() }}">
What word is being spoken?
<input type="text" id="wrong_word" name="wrong_word">
<input form="{{ recording.id }}-wrong-word" type="submit" value="Save" class="button button--success button--small save-wrong-word" data-rec-id={{ recording.id }}>
<input type="button" class="button button--fail button--small" value="Cancel" data-rec-id={{ recording.id }})" onclick="hideWrongWordDiv('{{ recording.id }}')">
<input type="button" class="button button--fail button--small" value="Cancel" data-cy="cancel-wrong-word-button" data-rec-id={{ recording.id }})">
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be a <button>?

Suggested change
<input type="button" class="button button--fail button--small" value="Cancel" data-cy="cancel-wrong-word-button" data-rec-id={{ recording.id }})">
<button type="button" class="button button--fail button--small" data-cy="cancel-wrong-word-button" data-rec-id={{ recording.id }})">Cancel</button>

@@ -45,11 +6,13 @@
<div class="table-responsive">

<div>
<button class="button button--success button--back" onclick='goBack()'>Back</button>
<button data-cy="back-button" class="button button--success button--back">Back</button>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a really pendatic note, but this should be an <a> with the back page as its href. If you know what page it should go "back" to in advance, that href can be hardcoded. Otherwise, this answer from StackOverflow is really nice:

// adapted from: https://stackoverflow.com/a/46163215/6626414
for (let el of document.querySelectorAll('a.button--back')) {
    el.setAttribute('href', document.referrer);

    // this remains the same!
    el.addEventListener('click', (evt) => {
        window.history.back();
    })
}

@@ -4,6 +4,6 @@ <h5>Edit Segment</h5>
<input type="hidden" name="csrfmiddlewaretoken" value="{{ csrf_token }}">
{{ form }}
<input data-cy="save-button" type="submit" class="button button--success" value="Save">
<input data-cy="cancel-button" type="button" class="button button--fail" onclick="hideDiv()" value="Cancel">
<input data-cy="cancel-button" type="button" class="button button--fail" value="Cancel">
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be a <button>?

Suggested change
<input data-cy="cancel-button" type="button" class="button button--fail" value="Cancel">
<button type="button" data-cy="cancel-button" type="button" class="button button--fail">Cancel</button>


document.addEventListener('DOMContentLoaded', () => {
for (let button of document.querySelectorAll('[data-segment-name]')) {
button.addEventListener("click", async (e) => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
button.addEventListener("click", async (e) => {
button.addEventListener("click", (e) => {

}

for (let button of document.querySelectorAll('[data-cy="accept-button"], [data-cy="revert-button"]')) {
button.addEventListener("click", async(e) => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
button.addEventListener("click", async(e) => {
button.addEventListener("click", (e) => {

}

for (let button of document.querySelectorAll('[data-cy="back-button"]')) {
button.addEventListener("click", async(e) => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
button.addEventListener("click", async(e) => {
button.addEventListener("click", (e) => {


function showDiv() {
document.getElementById('edit').style.display = "block";
document.getElementById('id_cree').focus()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: assigning focus programmatically is considered not a great practice, but here, I don't think it matters much. Always be careful with focus stealing.

menu.classList.add("menu__none");
menu.classList.remove("menu__block");
document.addEventListener("DOMContentLoaded", () => {
for (let link of document.querySelectorAll('[data-cy="show-flex-button"]')) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So "flex" button refefers to 'flex as in "cirum" and not as in "-box". Because I thought this was a like a button { display: flex; } at first 😂 😂 😂


document.addEventListener("DOMContentLoaded", () => {
for (let button of document.querySelectorAll('[data-cy="wrong-word-button"]')) {
button.addEventListener("click", async (e) => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
button.addEventListener("click", async (e) => {
button.addEventListener("click", (e) => {

}

for (let button of document.querySelectorAll('[data-cy="cancel-wrong-word-button"]')) {
button.addEventListener("click", async (e) => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
button.addEventListener("click", async (e) => {
button.addEventListener("click", (e) => {

Copy link
Contributor

@andrewdotn andrewdotn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good

Only general comment is that sometimes you’re putting semicolons at the ends of lines and sometimes not, so you might want to start using prettier to just do all the code formatting for you.

Comment on lines +19 to +21
const transcription = e.target.dataset.transcription
const translation = e.target.dataset.translation
const analysis = e.target.dataset.analysis
Copy link
Contributor

@andrewdotn andrewdotn May 18, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you want to use some fancier syntax*

Suggested change
const transcription = e.target.dataset.transcription
const translation = e.target.dataset.translation
const analysis = e.target.dataset.analysis
const { transcription, translation, analysis } = e.target.dataset;

*I think this has now has excellent browser support

// Helper functions that are needed across multiple JS files


function getElementByPhraseId(className, phraseId) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should be able to do a lookup using the DOM API instead of having to do a linear scan:

document.querySelector(`.${className}[data-phrase-id=${phraseId}]`)

That said, I know there were issues with quoting related to the format of the ID that may make that trickier. That’s one reason that automatic numeric ID columns are so handy.

@nienna73 nienna73 marked this pull request as draft June 9, 2021 17:10
@nienna73
Copy link
Contributor Author

nienna73 commented Jun 9, 2021

I converted this PR to a draft as it needs quite a bit of work and is no longer my top priority.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants