Dynamically give Id to textbox (Server side control) in asp:Repeater - c#

In my <asp:Repeater></asp:Repeater> - There is one hidden field, textbox and button.
When data will be bound, then hidden filed will get User Id like below code
<asp:HiddenField ID="hide" Value='<%#Eval("UserId")%>' runat="server"/>
and ItemDataBound event will be called and in this function, i am getting value from hidden field and concatenating that value as a Id in text box. like below code
TextBox txt = (TextBox)e.Item.FindControl("txtReplyArea");
HiddenField hf = (HiddenField)e.Item.FindControl("hide");//1
txt.ID = "txtReplyArea" + hf.Value;//txtReplyArea1
Suppose only one record comes from database and their UserId is 1. Then textbox Id should be "textReplyArea1". From now, all are correct.
I am not sure, it's correct way to giving dynamic Id to repeater control but i think, it's correct.
Problem -
When i click on button and i get a items from repeater and textbox from Id by finding control from repeater then it shows null.
int areaId = int.Parse((sender as Button).CommandArgument);//1
string id="txtReplyArea"+areaId;//txtReplyArea1
foreach (RepeaterItem item in repeaterBlog.Items)
{
TextBox tb = item.FindControl(id) as TextBox;//tb = null
}
Code of aspx page
<%# Page Title="Messages" Language="C#" MasterPageFile="~/Menu.master" AutoEventWireup="true" CodeFile="Messages.aspx.cs" Inherits="Messages" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" Runat="Server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
<div style="width:70%;">
<asp:Repeater ID="repeaterBlog" runat="server" OnItemDataBound="repeaterBlog_ItemDataBound">
<HeaderTemplate>
<table>
</HeaderTemplate>
<ItemTemplate>
<tr >
<td>
<asp:HiddenField ID="hide" Value='<%#Eval("UserId")%>' runat="server"/>
<asp:TextBox ID="txtReplyArea" runat="server" TextMode="Multiline" Columns="70" Rows="8" Visible="false"></asp:TextBox>
</td>
</tr>
<tr>
<td style="margin-left:47%;">
<asp:Button ID="btnReply" runat="server" Text="Reply" OnClick="btnReplyClicked" AutoPostBack="True" CommandArgument='<%#Eval("UserId")%>'/>
</td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
</div>
</asp:Content>
Code of aspx.cs
SqlCommand cmd;
SqlDataReader sdr;
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostBack)
{
String cs = ConfigurationManager.ConnectionStrings["myWebsite"].ConnectionString;
using (SqlConnection con = new SqlConnection(cs))
{
cmd = new SqlCommand("select * from ContactMessage", con);
con.Open();
sdr = cmd.ExecuteReader();
repeaterBlog.DataSource = sdr;
repeaterBlog.DataBind();
con.Close();
}
}
}
public void repeaterBlog_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
TextBox txt = (TextBox)e.Item.FindControl("txtReplyArea");
HiddenField hf = (HiddenField)e.Item.FindControl("hide");
txt.ID = "txtReplyArea" + hf.Value;
}
}
protected void btnReplyClicked(object sender, EventArgs e)
{
int areaId = int.Parse((sender as Button).CommandArgument);
string id="txtReplyArea"+areaId;
foreach (RepeaterItem item in repeaterBlog.Items)
{
TextBox tb = item.FindControl(id) as TextBox;
}
}
}

This worked for me. Notice that I removed EnableViewState from the repeater and added OnItemDatabound event.
<asp:Repeater ID="repeaterBlog" runat="server" OnItemDataBound="repeaterBlog_ItemDataBound">
<HeaderTemplate>
<table>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td>
<asp:HiddenField ID="hide" Value='<%#Eval("UserId")%>' runat="server" />
<asp:TextBox ID="txtReplyArea" runat="server" TextMode="Multiline" Columns="70" Rows="8"
Visible="false"></asp:TextBox>
</td>
</tr>
<tr>
<td style="margin-left: 47%;">
<asp:Button ID="btnReply" runat="server" Text="Reply" OnClick="btnReplyClicked" AutoPostBack="True"
CommandArgument='<%#Eval("UserId")%>' />
</td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
protected void Page_Load(object sender, EventArgs e)
{
DataTable dt = new DataTable();
dt.Columns.Add("UserId");
DataRow dr = dt.NewRow();
dr[0] = 34;
dt.Rows.Add(dr);
repeaterBlog.DataSource = dt;
repeaterBlog.DataBind();
}
public void repeaterBlog_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
TextBox txt = (TextBox)e.Item.FindControl("txtReplyArea");
HiddenField hf = (HiddenField)e.Item.FindControl("hide");
txt.ID = "txtReplyArea" + hf.Value;
}
}
protected void btnReplyClicked(object sender, EventArgs e)
{
int areaId = int.Parse((sender as Button).CommandArgument);
string id = "txtReplyArea" + areaId;
foreach (RepeaterItem item in repeaterBlog.Items)
{
TextBox tb = item.FindControl(id) as TextBox;
}
}

