Showing posts with label buttons. Show all posts
Showing posts with label buttons. Show all posts

Saturday, March 24, 2012

Trouble viewing ASP buttons on a web form

Hi,

I am a long-time java programmer, trying to learn about ASP.NET. I am trying write a simple "Hello, Browser" web form using the Visual Studio .NET web form designer. The form consists of a web form label and 3 web form buttons. The buttons don't perform any function. However, when I build and run the program, a browser pops up, but only displays the label and not the buttons. Can anyone tell me what the problem might be? Is it a problem with the code, or maybe some settings?

Thank YouCan you post your code?
If you installed IIS after Visual Studio .NET, you have to register ASP.NET with IIS. You can do this by opening a VS.NET command prompt (i.e. Start > Programs > Visual Studio .NET > Tools > Command Prompt) and typing:

aspnet_regiis -i

That should do the trick. ;)
Super!

This forum is such an amazing resource. I would have never guessed that on my own. Stanley Tan, your solution worked.

Thank you. Thank You. Thank You.

trouble with click events on dynamically created link buttons

I've read quite a few different message on various boards and for some
reason I'm still having trouble wrapping my head around this viewstate
maintenance and trying to get these dynamically created link buttons
to stay wired up to their click events.

I have what is basically a simply survey question generation page. The
page first displays a few static fields and a dropdownlist of various
options for the user to select. When the user selects an option from
the list the page will generate a new table with 5 rows of textboxes,
drop down lists, and link buttons (to delete a row if desired). There
is also a static insert button to allow users to add additional rows
if needed.

Saving the data in the fields during postback isn't an issue, but I'm
stuck in two situations depending on how I adjust the code. First is
that I put the rebuilding of the controls in the Page_load and users
are forced to click twice on the static Insert Row button to add a row
or they have to click twice on a dynamic Delete Row link button to
remove a row. If I take the rebuilding of the controls out of the
Page_Load then the Insert Row button works fine, but clicking on a
Delete Row link button causes the click event to not fire and all the
dynamic controls disappear from the page.

Does anyone have any suggestions on what I need to do to fix this so
it's written correctly and will operate as intended? (if you need more
detail or code please ask)

Thank you for your help.

--Code Snippets (this setup requires 2 clicks on a button before the
click event appears to do anything--

Private Sub Page_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load

If Not IsPostBack Then
LoadQuestionTypes()
End If

RebuildControls()

End Sub
--------
Private Sub ddlQuestionType_SelectedIndexChanged(ByVal sender As
System.Object, ByVal e As System.EventArgs) Handles
ddlQuestionType.SelectedIndexChanged

...
BuildEmptyFive()
...

End Sub
--------
Private Sub BuildEmptyFive()

Dim IDArray As New ArrayList
Dim tblAnswers As New Table
Dim x As Integer

For x = 1 To 5

Dim row As New TableRow
Dim ID As String

ID = Left(System.Guid.NewGuid.ToString, 8)

Dim cell1 As New TableCell
cell1.Controls.Add(BuildTextBox("txtChoice-" & ID, 140))

Dim cell2 As New TableCell
cell2.Controls.Add(BuildDropDownList("ddlFamily-" & ID, 150,
"Family"))

Dim cell3 As New TableCell
cell3.Controls.Add(BuildDropDownList("ddlAttribute-" & ID, 150,
"Attributes"))

Dim cell4 As New TableCell
cell4.Controls.Add(BuildTextBox("txtScore-" & ID, 40))

Dim cell5 As New TableCell
cell5.Controls.Add(BuildLinkButton("lnkDelete-" & ID))

row.Cells.Add(cell1)
row.Cells.Add(cell2)
row.Cells.Add(cell3)
row.Cells.Add(cell4)
row.Cells.Add(cell5)

tblAnswers.Rows.Add(row)
IDArray.Add(ID)
Next

plhDynControls.Controls.Add(tblAnswers)

'Insert Array containing ID of each row
If IsNothing(ViewState.Item("IDArray")) Then
ViewState.Add("IDArray", IDArray)
Else
ViewState.Item("IDArray") = IDArray
End If

End Sub
----------
Private Sub btnInsert_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles btnInsert.Click

'Add a new ID to the viewstate which will cause a new row to be
inserted when the viewstate is rebuilt
Dim IDArray As ArrayList
IDArray = CType(ViewState.Item("IDArray"), ArrayList)
IDArray.Add(Left(Guid.NewGuid.ToString, 8))
ViewState.Item("IDArray") = IDArray

'RebuildControls() 'unremark this and remove from page_load to get
insert button to work perfectly (delete no workie though)

End If

End Sub
----------
Private Sub lnkDelete_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs)

Dim IDArray As ArrayList
IDArray = CType(ViewState.Item("IDArray"), ArrayList)

Dim ID As String = Right(CType(sender, LinkButton).ID.ToString, 8)
IDArray.RemoveAt(IDArray.IndexOf(ID))

ViewState.Item("IDArray") = IDArray

End Sub
-----------
this is how I generate the link button dynamically
Private Function BuildLinkButton(ByVal name As String) As LinkButton

Dim lnkLink As New LinkButton
lnkLink.ID = name
lnkLink.Text = "Delete"
AddHandler lnkLink.Click, AddressOf lnkDelete_Click

Return lnkLink

End Function
-----------
Private Sub RebuildControls()

If IsNothing(ViewState.Item("IDArray")) Then
Exit Sub
End If

Dim IDArray As ArrayList
IDArray = CType(ViewState.Item("IDArray"), ArrayList)

Dim tblAnswers As New Table
Dim x As Integer

For x = 0 To IDArray.Count - 1

Dim row As New TableRow

Dim cell1 As New TableCell
cell1.Controls.Add(BuildTextBox("txtChoice-" &
Convert.ToString(IDArray.Item(x)), 140, Request.Form.Item("txtChoice-"
& Convert.ToString(IDArray.Item(x)))))

Dim cell2 As New TableCell
cell2.Controls.Add(BuildDropDownList("ddlFamily-" &
Convert.ToString(IDArray.Item(x)), 150, "Family",
Request.Form.Item("ddlFamily-" & Convert.ToString(IDArray.Item(x)))))

Dim cell3 As New TableCell
cell3.Controls.Add(BuildDropDownList("ddlAttribute-" &
Convert.ToString(IDArray.Item(x)), 150, "Attributes",
Request.Form.Item("ddlAttribute-" &
Convert.ToString(IDArray.Item(x)))))

Dim cell4 As New TableCell
cell4.Controls.Add(BuildTextBox("txtScore-" &
Convert.ToString(IDArray.Item(x)), 40, Request.Form.Item("txtScore-" &
Convert.ToString(IDArray.Item(x)))))

Dim cell5 As New TableCell
cell5.Controls.Add(BuildLinkButton("lnkDelete-" &
Convert.ToString(IDArray.Item(x))))

row.Cells.Add(cell1)
row.Cells.Add(cell2)
row.Cells.Add(cell3)
row.Cells.Add(cell4)
row.Cells.Add(cell5)

tblAnswers.Rows.Add(row)

Next

plhDynControls.Controls.Add(tblAnswers)

End Sub
---------
Let me know if seeing anything else might help. Thanks again.Amoril

