InnerHTML in Div dynamic - HyperLink problem in ASP - asp.net

I want dynamical add HTML on my div.
I do this with:
newsAllScroller.InnerHtml = newsAllScroller.InnerHtml + "<br><center><b>";
List<DAL.News> newsList = DAL.NewsHandler.GetAllNews();
foreach (DAL.News n in newsList)
{
newsAllScroller.InnerHtml = newsAllScroller.InnerHtml + "<br>" + n.Betreff + " - ("
+ "<asp:HyperLink ID=\"news"+n.NewsID+"\" runat=\"server\" NavigateUrl=\"~/News.aspx?id=" + n.NewsID + "\""
+ " CssClass=\"newsLink\">"
+ "..."
+ "</asp:HyperLink>"
+ ")";
}
newsAllScroller.InnerHtml = newsAllScroller.InnerHtml + "</center></b>";
The HyperLink is not working (you cannot click it).
When I copy the hyperlink from the browser-source-code into an aspx-page it works, so it seems the syntax is all correct - but it doasn't work via code, why?

You cannot add server side control to HTML and think of it to behave normally, you would have to modify your code to
newsAllScroller.InnerHtml = newsAllScroller.InnerHtml + "<br>" + n.Betreff + " - ("
+ "<a href ="/News.aspx?id=" + n.NewsID + "\""
+ " class=\"newsLink\">"
+ "... </a>"
+ ")";

Because the aspx page is parsed only once before the output is sent to the browser. You can't print/output something and expect it to be parsed once more.

You should use a Repeater instead of appending text to InnerHtml. Something like this:
<asp:Repeater ID="myRepeater" runat="server" OnItemDataBound="myRepeater_ItemDataBound">
<ItemTemplate>
<br/><asp:Literal ID="myText" runat="server"/> - (<asp:HyperLink ID="myLink" runat="server" CssClass="newsLink" Text="..."/>)
</ItemTemplate>
</asp:Repeater>
...and then in code-behind:
void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
myRepeater.DataSource = DAL.NewsHandler.GetAllNews();
myRepeater.DataBind();
}
}
void myRepeater_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item ||
e.Item.ItemType == ListItemType.AlternatingItem)
{
var myText = e.Item.FindControl("myText") as Literal;
var myLink = e.Item.FindControl("myLink") as HyperLink;
var news = e.Item.DataItem as DAL.News;
if (myText != null && myLink != null && news != null)
{
myText.Text = news.Betreff;
myLink.NavigateUrl = "~/News.aspx?id=" + news.NewsID;
}
}
}
I haven't tried the code myself but it should point you in the right direction. Check out the Repeater documentation for more information and examples.

Related

how to change the format of datetime column when it is bound dynamically in gridview

protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
DateTime dt,dt1;
if (e.Row.RowType == DataControlRowType.DataRow)
{
dt = Convert.ToDateTime(e.Row.Cells[4].Text);
e.Row.Cells[4].Text = dt.Month.ToString() + "/" + dt.Day.ToString() + "/" + dt.Year.ToString();
dt1 = Convert.ToDateTime(e.Row.Cells[5].Text);
e.Row.Cells[5].Text = dt1.Month.ToString() + "/" + dt1.Day.ToString() + "/" + dt1.Year.ToString();
}
}
This is my code and the column with index 5 is a datetime the problem is that it can be NULL so the following error turns up when it is
"String was not recognized as a valid DateTime"
Any Solution Please help??!
thank u!
Try using DateTime.TryParse instead and only if it returns true run the rest of the code
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
DateTime dt,dt1;
if (e.Row.RowType == DataControlRowType.DataRow)
{
bool success = DateTime.TryParse(e.Row.Cells[4].Text, dt);
if(success)
{
e.Row.Cells[4].Text = dt.Month.ToString() + "/" + dt.Day.ToString() + "/" + dt.Year.ToString();
dt1 = Convert.ToDateTime(e.Row.Cells[5].Text);
e.Row.Cells[5].Text = dt1.Month.ToString() + "/" + dt1.Day.ToString() + "/" + dt1.Year.ToString();
}
}
}
Did you try a simple check?
something like
if (!String.IsNullOrEmpty(e.Row.Cells[4].Text))
e.Row.Cells[4].Text = Convert.ToDateTime(e.Row.Cells[4].Text).ToString("MM/dd/yyyy");
else
e.Row.Cells[4].Text = "-";
What about setting the BoundField.DataFormatString and the BoundField.NullDisplayText properties, like:
<asp:GridView ID="BoundFieldExample" runat="server">
<Columns>
<asp:BoundField DataFormatString="{0:d}" NullDisplayText="Not Found" />
</Columns>
</asp:GridView>
The above will display dates in short date string format for the current culture and the text "Not Found" for Null values.
See GridView BoundField Class for more information.