You can try like this
<asp:TextBox ID='<%# "txtReplyArea" + Convert.ToString(Eval("UserId")%>)' runat="server" TextMode="Multiline" Columns="70" Rows="8" Visible="false"></asp:TextBox>

Related

displaying read more option when user enters large amount of data in richtextbox

I have a richtextbox and a gridview.
When I enter the data into the richtextbox, it should be displayed in a gridview and saved in database.
Now my requirement is that, if i am entering a paragraph or a large amount of data I should display a "readmore" button, that when clicked, display the complete data.
<%# Register Assembly="FreeTextBox" Namespace="FreeTextBoxControls" TagPrefix="FTB" %>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Richtextbox Sample</title>
<script type="text/javascript">
function validate() {
var doc = document.getElementById('FreeTextBox1');
if (doc.value.length == 0) {
alert('Please Enter data in Richtextbox');
return false;
}
}
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<table>
<tr>
<td>
<FTB:FreeTextBox ID="FreeTextBox1" runat="server">
</FTB:FreeTextBox>
</td>
<td valign="top">
<asp:GridView runat="server" ID="gvdetails" AutoGenerateColumns="false">
<Columns>
<asp:TemplateField HeaderText="RichtextBoxData">
<ItemTemplate>
<asp:Label ID="lbltxt" runat="server" Text='<%#Bind("RichtextData") %>'/>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</td>
</tr>
</table>
</div>
<asp:Button ID="btnSubmit" runat="server" OnClientClick="return validate()"
Text="Submit" onclick="btnSubmit_Click" />
<br />
<asp:Label ID="lbltxt" runat="server"/>
</form>
</body>
</html>
c# code-
SqlConnection con = new SqlConnection("Data Source=SureshDasari;Integrated Security=true;Initial Catalog=MySampleDB");
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
BindGridview();
}
protected void BindGridview()
{
con.Open();
SqlCommand cmd = new SqlCommand("select RichTextData from RichTextBoxData", con);
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataSet ds = new DataSet();
da.Fill(ds);
gvdetails.DataSource = ds;
gvdetails.DataBind();
}
protected void btnSubmit_Click(object sender, EventArgs e)
{
con.Open();
SqlCommand cmd = new SqlCommand("insert into RichTextBoxData(RichTextData) values(#Richtextbox)", con);
cmd.Parameters.AddWithValue("#Richtextbox", FreeTextBox1.Text);
cmd.ExecuteNonQuery();
con.Close();
FreeTextBox1.Text = "";
BindGridview();
}
first in your select query add id of your text(your primary key of table RichTextBoxData)
and in gridview make it,s visible =false like this
<asp:TemplateField HeaderText="id" InsertVisible="False" Visible="False">
<ItemTemplate>
<asp:Label ID="Label2" runat="server" Text='<%# Bind("id") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
and then
protected void gvdetails_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
Label lb =e.Row.FindControl("lbltxt") as Label;
if (lb.Text.Length > 15)//any length u want
{
DataRow drv = ((DataRowView)e.Row.DataItem).Row;
int tempID = Convert.ToInt32(drv["id"].ToString());
HyperLink hp = new HyperLink();
hp.Text = "read more";
hp.NavigateUrl = "~/mydetails.aspx?id=" + tempID;
e.Row.Cells[1].Controls.Add(hp);
lb.Text = lb.Text.Substring(0, 15);
}
}
}
and on page_load of mydetails.aspx make
query to select RichTextData where id=request.querystring["id"]

How to add Multiple (Nested) Categories by Using Nested Repeater?

