How to pass 2 parameters through RegisterStartupScript? - javascript

I have a javascript function "initialize (latitude, longitude)" and when I click on my button I want to pass the value from my textbox to do something.
Protected Sub btnLat_Click(ByVal sender As Object, ByVal e As System.EventArgs)
Dim latit As TextBox = formView.FindControl("nr_latitudeTextBox")
Dim longit As TextBox = formView.FindControl("nr_longitudeTextBox")
Page.ClientScript.RegisterStartupScript(Me.GetType(), "initialize", "initialize(" & latit.Text, longit.Text & ");", True)
End Sub
But when I try to do this I get the error
Overload resolution failed because no accessible "RegisterStartupScript" accepts this number of arguments.

You have just implemented the code wrongly. Change it to.
If your initialize function expects string variables then use the code;
Page.ClientScript.RegisterStartupScript(Me.GetType(),
"initialize", "initialize('" & latit.Text & "','" & longit.Text & "');", True)
If initialize expects integers then;
Page.ClientScript.RegisterStartupScript(Me.GetType(),
"initialize", "initialize(" & latit.Text & "," & longit.Text & ");", True)

Related

VBA: Downloading a file behind JavaScript link

How do you write VBA code to download a file sitting behind a JavaScript link? There are many resources on how to download a file from a specific link using VBA, however, none show how to download a file behind a JavaScript link.
In example, how do you download the file behind "Export to Spreadsheet" on this website:
https://www.vanguardinvestments.com.au/retail/ret/investments/product.html#/fundDetail/wholesale/portId=8101/assetCode=equity/?prices
Do we still declare and use urlmon?
'Declaration of API function for Office 2010+
Private Declare PtrSafe Function URLDownloadTOFile Lib "urlmon" Alias
"URLDownloadToFileA" ( _
ByVal pCaller As LongPtr, _
ByVal sZURL As String, _
ByVal szFileName As String, _
ByVal dwReserved As LongPtr, _
ByVal lpfnCB As LongPtr _
) As LongPtr
#Else
'Declaration of API function for pre Office 2010 versions
Private Declare Function URLDownloadTOFile Lib "urlmon" Alias
"URLDownloadToFileA" ( _
ByVal pCaller As Long, _
ByVal sZURL As String, _
ByVal szFileName As String, _
ByVal dwReserved As Long, _
ByVal lpfnCB As Long _
) As Long
#End If
Sub DownloadOneFile()
Dim FileURL As String
Dim DestinationFile As String
'How do you modify this to handle a javascript link?
FileURL = "https://www.vanguardinvestments.com.au/retail/ret/investments/product.html#/fundDetail/wholesale/portId=8101/assetCode=equity/?prices"
DestinationFile = "C:\VBA\prices.csv"
URLDownloadToFile 0, FileURL, DestinationFile, 0, 0
End Sub
This will fire the event. Credit to #Greedo for the principle of waiting for page to load by looping until a specified element is visible in the window. Sorry about the dreaded send keys.
Public Sub DownloadFile()
Dim objIE As InternetExplorer, currPage As HTMLDocument, url As String
url = "https://www.vanguardinvestments.com.au/retail/ret/investments/product.html#/fundDetail/wholesale/portId=8101/assetCode=equity/?prices"
Set objIE = New InternetExplorer
objIE.navigate url
Do While objIE.Busy = True Or objIE.readyState <> 4: DoEvents: Loop
Set currPage = objIE.document
objIE.Visible = True
Dim myDiv As HTMLDivElement: Set myDiv = currPage.getElementById("price-distribution")
Dim elemRect As IHTMLRect: Set elemRect = myDiv.getBoundingClientRect
Do Until elemRect.bottom > 0
currPage.parentWindow.scrollBy 0, 10000
Set elemRect = myDiv.getBoundingClientRect
Loop
objIE.document.getElementsByClassName("export_icon hideOnSml ng-binding")(0).FireEvent "onclick"
Application.SendKeys "%{S}"
End Sub
If necessary you might add something like the following before the send keys to ensure window is up but seems to work as is at present.
Dim objShell As Shell
Set objShell = New Shell
Application.Wait Now + TimeSerial(0, 0, 10) 'alter to give enough time for window
For Each objIE In objShell.Windows
If TypeName(objIE.document) = "HTMLDocument" Then
If InStr(objIE.document.title, "vanguard") > 0 Then
objIE.Visible = True
Exit For
End If
End If
Next objIE