Dynamically adding a commandbutton in ASP.NET

I have a page with a dynamically created command button.
I need to dynamically wire up a click event so I can grab the CommandArgument of the clicked button.
Button b = new Button();
b.ID = "btnTrigger2";
b.CssClass = "hiddenBtn";
b.CommandName = "lbl3";
b.Click += new EventHandler(btnTrigger_Click);
The problem is the last line - I can't wire up an EventHandler this way - I need to use the standard EventArgs instead of CommandEventArgs.
Anyone have any suggestions on getting this to work? There's got to be a way...
EDIT
Figured I'd post the code that finally worked in case anyone else tries to do the same thing.
`string tabLoadedScript = string.Empty;
string postBackScript = string.Empty;
string script = " <script language='javascript' type='text/javascript'>" + System.Environment.NewLine;
script += "function clientActiveTabChanged(sender, args) {" + System.Environment.NewLine;
int i = 0;
foreach(TabPanel tp in tc1.Tabs)
{
Button b = new Button();
b.ID = "btn" + tp.ClientID;
b.CssClass = "hiddenBtn";
b.CommandName = tp.ID;
b.Command += btnTrigger_Click;
this.form1.Controls.Add(b);
AsyncPostBackTrigger trg = new AsyncPostBackTrigger();
trg.ControlID = "btn" + tp.ClientID;
tabLoadedScript += "var isTab" + tp.ClientID + "loaded=$get('" + tp.Controls[0].ClientID + "');" + System.Environment.NewLine;
postBackScript += "if(!isTab" + tp.ClientID + "loaded && sender.get_activeTabIndex() == " + i + ") {" + System.Environment.NewLine;
postBackScript += "__doPostBack('" + b.ClientID + "','');}" + System.Environment.NewLine;
i++;
}
script += tabLoadedScript;
script += postBackScript;
script += "}" + System.Environment.NewLine;
script += "</script>";
this.ClientScript.RegisterClientScriptBlock(this.GetType(), "cs", script, false);
protected void btnTrigger_Click(object sender, CommandEventArgs e)
{
System.Threading.Thread.Sleep(2500);
Panel ctrl = (Panel) FindControlRecursive(this, "pnl" + e.CommandName);
ctrl.Visible = true;
}
public static Control FindControlRecursive(Control Root, string Id)
{
if(Root.ID == Id)
return Root;
foreach(Control Ctl in Root.Controls)
{
Control FoundCtl = FindControlRecursive(Ctl, Id);
if(FoundCtl != null)
return FoundCtl;
}
return null;
}
`
You can still access the CommandArgument using the the first argument passed to the click handler.
Something like:
protected void btnTrigger_Click(object sender, EventArgs e)
{
Button btnTrigger = sender as Button;
String commandArgument = btnTrigger.CommandArgument;
.
.
.
.
//Other code....
}
You need to use the Command event instead of the Click event. Also, assuming you're using a recent version of Visual Studio and .Net, you can simply change the event registration from
b.Click += new EventHandler(btnTrigger_Click);
to
b.Command += btnTrigger_Click
The explicit typing of the delegate is redundant and will be inferred by the compiler. You can now change the signature of your event handler to:
protected void btnTrigger_Click(object sender, CommandEventArgs e)
And the code should work as desired.
Unfortunately, the default code snippets in Visual Studio still generate this old-style event listener code.

Problem with ScriptManager and ASP.NET AJAX Timer

