Home

Trigger TextBox TextInput event not work

var textbox = new TextBox().Dump();
textbox.Click += (s, e) => "Trigger Click".Dump();
textbox.TextInput += (s, e) => "Trigger TextInput".Dump();

// Trigger Click is work
textbox.HtmlElement.InvokeMethod(false, "click");

// Trigger TextInput accour Exception
textbox.HtmlElement.InvokeMethod(false, "textinput");

How to fix the code to trigger TextInput event

Comments

  • edited January 9

    JavaScript from exception:

    targetElement = document.getElementById ('EL11');
    if (targetElement == null) return '!^§NotFound§^!';
    targetElement.textInput();
    return true;
    

    Element is input:

    <input id="EL11" type="text" value="" style="width:30em">
    

    Looks like there is a no such method for input.

  • So is there any way to trigger TextInput event by code?

  • I'm a little confused by what you are trying to do.

    The events are so you can run your own linqpad code when some javascript event occurs.
    InvokeMethod is so you can run javascript code from your linq code.

    But it looks like you are trying to invoke TextInput to call a javascript method simply so that the javascript method calls your own linqpad code - why not just call your linqpad code directly?

  • edited January 10

    InvokeMethod does not trigger event. It calls HTML element's function. In this case you are being lucky with click 'cause it is a real HTMLElement function. It is just a coincidence: click function triggers click event.

    Could you elaborate on what you are trying to do?

  • I have a code to set textBox.Text = "something" , and I need to tirgger textBox's InputText at the same time

  • Workaround:

    var textbox = new LINQPad.Controls.TextBox().Dump();
    textbox.TextInput += TextInputHeader;
    
    textbox.Text = "new text";
    TextInputHeader(textbox, EventArgs.Empty); // Call it directly. Note that EventArgs is Empty
    
    void TextInputHeader(object? sender, EventArgs e) => "Trigger TextInput".Dump();
    

    I used Shift+Alt+R to open in ILSpy and navigate implementation and it looks like a bug to me: JS event listener must be called on property change but it's not. I'll report it via LINQPad.

  • input event is not fired when TextBox.Text is changed:

    void TextInputHeader(object? sender, EventArgs e) => "Trigger TextInput".Dump();
    
    var textbox = new LINQPad.Controls.TextBox().Dump();
    textbox.TextInput += TextInputHeader;
    //TextInputHeader(textbox, EventArgs.Empty);
    
    textbox.Text = "new text"; // <--- Event is not fired here, see below
    

    Implementation details:

    // LINQPad.Controls.TextBox
    public event EventHandler TextInput
    {
        add
        {
            HtmlElement.AddEventListener("input", value); // Add input event.
        }
    }
    
    public string Text
    {
        set
        {
            HtmlElement["value"] = value ?? ""; // Set value
        }
    }
    
    // LINQPad.Controls.Core.HtmlElement
    public string this[string attribute]
    {
        get
        {
            return GetAttribute(attribute);
        }
        set
        {
            SetAttribute(attribute, value); // Set value
        }
    }
    
    // Event is not fired here:
    public void SetAttribute(string name, string value)
    {
        if (Name == null && !name.StartsWith("!"))
        {
            Children?.FirstOrDefault()?.SetAttribute(name, value);
        }
        else if (IsDumped && ID != null)
        {
            Server?.SetHtmlElementAttribute(ID, name, value); // <--- I expected this to fire an event 
        }
        lock (_lock)
        {
            _attributes[name] = value;
        }
    }
    
  • edited January 13

    I took a brief look at this last Friday, but didn't have much time to delve further. What I did observe is the event does trigger if you actually type into the TextBox. This makes sense when you consider the name of the event the code hooks into. "TextInput", not "TextChanged". Not sure this is a bug here, though perhaps a feature request.

    The initial recommendation stands: If you changing the text in code, call the accompanying event code along with it (and consider writing a single method to do both).

  • @rorourke - that's correct. The TextInput event forwards the HTML element's Input event.

    Reliably responding to programmatic changes is tricky because the value can also be changed directly via JavaScript (bypassing LINQPad's C# wrapper):
    https://stackoverflow.com/questions/55033836/how-do-you-listen-detect-changes-to-an-input-value-when-the-input-value-is-c

  • I give up and find another way
    I achieve by InvokeScript with JS dispatchEvent

    public class SV_InvokeScript  {
      public static void TriggerById_Input(string id) =>
        TriggerEventById(id, OpEvent.input);
    
      public static void TriggerById_Click(string id) =>
        TriggerEventById(id, OpEvent.click) ;
    
      public static void TriggerEventById(string id, OpEvent eventName) {
        new SV_SweetAlert();
    
        Util.InvokeScript(false, "eval", @$"
    try {{
      var target = document.getElementById('{id}');
      if(target === null)
        throw new Error('not found id : {id} ');
      target.dispatchEvent(new Event('{eventName.ToString()}'));        
    }} catch (error) {{
      swal('JS error!', error.message + error.stack, 'error');        
    }}
        ");
      }
    
      public enum OpEvent {
        input,
        click,
      }
    }
    
  • @rovingwind said:

      swal('JS error!', error.message + error.stack, 'error');        
    

    swal should be included separately. I don't see a corresponding script tag.

  • @i2van said:

    @rovingwind said:

      swal('JS error!', error.message + error.stack, 'error');        
    

    swal should be included separately. I don't see a corresponding script tag.

    I implement in new SV_SweetAlert(); to using SweetAlert.js

    public class SV_SweetAlert {
      public const string UrlSweetAlertJs = "https://unpkg.com/sweetalert/dist/sweetalert.min.js";
      public static void UsingSweetAlertJs() => Util.HtmlHead.AddScriptFromUri(UrlSweetAlertJs);
    
      public SV_SweetAlert() {
        UsingSweetAlertJs();
      }
    }
    
Sign In or Register to comment.