Get report parameters as URL string

I have an application that serves SSRS reports. A given report is accessed in the following way:
https://reportserver.com/reportname
Upon clicking View Report, a postback is submitted to the report server with the user-defined parameters. I need to grab these user-defined parameters and parse them as a URL string.
Desired result: https://reportserver.com/reportname?param1=foo&param2=bar
I found this doc that gets me close to what I need. This method should allow me to grab all visible parameters and parse them myself, but I need hidden parameters as well.
How can I build this parameter string? We're using JavaScript/jQuery in the front end so it may be possible to grab this client-side before the POST, but I haven't found a way of doing this either.
I got it working. Fair warning: I'm new to ASP.NET so this is likely not an ideal solution.
I added an event handler to the report viewer control's code behind. This queries the execution log, grabbing the parameters selected most recently by the user. It is meant to be triggered when a button called "Save Report" is clicked. If you try to handle this with a Load or PreRender event handler it will fire before the row has a chance to insert into the database, giving you the result of the user's second most recent execution parameters.
Define the Button (.ascx file)
<asp:LinkButton ID="SaveReportButton" runat="server" title="Save this Report"></asp:LinkButton>
Add event handler to code behind (.ascx.vb file)
Protected Sub SaveReportButton_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles SaveReportButton.Click
Dim conn As New SqlConnection(<connection string here>)
Dim cmd As New SqlCommand("SELECT TOP 1 Parameters FROM [ReportServer].[dbo].[ExecutionLogStorage] WHERE <qualify on user, timestamp, etc. here>", conn)
cmd.Parameters.AddWithValue(<query parameter here>)
conn.Open()
Dim result = cmd.ExecuteScalar()
' Prevents NullReferenceException from result.ToString() in case no result is found
If (result IsNot Nothing)
' Redirect based on parameter string retrieved from log
Response.Redirect(HttpContext.Current.Request.Url.AbsoluteUri & "?" & result.ToString())
End If
conn.Close()
End Sub
Call postback from JavaScript on button click
<li>
<a href=\'javascript:WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions(<reference SaveReportButton with appropriate arguments>)\' id="SaveReportButton" title="Save Report">
Save Report
</a>
</li>
Documentation on WebForm_DoPostBackWithOptions() and WebForm_PostBackOptions() is sparse, but a colleague has already done it this way so I followed suit for consistency's sake because it works.
I've created URLs for reports with parameters 3 different ways. A combination of the the first two may get you closer to solving your problem.
Use custom code in the report properties.
Public Function ShowParameterValues(ByVal parameter As Parameter) As String
Dim s as String = String.Empty
Try
If parameter.IsMultiValue then
s = "Multivalue: "
For i as integer = 0 to parameter.Count-1
s = s + CStr(parameter.Value(i)) + " "
Next
Else
s = "Single value: " + CStr(parameter.Value)
End If
Return s
Catch ex As Exception
Return "error"
End Try
End Function
OR
Use a hyperlink in the report.
=Globals!ReportServerUrl + "/ReportServer?"
+ Replace(Globals!ReportFolder, " ", "+") + "%2f"
+ Replace(Globals!ReportName, " ", "+") + "&rs:Command=Render"
+ "&boolean_value=" + CStr(Parameters!boolean_value.Value)
+ "&single_value_parameter=" + Parameters!single_value_parameter.Value
+ "&multi_value_parameter=" + Join(Parameters!multi_value_parameter.Value, "&multi_value_parameter=")
+ IIf(IsNothing(Parameters!week_date_start.Value), "&week_date_start:isnull=True", "&week_date_start=" & Format(Parameters!week_date_start.Value, Variables!FormatDate.Value))
+ IIf(IsNothing(Parameters!week_date_end.Value), "&week_date_end:isnull=True", "&week_date_end=" & Format(Parameters!week_date_end.Value, Variables!FormatDate.Value))
Also, I usually add this as a report variable and then you can have a standard textbox for the footer that doesn't have to change.
=Variables!UrlReportWithParameters.Value
OR
Use the execution log. Check out the column URL_Report_Filtered
--Purpose: to search the reporting services execution log
DECLARE #all_value AS VARCHAR(10) = '<ALL>';
DECLARE #LogStatus AS VARCHAR(50) = '<ALL>';
DECLARE #ReportFolder AS VARCHAR(450) = 'Testing';
DECLARE #ReportName AS VARCHAR(450) = '<ALL>';
DECLARE #UserName AS VARCHAR(260) = '<ALL>';
DECLARE #GroupByColumn AS VARCHAR(50) = 'Report Folder';
DECLARE #StartDate AS DATETIME = NULL;
DECLARE #EndDate AS DATETIME = NULL;
WITH
report_users
AS
(
SELECT
[UserID]
, [UserName]
, [SimpleUserName] = UPPER(RIGHT([UserName], (LEN([UserName])-CHARINDEX('\',[UserName]))))
FROM
[dbo].[Users]
)
,
report_catalog
AS
(
SELECT
rpt.[ItemID]
, rpt.[CreatedById]
, rpt.[ModifiedById]
, rpt.[Type]
, rpt.[Name]
, [ReportName] = rpt.[Name]
, rpt.[Description]
, rpt.[Parameter]
, [CreationDate] = CONVERT(DATETIME, CONVERT(VARCHAR(11), rpt.[CreationDate], 13))
, [ModifiedDate] = CONVERT(DATETIME, CONVERT(VARCHAR(11), rpt.[ModifiedDate], 13))
, [ReportFolder] = SUBSTRING(rpt.[Path], 2, LEN(rpt.[Path])-LEN(rpt.[Name])-2)
, rpt.[Path]
, [URL_ReportFolder] = 'http://' + Host_Name() + '/Reports/Pages/Report.aspx?ItemPath=%2f' + SUBSTRING(rpt.[Path], 2, LEN(rpt.[Path])-LEN(rpt.[Name])-2) + '&ViewMode=List'
, [URL_Report] = 'http://' + Host_Name() + '/Reports/Pages/Report.aspx?ItemPath=%2f' + SUBSTRING(rpt.[Path], 2, LEN(rpt.[Path])-LEN(rpt.[Name])-2) + '%2f' + rpt.[Name]
, [ReportDefinition] = CONVERT(VARCHAR(MAX), CONVERT(VARBINARY(MAX), rpt.[Content]))
, [HostName] = Host_Name()
FROM
[dbo].[Catalog] AS rpt
WHERE
1=1
AND rpt.[Type] = 2
)
SELECT
[GroupBy1] =
CASE
WHEN #GroupByColumn = 'Report Name' THEN rpt.[ReportName]
WHEN #GroupByColumn = 'Report Folder' THEN rpt.[ReportFolder]
WHEN #GroupByColumn = 'User Id' THEN usr.[SimpleUserName]
ELSE '<N/A>'
END
, rpt.[Path]
, rpt.[ReportFolder]
, rpt.[Name]
, rpt.[URL_ReportFolder]
, rpt.[URL_Report]
, [URL_Report_Filtered] = rpt.[URL_Report] + '&rs:Command=Render&' + CONVERT(VARCHAR(max), el.[Parameters])
, [UserName] = usr.[SimpleUserName]
, el.[Status]
, el.[TimeStart]
, el.[RowCount]
, el.[ByteCount]
, el.[Format]
, el.[Parameters]
, [TotalSeconds] = CONVERT(CHAR(8),DATEADD(ms,(el.[TimeDataRetrieval] + el.[TimeProcessing] + el.[TimeRendering]),0),108)
, [TimeDataRetrieval] = CONVERT(CHAR(8),DATEADD(ms,el.[TimeDataRetrieval],0),108)
, [TimeProcessing] = CONVERT(CHAR(8),DATEADD(ms,el.[TimeProcessing],0),108)
, [TimeRendering] = CONVERT(CHAR(8),DATEADD(ms,el.[TimeRendering],0),108)
, [OrderbyDate] = CAST([TimeStart] AS DATETIME)
FROM
report_catalog AS rpt
LEFT JOIN [dbo].[ExecutionLog] AS el ON el.[ReportID] = rpt.[ItemID]
LEFT JOIN report_users AS usr ON el.[UserName] = usr.[UserName]
WHERE
1=1
AND (#all_value IN(#LogStatus) OR el.[Status] IN(#LogStatus))
AND (#all_value IN (#ReportFolder) OR rpt.[ReportFolder] IN(#ReportFolder))
AND (#all_value IN(#ReportName) OR rpt.[ReportName] IN(#ReportName))
AND (#all_value IN(#UserName) OR usr.[SimpleUserName] IN(#UserName))
AND (#StartDate IS NULL OR CONVERT(DATETIME, CONVERT(VARCHAR(11), el.[TimeStart], 13)) >= #StartDate)
AND (#EndDate IS NULL OR CONVERT(DATETIME, CONVERT(VARCHAR(11), el.[TimeStart], 13)) <= #EndDate)

Adding a character on a string from a HTMLInput using javascript

I have this htmlInput in an ASP:Repeater that I want to be formatted in time format (e.g: 13:39) on its keypress. So far I have this code in repeater databound:
Protected Sub rpt_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.RepeaterItemEventArgs) Handles rpt.ItemDataBound
If e.Item.ItemType = ListItemType.Item OrElse e.Item.ItemType = ListItemType.AlternatingItem Then
Dim txt As HtmlInputText = DirectCast(e.Item.FindControl("txtKmRun"), HtmlInputText)
If txt IsNot Nothing Then
txt.Attributes.Add("onkeypress", "return kmRun('" & txt.Value & "');")
End If
End If
End Sub
..and this is in the JavaScript:
<script>
function kmRun(myValue) {
String x = myValue;
x = x.substring(0, 2) + ":" + x.substring(2, x.length());
alert(x); //alert to test display but is not working
//HOW TO PASS x VALUE TO BACK TO THE TEXTBOX?
}
</script>
Tested the onkeypress attribute with a simple javascriptalert message and it worked but when modified with value passing, there's no return value. So I guess, the error starts there.
Additional question is when the javascriptpart works, how to return the "converted" string value back to the htmlInput? Is there any other solution for this problem that will not use a PostBack?
Thanks.
===================
This is the working code:
Protected Sub rpt_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.RepeaterItemEventArgs) Handles rpt.ItemDataBound
If e.Item.ItemType = ListItemType.Item OrElse e.Item.ItemType = ListItemType.AlternatingItem Then
Dim txt As HtmlInputText = DirectCast(e.Item.FindControl("txtKmRun"), HtmlInputText)
If txt IsNot Nothing Then
txt.Attributes.Add("onkeypress", "return kmRun(this);")
End If
End If
End Sub
<script>
function kmRun(x) {
if (x.value.length > 2) {
x.value = x.value.substring(0, 2) + ":" + x.value.substring(2, x.value.length);
}
}
</script>
You don't need to declare another variable, you can use the myValue parameter.
I'd recommend to use onchange="kmRun(this)" instead onkeypress="kmRun(this)", because you got to change the content, to finally be formatted by the code.
By using this, you can get all attributes of the textBox control.
You might try something like this, in your javascript code:
function kmRun(control) {
control.value = control.value.substring(0, 2) + ":" + control.value.substring(2, control.value.length);
}
<input id="txt" type="text" onchange="kmRun(this)" value="" />
There are some problems with your logic.
You're sending txt.Value inside your ItemDataBound, but it will be a fixed value when rendered in your HTML, since it will not get updated when the user types. You must change that:
txt.Attributes.Add("onkeypress", "return kmRun(this.value);")
The keyword this above refers to your input, and whenever the user types, it will get updated.
Javascript is not a typed language, there is no String x = declaration. You must use:
var x = myValue;
You shouldn't use .substring(0, 2) directly without validating if the field has more than two characters, because if it doesn't, the browser will throw an error.
You're using .length as it was a method, but it's a property. Don't use the parenthesis ().
Finally, to pass the value back to your TextBox, you can do:
this.value = x;

On Click event not firing from code behind

In my code below , my ("OnClick") is not firing. Does anyone know why?
e.Row.Cells(1).Attributes("OnClick") = "window.location.href='MachineSweepLite.aspx?AreaID='" _
+ GridView1.DataKeys(e.Row.RowIndex).Values("ID").ToString()
Protected Sub GridView1_RowDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles GridView1.RowDataBound
If e.Row.RowType = DataControlRowType.DataRow Then
e.Row.Cells(1).Attributes("onmouseover") = "this.style.cursor='hand';this.style.textDecoration='underline';"
e.Row.Cells(1).Attributes("onmouseout") = "this.style.textDecoration='none';"
Dim Index As Integer = e.Row.RowIndex
e.Row.Cells(1).Attributes("OnClick") = "window.location.href='MachineSweepLite.aspx?AreaID='" + GridView1.DataKeys(e.Row.RowIndex).Values("ID").ToString
End If
End Sub
Edit above.
You have a error in your attribute, as you are adding the value of the ID after the closing single quote...
For example, if the ID was 12, you're sending this to the browser...
window.location.href='MachineSweepLite.aspx?AreaID='12
Note that the 12 is not part of the URL.
You should have the following instead...
e.Row.Cells(1).Attributes("onclick") =
string.Format("window.location.href='MachineSweepLite.aspx?AreaID={0}';",
GridView1.DataKeys(e.Row.RowIndex).Values("ID").ToString())
Also note, as of .NET 4.0 it is unnecessary to have the _ character when spanning over multiple lines.
e.Row.Attributes("onClick") = "CallFunction('" & Convert.ToString(GridView1.DataKeys(e.Row.RowIndex).Values("ID")) & "');"
JS code:
function CallFunction(val)
{
// do your login here
}

Perform code-behind Function/Sub from javascript (VB.NET)

In my project, there are 3 user controls; BasicContact, BasicDetail and ActionTime. They are in EditOrder.aspx page.
There is "ReportDate" property (Date type) in BasicContact, RadioButtonList "rdl_Priority" (with integer value from "prio_id" field) in BasicDetail and "CheckDate" property in ActionTime. The ReportDate value is derived from txt_ReportDate and txt_ReportTime and CheckDate value is derived from txt_CheckDate and txt_CheckTime.
My objective is to calculate Checkdate after I add date into ReportDate and click on radiobuttonlist. Checkdate will be calculated from ReportDate (date) + SLAHour (hour, get from "GetSLAHour" method where input is prio_id) and then set text in txt_CheckDate and txt_CheckTime.
Right now, I was be able to complete this task using Postback. I create custom event and raise it in RadioButtonList selectedIndexchanged method. After that, event is handled in code behind of EditOrder page. Here are my code.
BasicDetail - RadioButtonList
<asp:RadioButtonList ID="rdl_Priority" runat="server" RepeatDirection="Horizontal" AutoPostBack="true" />
BasicDetail - codeBehind
Public Event priorityClicked As System.EventHandler
Private Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Init
If Not IsPostBack Then SetupList()
End Sub
Private Sub SetupList()
Dim ctx As New StsDataContext
With rdl_Priority
Dim Result = (From r In ctx.Priorities Order By r.display_order)
If Result.Count > 0 Then
.DataTextField = "prio_name"
.DataValueField = "prio_id"
.DataSource = Result
.DataBind()
Else
lbl_Priority.Visible = False
rdl_Priority.Visible = False
End If
End With
End Sub
Protected Sub rdl_Priority_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles rdl_Priority.SelectedIndexChanged
RaiseEvent priorityClicked(sender, e)
End Sub
EditOrder - codeBehind
Private Sub BasicDetail_priorityClicked(ByVal sender As Object, ByVal e As System.EventArgs) Handles BasicDetail.priorityClicked
Dim reportDate As Date? = BasicContact.ReportDate
Dim SLAHour As Integer? = GetSLAHour(BasicDetail.PriorityId)
If reportDate.HasValue AndAlso SLAHour.HasValue Then
ActionTime.CheckDate = CDate(reportDate).AddHours(CDbl(SLAHour))
End If
End Sub
However, I don't want the page to be refreshed (no postback). I don't know how to call the function or sub from javascript. I have tried PageMethod but it cause error in runtime saying that the method is not supported. Anyway, if there is a better way than calling code-behind from javascript, please let me know.
Thanks in advance
Ok Sorry, here is my solution
Since for now I used PageMethod to solve this problem, I don't need raise event function from code behind anymore so I deleted all the codes I have posted to ask my own question.
First, I added javascript function to each item in RadioButtonList in BasicDetail code behind
BasicDetail - Code behind
Private Sub rdl_Priority_DataBound(ByVal sender As Object, ByVal e As System.EventArgs) Handles rdl_Priority.DataBound
For Each li As ListItem In rdl_Priority.Items
Dim slaHour As Integer? = GetSLAHour(li.Value)
li.Attributes.Add("onclick", "return CalCheckDate(" & If(slaHour.HasValue, CStr(slaHour), "null") & ");")
Next
End Sub
This "CalCheckDate" function added to each button is implemented in EditOrder page (user control's parent page)
EditOrder.aspx
<script type="text/javascript">
function CalCheckDate(hour) {
var hid_ServId = document.getElementById('<%=hid_ServId.ClientID%>');
var txt_reportDate = document.getElementById('<%=BasicContact.ReportDateTextName%>');
var txt_reportTime = document.getElementById('<%=BasicContact.ReportTimeTextName%>');
PageMethods.GetCheckDateTime(hid_ServId.value, txt_reportDate.value, txt_reportTime.value, hour, OnGetCheckDateComplete, OnGetCheckDateError);
}
function OnGetCheckDateComplete(result) {
var txt_checkDate = document.getElementById('<%=ActionTime.CheckDateTextName%>');
var txt_checkTime = document.getElementById('<%=ActionTime.CheckTimeTextName%>');
var chkDateTime = result.split(" ");
txt_checkDate.value = chkDateTime[0];
txt_checkTime.value = chkDateTime[1];
}
function OnGetCheckDateError(e)
{
alert(e._message);
}
</script>
Child control within user control, such as txt_ReportDate in BasicContact, can be derived by creating property in BasicContact as follows:
BasicContact - Code Behind
Public ReadOnly Property ReportDateTextName() As String
Get
Return txt_ReportDate.ClientID
End Get
End Property
This property is used in "CalCheckDate" function to get its value and pass it to PageMethod function. Other controls can be derived in the same way.
Last step is coding PageMethods function, "GetCheckDateTime", in EditOrder code behind
EditOrder - Code Behind
<System.Web.Services.WebMethod()> _
Public Shared Function GetCheckDateTime(ByVal servId As String, ByVal ReportDate As String, ByVal ReportTime As String, ByVal hour As String) As String
Dim checkDate As String, checkTime As String
'************************************************************************
'Calculate check and time date from input ReportDate, ReportTime and hour
'************************************************************************
Return checkDate & " " & checkTime
End Function
The result is returned to "OnGetCheckDateComplete" function in javascript (or "OnGetCheckDateError" if there is an exception). Here, I split the String and use its value to set text in textbox.

Categories

Resources