I am currently working on a project in vb.net and I am having trouble getting my custom validator to work on a radcombobox. When I run my application and test the validation it is not being invoked, causing my application to break. I am not looking into client side validation, just server side. Below is the code I have been using.
Aspx code
<td>
<telerik:RadComboBox ID="radcomboboxListTimeZone" runat="server" BorderColor="#bbe0ef"
BorderWidth="2px" Width="400px" MaxHeight="200px"
DataSourceID="ObjectDataSourceListTimeZones"
DataTextField="DisplayName" DataValueField="StandardName" SelectedValue='<%#
Bind("TimeZoneStandardName")%>'>
</telerik:RadComboBox>
<asp:CustomValidator ID="CustomValidatorTimeZone" runat="server" ErrorMessage="Please select a
valid Time Zone Standard Name" ControlToValidate="radcomboboxListTimeZone"
OnServerValidate="CustomValidatorListTimeZone_ServerValidate">•</asp:CustomValidator>
</td>
Server side code
Protected Sub CustomValidatorListTimeZone_ServerValidate(ByVal source As Object, ByVal args As
ServerValidateEventArgs)
Dim radcomboboxListTimeZone As RadComboBox =
CType(FormViewTimeZones.FindControl("radcomboboxListTimeZone"), RadComboBox)
Dim selectedValue As String = radcomboboxListTimeZone.SelectedValue
If selectedValue = "Coordinated Universal Time" Then
args.IsValid = False
Else
args.IsValid = True
End If
End Sub
Any help would be much appreciated.
I managed to get the server side custom validation working. To do this I created a validation group
<asp:ValidationSummary ID="ValidationSummaryEditItem" runat="server" ValidationGroup="TimeZone" />
and set
CausesValidation="true"
on the edit button and added
ValidationGroup="TimeZone"
to both the edit button and the custom validator
Today, I have decided to migrate WebView control to WebView2 control in a VB.net application.
I have installed WebView2 from NuGet and I have changed declarations and initialization lines (only 4 lines in my VB program because I'm using 2 WebView2).
When I build my application, Visual Studio 2019 indicates that ScriptNotify event is not an event of WebView2!
Private Sub wvSelect_ScriptNotify(
sender As Object,
e As WebViewControlScriptNotifyEventArgs) Handles wvSelect.ScriptNotify
Using old WebView control, this event is generated using windows.external.notify Javascript function.
function clickPlus(e) { window.external.notify("+PLUS:"); }
Which event is replacing ScriptNotify event in WebView2 control?
I'm interested to know the new event and also how this event is called from Javascript.
A few possible scenarios to handle event notifications with WebView2:
See also: Use JavaScript in WebView for extended scenarios.
Generic initialization:
The WebView2 instance is named myWebView2.
Using basic methods: for example, the JSON deserialization is performed using JavaScriptSerializer. You probably have Json.Net or System.Text.Json instead.
Also assuming WinForms, you haven't specified the GUI framework
Private Async Sub Load(sender As Object, e as EventArgs) Handles MyBase.Load
await myWebView2.EnsureCoreWebView2Async(Nothing)
End Sub
Also, I'm using this simple class model, used to deserialize the JSON message received, since WebView2.WebMessageReceived assumes a JSON format; you can pass whatever string you want, though.
Private Class JsonEventMessage
Public Property Element As String
Public Property Value As String
End Class
1 - In this scenario, javascript Functions are already defined in the HTML
Using JSON.stringify() to emphasize that the return value is a JSON object
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
function SomeFunction(e, v) {
var json = JSON.stringify({ Element:e.target.id, Value:v });
window.chrome.webview.postMessage(json);
}
</script>
</head>
<body>
<script>
document.getElementById("div1").addEventListener("click", function(e) {SomeFunction(e, '+PLUS:')});
</script>
<div id="div1">Some Text to Click</div>
</body>
</html>
In this case, you just need to subscribe to the WebMessageReceived event and deserialize the JSON:
AddHandler myWebView2.WebMessageReceived, AddressOf myWebView2_WebMessageReceived
' [...]
Private Sub myWebView2_WebMessageReceived(sender As Object, e As CoreWebView2WebMessageReceivedEventArgs)
Dim message = New JavaScriptSerializer().Deserialize(Of JsonEventMessage)(e.TryGetWebMessageAsString())
Console.WriteLine(message.Element)
Console.WriteLine(message.Value)
End Sub
Note: I'm using e.TryGetWebMessageAsString() and not e.WebMessageAsJson since the latter is enclosed in quotes (double-stringified). It's better used when you pass a simple string.
2 - Here, a JavaScript Function that can notify a message is defined in HEAD, but no event handlers are added anywhere else.
Assume you will add HTML Elements at run-time or you don't want to add the event handlers in the HTML or anything else.
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
function SomeFunction(e, v) {
var json = JSON.stringify({ Element:e.target.id, Value:v });
window.chrome.webview.postMessage(json);
}
</script>
</head>
<body>
<div id="div1">Some Text to Click</div>
</body>
</html>
Subscribe to the WebMessageReceived event as before and to the NavigationCompleted event. This event is raised when the Document is loaded. We need this event, since, in the example, the event handlers are added to Elements in the Body, which is not available before this point.
In NavigationCompleted, we can add the JavaScript Function to a string and call the WebView2.ExecuteScriptAsync() method, which executes the script after the DOM is ready, otherwise GetElementById() would not find the target.
AddHandler myWebView2.WebMessageReceived, AddressOf myWebView2_WebMessageReceived
AddHandler myWebView2.NavigationCompleted, AddressOf myWebView2_NavigationCompleted
' [...]
Private Sub myWebView2_WebMessageReceived(sender As Object, e As CoreWebView2WebMessageReceivedEventArgs)
Dim message = New JavaScriptSerializer().Deserialize(Of JsonEventMessage)(e.TryGetWebMessageAsString())
' [...]
End Sub
Private Async Sub myWebView2_NavigationCompleted(sender As Object, e As CoreWebView2NavigationCompletedEventArgs)
Dim func As String =
"document.getElementById('div1').
addEventListener('click', function(e) {
SomeFunction(e, '+PLUS:')
});"
Await myWebView2.ExecuteScriptAsync(func)
End Sub
3 - This time, no JavaScript Functions are defined anywhere in the HTML.
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div id="div1">Some Text to Click</div>
</body>
</html>
Case 1:
Subscribe to the WebMessageReceived and NavigationCompleted events as before.
In NavigationCompleted, the JavaScript Function that posts the message is added to the event handler directly. Call ExecuteScriptAsync() to execute the script and add the Event Listener to a HTML Element.
AddHandler myWebView2.WebMessageReceived, AddressOf myWebView2_WebMessageReceived
AddHandler myWebView2.NavigationCompleted, AddressOf myWebView2_NavigationCompleted
' [...]
Private Sub myWebView2_WebMessageReceived(sender As Object, e As CoreWebView2WebMessageReceivedEventArgs)
Dim message = New JavaScriptSerializer().Deserialize(Of JsonEventMessage)(e.TryGetWebMessageAsString())
' [...]
End Sub
Private Async Sub myWebView2_NavigationCompleted(sender As Object, e As CoreWebView2NavigationCompletedEventArgs)
Dim func As String =
"document.getElementById('div1').
addEventListener('click', function(e) {
var json = JSON.stringify({Element:e.target.id, Value:'+PLUS:'});
window.chrome.webview.postMessage(json);
});"
Await myWebView2.ExecuteScriptAsync(func)
End Sub
Case 2:
Subscribe to the WebMessageReceived and WebView2.CoreWebView2InitializationCompleted.
In this case, we're adding an event listener to the Document, then determine which Element has been clicked using the Event.Target member and any other property or value that can be useful to handle the notification.
Here, I'm simply passing the [Event].target.id and [Event].target.innerText as JSON properties. You can of course get any other attribute necessary in your use-case.
AddHandler myWebView2.WebMessageReceived, AddressOf myWebView2_WebMessageReceived
AddHandler myWebView2.CoreWebView2InitializationCompleted, AddressOf myWebView2_CoreWebView2InitializationCompleted
' [...]
Private Sub myWebView2_WebMessageReceived(sender As Object, e As CoreWebView2WebMessageReceivedEventArgs)
Dim message = New JavaScriptSerializer().
Deserialize(Of JsonEventMessage)(e.TryGetWebMessageAsString())
' [...]
End Sub
Private Async Sub myWebView2_CoreWebView2InitializationCompleted(
sender As Object,
e As CoreWebView2InitializationCompletedEventArgs)
Dim func as String =
"document.addEventListener
('click', function(e) {
window.chrome.webview.postMessage(
JSON.stringify({ Element:e.target.id, Value:e.target.innerText })
);
});"
Await myWebView2.CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync(func)
End Sub
My problem is now solved and my solution is following ...
I want to display following HTML page
<div id="table">
<div id='Keyboard' class='panel'>
<div class='krow'>
<span class='k digit'>7</span>
<span class='k digit'>8</span>
<span class='k digit'>9</span>
<span class='k back'>⭠x</span>
</div>
<div class='krow'>
<span class='k digit'>4</span>
<span class='k digit'>5</span>
<span class='k digit'>6</span>
<span class='k delete'>x⭠</span>
</div>
<div class='krow'>
<span class='k digit'>1</span>
<span class='k digit'>2</span>
<span class='k digit'>3</span>
<span class='k clear'>⇤⋆</span>
</div>
<div class='krow'>
<span class='k empty'></span>
<span class='k digit'>0</span>
<span class='k point'>.</span>
<span class='k plus'><b>+</b></span>
</div>
</div>
</div>
To intercept click on digit <div>, I have written following Javascript lines
$(document).ready(function ()
{
$('.digit').click(function (ev) { clickDigit(ev); });
...
}
function clickDigit(e)
{
eDigit = e.target;
var sValue = eDigit.innerText;
window.chrome.webview.postMessage("+DIGIT:" + sValue);
}
As you can see, I call postMessage() function to send a notification to VB.Net code.
To initiaze and display my HTML code, I have written following lines
Private Sub Form_Load(sender As Object, e As EventArgs) Handles MyBase.Load
InitializeAsync()
End Sub
Async Sub InitializeAsync()
Await wvSelect.EnsureCoreWebView2Async()
wvSelect.NavigateToString(sHtmlText)
End Sub
where WebView2 control is defined in Designer part of my Form
Friend WithEvents wvSelect As Microsoft.Web.WebView2.WinForms.WebView2
Finally, to intercept JavaScript notification, I have written following VB.Net Code
Private Sub wvSelect_WebMessageReceived(sender As Object, e As CoreWebView2WebMessageReceivedEventArgs) _
Handles wvSelect.WebMessageReceived
Dim sValue As String = e.TryGetWebMessageAsString
Dim iPos = sValue.IndexOf(":")
Dim sAction = sValue.Substring(0, iPos)
sValue = sValue.Substring(iPos + 1)
Select Case sAction
Case "+DIGIT"
SendMessage(txtInput.Handle, WM_CHAR, AscW(sValue.Chars(0)), 0)
I hope than what I have reported in this answer can help others users and complete Jimi answer.
I've seen many questions around this one, but none hitting it directly.
I put a listbox on a page and populate it with three items from an Access database. I have a button on that page that will extract several values including the selected item from the listbox. Or I want to anyway.
I can see the item selected in windows (highlighted) when I click the button, but when I try to select it no item is available as selected in the listbox. The ListBox1.SelectedIndex is alway -1.
Here is the code from the page:
<asp:ListBox ID="ListBox1" runat="server">
<asp:ListItem Text="List1" />
<asp:ListItem Text="List2" />
<asp:ListItem Text="List3" />
</asp:ListBox>
Is there a property missing?
Here is the code from the code behind page:
Public Function getDept() As String
Dim dept As String
If ListBox1.SelectedIndex > -1 Then
dept = ListBox1.SelectedItem.Text
Else
dept = "CMS"
End If
Return dept
End Function
Please help, I have until about noon to figure this out.
There may some reasons:
1- Check if your page's viewstate is true.
2- Call your method after Page_Load event.
Where do you call the function?
Consider that you should call it after Page_Load event. Also your viewstate
I am having some automation trouble.
I am using HTML Object Library to automate an download. At the end of the automation process, I have to click a submit button of a form and then the download starts.
When I try to handle the dialog with the winapi32 function like this:
hWndDialog = 0
'Wait until the dialog is open
While hWndDialog = 0
hWndDialog = FindWindow(vbNullString, "Dateidownload")
Wend
'get the handle of the button
hWndDialogSpeichern = FindWindowEx(hWndDialog, 0, "Button", "&Speichern")
Call SetForegroundWindow(hWndDialog)
'send message
lRetval = SendMessage(hWndDialogSpeichern, &H5, ByVal 0&, ByVal 0&)
Nothing happens. I read something, that this isn't possible, because the dialog is modal?
So I try to send the POST data directly to the form's action. I think this is the best possibility even.
But I don't know what to send to the server.
Here the form in the html page:
<form action="/smarti/bismt/bismt/resexport" method="post">
<input class="active" type="button" onclick="submitform()" name="button_export" value="Export">
submitform() only check some values and then calls:
document.forms[0].submit();
However, when I send a POST request to "/smarti/bismt/bismt/resexport" I only get the page. I don't know how to set up the request header. Tried to use firebug, to see what is sending to the form, but saw nothing I recognized.
Did you try adding a question mark ? and then the names of the text input boxes? Like http://zip4.usps.com/zip4/zcl_3_results.jsp?zip5=92101.
I have a login page that stores a few values to localStorage (html5) then continues to a VB.Net page. I am looking for a method in VB that can read back those stored values and make them VB vars. Any ideas?
The VB.NET code-behind is running on the server and has no direct access to the local storage API of the browser.
You can, however, easily fill some hidden fields on the login page, using JavaScript, which will be posted on submit and can be read from the code-behind of the .NET page.
Something like this (not tested):
this.document.getElementById("HIDDEN_FIELD_ID").value = localStorage.STORED_VALUE;
...
<input type="hidden" id="HIDDEN_FIELD_ID" />
...
On the .NET page the value can be read like:
Request.Form("HIDDEN_FIELD_ID")
(There are other ways, but this one is easy to grasp.)
Be aware that login data in localStorage can be accessed (and modified) by the user, so make sure you are not creating a security risk.
This sample uses the above concept with VB Code:
Here is the html body element:
<body>
<form id="form1" runat="server">
<asp:HiddenField ID="hfLoaded" runat="server" />
<asp:HiddenField ID="hfLocalStorage" runat="server" />
</form>
<script type="text/javascript">
// Load LocalStorage
localStorage.setItem('strData', 'Local storage string to put into code behind');
function sendLocalStorageDataToServer()
{
// This function puts the localStorage value in the hidden field and submits the form to the server.
document.getElementById('<%=hfLocalStorage.ClientID%>').value = localStorage.getItem('strData');
document.getElementById('<%=form1.ClientID%>').submit();
}
// This checks to see if the code behind has received the value. If not, calls the function above.
if (document.getElementById('<%=hfLoaded.ClientID%>').value != 'Loaded')
sendLocalStorageDataToServer();
</script>
Here is the page load event:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim s As String
s = hfLocalStorage.Value
'This next line prevents the javascript from submitting the form again.
hfLoaded.Value = "Loaded"
End Sub
Now your code behind has the localStorage value available to it.