I'm having a serious problem with my ASP.NET AJAX application.
There is a javascript function in my application needs to be executed after the Timer_Tick event. Here's the code behind:
void SetValues()
{
try
{
StringBuilder sbScript = new StringBuilder();
sbScript.Append("<script language='javascript' type='text/javascript'>");
sbScript.Append("function UpdateValue() {");
for (int j = 0; j < iTotalDevices; j++)
{
sbScript.Append("setElementValue(" + j.ToString() + "," + DevicesInfo[j].X.ToString() + "," + DevicesInfo[j].Y.ToString() + "," + iStatus.ToString() + "," + DevicesInfo[j].DeviceID.ToString() + ");");
}
sbScript.Append("}");
sbScript.Append("</script>");
ScriptManager.RegisterStartupScript(this, this.GetType(), "myscript", sbScript.ToString(), false);
}
catch
{ }
}
protected void Timer1_Tick(object sender, EventArgs e)
{
///This function will get latest values from database
GetNewData();
SetValues();
}
When I call the javascript function 'UpdateValue' for the first time (at onload page event), it works correctly. But after the Timer_Tick event, it does nothing. This is the HTML code:
<script type="text/javascript" language="javascript">
function PageLoad() {
///Call function for the first time and it works
UpdateValue();
}
function setElementValue(index, value1, value2, value3...) {
///Set value for each element in object array
}
</script>
<body onload="PageLoad()">
<asp:ScriptManager ID="ScriptManager1" runat="server" />
<asp:Timer ID="Timer1" runat="server" OnTick="Timer1_Tick" Interval="30000">
</body>
What's the problem with the ScriptManager or the Timer_Tick event?
Many thanks,
It looks like you're registering the UpdateValue function each time Timer1_Tick executes.
Try changing your SetValues function to this:
void SetValues()
{
try
{
StringBuilder sbScript = new StringBuilder();
sbScript.Append("<script language='javascript' type='text/javascript'>");
for (int j = 0; j < iTotalDevices; j++)
{
sbScript.Append("setElementValue(" + j.ToString() + "," + DevicesInfo[j].X.ToString() + "," + DevicesInfo[j].Y.ToString() + "," + iStatus.ToString() + "," + DevicesInfo[j].DeviceID.ToString() + ");");
}
sbScript.Append("</script>");
ScriptManager.RegisterClientScriptBlock(this, this.GetType(), string.Format("myscript{0}", DateTime.Now.ToString("yyyyMMddHHmmss")), sbScript.ToString(), false);
}
catch
{ }
}
EDIT: Notice that I'm using RegisterClientScriptBlock instead of RegisterStartupScript. Also, "myscript" should be a unique key, so I just updated that part.
Following is my finished code:
void SetValues()
{
try
{
StringBuilder sbScript = new StringBuilder();
sbScript.Append("<script language='javascript' type='text/javascript'>");
sbScript.Append("Sys.Application.add_load(UpdateValue);");
sbScript.Append("function UpdateValue() {");
sbScript.Append("Sys.Application.remove_load(UpdateValue);");
for (int j = 0; j < iTotalDevices; j++)
{
sbScript.Append("setElementValue(" + j.ToString() + "," + DevicesInfo[j].X.ToString() + "," + DevicesInfo[j].Y.ToString() + "," + iStatus.ToString() + "," + DevicesInfo[j].DeviceID.ToString() + ");");
}
sbScript.Append("}");
sbScript.Append("</script>");
ScriptManager.RegisterStartupScript(this, Time1.GetType(), "UpdateValue", sbScript.ToString(), false);
}
catch
{ }
}

ASP.NET TextBox TextChanged event not firing in custom EditorPart

