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!

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.

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.

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.