I want to add multiple category->subcategory-> sub-subcategory using nested repeater:
http://i.stack.imgur.com/bMiYZ.png
Similar to this but having more categories and sub-categories from database.
<form id="form1" runat="server">
<div>
<ul>
<asp:Repeater ID="outerRep" runat="server" OnItemDataBound="outerRep_ItemDataBound">
<ItemTemplate>
<li>
<asp:Label Font-Size="Large" Font-Bold="true" ID="lblCategoryName" runat="server" Text='<%# Eval("CategoryName") %>' />
</li>
<ul>
<asp:Repeater ID="innerRep" runat="server">
<ItemTemplate>
<li style="background-color: AliceBlue">
<asp:HyperLink ID="hlProductName" runat="server" Text='<%# Eval("SubCategoryName")%>' />
</li>
</ItemTemplate>
</asp:Repeater>
</ul>
</ItemTemplate>
</asp:Repeater>
</ul>
</div>
</form>
Codebehind:
protected void Page_Load(object sender, EventArgs e)
{
BindData();
}
private void BindData()
{
SqlConnection myConnection = new SqlConnection("Data Source=.; uid=sa; pwd=xxx;database=registration;");
SqlCommand myCommand = new SqlCommand("usp_GetProductsForCategories", myConnection);
myCommand.CommandType = CommandType.StoredProcedure;
SqlDataAdapter ad = new SqlDataAdapter(myCommand);
DataSet ds = new DataSet();
ad.Fill(ds);
// Attach the relationship to the dataSet
ds.Relations.Add(new DataRelation(
"CategoriesRelation",
ds.Tables[0].Columns["CategoryID"],
ds.Tables[1].Columns["CategoryID"]));
outerRep.DataSource = ds.Tables[0];
outerRep.DataBind();
}
protected void outerRep_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item ||
e.Item.ItemType == ListItemType.AlternatingItem)
{
DataRowView drv = e.Item.DataItem as DataRowView;
Repeater innerRep = e.Item.FindControl("innerRep") as Repeater;
innerRep.DataSource = drv.CreateChildView("CategoriesRelation");
innerRep.DataBind();
}
}
or any better way to do it? Please help.

radiobuttonlist in repeater control

i have been working on a project as i got stucked in one of the problem as,i have a repeater and radiobuttonlist inside it, i want to fill radiobuttonlist from my database but i am getting an error as object reference not set to the instance of an object.
aspx code
<asp:Repeater ID="Repeater1" runat="server"OnItemDataBound="fillRepeater_onitembound">
<HeaderTemplate>
</HeaderTemplate>
<AlternatingItemTemplate>
</AlternatingItemTemplate>
<ItemTemplate>
<table style="width:1100px">
<tr style="width:1100px">
<asp:Label ID="lbl_teachername" runat="server" Text='<%#Eval("teachername") %>' ></asp:Label>
<asp:Label ID="lbl_teachercode" runat="server" Text='<%#Eval("teachercode") %>' style="display:none;" ></asp:Label>
</tr>
<br />
<tr>
<td style="width:150px">
<asp:Image ID="img_teacher" runat="server" ImageUrl="~/Images/staff.png" Height="100px" Width="100px"/>
</td>
<td >
<asp:RadioButtonList ID="radioatt" runat="server" OnSelectedIndexChanged="radioatt_OnSelectedIndexChanged" AutoPostBack="true" >
</asp:RadioButtonList>
</td>
</tr>
<tr>
<td>
</td>
</tr>
</table>
</ItemTemplate>
</asp:Repeater>
c# code
protected void fillRepeater_onitembound(object sender,RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
sql = "select Description,AttendanceCode from tblattendancecodes";
ds = obj.openDataset(sql);
ListItem li;
RadioButtonList rbtl = (RadioButtonList)e.Item.FindControl("radioatt");
for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
{
li = new ListItem();
li.Text = ds.Tables[0].Rows[i]["Description"].ToString();
li.Value = ds.Tables[0].Rows[i]["AttendanceCode"].ToString();
rbtl.Items.Add(li);
}
}
}
please help me out
Add the null check for radio button list and you will not get error of object reference. Please see the below code
c# code
protected void fillRepeater_onitembound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
sql = "select Description,AttendanceCode from tblattendancecodes";
ds = obj.openDataset(sql);
ListItem li;
RadioButtonList rbtl = (RadioButtonList)e.Item.FindControl("radioatt");
if (rbtl != null)
{
for (int i = 0; i < dt.Rows.Count; i++)
{
li = new ListItem();
li.Text = dt.Rows[i]["ApplicationName"].ToString();
li.Value = dt.Rows[i]["BuildNumber"].ToString();
rbtl.Items.Add(li);
}
}
}
}
I tried the code and it worked for me
Debug your code to find out which line is giving null or is not instantiated correctly and you will get the culprit code.

