Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to conditionally PreventDefault inside the input component in Blazor?

I want to prevent the default behavior of an input (html input tag with type="text") only when enter is pressed

protected void HandleKeyPress(KeyboardEventArgs keyboardEventArgs)
{
    if (keyboardEventArgs.Key == "Enter")
    {
        // prevent default
    }     

    // rest of function  
}

I know that I can do things like @on{EVENT}:preventDefault but how to do this conditionally inside the event handler?

In javascript I can do something like

function(e){
    if(e.keyCode == 13) {
      e.preventDefault();
    }
    // rest of function
}

How to do the same in blazor?

Edit:

I'm making an input for a library and I can't change the button of the submit, I need to prevent this inside my input component.

like image 655
Vencovsky Avatar asked Apr 22 '20 19:04

Vencovsky


2 Answers

As mentioned earlier, you have to do this in JavaScript. If you execute this JavaScript code:

window.addEventListener("load", function () {
    //This will be called when a key is pressed
    var preventDefaultOnEnterCallback = function (e) {
        if (e.keyCode === 13 || e.key === "Enter") {
            // console.log("Prevented default.")
            e.preventDefault();
            return false;
        }
    };
    //This will add key event listener on all nodes with the class preventEnter.
    function setupPreventDefaultOnEnterOnNode(node, add) {
        if (node instanceof HTMLElement) {
            var el = node;
            //Check if main element contains class
            if (el.classList.contains("prevent-default-on-enter") && add) {
                // console.log("Adding preventer: " + el.id);
                el.addEventListener('keydown', preventDefaultOnEnterCallback, false);
            }
            else {
                // console.log("Removing preventer: " + el.id);
                el.removeEventListener('keydown', preventDefaultOnEnterCallback, false);
            }
        }
    }
    //This will add key event listener on all nodes with the class preventEnter.
    function setupPreventDefaultOnEnterOnElements(nodelist, add) {
        for (var i = 0; i < nodelist.length; i++) {
            var node = nodelist[i];
            if (node instanceof HTMLElement) {
                var el = node;
                //Check if main element contains class
                setupPreventDefaultOnEnterOnNode(node, add);
                //Check if any child nodes contains class
                var elements = el.getElementsByClassName("prevent-default-on-enter");
                for (var i_1 = 0; i_1 < elements.length; i_1++) {
                    setupPreventDefaultOnEnterOnNode(elements[i_1], add);
                }
            }
        }
    }
    // Create an observer instance linked to the callback function
    // Read more: https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver
    var preventDefaultOnEnterObserver = new MutationObserver(function (mutations) {
        for (var _i = 0, mutations_1 = mutations; _i < mutations_1.length; _i++) {
            var mutation = mutations_1[_i];
            if (mutation.type === 'childList') {
                // A child node has been added or removed.
                setupPreventDefaultOnEnterOnElements(mutation.addedNodes, true);
            }
            else if (mutation.type === 'attributes') {
                if (mutation.attributeName === "class") {
                    console.log('The ' + mutation.attributeName + ' attribute was modified on' + mutation.target.id);
                    //class was modified on this node. Remove previous event handler (if any).
                    setupPreventDefaultOnEnterOnNode(mutation.target, false);
                    //And add event handler if class i specified.
                    setupPreventDefaultOnEnterOnNode(mutation.target, true);
                }
            }
        }
    });
    // Only observe changes in nodes in the whole tree, but do not observe attributes.
    var preventDefaultOnEnterObserverConfig = { subtree: true, childList: true, attributes: true };
    // Start observing the target node for configured mutations
    preventDefaultOnEnterObserver.observe(document, preventDefaultOnEnterObserverConfig);
    //Also check all elements when loaded.
    setupPreventDefaultOnEnterOnElements(document.getElementsByClassName("prevent-default-on-enter"), true);
});

Then you only need to add (or remove) the CSS class prevent-default-on-enter to your inputs where you want to have this behavior.

<input type="text" class="prevent-default-on-enter" />

<button type="submit" class="prevent-default-on-enter">Submit</button>

You can do this on the fly. No need to interact with JavaScript in your razor code :-)

like image 157
PEK Avatar answered Sep 22 '22 20:09

PEK


To achieve what you need you need to set html of your component like this

<input @onkeydown="KeyDown" @onkeydown:preventDefault="shouldPrevent" type="text" />
<p>@eventText</p>

You can set preventDefault as a variable and then change it in your C# code

@code {
    private bool shouldPrevent;
    private string eventText = "";

    private void KeyDown(KeyboardEventArgs e){
        if(e.Code is "Enter"){
            eventText = "Enter pressed";
            shouldPrevent = true;
            return;
        }
        eventText = "";
        shouldPrevent = false;
    }
}

Here you can check blazorfiddle with working code.

like image 39
Sousuke Avatar answered Sep 24 '22 20:09

Sousuke