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
-
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?
-
InvokeMethod
does not trigger event. It calls HTML element's function. In this case you are being lucky withclick
'cause it is a realHTMLElement
function. It is just a coincidence:click
function triggersclick
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 whenTextBox.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; } }
-
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'sInput
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 dispatchEventpublic 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(); } }