Toggle display the child DataList

I am try to toggle the display subnet data(childList). This codes below are working fine, but not able to toogle the display. When I click on the (+) sign, the ChildList dataList expands and displays the list subset data (Contact). However, I want to change the (+) to (-) when childList data expanded. And when user clicks on (-), it will collapse back (the child list disappear)
Any idea how to do this? an example code would be great since I am a newbie of ASP.NET.
<table width="595px">
<asp:DataList BackColor="#ffffff" id="DataList1" DataSourceID="dsCompanyList" runat="server" Width="100%" DataKeyField="Company">
<ItemTemplate>
<tr>
<td>
<asp:LinkButton ID="LinkButton1" runat="server" Text="+" CommandArgument='<%#Container.ItemIndex%>'
OnCommand="LinkButton1_Command"
></asp:LinkButton>
</td>
<td><%#Eval("Row")%></td>
<td><%#Eval("Company")%></td>
</tr>
<asp:Panel ID="pnlChildView" runat="server">
<asp:DataList ID="childList" runat="server" Width="100%">
<ItemTemplate>
<tr>
<td><%#Eval("FirstName")%></td>
<td><%#Eval("LastName")%></td>
</tr>
</ItemTemplate>
</asp:DataList>
</asp:Panel>
</ItemTemplate>
</asp:DataList>
</table>
Code Behind:
public partial class _CompanyList2 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void LinkButton1_Command(object sender, CommandEventArgs e)
{
//pass index of item in command argument
int itemIndex = Convert.ToInt32(e.CommandArgument);
//depending on your needs bind the details on demand
//or preload during ItemDataBound
Panel childViewPanel = (Panel)DataList1.Items[itemIndex].FindControl("pnlChildView");
if (childViewPanel != null)
{
//toggle visibility of childViewPanel and bind child list if panel is visible
DataList childList = (DataList)childViewPanel.FindControl("childList");
if (childList != null)
{
//int keyValue = (int)DataList1.DataKeys[itemIndex];
string keyValue = (string)DataList1.DataKeys[itemIndex];
using (SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["connApps"].ConnectionString))
{
con.Open();
using (SqlCommand cmd = new SqlCommand("SELECT FirstName, LastName FROM dbo.Import_CompanyContact WHERE REPLACE(Company, '''', '') = '" + keyValue + "'", con))
{
cmd.CommandType = CommandType.Text;
using (SqlDataReader dr = cmd.ExecuteReader())
{
childList.DataSource = dr;
childList.DataBind();
}
}
}
}
}
}
}

Clicking HyperLink causes Update Panel to perform Full PostBack?