You cannot use NewGuid function for ids because it'll generate different id
on every call (it means also on every postback) so events for all dynamically
created controls will not be fired. And you want be able to find a value
entered by the user. Use x (loop counter) with contact prefix instead. Have
also in mind you should recreate controls in page_init (but do not access
viewstate at this stage because it's simply not collected yet) as they will
automatically recreate their state.

Hope it helps

"Amoril" wrote:

Quote:

Originally Posted by

I've read quite a few different message on various boards and for some
reason I'm still having trouble wrapping my head around this viewstate
maintenance and trying to get these dynamically created link buttons
to stay wired up to their click events.
>
I have what is basically a simply survey question generation page. The
page first displays a few static fields and a dropdownlist of various
options for the user to select. When the user selects an option from
the list the page will generate a new table with 5 rows of textboxes,
drop down lists, and link buttons (to delete a row if desired). There
is also a static insert button to allow users to add additional rows
if needed.
>
Saving the data in the fields during postback isn't an issue, but I'm
stuck in two situations depending on how I adjust the code. First is
that I put the rebuilding of the controls in the Page_load and users
are forced to click twice on the static Insert Row button to add a row
or they have to click twice on a dynamic Delete Row link button to
remove a row. If I take the rebuilding of the controls out of the
Page_Load then the Insert Row button works fine, but clicking on a
Delete Row link button causes the click event to not fire and all the
dynamic controls disappear from the page.
>
Does anyone have any suggestions on what I need to do to fix this so
it's written correctly and will operate as intended? (if you need more
detail or code please ask)
>
Thank you for your help.
>
--Code Snippets (this setup requires 2 clicks on a button before the
click event appears to do anything--
>
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load
>
If Not IsPostBack Then
LoadQuestionTypes()
End If
>
RebuildControls()
>
End Sub
--------
Private Sub ddlQuestionType_SelectedIndexChanged(ByVal sender As
System.Object, ByVal e As System.EventArgs) Handles
ddlQuestionType.SelectedIndexChanged
>
...
BuildEmptyFive()
...
>
End Sub
--------
Private Sub BuildEmptyFive()
>
Dim IDArray As New ArrayList
Dim tblAnswers As New Table
Dim x As Integer
>
For x = 1 To 5
>
Dim row As New TableRow
Dim ID As String
>
ID = Left(System.Guid.NewGuid.ToString, 8)
>
Dim cell1 As New TableCell
cell1.Controls.Add(BuildTextBox("txtChoice-" & ID, 140))
>
Dim cell2 As New TableCell
cell2.Controls.Add(BuildDropDownList("ddlFamily-" & ID, 150,
"Family"))
>
Dim cell3 As New TableCell
cell3.Controls.Add(BuildDropDownList("ddlAttribute-" & ID, 150,
"Attributes"))
>
Dim cell4 As New TableCell
cell4.Controls.Add(BuildTextBox("txtScore-" & ID, 40))
>
Dim cell5 As New TableCell
cell5.Controls.Add(BuildLinkButton("lnkDelete-" & ID))
>
row.Cells.Add(cell1)
row.Cells.Add(cell2)
row.Cells.Add(cell3)
row.Cells.Add(cell4)
row.Cells.Add(cell5)
>
tblAnswers.Rows.Add(row)
IDArray.Add(ID)
Next
>
plhDynControls.Controls.Add(tblAnswers)
>
'Insert Array containing ID of each row
If IsNothing(ViewState.Item("IDArray")) Then
ViewState.Add("IDArray", IDArray)
Else
ViewState.Item("IDArray") = IDArray
End If
>
End Sub
----------
Private Sub btnInsert_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles btnInsert.Click
>
'Add a new ID to the viewstate which will cause a new row to be
inserted when the viewstate is rebuilt
Dim IDArray As ArrayList
IDArray = CType(ViewState.Item("IDArray"), ArrayList)
IDArray.Add(Left(Guid.NewGuid.ToString, 8))
ViewState.Item("IDArray") = IDArray
>
'RebuildControls() 'unremark this and remove from page_load to get
insert button to work perfectly (delete no workie though)
>
End If
>
End Sub
----------
Private Sub lnkDelete_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs)
>
Dim IDArray As ArrayList
IDArray = CType(ViewState.Item("IDArray"), ArrayList)
>
Dim ID As String = Right(CType(sender, LinkButton).ID.ToString, 8)
IDArray.RemoveAt(IDArray.IndexOf(ID))
>
ViewState.Item("IDArray") = IDArray
>
End Sub
-----------
this is how I generate the link button dynamically
Private Function BuildLinkButton(ByVal name As String) As LinkButton
>
Dim lnkLink As New LinkButton
lnkLink.ID = name
lnkLink.Text = "Delete"
AddHandler lnkLink.Click, AddressOf lnkDelete_Click
>
Return lnkLink
>
End Function
-----------
Private Sub RebuildControls()
>
If IsNothing(ViewState.Item("IDArray")) Then
Exit Sub
End If
>
Dim IDArray As ArrayList
IDArray = CType(ViewState.Item("IDArray"), ArrayList)
>
Dim tblAnswers As New Table
Dim x As Integer
>
For x = 0 To IDArray.Count - 1
>
Dim row As New TableRow
>
Dim cell1 As New TableCell
cell1.Controls.Add(BuildTextBox("txtChoice-" &
Convert.ToString(IDArray.Item(x)), 140, Request.Form.Item("txtChoice-"
& Convert.ToString(IDArray.Item(x)))))
>
Dim cell2 As New TableCell
cell2.Controls.Add(BuildDropDownList("ddlFamily-" &
Convert.ToString(IDArray.Item(x)), 150, "Family",
Request.Form.Item("ddlFamily-" & Convert.ToString(IDArray.Item(x)))))
>
Dim cell3 As New TableCell
cell3.Controls.Add(BuildDropDownList("ddlAttribute-" &
Convert.ToString(IDArray.Item(x)), 150, "Attributes",
Request.Form.Item("ddlAttribute-" &
Convert.ToString(IDArray.Item(x)))))
>
Dim cell4 As New TableCell
cell4.Controls.Add(BuildTextBox("txtScore-" &
Convert.ToString(IDArray.Item(x)), 40, Request.Form.Item("txtScore-" &
Convert.ToString(IDArray.Item(x)))))
>
Dim cell5 As New TableCell
cell5.Controls.Add(BuildLinkButton("lnkDelete-" &
Convert.ToString(IDArray.Item(x))))
>
row.Cells.Add(cell1)
row.Cells.Add(cell2)
row.Cells.Add(cell3)
row.Cells.Add(cell4)
row.Cells.Add(cell5)
>
tblAnswers.Rows.Add(row)
>
Next
>
plhDynControls.Controls.Add(tblAnswers)
>
End Sub
---------
Let me know if seeing anything else might help. Thanks again.
>
>


The only place that I use NewGuid to assign the ID's is in the
BuildEmptyFive sub (only fired after the user selects an item from the
drop down), for RebuildingControls sub I pull the ID's out of the
IDArray in the ViewState, so that shouldn't be an issue.

Moving the RebuildControls() sub from Page_Load to Page_Init actually
made the issue worse, now when I click on the static Insert Row button
or the dynamics link buttons to delete a row, all the dynamic controls
disappear. The static button fires it's event, but the link buttons
don't. Perhaps I'm not understanding what you mean by that since
without accessing the IDArray in the viewstate I won't know how many
controls need to be recreated.

