# Instant type:answer feedback for Cloze Note Type

**URL:** <https://forums.ankiweb.net/t/instant-type-answer-feedback-for-cloze-note-type/40631>\
**Category:** Card Design\
**Created:** [February 2, 2024, 10:50am UTC](https://forums.ankiweb.net/t/instant-type-answer-feedback-for-cloze-note-type/40631 "2024-02-02T10:50:53Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![a\_ps](https://avatars.discourse-cdn.com/v4/letter/a/b5e925/32.png) [@a\_ps](https://forums.ankiweb.net/u/a_ps)\
**Post date:** [February 2, 2024, 10:50am UTC](https://forums.ankiweb.net/t/instant-type-answer-feedback-for-cloze-note-type/40631/1 "2024-02-02T10:50:53Z")

</div>

Is there a way to implement this code, that’s made for basic note type to be used in a cloze note type?

```auto
<script>
  (() => {
  /**
   * Type-in-the-answer live feedback for Anki
   * @author Matthias Metelka | @kleinerpirat
   */
    /* Helper functions to keep caret position while typing */
    const getCaretPosition = (contenteditable) => {
      contenteditable.focus();
      let _range = document.getSelection().getRangeAt(0);
      let range = _range.cloneRange();
      range.selectNodeContents(contenteditable);
      range.setEnd(_range.endContainer, _range.endOffset);
      return range.toString().length;
    };
    const setCaretPosition = (contenteditable, pos) => {
      contenteditable.focus();
      document.getSelection().collapse(contenteditable, pos);
    };

    /* Replace input with contenteditable div */
    const input = document.getElementById("typeans");
    const editable = document.createElement("div");
    editable.contentEditable = true;
    editable.id = "typeans";
    editable.innerHTML = input.value;
    input.replaceWith(editable);

    editable.addEventListener("input", () => {
      const pos = getCaretPosition(editable);
      /* Anki uses value attribute to compare answer */
      editable.value = editable.innerText;

      editable.innerHTML = (() => {
        const letters = editable.innerText.split("");
        const word = "{{Answer}}";
        let html = "";
        letters.forEach((letter, i) => {
          html += `<span class="${
            letter == word[i] ? "typeGood" : "typeBad"
          }">${letter}</span>`;
        });
        return html;
      })();
      setCaretPosition(editable, pos);
    });
  })();
</script>

```

```auto
[contenteditable]#typeans {
  border: thin solid var(--border);
  background: var(--frame-bg);
}

```

---

<div class="post-metadata">

**Author:** ![jcznk](https://sea2.discourse-cdn.com/flex002/user_avatar/forums.ankiweb.net/jcznk/32/15215_2.png) [@jcznk](https://forums.ankiweb.net/u/jcznk)\
**Post date:** [February 2, 2024, 11:48am UTC](https://forums.ankiweb.net/t/instant-type-answer-feedback-for-cloze-note-type/40631/2 "2024-02-02T11:48:04Z")

</div>

Maybe try this. It is a simplified version of the template I’m currently using:

Front Template:

```auto
{{cloze:Text}}

<!----------------------------------------------------->

<script>
var currentCloze = document.querySelectorAll(".cloze");

// Hide the original cloze elements and create input boxes
for (i = 0; i < currentCloze.length; i++) {
  currentCloze[i].style.display = "none";
  const input = document.createElement("input");
  input.type = "text";
  input.classList.add("custom_typebox");

  currentCloze[i].insertAdjacentElement("afterend", input);
}

var ctb = document.querySelectorAll('.custom_typebox');

// Iterate through custom_typebox elements to set placeholders and adjust widths
for (j = 0; j < ctb.length; j++) {
  var text = document.getElementsByClassName('cloze')[j].innerText; 
  var result = text.replace("[...]", "");
  var final_result = result.slice(1,-1);
  ctb[j].placeholder = final_result;
  
// Create a hidden element to calculate the actual width of the placeholder
  var hiddenElement = document.createElement('span');
  hiddenElement.innerText = final_result;
  hiddenElement.style.visibility = 'hidden';
  hiddenElement.style.whiteSpace = 'pre'; // Preserve white spaces

// Insert the hidden element into the page and use it to calculate the actual width of the placeholder
  document.body.appendChild(hiddenElement);
  var placeholderWidth = hiddenElement.getBoundingClientRect().width;

// Remove the hidden element from the page
  hiddenElement.parentNode.removeChild(hiddenElement);

// Set the width of the input field
  ctb[j].style.width = placeholderWidth + 9 + "px";
}
</script>

<!----------------------------------------------------->

