Flexible Cloze [Support thread]

Yet another cloze variant but this one is written entirely client side (JavasScript).

Ideas for the functionality of this cloze variant blatantly stolen from trgkanki’s Cloze (Hide all) [Cloze (Hide All) - AnkiWeb] and RisingOrange’s Enhanced Cloze (for Anki 2.1) [Enhanced Cloze (for Anki 2.1) - AnkiWeb] - both of which are excellent addons. However all code written from scratch (ok, I peeked at some other code)

ALL CREDIT FOR INNOVATION GOES TO TRGANKI AND RISINGORANGE

2 Likes

Can you tell where i need to edit to make the cloze blur or show “…” rather than solid box?
Also, is image occlusion supported under this card?

To change the cloze formatting open Tools->Mange Note Types->Flexible Cloze->Cards->Styling.

To change what is displayed when the cloze is hidden: Under .fcz-config:

/* Flexible cloze configuration===================== */
.fcz-config {
–cloze-element: “div”;
–inactive-prompt: “insert your prompt here”;
–active-prompt: “insert your prompt here”;
–key-next-cloze: “j”;
–key-previous-cloze: “h”;
–key-toggle-all: “k”;
–iteration-hides-previous: “true”;
}

To change the styling of the cloze “boxes”: I recommend keeping edits outside the FCZ begin/end and since CSS is cascading the last rule is the one that is applied so overriding default styling should be done below the FCZ end-line. So, override the default styles for .fcz-active and .fcz-inactive classes (FCZ default styling is detailed under the “Cloze styling” heading inside the FCZ being/end tags). Setting an attribute to unset removes all previous styling and with keyword all you can catch all attributes (google “css initial unset” for more details).

Below example removes all “box” formatting and only displays the prompt/hint/answer text in blue for active clozes and gray for inactive clozes (inserted below the FCZ end-line):

.fcz-active, .fcz-active[state]
{ all: unset; cursor: pointer; color: blue;}

fcz-inactive, .fcz-inactive[state]
{ all: unset; cursor: pointer; color: gray;}

Regarding image occlusion: Depending on what you mean. You can include images in the cloze content and/or hints, that’s no problem. However if you mean functionality as with the Image Occlusion Enhanced add-on: no. I see no technical issues implementing a similar functionality as Image Occlusion Enhanced (it would just be floating divs covering parts of an image) however that would mean you could no longer contain everything client side (you’d need some interface from the editor to insert the image and “draw boxes” over the areas you want to cover). Such an implementation would have to be written from scratch - it would have nothing to do with the Image Occlusion Enhanced add-on. Also it would involve several orders of magnitude of more code.

Hi, thanks for your template it works very well, I wonder if there is a way to make it start from first cloze despite if there is an active showed cloze or not .
thanks
PS: Because I change it a little to make it to not toggle hide after toggle showed so to keep the answers showed when moving to next one so i want it to start from top always despite if I clicked in one answer in middle.

That’s not possible with the current implementation, but if you want it you can manually edit the JS on the front to make it disregard active vs. inactive clozes when cycling. Just at a glance it would include something like changing the following lines:

  • "if(!first && active) { first = id_str; }" to "if(!first) { first = id_str; }"
  • "nds = [...document.querySelectorAll('[id^="fcz-id-"].fcz-active')];" to "nds = [...document.querySelectorAll('[id^="fcz-id-"]')];"
  • "nodes = [...document.querySelectorAll('[id^="fcz-id-"].fcz-active')];" to "nodes = [...document.querySelectorAll('[id^="fcz-id-"]')];"

Bear in mind that I haven’t tried the above so it might not work, there may be some other logic that discerns between active and inactive that would be implicated here, can’t remember of the top of my head.

It’s worked but after I modified those also with your solution:

  1. nds = [...document.querySelectorAll('[id^="fcz-id-"]')]; nds = [...document.querySelectorAll('[id^="fcz-id-"][state="hint"]')];
  2. nnd = nd to nnd = nds[i++]
  3. subtring(7) to substring(4)
    Thanks for your help

Thanks for your reply. I will try your suggestions

Hi,

  1. Is it possible to display the answer( back side card) inline rather than a separate block?
  2. Will it be possible to display only the active close and blur the inactive ones- as in the Massive cloze cards?

To display the answer inline just override the display property for the following classes to the option that suits your needs:
.fcz-active[state=hint] <== Front side, when the cloze is in “hint” state, default inline-block
.fcz-active[state=show] <== Front side, when the cloze is in “show” state, default block
.fcz-active[state=answer] <== Back side, when the cloze is in “answer” state, default block
.fcz-inactive[state=hide] <== Front side, when the cloze is in “hide” state, default inline-block
.fcz-inactive[state=hint] <== Front side, when the cloze is in “hint” state, default inline-block
.fcz-inactive[state=show] <== Front and back side, when the cloze is in “show” state, default block

To override just add a new CSS rule at the end of the Styling tab, for instance
.fcz-active[state=hint], .fcz-active[state=show], .fcz-active[state=answer],
.fcz-inactive[state=hide], .fcz-inactive[state=hint], .fcz-inactive[state=show]
{ display: inline; }