Any more detail you could provide would be appreciated.
Hi again,

Oh yes, you're right but no need for that. it's easier to use row index and
a constant prefix for a particular control type (attribute, score,etc). I'll
try to provide a fully working example later on today.

take care
--
Milosz

"Amoril" wrote:

Quote:

Originally Posted by

The only place that I use NewGuid to assign the ID's is in the
BuildEmptyFive sub (only fired after the user selects an item from the
drop down), for RebuildingControls sub I pull the ID's out of the
IDArray in the ViewState, so that shouldn't be an issue.
>
Moving the RebuildControls() sub from Page_Load to Page_Init actually
made the issue worse, now when I click on the static Insert Row button
or the dynamics link buttons to delete a row, all the dynamic controls
disappear. The static button fires it's event, but the link buttons
don't. Perhaps I'm not understanding what you mean by that since
without accessing the IDArray in the viewstate I won't know how many
controls need to be recreated.
>
Any more detail you could provide would be appreciated.
>
>


Hi again,

Actually we have to use guid because you can delete row, which i didn't pick
up before. Anyway, i created fully working example for you. You should be
fine from this point

-- begin aspx code --

<%@dotnet.itags.org. Page Language="VB" AutoEventWireup="false" CodeFile="Survey.aspx.vb"
Inherits="Survey" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:DropDownList runat="server" ID="questions" AutoPostBack="true">
<asp:ListItem Text="Please Select a Question..." />
<asp:ListItem Text="What are your names?" />
<asp:ListItem Text="Name all girlfriends you have had in your life" />
</asp:DropDownList>
<asp:Panel runat="server" ID="container" />
<asp:Panel runat="server" ID="surveyOptions">
<asp:Button ID="btnAddRow" runat="server" Text="Add row" />
<asp:Button ID="btnSubmit" runat="server" Text="Submit Survey"/>
</asp:Panel>
</div>
</form>
</body>
</html>
-- end aspx code --

-- begin vb.net code --

Partial Class Survey
Inherits System.Web.UI.Page

Protected Sub Page_Load(ByVal sender As Object, ByVal e As
System.EventArgs) Handles Me.Load
RecreateRows()
End Sub

Protected Sub questions_SelectedIndexChanged(ByVal sender As Object, ByVal
e As System.EventArgs) Handles questions.SelectedIndexChanged

Const DefaultRowCount As Integer = 5

' clear everything
IDs.Clear()

If CType(sender, DropDownList).SelectedIndex >= 0 Then
' create x default empty rows
For i As Integer = 1 To DefaultRowCount
IDs.Add(GenerateId())
Next
End If

RecreateRows()

End Sub

Private Sub RecreateRows()

container.Controls.Clear()

For Each id As String In IDs
AddAnswerRow(id)
Next

surveyOptions.Visible = IDs.Count 0

End Sub

Private Const RowIdPrefix As String = "row"
Private Const TextBoxIdPrefix As String = "txt"
Private Const DropDownListIdPrefix As String = "ddl"

Private Sub AddAnswerRow(ByVal id As String)

Dim panel As Panel
Dim textBox As TextBox
Dim linkButton As LinkButton
Dim dropDownList As DropDownList

' row panel
panel = New Panel()
panel.ID = RowIdPrefix & id

' answer text box
textBox = New TextBox()
textBox.ID = TextBoxIdPrefix & id

' delete button
linkButton = New LinkButton()
linkButton.ID = "btn" & id
linkButton.Text = "delete"
linkButton.CommandArgument = id
AddHandler linkButton.Command, New CommandEventHandler(AddressOf
DeleteAnswerRow)

dropDownList = New DropDownList()
dropDownList.ID = DropDownListIdPrefix & id
dropDownList.Items.Add(New ListItem("Value0", "0"))
dropDownList.Items.Add(New ListItem("Value1", "1"))
dropDownList.Items.Add(New ListItem("Value2", "2"))

panel.Controls.Add(textBox)
panel.Controls.Add(dropDownList)
panel.Controls.Add(linkButton)
container.Controls.Add(panel)

End Sub

Private Sub DeleteAnswerRow(ByVal source As Object, ByVal e As
CommandEventArgs)

Dim id As String = CType(e.CommandArgument, String)
Dim control As Control = container.FindControl(RowIdPrefix & id)

If (Not control Is Nothing) Then
container.Controls.Remove(control)

Dim index As Integer = IDs.IndexOf(id)
If index <-1 Then
IDs.RemoveAt(index)
End If

End If

End Sub

Private ReadOnly Property IDs() As ArrayList
Get
Dim value As Object = ViewState("IDs")
If value Is Nothing Then
value = New ArrayList()
ViewState("IDs") = value
End If
Return value
End Get
End Property

Private Function GenerateId() As String
Return Guid.NewGuid().ToString("N")
End Function

Protected Sub btnAddRow_Click(ByVal sender As Object, ByVal e As
System.EventArgs) Handles btnAddRow.Click

Dim id As String = GenerateId()

IDs.Add(id)
AddAnswerRow(id)

End Sub

Protected Sub btnSubmit_Click(ByVal sender As Object, ByVal e As
System.EventArgs) Handles btnSubmit.Click

' obtain results
Dim textBox As TextBox
Dim dropDownList As DropDownList

For Each id As String In IDs

'
' text box value
'
textBox = CType(container.FindControl(TextBoxIdPrefix & id), TextBox)

If (Not textBox Is Nothing) Then
Dim textBoxValue As String = textBox.Text
End If

'
' drop down list selected value
'
dropDownList = CType(container.FindControl(DropDownListIdPrefix & id),
DropDownList)

If (Not dropDownList Is Nothing) Then
Dim dropDownListValue As String = dropDownList.SelectedValue
End If

Next

End Sub

End Class

-- end vb.net code --
Milosz

"Milosz Skalecki [MCAD]" wrote:

Quote:

Originally Posted by

Hi again,
>
Oh yes, you're right but no need for that. it's easier to use row index and
a constant prefix for a particular control type (attribute, score,etc). I'll
try to provide a fully working example later on today.
>
take care
--
Milosz
>
>
"Amoril" wrote:
>

Quote:

Originally Posted by

The only place that I use NewGuid to assign the ID's is in the
BuildEmptyFive sub (only fired after the user selects an item from the
drop down), for RebuildingControls sub I pull the ID's out of the
IDArray in the ViewState, so that shouldn't be an issue.

Moving the RebuildControls() sub from Page_Load to Page_Init actually
made the issue worse, now when I click on the static Insert Row button
or the dynamics link buttons to delete a row, all the dynamic controls
disappear. The static button fires it's event, but the link buttons
don't. Perhaps I'm not understanding what you mean by that since
without accessing the IDArray in the viewstate I won't know how many
controls need to be recreated.

Any more detail you could provide would be appreciated.


Excellent, thank you very much for your help, it's working great.

trouble with click events on dynamically created link buttons

