I'm trying to make some simple code to increate a number in a DataBase with a repeater onitemcommand that sends a id & a commandname.
The code to increase the int in the Database works fine, but when I then try to add a redirection to "The Article page" where you can read the whole article.
So my question how can I redirect with a LinkButton & make Query Strings in the redirection as shown below in a <a> (HTML5) tag inside the linkbutton // If I add the <a> (HTML5) tag it doesn't update the int in database // if I remove the <a> (HTML5) tag it will update the database int but won't redirect with the Query Strings.
<asp:Repeater ID="Repeater_Frontpage" OnItemCommand="Repeater_Frontpage_ItemCommand" DataSourceID="SqlDataSource1" runat="server">
<ItemTemplate>
<asp:LinkButton CommandName="Visit" CommandArgument='<%# Eval("news_id") %>' runat="server">Read More</asp:LinkButton>
</ItemTemplate>
</asp:Repeater>
protected void Repeater_Frontpage_ItemCommand(object source, RepeaterCommandEventArgs e)
{
if (e.CommandName == "Visit")
{
SqlConnection conn = new SqlConnection(Helpers.ConnectionString);
SqlCommand cmd = new SqlCommand();
cmd.Connection = conn;
int userId = int.Parse(e.CommandArgument.ToString());
cmd.CommandText = "UPDATE News SET news_visits = news_visits + 1 WHERE news_id =" + userId;
conn.Open();
cmd.ExecuteNonQuery();
conn.Close();
}
}
You can set ItemIndex as a CommandArgument
CommandArgument='<%# Container.ItemIndex %>'
And then you can get the row from the Repeater DataSource
protected void repeater_ItemCommand(object source, RepeaterCommandEventArgs e)
{
if (e.CommandName == "Visit")
{
var rowIndex = (int)e.CommandArgument;
//Here I am assuming that your data source is a DataTable
var row = ((DataTable)repeater.DataSource).Rows[0];
var newsID = row.Field<int>("newsID");
var categoriesID = row.Field<int>("fk_categories_id");
Response.Redirect($"Article.aspx?category_id={categoriesID}& amp;news_id={categoriesID}");
Response.Write($"Do something with {e.CommandArgument}");
}
}
Related
Currently i have two problems.
Problem 1. Im trying to change the Visibility of two Panels based on what value the reader gets from reader["Maskine_Type"].ToString() as you can see in the Codebehind below. Because the Panels are inside a repeater i also use the:
Panel PanelTilbud = (Panel)Page.FindControl("PanelTilbud"); again you can see below. however, when i run the code it gives me a Object reference not set to an instance of an object on PanelTilbud.Visible = true; i assume because it still cant find the Panels. i tested with panels outside of the repeater and it works fine.
I also tried to make the Repeater OnItemDataBound="Repeater1_ItemDataBound"
and changed to Panel PanelTilbud = (Panel)e.Item.FindControl("PanelTilbud");
However then i get the error Insufficient stack to continue executing the program safely
Problem 2.
Inside one of the panels, i run this code
<%# (Eval("Maskine_Tilbud").ToString().Substring(Eval("Maskine_Tilbud").ToString().Length - 2))%>
in order to remove the first two characters in the string from Eval("Maskine_Tilbud") which works fine, however most records in the database will have a null inMaskine_Tilbud and if its null i get the error StartIndex cannot be less than zero which makes sense, but i dont know how else to remove the first two characters from Eval("Maskine_Tilbud")
.aspx markup
<asp:Repeater ID="Repeater1" runat="server">
<ItemTemplate>
<asp:Panel ID="PanelTilbud" runat="server" Visible="false">
<hr />
<h4 class="radfont text-center">Tilbud! -<%# (Eval("Maskine_Tilbud").ToString().Substring(Eval("Maskine_Tilbud").ToString().Length - 2))%>% pr dag!</h4>
</asp:Panel>
<asp:Panel ID="PanelNormal" runat="server">
<hr />
<h4 class="text-center orangeFont"><%#Eval("Maskine_pris") %><span class="hvidfont">,- pr dag inkl moms</span>
<span class="orangeFont">(<%#Eval("Maskine_Upris") %>,- ekskl)</span>
</h4>
<hr />
</asp:Panel>
</ItemTemplate>
</asp:Repeater>
My Codebehind - in Page_Load
SqlConnection conn = new SqlConnection();
conn.ConnectionString = ConfigurationManager.ConnectionStrings["DatabaseConnectionString1"].ToString();
SqlCommand cmd = new SqlCommand();
cmd.Connection = conn;
cmd.CommandText = "SELECT top 1 * FROM [Maskiner] INNER JOIN Maskine_kategori ON Maskiner.Maskine_Kategorinavn = Maskine_kategori.Maskine_kategori_id WHERE ([Maskine_id] = #Maskine_id)";
cmd.Parameters.Add("#Maskine_id", SqlDbType.Int).Value = Request.QueryString["Maskine_id"];
conn.Open();
SqlDataReader reader = cmd.ExecuteReader();
Panel PanelTilbud = (Panel)Page.FindControl("PanelTilbud");
Panel PanelNormal = (Panel)Page.FindControl("PanelNormal");
if (reader.Read())
{
if (reader["Maskine_Type"].ToString() == "Tilbud")
{
PanelTilbud.Visible = true;
PanelNormal.Visible = false;
}
if (reader["Maskine_Type"].ToString() == "Normal")
{
PanelTilbud.Visible = false;
PanelNormal.Visible = true;
}
}
conn.Close();
DataTable select_favorit_db = new DataTable();
SqlDataAdapter dt = new SqlDataAdapter(cmd);
dt.Fill(select_favorit_db);
Repeater1.DataSource = select_favorit_db;
Repeater1.DataBind();
I hope you can understand my questions.
Late to the party here. Just thought I should add that you can have methods in your page and use them in your data binding expressions. Sample:
ASPX:
<form id="form1" runat="server">
<asp:Repeater ID="rep" runat="server">
<ItemTemplate>
<asp:Label ID="lab" runat="server"
Text='<%# Trim2Chars(Eval("test")) %>'></asp:Label>
</ItemTemplate>
</asp:Repeater>
</form>
Code behind:
protected void Page_Load(object sender, EventArgs e)
{
//create fake data for demo and bind to repeater
var data = Enumerable.Range(0, 10).Select(i => new { test = "foo " + i });
rep.DataSource = data;
rep.DataBind();
}
public string Trim2Chars(object input)
{
string inputString = input as string;
if (inputString == null)
return "";
if (inputString.Length < 2)
return inputString;
return inputString.Substring(2);
}
This way, you can keep the ASPX file a bit cleaner and have more complex data binding expressions evaluated in the code behind.
You can set the Visibility in the Control itself
<asp:Panel ID="PanelTilbud" runat="server" Visible='<%# Eval("Maskine_Type").ToString() == "myValue" %>'>
</asp:Panel>
Or in the ItemDataBound event code behind
protected void Repeater1_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
//use findcontrol to find the panel and cast it as one
Panel panel = e.Item.FindControl("PanelTilbud") as Panel;
//get the current datarowview
DataRowView row = e.Item.DataItem as DataRowView;
//check the value and change the panel visibility
if (row["Maskine_Type"].ToString() == "myValue")
{
panel.Visible = true;
}
}
To check for NULL values you have to use a ternary operator.
<%# !string.IsNullOrEmpty(Eval("Maskine_Type").ToString()) ? Eval("Maskine_Type").ToString().Substring(0, Eval("Maskine_Type").ToString().Length - 2) : "Field is empty" %>
I build a demo application in which I used a checkbox list to get the hobbies and enter those values in the database as follows:
The ASP code for checkbox list is:
<asp:CheckBoxList ID="chkboxlsthobbies" runat="server" RepeatDirection="Horizontal">
<asp:ListItem>cricket</asp:ListItem>
<asp:ListItem>football</asp:ListItem>
<asp:ListItem>pool</asp:ListItem>
<asp:ListItem>basketball</asp:ListItem>
<asp:ListItem>rugby</asp:ListItem>
</asp:CheckBoxList>
<asp:Button ID="Button1" runat="server" Text="submit" OnClick="Button1_Click" />
And the corresponding C# code to enter that value in database is as follows:
protected void Button1_Click(object sender, EventArgs e)
{
string str = string.Empty;
foreach (ListItem item in chkboxlsthobbies.Items)
{
if (item.Selected)
{
str += string.Format("{0}, ", item.Text);
}
}
SqlCommand cmd = new SqlCommand("insert into [CheckboxTable] values('" + str + "')", con);
con.Open();
cmd.ExecuteNonQuery();
con.Close();
bindgrid();
}
Now I am using a Gridview to bind that table data and display it and in that, I am having a onRowEditing and onRowDeleting event.
The Gridview code is as follows:
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:Button ID="gvtxtedit" runat="server" CommandName="Edit" Text="Edit" />
<asp:Button ID="gvtxtdelete" runat="server" CommandName="Delete" Text="Delete" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Hobbies">
<ItemTemplate>
<asp:Label ID="gvlblfirstname" runat="server" Text='<%#Eval("Hobbies") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
And the Gridview bind method is as follows:
protected void bindgrid()
{
SqlCommand cmd = new SqlCommand("select * from [CheckboxTable]", con);
con.Open();
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataTable dt = new DataTable();
da.Fill(dt);
GridView1.DataSource = dt;
GridView1.DataBind();
}
And now I am completely stuck in this problem generally I am able to fetch the value of any field back to TextBox or a Dropdown list on the form
Example:
txtfirstname.Text = dt.Rows[0]["firstname"].ToString();
inside the onRowEditing event to fetch the field value back to the control on the form, which I can do for textbox and dropdown.
The problem is I am not able to figure out that how to fetch the multiple values separated by a "," back to a checkbox list, because there are multiple values, I have been trying this for a long time.
Final problem is that fetch the values in database back to the checkbox list inside the onRowEditing event of GridView.
I wrote this onRowEditing Gridview function to implement the above functionality i.e: to fetch the checkbox list values saved in database back to the checkbox list on the form inside the onRowEditing event of Gridview
protected void GridView1_RowEditing(object sender, GridViewEditEventArgs e)
{
chkboxlsthobbies.ClearSelection();
//Get the ID
int id = Int32.Parse(GridView1.DataKeys[Int32.Parse(e.NewEditIndex.ToString())].Values["ID"].ToString());
SqlCommand cmd = new SqlCommand("select * from CheckboxTable where ID = '"+id+"'", con);
con.Open();
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataTable dt = new DataTable();
da.Fill(dt);
con.Close();
// Get the exact column and save it in a string.
string str = dt.Rows[0]["Hobbies"].ToString();
string[] strlist = str.Split(',').Select(t => t.Trim()).ToArray(); //Split into array and trim it.
//Finally the main functionality to check the values in checkbox list.
foreach (string s in strlist)
{
foreach (ListItem item in chkboxlsthobbies.Items)
{
if (item.Value == s)
{
item.Selected = true;
break;
}
}
}
Thank You.
I have an aspx page that displays a gridview of questions waiting on review with 10 questions shown per page. If a question is selected it is opened in a new page where the reviewer can either submit a review or cancel and return to the list of questions needing review.
Currently this works fine, but have a request from the reviewers so that if they are on page 4 of the gridview when they go to a question, they get returned to page 4 if they hit cancel and return to the list of questions (currently they are returned to page 1).
So I am setting a couple session variables to capture the question selected and to capture the pageindex of the gridview control for future use. Trying to use the session variable for the questionId on the page load of the detail page, but it is not being passed. On returning to the Review List page the pageindex that is being set on the gridview is always 0, not the session variable.
Updated Gridview control (note two controls, one hyperlink(which should go away once the other linkbutton control works):
<asp:GridView ID="GridView1" runat="server" Caption="Questions Awaiting Review" AllowSorting="True" PagerSettings-Mode="NumericFirstLast" OnPageIndexChanging="GridView1_PageIndexChanging"
CaptionAlign="Top" EmptyDataText="No Questions Pending Review." PageSize="10" AllowPaging="true" PagerStyle-HorizontalAlign="Center" PagerStyle-Font-Size="Large" DataKeyNames="QuestionID"
AutoGenerateColumns="false" AlternatingRowStyle-BackColor="#cccccc">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:Label ID="QuestionID" runat="server" Text='<%# Eval("QuestionID") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="KeyObjective" HeaderText="Key Objective" ItemStyle-Width="250" />
<asp:BoundField DataField="SubmitDate" HeaderText="Submitted Date" ItemStyle-Width="60" />
<asp:TemplateField>
<ItemTemplate>
<asp:HyperLink ID="Details" runat="server" NavigateUrl='<%#"~/Review/ReviewDetail.aspx?Id=" + Eval("QuestionID") +"&PageIndex=" + GridView1.PageIndex %>'>View Question</asp:HyperLink>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton ID="Details2" runat="server" Text="Session" OnClick="Session_OnClick"></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
OnClick Event for the second button:
protected void Session_OnClick(object sender, EventArgs e)
{
Session["PageIndex"] = GridView1.PageIndex;
Session["QuestionId"] = GridView1.SelectedDataKey;
Response.Redirect("~/Review/ReviewDetail.aspx", false;
}
Connection string on the detail page which is now not getting a value for the parameter "QuestionID"; ):
SqlCommand command = new SqlCommand("QuestionDetail", Conn);
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add(new SqlParameter("#QuestionID", SqlDbType.BigInt));
command.Parameters["#QuestionID"].Value = Convert.ToInt64(Session["QuestionId"]);
Conn.Open();
SqlDataReader reader = command.ExecuteReader();
PageLoad and gridview binding on the ReviewList page that should be using session variable to set page of grid control, but is always going to default of page 0:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
bindGridView();
}
else
{
if (Convert.ToInt32(Session["PageIndex"]) !=0)
{
GridView1.PageIndex = Convert.ToInt32(Session["PageIndex"]);
bindGridView();
}
}
}
private void bindGridView()
{
string connectionString = WebConfigurationManager.ConnectionStrings["CS1"].ConnectionString;
string selectSQL = String.Format("Select QuestionID, KeyObjective, SubmitDate from Questions where Author <> '{0}' and QuestionID not in(Select QuestionID from Review where Reviewer = '{0}')", User.Identity.Name);
SqlConnection con = new SqlConnection(connectionString);
SqlCommand cmd = new SqlCommand(selectSQL, con);
SqlDataAdapter adapter = new SqlDataAdapter(cmd);
DataSet ds = new DataSet();
adapter.Fill(ds, "Review");
GridView1.DataSource = ds;
GridView1.DataBind();
}
Your error probably means that Request["Id"] is empty or does not exists. Always check if QueryStrings exist and do the conversions of user inputs that are likely to fail inside a try-catch block.
protected void Page_Load(object sender, EventArgs e)
{
long QuestionID = -1;
//check if the Id QueryString exists
if (Request.QueryString["Id"] != null)
{
//try to convert to int64
try
{
QuestionID = Convert.ToInt64(Request.QueryString["Id"]);
}
catch
{
}
}
//if valid QuestionID
if (QuestionID >= 0)
{
using (SqlConnection connection = new SqlConnection(Common.connectionString))
using (SqlCommand command = new SqlCommand("QuestionDetail", connection))
{
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add("#QuestionID", SqlDbType.BigInt).Value = QuestionID;
//try to execute the stored procedure
try
{
connection.Open();
command.ExecuteNonQuery();
}
catch (Exception ex)
{
//handle sql error
Literal1.Text = ex.Message;
}
}
}
}
And why do you do a PostBack on the first button? That is not needed just to redirect to a different url. Change it to:
<asp:HyperLink ID="HyperLink1" runat="server" NavigateUrl='<%#"~/Review/ReviewDetail.aspx?Id=" + Eval("QuestionID") %>'>View Question</asp:HyperLink>
Or with the Page Index also in the QueryString:
<asp:HyperLink ID="HyperLink1" runat="server" NavigateUrl='<%#"~/Review/ReviewDetail.aspx?Id=" + Eval("QuestionID") + "&Page=" + GridView2.PageIndex %>'>View Question</asp:HyperLink>
UPDATE
If you really want to do a PostBack to set the Sessions you can use the OnRowCommand:
<asp:LinkButton ID="LinkButton1" CommandArgument='<%# Eval("QuestionID") %>' runat="server" CommandName="viewQuestion">View Question</asp:LinkButton>
CS
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "viewQuestion")
{
Session["PageIndex"] = GridView1.PageIndex;
Session["QuestionId"] = e.CommandArgument.ToString();
Response.Redirect("~/Review/ReviewDetail.aspx?Id=" + Convert.ToString(Session["QuestionId"]));
}
}
I am trying to get the data using column index and not the column name using the <%#Eval('foo')%> expression (or any other way) in my repeater control.
here are my codes :
page :
<asp:Repeater ID="rptrHeatingNavien" runat="server">
<ItemTemplate>
<li class="icon-font"><a href="/Products/?Id=<%#Eval('get-data-by-index[0]')%>><a><%#Eval('get-data-by-index[1]')%></a></li>
</ItemTemplate>
</asp:Repeater>
code-behind:
string connectionString = ConfigurationManager.ConnectionStrings["connection"].ConnectionString;
SqlConnection sqlCon = new SqlConnection(connectionString);
SqlDataAdapter sqlDa = new SqlDataAdapter("SELECT * FROM Products", sqlCon);
DataSet ds = new DataSet();
sqlDa.Fill(ds);
rptr.DataSource = dsSideMenu.Tables[0].Select("category = '1-1-1'");
rptr.DataBind();
the problem here is that for some reason(I'd be more than happy to know why), I cannot use column names for the rows that I am binding to my repeater control.(And I double checked that they actually have the data in them).So the only solution that is in front of me is to get them by their column indexes, and I have no idea how I can do it.Any solutions?
Assuming that you are binding a collection of SuperItem objects (SuperItem type supports index-based access) you can handle ItemDataBound event:
<asp:Repeater ID="rptrHeatingNavien" runat="server" OnItemDataBound="rptrHeatingNavien_ItemDataBound">
<ItemTemplate>
<li class="icon-font">
<asp:HyperLink runat="server" ID="productLink" />
</ItemTemplate>
</asp:Repeater>
Code-behind:
protected void rptrHeatingNavien_ItemDataBound(object sender, EventArgs e)
{
if(e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
var item = (SuperItem) e.Item.DataItem;
var link = (HyperLink) e.Item.FindControl("productLink");
link.NavigateUrl = string.Format("/Products/?Id={0}", item[0].ToString());
link.Text = item[1].ToString();
}
}
I have a grid view with link buttons. When clicking on it, I want to perform some operation, and also need to make the clicked link button invisible. How to make it invisible?
My code:
<asp:TemplateField ShowHeader="true" HeaderText="Theory">
<ItemTemplate>
<asp:LinkButton ID="lb_theory" runat="server" CausesValidation="false" CommandArgument='<%#Eval("student_id")%>' OnClientClick="this.disabled = true; " CommandName="theory_remove" Text="Remove"
command = "lnk_Click" ></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField ShowHeader="true" HeaderText="Practical">
<ItemTemplate>
<asp:LinkButton ID="lb_practical" runat="server" CausesValidation="false"
CommandArgument='<%#Eval("student_id")%>' CommandName="practical_remove" Text="Remove"></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
and
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "theory_remove")
{
string st_id = Convert.ToString(e.CommandArgument.ToString());
string t_id = (string)Session["test"];
SqlConnection con = obj.getcon();
con.Open();
string theory_state = "0";
SqlCommand cmd = new SqlCommand("update student_vs_testsession_details set theory='" + theory_state+ "' WHERE student_id='" + st_id + "' and testsession_id='" + t_id + "'", con);
int temp = cmd.ExecuteNonQuery();
}
}
Try this way
protected void gridview__RowCommand(object sender, GridViewRowEventArgs e)
{
GridViewRow row = (GridViewRow)(((LinkButton)e.CommandSource).NamingContainer);
LinkButton lnkbtn = (LinkButton)row.FindControl(”lnkbtnActionNames”);
lnkbtn .Visible = false;
}
I would personally use Knockout JS or jQuery to manage all my client side functionality just as hiding and manipulating html elements.
Add this to your GridView1_RowCommand event
LinkButton mybutton = (LinkButton)sender;
mybutton.Visible = false;
use javascript to hide that. Add onclientclick event and write code in javascript to hide that. First client code will run and then server side. So the button will be hide at that time.