This is a classic sort of question, I suppose, but it seems that most people are interested in having the textbox cause a postback. I'm not. I just want the event to fire when a postback occurs.
I have created a webpart with a custom editorpart. The editorpart renders with a textbox and a button. Clicking the button causes a dialog to open. When the dialog is closed, it sets the value of the textbox via javascript and then does __doPostBack using the ClientID of the editorpart.
The postback happens, but the TextChanged event never fires, and I'm not sure if it's a problem with the way __doPostBack is invoked, or if it's because of the way I'm setting up the event handler, or something else. Here's what I think is the relevant portion of the code from the editorpart:
protected override void CreateChildControls()
{
_txtListUrl = new TextBox();
_txtListUrl.ID = "targetSPList";
_txtListUrl.Style.Add(HtmlTextWriterStyle.Width, "60%");
_txtListUrl.ToolTip = "Select List";
_txtListUrl.CssClass = "ms-input";
_txtListUrl.Attributes.Add("readOnly", "true");
_txtListUrl.Attributes.Add("onChange", "__doPostBack('" + this.ClientID + "', '');");
_txtListUrl.Text = this.ListString;
_btnListPicker = new HtmlInputButton();
_btnListPicker.Style.Add(HtmlTextWriterStyle.Width, "60%");
_btnListPicker.Attributes.Add("Title", "Select List");
_btnListPicker.ID = "browseListsSmtButton";
_btnListPicker.Attributes.Add("onClick", "mso_launchListSmtPicker()");
_btnListPicker.Value = "Select List";
this.AddConfigurationOption("News List", "Choose the list that serves as the data source.",
new Control[] { _txtListUrl, _btnListPicker });
if (this.ShowViewSelection)
{
_txtListUrl.TextChanged += new EventHandler(_txtListUrl_TextChanged);
_ddlViews = new DropDownList();
_ddlViews.ID = "_ddlViews";
this.AddConfigurationOption("View", _ddlViews);
}
}
protected override void OnPreRender(EventArgs e)
{
ScriptLink.Register(this.Page, "PickerTreeDialog.js", true);
string lastSelectedListId = string.Empty;
if (!this.WebId.Equals(Guid.Empty) && !this.ListId.Equals(Guid.Empty))
{
lastSelectedListId = SPHttpUtility.EcmaScriptStringLiteralEncode(
string.Format("SPList:{0}?SPWeb:{1}:", this.ListId.ToString(), this.WebId.ToString()));
}
string script = "\r\n var lastSelectedListSmtPickerId = '" + lastSelectedListId + "';"
+ "\r\n function mso_launchListSmtPicker(){"
+ "\r\n if (!document.getElementById) return;"
+ "\r\n"
+ "\r\n var listTextBox = document.getElementById('" + SPHttpUtility.EcmaScriptStringLiteralEncode(_txtListUrl.ClientID) + "');"
+ "\r\n if (listTextBox == null) return;"
+ "\r\n"
+ "\r\n var serverUrl = '" + SPHttpUtility.EcmaScriptStringLiteralEncode(SPContext.Current.Web.ServerRelativeUrl) + "';"
+ "\r\n"
+ "\r\n var callback = function(results) {"
+ "\r\n if (results == null || results[1] == null || results[2] == null) return;"
+ "\r\n"
+ "\r\n lastSelectedListSmtPickerId = results[0];"
+ "\r\n var listUrl = '';"
+ "\r\n if (listUrl.substring(listUrl.length-1) != '/') listUrl = listUrl + '/';"
+ "\r\n if (results[1].charAt(0) == '/') results[1] = results[1].substring(1);"
+ "\r\n listUrl = listUrl + results[1];"
+ "\r\n if (listUrl.substring(listUrl.length-1) != '/') listUrl = listUrl + '/';"
+ "\r\n if (results[2].charAt(0) == '/') results[2] = results[2].substring(1);"
+ "\r\n listUrl = listUrl + results[2];"
+ "\r\n listTextBox.value = listUrl;"
+ "\r\n __doPostBack('" + this.ClientID + "','');"
+ "\r\n }"
+ "\r\n LaunchPickerTreeDialog('CbqPickerSelectListTitle','CbqPickerSelectListText','websLists','', serverUrl, lastSelectedListSmtPickerId,'','','/_layouts/images/smt_icon.gif','', callback);"
+ "\r\n }";
this.Page.ClientScript.RegisterClientScriptBlock(typeof(ListPickerEditorPart), "mso_launchListSmtPicker", script, true);
if ((!string.IsNullOrEmpty(_txtListUrl.Text) && _ddlViews.Items.Count == 0) || _listSelectionChanged)
{
_ddlViews.Items.Clear();
if (!string.IsNullOrEmpty(_txtListUrl.Text))
{
using (SPWeb web = SPContext.Current.Site.OpenWeb(this.WebId))
{
foreach (SPView view in web.Lists[this.ListId].Views)
{
_ddlViews.Items.Add(new ListItem(view.Title, view.ID.ToString()));
}
}
_ddlViews.Enabled = _ddlViews.Items.Count > 0;
}
else
{
_ddlViews.Enabled = false;
}
}
base.OnPreRender(e);
}
void _txtListUrl_TextChanged(object sender, EventArgs e)
{
this.SetPropertiesFromChosenListString(_txtListUrl.Text);
_listSelectionChanged = true;
}
Any ideas?
Update: I forgot to mention these methods, which are called above:
protected virtual void AddConfigurationOption(string title, Control inputControl)
{
this.AddConfigurationOption(title, null, inputControl);
}
protected virtual void AddConfigurationOption(string title, string description, Control inputControl)
{
this.AddConfigurationOption(title, description, new List<Control>(new Control[] { inputControl }));
}
protected virtual void AddConfigurationOption(string title, string description, IEnumerable<Control> inputControls)
{
HtmlGenericControl divSectionHead = new HtmlGenericControl("div");
divSectionHead.Attributes.Add("class", "UserSectionHead");
this.Controls.Add(divSectionHead);
HtmlGenericControl labTitle = new HtmlGenericControl("label");
labTitle.InnerHtml = HttpUtility.HtmlEncode(title);
divSectionHead.Controls.Add(labTitle);
HtmlGenericControl divUserSectionBody = new HtmlGenericControl("div");
divUserSectionBody.Attributes.Add("class", "UserSectionBody");
this.Controls.Add(divUserSectionBody);
HtmlGenericControl divUserControlGroup = new HtmlGenericControl("div");
divUserControlGroup.Attributes.Add("class", "UserControlGroup");
divUserSectionBody.Controls.Add(divUserControlGroup);
if (!string.IsNullOrEmpty(description))
{
HtmlGenericControl spnDescription = new HtmlGenericControl("div");
spnDescription.InnerHtml = HttpUtility.HtmlEncode(description);
divUserControlGroup.Controls.Add(spnDescription);
}
foreach (Control inputControl in inputControls)
{
divUserControlGroup.Controls.Add(inputControl);
}
this.Controls.Add(divUserControlGroup);
HtmlGenericControl divUserDottedLine = new HtmlGenericControl("div");
divUserDottedLine.Attributes.Add("class", "UserDottedLine");
divUserDottedLine.Style.Add(HtmlTextWriterStyle.Width, "100%");
this.Controls.Add(divUserDottedLine);
}
It can help, if the class declaring the event handler (in your case the editorpart, I guess) implements System.Web.UI.INamingContainer. And do you add _txtListUrl to the Controls collection?
EDIT:
Make sure that the AutoPostBack property of _txtListUrl is set to true (_txtListUrl.AutoPostBack = true).
_txtListUrl.Attributes.Add("onChange" might interfere with the event handler.
TextChanged is invoked only, when the text box looses the focus.

Trigger Problem, Update Panel Does Not Work?

I create dynamic LinkButton and I add LinkButton's Click Trigger to UpdatePanel.
Now, When I first click to any one of link button trigger is runing good and show my select whitout POSTBACK. After That, I click other LinkButton All Page Loading and POSTBACK running so Trigger Does Not Work!
What is the problem ? Please Help!
protected void Page_Load(object sender, EventArgs e)
{
ShowAllCar();
}
public void ShowAllCar()
{
dsAraclarTableAdapters.tblAraclarTableAdapter _t=new dsAraclarTableAdapters.tblAraclarTableAdapter();
dsAraclar.tblAraclarDataTable _m =_t.GetData();
int i=0;
UpdatePanel1.Triggers.Clear();
pnlAraclar.Controls.Clear();
foreach (DataRow _row in _m.Rows)
{
LinkButton _linkbutton =new LinkButton();
i++;
_linkbutton.ID ="Option" + i.ToString();
_linkbutton.Text = "<img src='" + _row["Resim"].ToString() + "' border='0'/> <b>" + _row["Marka"].ToString() + " " + _row["Model"].ToString() + "</b><br/>" + _row["Ozellikler"].ToString() + " : " + _row["KisFiyat"].ToString() + ":" + _row["YazFiyat"].ToString();
_linkbutton.CssClass="ContextMenuItem";
_linkbutton.PostBackUrl = "";
_linkbutton.Click +=new EventHandler(OnCarSelect);
pnlAraclar.Controls.Add(_linkbutton);
AsyncPostBackTrigger _trigger = new AsyncPostBackTrigger();
_trigger.ControlID = _linkbutton.ID;
_trigger.EventName = "Click";
UpdatePanel1.Triggers.Add(_trigger);
}
}
protected void OnCarSelect(object sender, EventArgs e)
{
lblSelection.Text = "You selected <b>" + ((LinkButton)sender).Text + "</b>.";
}
You need to add the controls back to the control tree earlier in the page life cycle:
PreInit Use this event for
the following:
...
* Create or re-create dynamic controls.
...
ASP.NET Page Life Cycle Overview

Resources