I've read quite a few different message on various boards and for some
reason I'm still having trouble wrapping my head around this viewstate
maintenance and trying to get these dynamically created link buttons
to stay wired up to their click events.
I have what is basically a simply survey question generation page. The
page first displays a few static fields and a dropdownlist of various
options for the user to select. When the user selects an option from
the list the page will generate a new table with 5 rows of textboxes,
drop down lists, and link buttons (to delete a row if desired). There
is also a static insert button to allow users to add additional rows
if needed.
Saving the data in the fields during postback isn't an issue, but I'm
stuck in two situations depending on how I adjust the code. First is
that I put the rebuilding of the controls in the Page_load and users
are forced to click twice on the static Insert Row button to add a row
or they have to click twice on a dynamic Delete Row link button to
remove a row. If I take the rebuilding of the controls out of the
Page_Load then the Insert Row button works fine, but clicking on a
Delete Row link button causes the click event to not fire and all the
dynamic controls disappear from the page.
Does anyone have any suggestions on what I need to do to fix this so
it's written correctly and will operate as intended? (if you need more
detail or code please ask)
Thank you for your help.
--Code Snippets (this setup requires 2 clicks on a button before the
click event appears to do anything--
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load
If Not IsPostBack Then
LoadQuestionTypes()
End If
RebuildControls()
End Sub
--
Private Sub ddlQuestionType_SelectedIndexChanged(ByV
al sender As
System.Object, ByVal e As System.EventArgs) Handles
ddlQuestionType.SelectedIndexChanged
...
BuildEmptyFive()
...
End Sub
--
Private Sub BuildEmptyFive()
Dim IDArray As New ArrayList
Dim tblAnswers As New Table
Dim x As Integer
For x = 1 To 5
Dim row As New TableRow
Dim ID As String
ID = Left(System.Guid.NewGuid.ToString, 8)
Dim cell1 As New TableCell
cell1.Controls.Add(BuildTextBox("txtChoice-" & ID, 140))
Dim cell2 As New TableCell
cell2.Controls.Add(BuildDropDownList("ddlFamily-" & ID, 150,
"Family"))
Dim cell3 As New TableCell
cell3.Controls.Add(BuildDropDownList("ddlAttribute-" & ID, 150,
"Attributes"))
Dim cell4 As New TableCell
cell4.Controls.Add(BuildTextBox("txtScore-" & ID, 40))
Dim cell5 As New TableCell
cell5.Controls.Add(BuildLinkButton("lnkDelete-" & ID))
row.Cells.Add(cell1)
row.Cells.Add(cell2)
row.Cells.Add(cell3)
row.Cells.Add(cell4)
row.Cells.Add(cell5)
tblAnswers.Rows.Add(row)
IDArray.Add(ID)
Next
plhDynControls.Controls.Add(tblAnswers)
'Insert Array containing ID of each row
If IsNothing(ViewState.Item("IDArray")) Then
ViewState.Add("IDArray", IDArray)
Else
ViewState.Item("IDArray") = IDArray
End If
End Sub
--
Private Sub btnInsert_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles btnInsert.Click
'Add a new ID to the viewstate which will cause a new row to be
inserted when the viewstate is rebuilt
Dim IDArray As ArrayList
IDArray = CType(ViewState.Item("IDArray"), ArrayList)
IDArray.Add(Left(Guid.NewGuid.ToString, 8))
ViewState.Item("IDArray") = IDArray
'RebuildControls() 'unremark this and remove from page_load to get
insert button to work perfectly (delete no workie though)
End If
End Sub
--
Private Sub lnkDelete_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs)
Dim IDArray As ArrayList
IDArray = CType(ViewState.Item("IDArray"), ArrayList)
Dim ID As String = Right(CType(sender, LinkButton).ID.ToString, 8)
IDArray.RemoveAt(IDArray.IndexOf(ID))
ViewState.Item("IDArray") = IDArray
End Sub
--
this is how I generate the link button dynamically
Private Function BuildLinkButton(ByVal name As String) As LinkButton
Dim lnkLink As New LinkButton
lnkLink.ID = name
lnkLink.Text = "Delete"
AddHandler lnkLink.Click, AddressOf lnkDelete_Click
Return lnkLink
End Function
--
Private Sub RebuildControls()
If IsNothing(ViewState.Item("IDArray")) Then
Exit Sub
End If
Dim IDArray As ArrayList
IDArray = CType(ViewState.Item("IDArray"), ArrayList)
Dim tblAnswers As New Table
Dim x As Integer
For x = 0 To IDArray.Count - 1
Dim row As New TableRow
Dim cell1 As New TableCell
cell1.Controls.Add(BuildTextBox("txtChoice-" &
Convert.ToString(IDArray.Item(x)), 140, Request.Form.Item("txtChoice-"
& Convert.ToString(IDArray.Item(x)))))
Dim cell2 As New TableCell
cell2.Controls.Add(BuildDropDownList("ddlFamily-" &
Convert.ToString(IDArray.Item(x)), 150, "Family",
Request.Form.Item("ddlFamily-" & Convert.ToString(IDArray.Item(x)))))
Dim cell3 As New TableCell
cell3.Controls.Add(BuildDropDownList("ddlAttribute-" &
Convert.ToString(IDArray.Item(x)), 150, "Attributes",
Request.Form.Item("ddlAttribute-" &
Convert.ToString(IDArray.Item(x)))))
Dim cell4 As New TableCell
cell4.Controls.Add(BuildTextBox("txtScore-" &
Convert.ToString(IDArray.Item(x)), 40, Request.Form.Item("txtScore-" &
Convert.ToString(IDArray.Item(x)))))
Dim cell5 As New TableCell
cell5.Controls.Add(BuildLinkButton("lnkDelete-" &
Convert.ToString(IDArray.Item(x))))
row.Cells.Add(cell1)
row.Cells.Add(cell2)
row.Cells.Add(cell3)
row.Cells.Add(cell4)
row.Cells.Add(cell5)
tblAnswers.Rows.Add(row)
Next
plhDynControls.Controls.Add(tblAnswers)
End Sub
--
Let me know if seeing anything else might help. Thanks again.Amoril
You cannot use NewGuid function for ids because it'll generate different id
on every call (it means also on every postback) so events for all dynamicall
y
created controls will not be fired. And you want be able to find a value
entered by the user. Use x (loop counter) with contact prefix instead. Have
also in mind you should recreate controls in page_init (but do not access
viewstate at this stage because it’s simply not collected yet) as they wil
l
automatically recreate their state.
Hope it helps
"Amoril" wrote:

