Skip to content

Instantly share code, notes, and snippets.

@noppelmax
Created August 28, 2025 18:13
Show Gist options
  • Select an option

  • Save noppelmax/32d01c8d160f19b3d0bf2c5298c761a4 to your computer and use it in GitHub Desktop.

Select an option

Save noppelmax/32d01c8d160f19b3d0bf2c5298c761a4 to your computer and use it in GitHub Desktop.

Revisions

  1. noppelmax created this gist Aug 28, 2025.
    119 changes: 119 additions & 0 deletions preference_easy_fill_in.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,119 @@
    // ==UserScript==
    // @name Input preferences in HotCrp with one keypress
    // @namespace myhotcrp
    // @version 1.1
    // @description Link the key presses 1,2,3,0,9 to the respective preferences. 9 is -1.
    // @match https://*.hotcrp.com/*
    // @author Maximilan Noppel
    // @grant none
    // ==/UserScript==

    (function() {
    'use strict';

    const keyMap = {
    '1': '1',
    '2': '2',
    '3': '3',
    '0': '0',
    '9': '-1'
    };

    // Helper to simulate events
    function simulateKeyEvents(element, char) {
    // Keydown
    element.dispatchEvent(new KeyboardEvent('keydown', {
    key: char,
    code: 'Digit' + char,
    keyCode: char.charCodeAt(0),
    which: char.charCodeAt(0),
    bubbles: true,
    cancelable: true
    }));

    // Keypress
    element.dispatchEvent(new KeyboardEvent('keypress', {
    key: char,
    code: 'Digit' + char,
    keyCode: char.charCodeAt(0),
    which: char.charCodeAt(0),
    bubbles: true,
    cancelable: true
    }));

    // Input event (to trigger any input listeners)
    element.dispatchEvent(new InputEvent('input', {
    bubbles: true,
    cancelable: true,
    data: char,
    inputType: 'insertText'
    }));

    // Keyup
    element.dispatchEvent(new KeyboardEvent('keyup', {
    key: char,
    code: 'Digit' + char,
    keyCode: char.charCodeAt(0),
    which: char.charCodeAt(0),
    bubbles: true,
    cancelable: true
    }));
    }

    // Simulate pressing Enter key on the element
    function simulateEnter(element) {
    ['keydown','keypress','keyup'].forEach(type => {
    element.dispatchEvent(new KeyboardEvent(type, {
    key: 'Enter',
    code: 'Enter',
    keyCode: 13,
    which: 13,
    bubbles: true,
    cancelable: true
    }));

    });
    }

    window.addEventListener('keypress', function(event) {
    console.log(event.key);
    // Don't interfere if typing in inputs, textareas, or contenteditable
    const tag = event.target.tagName.toLowerCase();
    if (tag === 'input' || tag === 'textarea' || event.target.isContentEditable) return;

    const val = keyMap[event.key];
    if (val === undefined) return;

    const field = document.getElementById('revprefform_d');
    const nextLink = document.getElementById('n-next');

    if (!field) {
    console.warn('Field with id "revprefform_d" not found.');
    return;
    }
    if (!nextLink) {
    console.warn('Link with id "n-next" not found.');
    return;
    }

    event.preventDefault(); // prevent default action for these keys

    // Focus field
    field.focus();

    // Clear field value first
    field.value = '';

    // If val is -1, it's two chars (minus and 1), so simulate both separately
    const chars = val.split('');
    chars.forEach(c => simulateKeyEvents(field, c));

    // After input, set the actual value to be safe
    field.value = val;

    // Simulate pressing Enter to submit input
    simulateEnter(field);

    });

    })();