If you want them to look differently (text instead of box, other colors, different size etc.) use the same classes and override the appropriate properties (and the --fcz-active-prompt and --fcz-inactive-prompt for text to display).

To display active clozes only - depends on what you mean, to not show the inactive clozes you can style them as per above changing display to none:
.fcz-inactive[state=hide], .fcz-inactive[state=hint], .fcz-inactive[state=show]
{ display: none; }

However that will still leave all non-clozed text visible. With current implementation there is no logic to hide “irrelevant” non-clozed text but if you know some JavaScript you could hide it. Example logic would be assuming the following: [text1][inactive cloze1][text2][active cloze1][text3][inactive cloze2][text4] - only insert text following the preceding inactive cloze, the active cloze and text following active cloze (so here text2-active cloze 1-text3) on page load (the init() in the JavaScript on the front side). Alternatively insert the unwanted parts but put them in a div and set display to none. That would not be foolproof though, if you were to make a table and have different clozes in different cells these solutions would break the HTML (since it would not insert/break the table tag into parts in different diffs), you’d need some more logic to determine where to “hide to and from” to handle that.

Plz help, I couldn’t find a thread specific to my problem so I hope you can help: I’m trying to follow an Anki tutorial, however, I downloaded it from an apple computer and none of the options on the tutorial are available to me. I tried cloze flashcards but it showed up as a basic reverse flashcard. I tried a basic type in the answer flashcard, but when I tried it there was no answer box, again only a basic reverse flashcard. Why don’t I have the resources everyone else has? Thank you for your time!

I am not sure I understand what you mean but as you are following an Anki tutorial I am guessing you are new to Anki? Just to make sure we are talking about the same things, let me know where your problems are in the following steps:

  1. Open Anki and select “Add” (or press A), this opens the “Add” window

  2. Select Type “Cloze”, this shows fields “Text” and “Back Extra”

  3. Enter text, hightlight some part of it and press “[…]” (or press Ctrl+Shift+C), this should wrap the highlighted text like so {{c1::highlighted text}}

  4. Press “Add” and then “Close”

  5. In main window select the deck you added the note to and press “Study Now” this should bring up the card with the cloze hidden behind […] in blue

  6. Press show answer and the clozed out text should be shown.

Which of the above steps are causing the problem?

New update, see add-on page.

1 Like

A user question: It would seem that similar functionality as what is provided by Glutanimates Cloze Overlapper (Cloze Overlapper - AnkiWeb) can be achieved with FCZ by setting --iteration-hides-previous: “true”; and then making the list with the same ordinal eg:
1. {{c1:Blabla}}
2. {{c1:Bleble}}
3. {{c1:Blibli}}
4. {{c1:Bloblo}}

The functionality will not be identical with Cloze Overlapper though as you would get the entire list from top to bottom every time (rather than just item 3 in the list for example).

