Dynamically changing a url in a repeater control

J

JPH

Hi all

I have made a menu using an ascx control and have embedded it into a
page. It uses a Repeater to display a list of hyperlinks:

<itemtemplate>
<li>
<a href='news.aspx?newsID=<%#
DataBinder.Eval(Container.DataItem,"newsID") %>'>
<%# DataBinder.Eval(Container.DataItem, "newsHeadline") %>
</a>
</li>
</itemtemplate>


What I would like to do is reuse this menu control in any page that
needs a dynamic menu. I can find out what the parent form is by using:
this.Parent.ToString(); so its easy to switch stored procedures in my
code behind page to get the valid menu links. However, I'm not sure how
to dynamically switch the
code in the html side of things. For instance, if it was a projects
page that had the menu embedded into it, the url should read something
like this:

<a href='project.aspx?projectID=<%#
DataBinder.Eval(Container.DataItem,"projectID") %>'>
<%# DataBinder.Eval(Container.DataItem, "projectTitle") %>
</a>


I have tried using a literal and writing the html to it on the fly but
it got nasty.


Any help is much appreciated


Thanks
John
 
S

Siva M

You may consider using 'helper functions'. Your Repeater control's
ItemTemplate (in Project.aspx) may have something like this:

<li>
<%# BuildLink ((int)(DataBinder.Eval(Container.DataItem, "projectTitle")),
(string)(DataBinder.Eval(Container.DataItem, "projectTitle"))) %>
</li>

And BuildLink() method (in the control's code-behind) will dynamically
create the markup for the link based on the current page's name.

protected string BuildLink(int id, string title)
{
if (<current page is project>)
{
return "<a href='project.aspx?projectID=" + id.ToString() + "'>" +
title + "</a>";
}
else if (<current page is news>)
{
// Do the same as above
}
}

Hope you got the idea...

Hi all

I have made a menu using an ascx control and have embedded it into a
page. It uses a Repeater to display a list of hyperlinks:

<itemtemplate>
<li>
<a href='news.aspx?newsID=<%#
DataBinder.Eval(Container.DataItem,"newsID") %>'>
<%# DataBinder.Eval(Container.DataItem, "newsHeadline") %>
</a>
</li>
</itemtemplate>


What I would like to do is reuse this menu control in any page that
needs a dynamic menu. I can find out what the parent form is by using:
this.Parent.ToString(); so its easy to switch stored procedures in my
code behind page to get the valid menu links. However, I'm not sure how
to dynamically switch the
code in the html side of things. For instance, if it was a projects
page that had the menu embedded into it, the url should read something
like this:

<a href='project.aspx?projectID=<%#
DataBinder.Eval(Container.DataItem,"projectID") %>'>
<%# DataBinder.Eval(Container.DataItem, "projectTitle") %>
</a>


I have tried using a literal and writing the html to it on the fly but
it got nasty.


Any help is much appreciated


Thanks
John
 
J

JPH

Siva said:
You may consider using 'helper functions'. Your Repeater control's
ItemTemplate (in Project.aspx) may have something like this:

<li>
<%# BuildLink ((int)(DataBinder.Eval(Container.DataItem, "projectTitle")),
(string)(DataBinder.Eval(Container.DataItem, "projectTitle"))) %>
</li>

And BuildLink() method (in the control's code-behind) will dynamically
create the markup for the link based on the current page's name.

protected string BuildLink(int id, string title)
{
if (<current page is project>)
{
return "<a href='project.aspx?projectID=" + id.ToString() + "'>" +
title + "</a>";
}
else if (<current page is news>)
{
// Do the same as above
}
}

Hope you got the idea...
Cheers Siva That's fantastic!

Yes i think i follow you. If that works it will be cool and I can't see
any reason why it shouldn't

I've had enough of work today but As soon as i try it I will let you
know how I get on.

Thanks very much

John
 
J

JPH

Siva said:
You may consider using 'helper functions'. Your Repeater control's
ItemTemplate (in Project.aspx) may have something like this:

<li>
<%# BuildLink ((int)(DataBinder.Eval(Container.DataItem, "projectTitle")),
(string)(DataBinder.Eval(Container.DataItem, "projectTitle"))) %>
</li>