<script>
   /**
   * Type-in-the-answer live feedback for Anki (vague variant)
   * @author Matthias Metelka | @kleinerpirat
   * Modified by @jcznk (for cloze compatibility, replacements, etc.)
   * Any errors or oversights are to be attributed to me
   * Only works with Anki ~ 2.1.56 and more recent versions.
   */

for (i = 0; i < 999; i++) {
  (() => {
    const input = document.getElementsByClassName('custom_typebox')[i];
    const cloze_content = document.getElementsByClassName('cloze')[i].getAttribute("data-cloze").replace(/<.*?>/g, "").replace(/&lt;/g, '<').replace(/&gt;/g, '>').replace(/&amp;/g, '&'); 
    const answer = cloze_content;

    if (input) {
      input.addEventListener("input", () => {
        input.classList.add("typed");
        input.classList.toggle(
          "goodsofar",
          input.value.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "") == answer.substring(0, input.value.length).toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "")
        );
        input.classList.toggle(
          "correct",
          input.value.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "") == answer.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "")
        );
      });
    }
  })();
}
</script>

```

Styling section:

```auto
/* ------------------------------------------------------ INPUT */

input[type=text]{
  color: black;
  background-color: unset;
  text-align: center;
  cursor: text;
  min-width: 150px;
  width: 150px;
  border-radius: 5px;
  border-style: solid; 
  border-width: 1px;
 }
input[type=text]::placeholder {
  opacity: 0.5;
}
.night_mode input[type=text]::placeholder {
  color: white;
}

/* -------------------------------------------------- TYPECHECK */

.custom_typebox.typed {
  background-color: #ff9999;
}
.custom_typebox.typed.goodsofar {
  background-color: #ffff7f;
}
.custom_typebox.typed.correct {
  background-color: #99ff99;
}
.custom_typebox.typed::placeholder {
  color: black !important;
}

```

---

<div class="post-metadata">

**Author:** ![a\_ps](https://avatars.discourse-cdn.com/v4/letter/a/b5e925/32.png) [@a\_ps](https://forums.ankiweb.net/u/a_ps)\
**Post date:** [February 2, 2024, 12:20pm UTC](https://forums.ankiweb.net/t/instant-type-answer-feedback-for-cloze-note-type/40631/4 "2024-02-02T12:20:58Z")

</div>

WoW! Thank you! Worked a lot!

\*Getting used in the Forum

---

<div class="post-metadata">

**Author:** ![a\_ps](https://avatars.discourse-cdn.com/v4/letter/a/b5e925/32.png) [@a\_ps](https://forums.ankiweb.net/u/a_ps)\
**Post date:** [February 5, 2024, 8:10am UTC](https://forums.ankiweb.net/t/instant-type-answer-feedback-for-cloze-note-type/40631/5 "2024-02-05T08:10:11Z")

</div>

@jcznk, could you please help me? On the front card, I want to play audio only for c1, c2, and so on, but for some reason, the script returns blank for this TTS code:

```auto
{{tts de_DE voices=Apple_Anna_(Premium):cloze-only:Text}}

```

If I use it on the back card, it plays as expected.

Also, it plays c1 and c2 together. I haven’t figured out how to separate them, so that there’s one play for c1 and another for c2.

---

<div class="post-metadata">

**Author:** ![jcznk](https://sea2.discourse-cdn.com/flex002/user_avatar/forums.ankiweb.net/jcznk/32/15215_2.png) [@jcznk](https://forums.ankiweb.net/u/jcznk)\
**Post date:** [February 5, 2024, 4:59pm UTC](https://forums.ankiweb.net/t/instant-type-answer-feedback-for-cloze-note-type/40631/6 "2024-02-05T16:59:31Z")

</div>

Unfortunately, I never used tts in conjunction with cloze deletions, so I have no familiarity with the code.

My first impression, though, is that both your requests are pretty difficult/impossible to accomplish, except maybe by using add-ons or complex workarounds.

* * *

On a side note, you might want to add this script to the Front template. I forgot it to include it last time. It allows the use of the Enter key to flip the card, even when the focus is inside a custom typebox.

```auto
<script>
for (let i = 0; i < ctb.length; i++) {
    ctb[i].addEventListener("keydown", function(event) {
        if (event.key === 'Enter') {
            if (typeof (pycmd) !== 'undefined') {
                ctb[i].blur(); 
                pycmd('ans'); 
            }
        }
    });
}
</script>