However there is no current option to show “surrounding clozes” but that should only require a few lines of code to add. If so, how would you want it to function? A few ideas:

  • Generic approach: {{c1::#Blabla}} and --list-pre: "2"/--list-post: "3" where # would mean showing the --list-pre number of clozes before and --list-post number of clozes after. I.e. all lists get the same.
  • Easy edit: {{c1::#Blabla}} where # would mean show preceding cloze (I'm guessing the most common use case) and ## would mean show preceding and following cloze. I.e. can be determined at the level of the individual list item.
  • Highly configurable alt. 1: {{c1::##%%%Blabla}} where ## would mean show 2 clozes before and %%% would mean show 3 clozes after. Still editable at the level of the individual list item.
  • Highly configurable alt. 2: {{c1::#1#2#Blabla}} where #1#2# would mean "show one cloze before and 2 clozes after. Still editable at the level of the individual list item.

To facilitate editing/adding lists of the above, a JS-snipplet bound to a hot-key would be easy to create to “insert same ordinal clozes with # over each line in the selection” or similar.

Thoughts?

Is this just me, or does all the JS make this note type really slow? It takes around 12 s to load every card (around 20 clozes per card) on a 4750 Ryzen.

I am going out on a limb here but I think there may be something with your Anki setup… I do my reviews mainly on a tablet (which admittedly is decent spec, a S7+ tab) but I can also do them no problem on my Pixel 3 phone (just checked a 20-something cloze card on the phone, load time < 1s) or my 6 year old laptop that wasn’t even all that to begin with. I guess if your clozes contains a truckload of text or huge images there will be some file I/O time but nothing that should come close to 12s load time. From a JS perspective the little JS this addon adds is nothing compared to the fact that the reviewer loads jQuery for instance (granted it doesn’t call anything from it).

Ok, I will try to find out if it’s an addon conflict. I have been using Cloze hide all until now, and those cards load quickly. Trying to migrate to your addon however, bc card generation is not addon dependent (cloze hide all gets broken with every other release of anki).

BTW, could you help me replicate the minimal look of my previous cards with your addon? I could try to do it by trial and error, but this will take days with my codeing skills.

Front:
image

Back:

Pressing button:

@koermer
You have 500 clozes brackets, so if it runs slow in your device try what I do, I keep only cloze number that I usually use like only 10 maybe because when I keep it 500 clozes in front it runs slow

Ok, just tried adding a 400 000 character note with 1500 clozes, three of each ordinal up to 500 (granted, no images, I just made a large “lorem ipsum” and automated in a cloze around the second sentence of each line/paragraph). Load time was ~2s (which is faster than the time it took to paste that card into the Anki editor) and answer time (to “flip” the card) ~3s on my 6 y/o laptop (which wasn’t high spec when I got it). I am not certain that it is a cloze number issue only, unless you have a really low end spec machine, but I may be wrong.

To get that style of clozes you should in the “Styling” section of the card edit the “Cloze styling” bit. Without having tried it, it should be something like replacing the following:
/* CLOZE STYLING =============================================== /
/
Active clozes base look and feel, valid on front and back and all states */
.fcz-active
{ margin: 1px; padding : 5px; vertical-align: middle; min-width: 100px; min-height: 0.5em;
border-color: black; border-width: 2px; border-style: solid; }

/* Display form and style of active clozes on front */
.fcz-front .fcz-active
{ background-color: #FA8072; }

/* Display form and style of active clozes on back */
.fcz-back .fcz-active
{ background-color: #D0F0C0; }

/* Display form and style of hint-state active clozes (front and back), change to “inline” for a continuous line */
.fcz-active[state=hint]
{ display: inline-block; }

/* Display form and style of show-state active clozes (front and back), change to “inline” for a continuous line */
.fcz-active[state=show]
{ display: block; }

/* Inactive clozes base look and feel, valid on front and back and all states */
.fcz-inactive
{ margin: 1px; padding : 5px; vertical-align: middle; min-width: 100px; min-height: 0.5em;
border-color: black; border-width: 1px; border-style: solid; }

/* Display form and style of inactive clozes on front */
.fcz-front .fcz-inactive
{ background-color: #F0F0F0; }

/* Display form and style of inactive clozes on back */
.fcz-back .fcz-inactive
{ background-color: #F0F0F0; }

/* Display form of hide-state inactive clozes (front and back), change to “inline” for a continuous line */
.fcz-inactive[state=hide]
{ display: inline-block; }

/* Display form of hint-state inactive clozes (front and back), change to “inline” for a continuous line */
.fcz-inactive[state=hint]
{ display: inline-block; }

/* Display form of show-state inactive clozes (front and back), change to “inline” for a continuous line */
.fcz-inactive[state=show]
{ display: block; }

/* Exposed clozes base look and feel /
.fcz-expose
{ display: inline; }

with:

/
CLOZE STYLING =============================================== /
/
Active clozes base look and feel, valid on front and back and all states */
.fcz-active
{ display: inline; text-color: blue; }

.fcz-inactive
{ display: inline; }

/* Exposed clozes base look and feel */
.fcz-expose
{ display: inline; }

And in the .fcz-config (on the Styling page)

/* FLEXIBLE CLOZE CONFIGURATION======================================= /
.fcz-config {
–cloze-element: “div”; /
What HTML element the clozes will be wrapped in /
–inactive-prompt: “[…]”; /
<===== Text to display (if any) on inactive hidden clozes /
–active-prompt: “[…]”; /
<===== Text to display (if any) on active hidden clozes /
–key-next-cloze: “j”; /
Keyboard shortcut to iterate forward /
–key-previous-cloze: “h”; /
Keyboard shortcut to iterate backward /
–key-toggle-all: “k”; /
Keyboard shortcut to toggle all fields hide/show /
–iterate-from-top: “false”; /
true makes next/previous iteration always start from top /
–iterate-inactive: “false”; /
true makes next/previous navigation also iterate inactive clozes /
–iteration-hides-previous: “true”; /
false leaves cloze open when cycling forward/backward */
}

However as for the “Reveal all” there is no such button functionality at the moment, I can look at adding one later. For anyone wanting one straight away I would suggest:

  • Add a configuration option --show-inactive-on-back: "true/false"
  • Add logic to the back side script to only show inactive clozes when the above option is true
  • Add logic to the back side script with a button that toggles hide/show for the inactive clozes (iterate the fcz-data[‘clozes’] array) OR just add a button that calls the toggle_all() function (that should result in correct behavior)

REGARDING STYLING
As there have been a few questions regarding the default styling of the template not looking like “regular Anki clozes”. You can have the clozes display however you want by adjusting the CSS on the “Styling” page of the “Cards” dialog. To achieve the “regular Anki cloze styling”:

  1. In the “FLEXIBLE CLOZE CONFIGURATION” section set:
  • --cloze-element: "span";
  • --inactive-prompt: "[...]";
  • --active-prompt: "[...]";
  1. Replace all the content under the “CLOZE STYLING” section with .fcz-active { color: blue; font-weight: bold; }
  2. If by chance I am little off on the font-weight you can fine-tune it by starting at 400 which is normal font-weight and going upward (900 would be “very bold”). Similarly if by chance the blue nuance is off you can insert the correct RGB instead, e.g. #0000FF.