Creating a Button to Bury Current Card

I’m trying to create a button in Anki directly on the Card that, when clicked, buries the current card. Here’s what I have so far:

HTML/JavaScript (in card front):

<button id="buryButton" onclick="custom_bury_card()">Bury</button>

<script>
function custom_bury_card() {
    pycmd('custom_bury_card');
}
</script>

Python Add-on (__init__.py):

from aqt import mw, gui_hooks
from aqt.utils import tooltip

# Function to bury the current card
def custom_bury_card():
    card = mw.reviewer.card
    if card:
        mw.col.sched.buryCards([card.id])
        card.flush()
        mw.reset()
        mw.reviewer.card = card  # Update the current card in the reviewer
        tooltip("Card was buried.")  # Show a tooltip message

# Function to handle the JavaScript message
def on_webview_did_receive_js_message(handled, message, context):
    if message == "custom_bury_card":
        custom_bury_card()
        return (True, None)  # Indicate success with (True, None)
    
    return handled  # Return the original handled value otherwise

# Register hook to handle JavaScript messages
gui_hooks.webview_did_receive_js_message.append(on_webview_did_receive_js_message)

Despite setting up the button and the Python add-on to handle the custom_bury_card command, clicking the button does not bury the current card as expected.

I also tried to create a button in Anki that, when clicked, suspends the current card.

<button id="suspendButton" onclick="custom_suspend_card()">Suspend</button>

<script>
function custom_suspend_card() {
    pycmd('custom_suspend_card');
}
</script>

Python Add-on (__init__.py):

from aqt import mw, gui_hooks
from aqt.utils import tooltip

# Function to suspend the current card
def custom_suspend_card():
    card = mw.reviewer.card
    if card:
        mw.col.sched.suspendCards([card.id])
        card.flush()
        mw.reset()
        mw.reviewer.card = card  # Update the current card in the reviewer
        tooltip("Card was suspended.")  # Show a tooltip message

# Function to handle the JavaScript message
def on_webview_did_receive_js_message(handled, message, context):
    if message == "custom_suspend_card":
        custom_suspend_card()
        return (True, None)  # Indicate success with (True, None)
    
    return handled  # Return the original handled value otherwise

# Register hook to handle JavaScript messages
gui_hooks.webview_did_receive_js_message.append(on_webview_did_receive_js_message)

I would appreciate any guidance to make this button function correctly.
Thank you!

1 Like

I believe I’ve found the solution to my issue. The Python code appears to be working correctly now.

The functionality seems to work, but I had to introduce a 100ms latency before calling mw.reset() to prevent unintended burying of the next card. Is a 100ms delay normal in such implementations? Should I consider adjusting the order of my Python code or look into other potential issues?

mw.progress.timer(100, mw.reset, False) # Wait 100ms before calling mw.reset()

Using card.flush() resulted in an error message.

Here’s the complete code:

HTML and JavaScript code:

Insert this HTML code into your Anki card template:

<button id="buryButton" onclick="buryCard()">Bury</button>

Insert this JavaScript code into your Anki card template:

<script>
function buryCard() {
    pycmd('custom_bury_card');
}
</script>

Addon Python code:

from aqt import mw
from aqt.reviewer import Reviewer
from aqt.utils import tooltip
from anki.hooks import wrap

def custom_bury_card():
    card = mw.reviewer.card
    if card:
        card_id = card.id
        mw.col.sched.buryCards([card_id])
        tooltip("Card buried")  # Optional: Display confirmation message
        mw.progress.timer(100, mw.reset, False)  # Wait 100ms before calling mw.reset()

def linkHandler_wrap(reviewer, url):
    if url == "custom_bury_card":
        custom_bury_card()
    else:
        # Call the original link handler for other URLs
        originalLinkHandler(reviewer, url)

# Save the original link handler
originalLinkHandler = Reviewer._linkHandler

# Wrap the link handler with our custom function
Reviewer._linkHandler = wrap(Reviewer._linkHandler, linkHandler_wrap)

Is there a more efficient way without using a delay in the code?

Any insights or suggestions would be greatly appreciated.

Thank you!

Is there a more efficient way without using a delay in the code?

I think the mw.progress.timer(100, mw.reset, False) could be replaced with mw.col.update_card(card)? update_card is what you generally should be calling after modifying card information. I’m not entirely sure if update_card applies to scheduling information though.

1 Like

Thank you for the tip! I tested it, but unfortunately, I haven’t had any success yet. Here is the code I tried:

from aqt import mw
from aqt.reviewer import Reviewer
from aqt.utils import tooltip
from anki.hooks import wrap

def custom_bury_card():
    card = mw.reviewer.card
    if card:
        card_id = card.id
        mw.col.sched.buryCards([card_id])
        tooltip("Card buried")  # Optional: Shows a confirmation
        mw.col.update_card(card)

def linkHandler_wrap(reviewer, url):
    if url == "custom_bury_card":
        custom_bury_card()
    else:
        # Call the original link handler for other URLs
        originalLinkHandler(reviewer, url)

# Save the original link handler
originalLinkHandler = Reviewer._linkHandler

# Wrap the link handler with our custom function
Reviewer._linkHandler = wrap(Reviewer._linkHandler, linkHandler_wrap)

What could I be missing?

I think it won’t work unless you call CollectionOp. Here’s a reference:

Try copying the file and modifying it to suit your needs.

But you can bury a card by just pressing the - button on the keyboard. Adding another button seems redundant.

2 Likes

Thank you for your input and suggestion regarding using CollectionOp for handling card operations in Anki. I understand your point about the keyboard shortcut being a straightforward method for burying cards. I’m specifically looking to implement a button-based solution because I intend to use Anki on a Windows tablet where I won’t have access to a keyboard. This setup makes button controls more practical and quicker for me, especially when managing cards.

I’ve integrated the suggestions you provided into my code, but I’m still facing issues.

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