Update panel does a full post back when I am just trying to do a partial post back. I just want to be able to update the Repeater and not update the whole page when i click the hyperlinks previous page and next page .
protected void Page_Load(object sender, EventArgs e)
{
PagedDataSource objpd = new PagedDataSource();
string connStr = ConfigurationManager.ConnectionStrings["yafnet"].ConnectionString;
SqlConnection mySQLconnection = new SqlConnection(connStr);
if (mySQLconnection.State == ConnectionState.Closed)
{
mySQLconnection.Open();
}
SqlCommand mySqlSelect = new SqlCommand("SELECT * FROM [Comments]", mySQLconnection);
mySqlSelect.CommandType = CommandType.Text;
SqlDataAdapter mySqlAdapter = new SqlDataAdapter(mySqlSelect);
DataTable table = new DataTable();
mySqlAdapter.Fill(table);
objpd.DataSource = table.DefaultView;
objpd.AllowPaging = true;
objpd.PageSize = 1;
int currentPage;
if (Request.QueryString["page"] != null)
{
currentPage = Int32.Parse(Request.QueryString["page"]);
}
else
{
currentPage = 1;
}
objpd.CurrentPageIndex = currentPage - 1;
// Label1.Text = "Page " + currentPage + " of " + pds.PageCount;
if (!objpd.IsFirstPage)
{
linkPrev.NavigateUrl = Request.CurrentExecutionFilePath + "?page=" + (currentPage - 1);
}
if (!objpd.IsLastPage)
{
linkNext.NavigateUrl = Request.CurrentExecutionFilePath + "?page=" + (currentPage + 1);
}
Repeater1.DataSource = objpd;
Repeater1.DataBind();
}
This is my HTML
<div class="comment">
<asp:UpdatePanel ID="UpdatePanel1" UpdateMode="Conditional" runat="server">
<ContentTemplate>
<asp:Repeater ID="Repeater1" runat="server">
<HeaderTemplate>
<table class="commentsx" cellspacing="0">
</HeaderTemplate>
<ItemTemplate>
<tr>
<td class="name">
<div class="right">
<%# Eval("CommentUserName") %>
</div>
<div class="left">
<%# Eval("CommentDateTime") %>
</div>
</td>
</tr>
<tr>
<td>
<div class="mess">
<%# Eval("CommentMessage") %>
</div>
</td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
<asp:HyperLink ID="linkPrev" runat="server">Previous Page</asp:HyperLink>
<asp:HyperLink ID="linkNext" runat="server">Next Page</asp:HyperLink>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="Button1" EventName="DataBinding" />
</Triggers>
</asp:UpdatePanel>
</div>
Hyperlink controls don't do a postback at all, they evaluate to regular links that will do a GET, not a POST.
Since it seems you want something that looks like a link, but does a postback rather than a GET, what you need is a LinkButton. It looks like a link, but acts like a button and performs a postback.
Figure I would post an answer to my own question since I figure it out with help of Servy. Hyperlinks do a Get not a post that is why my previous code above was not working. So I rework my code to include the following.
I added Two buttons
Made Event Handlers for the Two buttons to create a POST
Here is my Code might help someone
public int CurrentPage
{
get
{
// look for current page in ViewState
object o = this.ViewState["_CurrentPage"];
if (o == null)
return 0; // default to showing the first page
else
return (int)o;
}
set
{
this.ViewState["_CurrentPage"] = value;
}
}
private void updateMessage()
{
PagedDataSource objpd = new PagedDataSource();
string connStr = ConfigurationManager.ConnectionStrings["yafnet"].ConnectionString;
SqlConnection mySQLconnection = new SqlConnection(connStr);
if (mySQLconnection.State == ConnectionState.Closed)
{
mySQLconnection.Open();
}
SqlCommand mySqlSelect = new SqlCommand("SELECT * FROM [Comments]", mySQLconnection);
mySqlSelect.CommandType = CommandType.Text;
SqlDataAdapter mySqlAdapter = new SqlDataAdapter(mySqlSelect);
DataTable table = new DataTable();
mySqlAdapter.Fill(table);
objpd.DataSource = table.DefaultView;
objpd.AllowPaging = true;
objpd.PageSize = 1;
objpd.CurrentPageIndex = CurrentPage;
//disable pre or next buttons if necessary
cmdPrev.Enabled = !objpd.IsFirstPage;
cmdNext.Enabled = !objpd.IsLastPage;
Repeater1.DataSource = objpd;
Repeater1.DataBind();
}
protected void Page_Load(object sender, EventArgs e)
{
updateMessage();
}
protected void cmdPrev_Click(object sender, EventArgs e)
{
// Set viewstate variable to the previous page
CurrentPage -= 1;
// Reload control
updateMessage();
}
protected void cmdNext_Click(object sender, EventArgs e)
{
// Set viewstate variable to the next page
CurrentPage += 1;
// Reload control
updateMessage();
}
here is my html
<div class="comment">
<asp:UpdatePanel ID="UpdatePanel1" UpdateMode="Conditional" runat="server">
<ContentTemplate>
<asp:Repeater ID="Repeater1" runat="server">
<HeaderTemplate>
<table class="commentsx" cellspacing="0">
</HeaderTemplate>
<ItemTemplate>
<tr>
<td class="name">
<div class="right">
<%# Eval("CommentUserName") %>
</div>
<div class="left">
<%# Eval("CommentDateTime") %>
</div>
</td>
</tr>
<tr>
<td>
<div class="mess">
<%# Eval("CommentMessage") %>
</div>
</td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
<asp:button id="cmdPrev" runat="server" text=" << " onclick="cmdPrev_Click"></asp:button>
<asp:button id="cmdNext" runat="server" text=" >> " onclick="cmdNext_Click"></asp:button></td>
</ContentTemplate>
</asp:UpdatePanel>
</div>

Categories