> I've read quite a few different message on various boards and for some
> reason I'm still having trouble wrapping my head around this viewstate
> maintenance and trying to get these dynamically created link buttons
> to stay wired up to their click events.
> I have what is basically a simply survey question generation page. The
> page first displays a few static fields and a dropdownlist of various
> options for the user to select. When the user selects an option from
> the list the page will generate a new table with 5 rows of textboxes,
> drop down lists, and link buttons (to delete a row if desired). There
> is also a static insert button to allow users to add additional rows
> if needed.
> Saving the data in the fields during postback isn't an issue, but I'm
> stuck in two situations depending on how I adjust the code. First is
> that I put the rebuilding of the controls in the Page_load and users
> are forced to click twice on the static Insert Row button to add a row
> or they have to click twice on a dynamic Delete Row link button to
> remove a row. If I take the rebuilding of the controls out of the
> Page_Load then the Insert Row button works fine, but clicking on a
> Delete Row link button causes the click event to not fire and all the
> dynamic controls disappear from the page.
> Does anyone have any suggestions on what I need to do to fix this so
> it's written correctly and will operate as intended? (if you need more
> detail or code please ask)
> Thank you for your help.
> --Code Snippets (this setup requires 2 clicks on a button before the
> click event appears to do anything--
> Private Sub Page_Load(ByVal sender As System.Object, ByVal e As
> System.EventArgs) Handles MyBase.Load
> If Not IsPostBack Then
> LoadQuestionTypes()
> End If
> RebuildControls()
> End Sub
> --
> Private Sub ddlQuestionType_SelectedIndexChanged(ByV
al sender As
> System.Object, ByVal e As System.EventArgs) Handles
> ddlQuestionType.SelectedIndexChanged
> ...
> BuildEmptyFive()
> ...
> End Sub
> --
> Private Sub BuildEmptyFive()
> Dim IDArray As New ArrayList
> Dim tblAnswers As New Table
> Dim x As Integer
> For x = 1 To 5
> Dim row As New TableRow
> Dim ID As String
> ID = Left(System.Guid.NewGuid.ToString, 8)
> Dim cell1 As New TableCell
> cell1.Controls.Add(BuildTextBox("txtChoice-" & ID, 140))
> Dim cell2 As New TableCell
> cell2.Controls.Add(BuildDropDownList("ddlFamily-" & ID, 150,
> "Family"))
> Dim cell3 As New TableCell
> cell3.Controls.Add(BuildDropDownList("ddlAttribute-" & ID, 150,
> "Attributes"))
> Dim cell4 As New TableCell
> cell4.Controls.Add(BuildTextBox("txtScore-" & ID, 40))
> Dim cell5 As New TableCell
> cell5.Controls.Add(BuildLinkButton("lnkDelete-" & ID))
> row.Cells.Add(cell1)
> row.Cells.Add(cell2)
> row.Cells.Add(cell3)
> row.Cells.Add(cell4)
> row.Cells.Add(cell5)
> tblAnswers.Rows.Add(row)
> IDArray.Add(ID)
> Next
> plhDynControls.Controls.Add(tblAnswers)
> 'Insert Array containing ID of each row
> If IsNothing(ViewState.Item("IDArray")) Then
> ViewState.Add("IDArray", IDArray)
> Else
> ViewState.Item("IDArray") = IDArray
> End If
> End Sub
> --
> Private Sub btnInsert_Click(ByVal sender As System.Object, ByVal e As
> System.EventArgs) Handles btnInsert.Click
> 'Add a new ID to the viewstate which will cause a new row to be
> inserted when the viewstate is rebuilt
> Dim IDArray As ArrayList
> IDArray = CType(ViewState.Item("IDArray"), ArrayList)
> IDArray.Add(Left(Guid.NewGuid.ToString, 8))
> ViewState.Item("IDArray") = IDArray
> 'RebuildControls() 'unremark this and remove from page_load to get
> insert button to work perfectly (delete no workie though)
> End If
> End Sub
> --
> Private Sub lnkDelete_Click(ByVal sender As System.Object, ByVal e As
> System.EventArgs)
> Dim IDArray As ArrayList
> IDArray = CType(ViewState.Item("IDArray"), ArrayList)
> Dim ID As String = Right(CType(sender, LinkButton).ID.ToString, 8)
> IDArray.RemoveAt(IDArray.IndexOf(ID))
> ViewState.Item("IDArray") = IDArray
> End Sub
> --
> this is how I generate the link button dynamically
> Private Function BuildLinkButton(ByVal name As String) As LinkButton
> Dim lnkLink As New LinkButton
> lnkLink.ID = name
> lnkLink.Text = "Delete"
> AddHandler lnkLink.Click, AddressOf lnkDelete_Click
> Return lnkLink
> End Function
> --
> Private Sub RebuildControls()
> If IsNothing(ViewState.Item("IDArray")) Then
> Exit Sub
> End If
> Dim IDArray As ArrayList
> IDArray = CType(ViewState.Item("IDArray"), ArrayList)
> Dim tblAnswers As New Table
> Dim x As Integer
> For x = 0 To IDArray.Count - 1
> Dim row As New TableRow
> Dim cell1 As New TableCell
> cell1.Controls.Add(BuildTextBox("txtChoice-" &
> Convert.ToString(IDArray.Item(x)), 140, Request.Form.Item("txtChoice-"
> & Convert.ToString(IDArray.Item(x)))))
> Dim cell2 As New TableCell
> cell2.Controls.Add(BuildDropDownList("ddlFamily-" &
> Convert.ToString(IDArray.Item(x)), 150, "Family",
> Request.Form.Item("ddlFamily-" & Convert.ToString(IDArray.Item(x)))))
> Dim cell3 As New TableCell
> cell3.Controls.Add(BuildDropDownList("ddlAttribute-" &
> Convert.ToString(IDArray.Item(x)), 150, "Attributes",
> Request.Form.Item("ddlAttribute-" &
> Convert.ToString(IDArray.Item(x)))))
> Dim cell4 As New TableCell
> cell4.Controls.Add(BuildTextBox("txtScore-" &
> Convert.ToString(IDArray.Item(x)), 40, Request.Form.Item("txtScore-" &
> Convert.ToString(IDArray.Item(x)))))
> Dim cell5 As New TableCell
> cell5.Controls.Add(BuildLinkButton("lnkDelete-" &
> Convert.ToString(IDArray.Item(x))))
> row.Cells.Add(cell1)
> row.Cells.Add(cell2)
> row.Cells.Add(cell3)
> row.Cells.Add(cell4)
> row.Cells.Add(cell5)
> tblAnswers.Rows.Add(row)
> Next
> plhDynControls.Controls.Add(tblAnswers)
> End Sub
> --
> Let me know if seeing anything else might help. Thanks again.
>
The only place that I use NewGuid to assign the ID's is in the
BuildEmptyFive sub (only fired after the user selects an item from the
drop down), for RebuildingControls sub I pull the ID's out of the
IDArray in the ViewState, so that shouldn't be an issue.
Moving the RebuildControls() sub from Page_Load to Page_Init actually
made the issue worse, now when I click on the static Insert Row button
or the dynamics link buttons to delete a row, all the dynamic controls
disappear. The static button fires it's event, but the link buttons
don't. Perhaps I'm not understanding what you mean by that since
without accessing the IDArray in the viewstate I won't know how many
controls need to be recreated.
Any more detail you could provide would be appreciated.
Hi again,
Oh yes, you're right but no need for that. it's easier to use row index and
a constant prefix for a particular control type (attribute, score,etc). I'll
try to provide a fully working example later on today.
take care
--
Milosz
"Amoril" wrote:

> The only place that I use NewGuid to assign the ID's is in the
> BuildEmptyFive sub (only fired after the user selects an item from the
> drop down), for RebuildingControls sub I pull the ID's out of the
> IDArray in the ViewState, so that shouldn't be an issue.
> Moving the RebuildControls() sub from Page_Load to Page_Init actually
> made the issue worse, now when I click on the static Insert Row button
> or the dynamics link buttons to delete a row, all the dynamic controls
> disappear. The static button fires it's event, but the link buttons
> don't. Perhaps I'm not understanding what you mean by that since
> without accessing the IDArray in the viewstate I won't know how many
> controls need to be recreated.
> Any more detail you could provide would be appreciated.
>
Hi again,
Actually we have to use guid because you can delete row, which i didn't pick
up before. Anyway, i created fully working example for you. You should be
fine from this point
-- begin aspx code --
<%@. Page Language="VB" AutoEventWireup="false" CodeFile="Survey.aspx.vb"
Inherits="Survey" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:DropDownList runat="server" ID="questions" AutoPostBack="true">
<asp:ListItem Text="Please Select a Question..." />
<asp:ListItem Text="What are your names?" />
<asp:ListItem Text="Name all girlfriends you have had in your life" />
</asp:DropDownList>
<asp:Panel runat="server" ID="container" />
<asp:Panel runat="server" ID="surveyOptions">
<asp:Button ID="btnAddRow" runat="server" Text="Add row" />
<asp:Button ID="btnSubmit" runat="server" Text="Submit Survey"/>
</asp:Panel>
</div>
</form>
</body>
</html>
-- end aspx code --
-- begin vb.net code --
Partial Class Survey
Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As
System.EventArgs) Handles Me.Load
RecreateRows()
End Sub
Protected Sub questions_SelectedIndexChanged(ByVal sender As Object, ByVal
e As System.EventArgs) Handles questions.SelectedIndexChanged
Const DefaultRowCount As Integer = 5
' clear everything
IDs.Clear()
If CType(sender, DropDownList).SelectedIndex >= 0 Then
' create x default empty rows
For i As Integer = 1 To DefaultRowCount
IDs.Add(GenerateId())
Next
End If
RecreateRows()
End Sub
Private Sub RecreateRows()
container.Controls.Clear()
For Each id As String In IDs
AddAnswerRow(id)
Next
surveyOptions.Visible = IDs.Count > 0
End Sub
Private Const RowIdPrefix As String = "row"
Private Const TextBoxIdPrefix As String = "txt"
Private Const DropDownListIdPrefix As String = "ddl"
Private Sub AddAnswerRow(ByVal id As String)
Dim panel As Panel
Dim textBox As TextBox
Dim linkButton As LinkButton
Dim dropDownList As DropDownList
' row panel
panel = New Panel()
panel.ID = RowIdPrefix & id
' answer text box
textBox = New TextBox()
textBox.ID = TextBoxIdPrefix & id
' delete button
linkButton = New LinkButton()
linkButton.ID = "btn" & id
linkButton.Text = "delete"
linkButton.CommandArgument = id
AddHandler linkButton.Command, New CommandEventHandler(AddressOf
DeleteAnswerRow)
dropDownList = New DropDownList()
dropDownList.ID = DropDownListIdPrefix & id
dropDownList.Items.Add(New ListItem("Value0", "0"))
dropDownList.Items.Add(New ListItem("Value1", "1"))
dropDownList.Items.Add(New ListItem("Value2", "2"))
panel.Controls.Add(textBox)
panel.Controls.Add(dropDownList)
panel.Controls.Add(linkButton)
container.Controls.Add(panel)
End Sub
Private Sub DeleteAnswerRow(ByVal source As Object, ByVal e As
CommandEventArgs)
Dim id As String = CType(e.CommandArgument, String)
Dim control As Control = container.FindControl(RowIdPrefix & id)
If (Not control Is Nothing) Then
container.Controls.Remove(control)
Dim index As Integer = IDs.IndexOf(id)
If index <> -1 Then
IDs.RemoveAt(index)
End If
End If
End Sub
Private ReadOnly Property IDs() As ArrayList
Get
Dim value As Object = ViewState("IDs")
If value Is Nothing Then
value = New ArrayList()
ViewState("IDs") = value
End If
Return value
End Get
End Property
Private Function GenerateId() As String
Return Guid.NewGuid().ToString("N")
End Function
Protected Sub btnAddRow_Click(ByVal sender As Object, ByVal e As
System.EventArgs) Handles btnAddRow.Click
Dim id As String = GenerateId()
IDs.Add(id)
AddAnswerRow(id)
End Sub
Protected Sub btnSubmit_Click(ByVal sender As Object, ByVal e As
System.EventArgs) Handles btnSubmit.Click
' obtain results
Dim textBox As TextBox
Dim dropDownList As DropDownList
For Each id As String In IDs
'
' text box value
'
textBox = CType(container.FindControl(TextBoxIdPrefix & id), TextBox)
If (Not textBox Is Nothing) Then
Dim textBoxValue As String = textBox.Text
End If
'
' drop down list selected value
'
dropDownList = CType(container.FindControl(DropDownListIdPrefix & id),
DropDownList)
If (Not dropDownList Is Nothing) Then
Dim dropDownListValue As String = dropDownList.SelectedValue
End If
Next
End Sub
End Class
-- end vb.net code --
Milosz
"Milosz Skalecki [MCAD]" wrote:
> Hi again,
> Oh yes, you're right but no need for that. it's easier to use row index an
d
> a constant prefix for a particular control type (attribute, score,etc). I'
ll
> try to provide a fully working example later on today.
> take care
> --
> Milosz
>
> "Amoril" wrote:
>
Excellent, thank you very much for your help, it's working great.