And BuildLink() method (in the control's code-behind) will dynamically
create the markup for the link based on the current page's name.

protected string BuildLink(int id, string title)
{
if (<current page is project>)
{
return "<a href='project.aspx?projectID=" + id.ToString() + "'>" +
title + "</a>";
}
else if (<current page is news>)
{
// Do the same as above
}
}

Hope you got the idea...

Actually Siva this can't work because the data Items aren't always
going to be projectTitle or projectID. When you set the repeater up in
the HTML you need the projectTitle and projectID to be variables so
they can be set from the code behind page.

I'm begining to think this is not doable

cheers

John
 
S

Siva M

JPH, I think I misunderstood the situation here. In order to achieve what
you are looking for the .ascx should be made as generic as possible:

1. Make the .ascx expose apporpriate properties to accept ID and Description
field names (values for these could be ProjectID and ProjectDesc
respectively)
2. Expose a property for setting the data source for the menu control
3. Override the DataBind method of the menu control

Here is a sample code for the .ascx control (watch for code-wrapping):

<code>

[ASCX]
<asp:Repeater ID="menuCtl" runat="server">
<ItemTemplate>
<ol>
<li>
<%# BuildLink (Container.DataItem) %>
</li>
</ol>
</ItemTemplate>
</asp:Repeater>

[CODE BEHIND]
public partial class MyMenu : System.Web.UI.UserControl
{
private object _ds = null;
private string _idProp = null;
private string _descProp = null;

public override void DataBind ()
{
menuCtl.DataSource = _ds;
menuCtl.DataBind ();
}

public object DataSource
{
get {return _ds;}
set {_ds = value;}
}

public string IDPropertyName
{
get { return _idProp; }
set { _idProp = value; }
}

public string DescPropertyName
{
get { return _descProp; }
set { _descProp = value; }
}

protected string BuildLink (object o)
{
DataRowView drv = (DataRowView)o;
if (<current page is project.aspx)
{
return "<a href='project.aspx?projectID=" + drv[_idProp] + "'>" +
drv[_descProp]+ "</a>";
}
else if (<current page is news.aspx)
{
return "<a href=news.aspx?newsID=" + drv[_idProp] + "'>" +
drv[_descProp]+ "</a>";
}
}

}
</code>

And here is how a typical .aspx page will utilize it:
<code>
[ASPX]
<%@ Register Src="~/MyMenu.ascx" TagName="mnu" TagPrefix="ctl" %>

<ctl:mnu id="ctlmnu" runat="server" DescPropertyName="ProjectName"
IDPropertyName="ProjectID"></ctl:mnu>

[CODE-BEHIND]
ctlmnu.DataSource = <data table with cols ProjectName and ProjectID to
create the menu>;
ctlmnu.DataBind ();
</code>

The control could be made even more generic though. But for simplicity sake
I left it as it is now...

Hope this helps.



Siva said:
You may consider using 'helper functions'. Your Repeater control's
ItemTemplate (in Project.aspx) may have something like this:

<li>
<%# BuildLink ((int)(DataBinder.Eval(Container.DataItem, "projectTitle")),
(string)(DataBinder.Eval(Container.DataItem, "projectTitle"))) %>
</li>

And BuildLink() method (in the control's code-behind) will dynamically
create the markup for the link based on the current page's name.

protected string BuildLink(int id, string title)
{
if (<current page is project>)
{
return "<a href='project.aspx?projectID=" + id.ToString() + "'>" +
title + "</a>";
}
else if (<current page is news>)
{
// Do the same as above
}
}

Hope you got the idea...

Actually Siva this can't work because the data Items aren't always
going to be projectTitle or projectID. When you set the repeater up in
the HTML you need the projectTitle and projectID to be variables so
they can be set from the code behind page.

I'm begining to think this is not doable

cheers

John
 
J

JPH

Thank you Siva for your detailed answer it's much appreciated.

I have to work on somthing else today but I will try this out ASAP and
let you know how I get on.

All the best

John

Siva said:
JPH, I think I misunderstood the situation here. In order to achieve what
you are looking for the .ascx should be made as generic as possible:

1. Make the .ascx expose apporpriate properties to accept ID and Description
field names (values for these could be ProjectID and ProjectDesc
respectively)
2. Expose a property for setting the data source for the menu control
3. Override the DataBind method of the menu control

Here is a sample code for the .ascx control (watch for code-wrapping):

<code>

[ASCX]
<asp:Repeater ID="menuCtl" runat="server">
<ItemTemplate>
<ol>
<li>
<%# BuildLink (Container.DataItem) %>
</li>
</ol>
</ItemTemplate>
</asp:Repeater>

[CODE BEHIND]
public partial class MyMenu : System.Web.UI.UserControl
{
private object _ds = null;
private string _idProp = null;
private string _descProp = null;

public override void DataBind ()
{
menuCtl.DataSource = _ds;
menuCtl.DataBind ();
}

public object DataSource
{
get {return _ds;}
set {_ds = value;}
}

public string IDPropertyName
{
get { return _idProp; }
set { _idProp = value; }
}

public string DescPropertyName
{
get { return _descProp; }
set { _descProp = value; }
}

protected string BuildLink (object o)
{
DataRowView drv = (DataRowView)o;
if (<current page is project.aspx)
{
return "<a href='project.aspx?projectID=" + drv[_idProp] + "'>" +
drv[_descProp]+ "</a>";
}
else if (<current page is news.aspx)
{
return "<a href=news.aspx?newsID=" + drv[_idProp] + "'>" +
drv[_descProp]+ "</a>";
}
}

}
</code>

And here is how a typical .aspx page will utilize it:
<code>
[ASPX]
<%@ Register Src="~/MyMenu.ascx" TagName="mnu" TagPrefix="ctl" %>

<ctl:mnu id="ctlmnu" runat="server" DescPropertyName="ProjectName"
IDPropertyName="ProjectID"></ctl:mnu>

[CODE-BEHIND]
ctlmnu.DataSource = <data table with cols ProjectName and ProjectID to
create the menu>;
ctlmnu.DataBind ();
</code>

The control could be made even more generic though. But for simplicity sake
I left it as it is now...

Hope this helps.



Siva said:
You may consider using 'helper functions'. Your Repeater control's
ItemTemplate (in Project.aspx) may have something like this:

<li>
<%# BuildLink ((int)(DataBinder.Eval(Container.DataItem, "projectTitle")),
(string)(DataBinder.Eval(Container.DataItem, "projectTitle"))) %>
</li>

And BuildLink() method (in the control's code-behind) will dynamically
create the markup for the link based on the current page's name.

protected string BuildLink(int id, string title)
{
if (<current page is project>)
{
return "<a href='project.aspx?projectID=" + id.ToString() + "'>" +
title + "</a>";
}
else if (<current page is news>)
{
// Do the same as above
}
}

Hope you got the idea...

Actually Siva this can't work because the data Items aren't always
going to be projectTitle or projectID. When you set the repeater up in
the HTML you need the projectTitle and projectID to be variables so
they can be set from the code behind page.

I'm begining to think this is not doable

cheers

John
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top