```

---

<div class="post-metadata">

**Author:** ![a\_ps](https://avatars.discourse-cdn.com/v4/letter/a/b5e925/32.png) [@a\_ps](https://forums.ankiweb.net/u/a_ps)\
**Post date:** [February 6, 2024, 6:49pm UTC](https://forums.ankiweb.net/t/instant-type-answer-feedback-for-cloze-note-type/40631/7 "2024-02-06T18:49:03Z")

</div>

Amazing all your help!

I found something that worked as well.

```auto
 [anki:tts lang=de_DE voices=Apple_Anna_(Premium)] {{Artikel}}{{Wort_DE}}[/anki:tts]

```

---

<div class="post-metadata">

**Author:** ![a\_ps](https://avatars.discourse-cdn.com/v4/letter/a/b5e925/32.png) [@a\_ps](https://forums.ankiweb.net/u/a_ps)\
**Post date:** [February 6, 2024, 6:55pm UTC](https://forums.ankiweb.net/t/instant-type-answer-feedback-for-cloze-note-type/40631/8 "2024-02-06T18:55:45Z")

</div>

I’ve been trying all day to convert the cloze script into a type-in-the-answer format, but unfortunately, I haven’t had any success.

By the way…do you have any type-in-the-answer card version of it?

---

<div class="post-metadata">

**Author:** ![jcznk](https://sea2.discourse-cdn.com/flex002/user_avatar/forums.ankiweb.net/jcznk/32/15215_2.png) [@jcznk](https://forums.ankiweb.net/u/jcznk)\
**Post date:** [February 6, 2024, 9:08pm UTC](https://forums.ankiweb.net/t/instant-type-answer-feedback-for-cloze-note-type/40631/9 "2024-02-06T21:08:59Z")

</div>

I’m not sure if I’ve understood what you’re trying to achieve. Would you please elaborate your request?

---

<div class="post-metadata">

**Author:** ![a\_ps](https://avatars.discourse-cdn.com/v4/letter/a/b5e925/32.png) [@a\_ps](https://forums.ankiweb.net/u/a_ps)\
**Post date:** [February 8, 2024, 7:20am UTC](https://forums.ankiweb.net/t/instant-type-answer-feedback-for-cloze-note-type/40631/10 "2024-02-08T07:20:00Z")

</div>

I achieved with this:

```auto
<div class="class">
    <input type="text" class="ctb" placeholder="Type your answer here..." id="typeans">
    <!-- Assuming there's a replay button or other elements -->
</div>

<script>
  (() => {
    const input = document.getElementById("typeans");
    const answer = "{{Wort_DE}}"; // Replace "CorrectAnswer" with your actual answer string

    if (input) {
      input.addEventListener("input", () => {
        input.classList.add("typed");
        input.classList.toggle(
          "goodsofar",
          input.value == answer.substring(0, input.value.length)
        );
        input.classList.toggle(
          "correct",
          input.value == answer
        );
      });
    }
  })();
</script>

```

I wanted a input text box that I could use on phone and mac, with all the type-in-text feedback.

---

<div class="post-metadata">

**Author:** ![jcznk](https://sea2.discourse-cdn.com/flex002/user_avatar/forums.ankiweb.net/jcznk/32/15215_2.png) [@jcznk](https://forums.ankiweb.net/u/jcznk)\
**Post date:** [February 13, 2024, 7:40pm UTC](https://forums.ankiweb.net/t/instant-type-answer-feedback-for-cloze-note-type/40631/12 "2024-02-13T19:40:25Z")

</div>

The “Type-in-the-answer live feedback” script I posted does not work on 2.1.54. Some of the code it interacts with (mainly, the `data-cloze` attribute) was only introduced around version ~ 2.1.56.

EDIT: added a comment about this to the script.

---

<div class="post-metadata">

**Author:** ![rx2](https://avatars.discourse-cdn.com/v4/letter/r/57b2e6/32.png) [@rx2](https://forums.ankiweb.net/u/rx2)\
**Post date:** [February 13, 2024, 7:53pm UTC](https://forums.ankiweb.net/t/instant-type-answer-feedback-for-cloze-note-type/40631/13 "2024-02-13T19:53:26Z")

</div>

Yeh I’ve figured out so I’ve deleted my message, but you’ve been pretty fast on answer my stupid question. Thank you so much!

It’s work seamlessly, the only thing I could figure it out is the @a_ps last code, with the answer box, I mean the script work pretty well just like this so it’s not a real problem.

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/flex002/uploads/anki2/original/1X/8f1279ababc5879d54e4838989f606cfe55af8c7.jpeg) [@system](https://forums.ankiweb.net/u/system)\
**Post date:** [March 14, 2024, 7:54pm UTC](https://forums.ankiweb.net/t/instant-type-answer-feedback-for-cloze-note-type/40631/14 "2024-03-14T19:54:02Z")

</div>

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.