Thursday, March 22, 2012

trouble with rollover buttons on master page

asp.net 2.0
Iv'e spent the last 3 or 4 hours trying to get this to work. I'm simply
trying to get rollover buttons to work on my master page.
1. The master page is in the root. "Website1"
2. The images for the buttons are in a subfolder off the root
("Website1\RolloverButtonsImages")
3. There are some pages that user the master that are in subfolders such ase
"Website1\LoggedInUsers"
The above is important because I believe that master pages is part of what's
goofing this up.
I have been using some rollover button code that uses this sort of code:
<a href="http://links.10026.com/?link=Default.aspx" onmouseover="setOverImg('1','');"
onmouseout="setOutImg('1','');" target=""> <img
src="RolloverButtonsImages/button1up.png" border="0" id="button1" vspace="1"
hspace="1"></a>
On my development machine, the only way I was able to get the images to work
properly was to hard code the roote into the paths like this:
<a href="http://links.10026.com/?link=/MySite1/Default.aspx" onmouseover="setOverImg('1','');"
onmouseout="setOutImg('1','');" target=""> <img
src="/MySite1/RolloverButtonsImages/button1up.png" border="0" id="button1"
vspace="1" hspace="1"></a>
That seemed to work ok. But when I moved it to a remote production server
things sort of fell apart and I kind of understand why. So someone told me
that it's probably not a good idea to use the "a href with an img in it"
type of layout for this because the whole ~ for the root can confuse a href
I guess. I'm new at a lot fo this so I guess maybe that's possible. And I
understand the reason NOT to hard code the root into things but that was the
only way i could get thigns to work at all before.
Pretty much EVERYTHING I find online suggests the simplest way to do this is
to instead use asp:imagebutton like this:
<asp:ImageButton ID="ImageButton1" runat="server"
ImageUrl="~/RolloverButtonsImages/button1up.png"
PostBackUrl="~/Default.aspx" /><br />
and putting some code like this in the Page_Load event:
ImageButton1.Attributes.Add("OnMouseOver",
"this.src='~/RolloverButtonsImages/button1over.png'")
ImageButton1.Attributes.Add("OnMouseOut",
"this.src='~/RolloverButtonsImages/button1up.png'")
Well that didn't work either. The image button markup itself does what I
expect. The image button shows up and when I click it it goes to my default
page regardless of where I am in the site. But the code above that's
supposed to change the image causes screwy behavior. When I mouse over the
image button, the image vanishes and it's replaced by the text "submit
query" on the page. I also tried putting If Not Page.IsPostback around the
above and that didn't help.
I tried all of this and it works on his site but it does NOT work for me on
master page layout I'm dealing with: http://aspalliance.com/317
What seems like should be pretty simple has turned into a nightmare for me.
Could someone give me some clear instructions on the best way to do this
considering all that I've said above? (master pages, subfolders, etc.)? I
need this to work so that the buttons link to the correct url no matter
where I am in the directory tree and so that they also display the correct
images no matter which page is running. Again, I think a big part of the
problem is that the buttons are on the MASTER page. There's got to be a
simple way to deal with this. i just haven't found it. I really don't care
if they're link buttons, image buttons, href's with html buttons or what as
long as it works and works consistently.
Thanks in advance,
Keiththere are a couple things to understand.
1) the master page is a control on the page referencing it, so any
relative url's are relative to the page's location, not the master. (the
browser doesn't know anthing about master pages).
2) the ~/url command (borrowed from unix web servers) is implemented by
asp.net code. on page render any server control with a url property,
asp.net check if the url starts with a "~", if so deteremines the
relative path from the vdir and replaces the "~" with it.
therefore:
<img src="http://pics.10026.com/?src=~/images/img.gif"> no translation done
<img src="http://pics.10026.com/?src=~/images/img.gif" runat="server" /> translation will be done
so you need to add runat=server to your <a> and <img> to get the "~"
support. for javascript you are out of luck, you will need to write your
own, or use hidden images:
<img id="iRollOver1" src="http://pics.10026.com/?src=~/rollover1.gif"
runat="server" style="display:none" />
then in javascript copy the src url. this has the advantage of
precaching the rollover images.
-- bruce (sqlwork.com)
Keith G Hicks wrote:
> asp.net 2.0
> Iv'e spent the last 3 or 4 hours trying to get this to work. I'm simply
> trying to get rollover buttons to work on my master page.
> 1. The master page is in the root. "Website1"
> 2. The images for the buttons are in a subfolder off the root
> ("Website1\RolloverButtonsImages")
> 3. There are some pages that user the master that are in subfolders such a
se
> "Website1\LoggedInUsers"
> The above is important because I believe that master pages is part of what
's
> goofing this up.
> I have been using some rollover button code that uses this sort of code:
> <a href="http://links.10026.com/?link=Default.aspx" onmouseover="setOverImg('1','');"
> onmouseout="setOutImg('1','');" target=""> <img
> src="http://pics.10026.com/?src=RolloverButtonsImages/button1up.png" border="0" id="button1" vspace="
1"
> hspace="1"></a>
> On my development machine, the only way I was able to get the images to wo
rk
> properly was to hard code the roote into the paths like this:
> <a href="http://links.10026.com/?link=/MySite1/Default.aspx" onmouseover="setOverImg('1','');"
> onmouseout="setOutImg('1','');" target=""> <img
> src="http://pics.10026.com/?src=/MySite1/RolloverButtonsImages/button1up.png" border="0" id="button1"
> vspace="1" hspace="1"></a>
> That seemed to work ok. But when I moved it to a remote production server
> things sort of fell apart and I kind of understand why. So someone told me
> that it's probably not a good idea to use the "a href with an img in it"
> type of layout for this because the whole ~ for the root can confuse a hre
f
> I guess. I'm new at a lot fo this so I guess maybe that's possible. And I
> understand the reason NOT to hard code the root into things but that was t
he
> only way i could get thigns to work at all before.
> Pretty much EVERYTHING I find online suggests the simplest way to do this
is
> to instead use asp:imagebutton like this:
> <asp:ImageButton ID="ImageButton1" runat="server"
> ImageUrl="~/RolloverButtonsImages/button1up.png"
> PostBackUrl="~/Default.aspx" /><br />
> and putting some code like this in the Page_Load event:
> ImageButton1.Attributes.Add("OnMouseOver",
> "this.src='~/RolloverButtonsImages/button1over.png'")
> ImageButton1.Attributes.Add("OnMouseOut",
> "this.src='~/RolloverButtonsImages/button1up.png'")
> Well that didn't work either. The image button markup itself does what I
> expect. The image button shows up and when I click it it goes to my defaul
t
> page regardless of where I am in the site. But the code above that's
> supposed to change the image causes screwy behavior. When I mouse over the
> image button, the image vanishes and it's replaced by the text "submit
> query" on the page. I also tried putting If Not Page.IsPostback around the
> above and that didn't help.
> I tried all of this and it works on his site but it does NOT work for me o
n
> master page layout I'm dealing with: http://aspalliance.com/317
> What seems like should be pretty simple has turned into a nightmare for me
.
> Could someone give me some clear instructions on the best way to do this
> considering all that I've said above? (master pages, subfolders, etc.)? I
> need this to work so that the buttons link to the correct url no matter
> where I am in the directory tree and so that they also display the correct
> images no matter which page is running. Again, I think a big part of the
> problem is that the buttons are on the MASTER page. There's got to be a
> simple way to deal with this. i just haven't found it. I really don't care
> if they're link buttons, image buttons, href's with html buttons or what a
s
> long as it works and works consistently.
> Thanks in advance,
> Keith
>
OK. Thanks Bruce. Your explanation about the tilde and runat="server" helped
a lot. But I'm lost on the other end.
Given the code shown below, here's what happens. All the buttons show up
when loading the page. They show up with the "out" image which is of course
correct. When I click one of them it directs to the correct page. That's
fine so far. They also show up and click to the correct pages as expected
when I'm viewing a page that's in a subfolder. So far so good. But the
rollover doesn't do anything. I don't get the "over" image at any time. No
errors, no funny behavior, just no image change.
There are 3 things shown below.
1 - the contents of a javascript file that's supposed to change the
images.
2 - the contents of my masterpage head section.
3 - one of the button definitions.
Here's the contents of the javascript file (which was created by a button
generating tool). The file is named RolloverButtonsImagesMenuScript.js and
is in the root. Notice the first line is var buttonFolder =
"~/RolloverButtonsImages/"; with the tilde (I've tried it without the tilde
as well and other variations I could think of too). I know this code works
generally because when I had this running on my development machien I had
hard coded the root folder name into just about everything. But when I got
to the remote server, things fell apart and I realized that was a mistake.
So here I am.
/*############### js file code begins here ###################*/
/*** SET BUTTON'S FOLDER HERE ***/
var buttonFolder = "~/RolloverButtonsImages/";
/*** SET BUTTONS' FILENAMES HERE ***/
upSources = new
Array("button1up.png","button2up.png","button3up.png","button4up.png","butto
n5up.png","button6up.png","button7up.png","button8up.png","button9up.png","b
utton10up.png","button11up.png");
overSources = new
Array("button1over.png","button2over.png","button3over.png","button4over.png
","button5over.png","button6over.png","button7over.png","button8over.png","b
utton9over.png","button10over.png","button11over.png");
//*** NO MORE SETTINGS BEYOND THIS POINT ***//
totalButtons = upSources.length;
//*** MAIN BUTTONS FUNCTIONS ***//
// PRELOAD MAIN MENU BUTTON IMAGES
function preload() {
for ( x=0; x<totalButtons; x++ ) {
buttonUp = new Image();
buttonUp.src = buttonFolder + upSources[x];
buttonOver = new Image();
buttonOver.src = buttonFolder + overSources[x];
}
}
// SET MOUSEOVER BUTTON
function setOverImg(But, ID) {
document.getElementById('button' + But + ID).src = buttonFolder +
overSources[But-1];
}
// SET MOUSEOUT BUTTON
function setOutImg(But, ID) {
document.getElementById('button' + But + ID).src = buttonFolder +
upSources[But-1];
}
//preload();
/*############### js file code ends here ###################*/
In the HEAD section of my master page I have this:
<head runat="server">
<title>Untitled Page</title>
<script src="http://pics.10026.com/?src=RolloverButtonsImagesMenuScript.js" language="javascript"
type="text/javascript"></script>
<link rel="SHORTCUT ICON" href="http://links.10026.com/?link=favicon.ico">
</head>
Finally, one of the buttons is defined in the master page markup as follows:
<a runat="server" href="http://links.10026.com/?link=~/Default.aspx" onmouseover="setOverImg('1','');"
onmouseout="setOutImg('1','');" target=""> <img runat="server"
src="~/RolloverButtonsImages/button1up.png" border="0" id="button1"
vspace="1" hspace="1"></a><br>
Hope you can help a little more.
Thanks,
Keith
Well I figured something out. I'd still love to know why all the things
below don't work but here's what is more important now. If I use an
asp:Imagebutton and do this:
<asp:ImageButton
ID="ImageButton1"
runat="server"
ImageUrl="~/RolloverButtonsImages/button3up.png"
onmouseover="this.src='~/RolloverButtonsImages/button3over.png'"
onmouseout="this.src='~/RolloverButtonsImages/button3up.png'">
</asp:ImageButton>
I know why the above does not work. The tilde in the "this.src..." does not
get calculated in the page source. I did a view source and asp does not
resolve the tilde. I think I know why but I have no idea how to write the
above so that it DOES work. I tried several variations but got nowhere. If I
take out the tilde and hard code the root, it does work but then I'm back to
my original problem where I don't want to hard code the root.
Thanks,
Keith
"Keith G Hicks" <krh@.comcast.net> wrote in message
news:uiSpE4CkIHA.944@.TK2MSFTNGP05.phx.gbl...
> OK. Thanks Bruce. Your explanation about the tilde and runat="server"
helped
> a lot. But I'm lost on the other end.
> Given the code shown below, here's what happens. All the buttons show up
> when loading the page. They show up with the "out" image which is of
course
> correct. When I click one of them it directs to the correct page. That's
> fine so far. They also show up and click to the correct pages as expected
> when I'm viewing a page that's in a subfolder. So far so good. But the
> rollover doesn't do anything. I don't get the "over" image at any time. No
> errors, no funny behavior, just no image change.
> There are 3 things shown below.
> 1 - the contents of a javascript file that's supposed to change the
> images.
> 2 - the contents of my masterpage head section.
> 3 - one of the button definitions.
>
> Here's the contents of the javascript file (which was created by a button
> generating tool). The file is named RolloverButtonsImagesMenuScript.js and
> is in the root. Notice the first line is var buttonFolder =
> "~/RolloverButtonsImages/"; with the tilde (I've tried it without the
tilde
> as well and other variations I could think of too). I know this code works
> generally because when I had this running on my development machien I had
> hard coded the root folder name into just about everything. But when I got
> to the remote server, things fell apart and I realized that was a mistake.
> So here I am.
> /*############### js file code begins here ###################*/
> /*** SET BUTTON'S FOLDER HERE ***/
> var buttonFolder = "~/RolloverButtonsImages/";
> /*** SET BUTTONS' FILENAMES HERE ***/
> upSources = new
>
Array("button1up.png","button2up.png","button3up.png","button4up.png","butto
>
n5up.png","button6up.png","button7up.png","button8up.png","button9up.png","b
> utton10up.png","button11up.png");
> overSources = new
>
Array("button1over.png","button2over.png","button3over.png","button4over.png
>
","button5over.png","button6over.png","button7over.png","button8over.png","b
> utton9over.png","button10over.png","button11over.png");
> //*** NO MORE SETTINGS BEYOND THIS POINT ***//
> totalButtons = upSources.length;
> //*** MAIN BUTTONS FUNCTIONS ***//
> // PRELOAD MAIN MENU BUTTON IMAGES
> function preload() {
> for ( x=0; x<totalButtons; x++ ) {
> buttonUp = new Image();
> buttonUp.src = buttonFolder + upSources[x];
> buttonOver = new Image();
> buttonOver.src = buttonFolder + overSources[x];
> }
> }
> // SET MOUSEOVER BUTTON
> function setOverImg(But, ID) {
> document.getElementById('button' + But + ID).src = buttonFolder +
> overSources[But-1];
> }
> // SET MOUSEOUT BUTTON
> function setOutImg(But, ID) {
> document.getElementById('button' + But + ID).src = buttonFolder +
> upSources[But-1];
> }
> //preload();
> /*############### js file code ends here ###################*/
> In the HEAD section of my master page I have this:
> <head runat="server">
> <title>Untitled Page</title>
> <script src="http://pics.10026.com/?src=RolloverButtonsImagesMenuScript.js" language="javascript"
> type="text/javascript"></script>
> <link rel="SHORTCUT ICON" href="http://links.10026.com/?link=favicon.ico">
> </head>
>
> Finally, one of the buttons is defined in the master page markup as
follows:
> <a runat="server" href="http://links.10026.com/?link=~/Default.aspx" onmouseover="setOverImg('1','');"
> onmouseout="setOutImg('1','');" target=""> <img runat="server"
> src="http://pics.10026.com/?src=~/RolloverButtonsImages/button1up.png" border="0" id="button1"
> vspace="1" hspace="1"></a><br>
>
> Hope you can help a little more.
> Thanks,
> Keith
>
>
Well I solved this finally. Can't believe it was that hard and nobody said
anything about how to resovle the url based on ~ in the "this.src..." code.
So I changed everything to ImageButtons:
<asp:ImageButton
ID="imgbtnDefault"
runat="server"
CausesValidation="false"
ImageUrl="~/RolloverButtonsImages/button1up.png"
PostBackUrl="~/Default.aspx"
BorderColor="white"
BorderStyle="solid"
BorderWidth="1px">
</asp:ImageButton>
Then in my pages Page_Load event handler I have this:
imgbtnDefault.Attributes.Add("onMouseOver", "src='" &
ResolveUrl("~/RolloverButtonsImages/button1over.png").ToString() & "'")
imgbtnDefault.Attributes.Add("onMouseOut", "src='" &
ResolveUrl("~/RolloverButtonsImages/button1up.png").ToString() & "'")
Works like a peach no matter whether it's on my development machien or in
production remote server and also handles it regardless of what foler the
page I'm on is in.
My only qualm is that the pages "view source" now shows the actual folder
name for the root. Not sure if that's a security issue or not. I'd be
anxious to hear if it is or not.
Keith