I have a gridview connected to a database by sqldatasource. I have multiple drop down lists and a table where users can select different data to filter the gridview.
I know how to set this up for one control but have no idea how to do it for multiple ones. Ideally what I would like to do is onfilterButton_Click the code behind connects to a stored procedure in the database. The parameters would depend on the filter options the user has chosen. I just don't know how to write the stored procedure. (I am not the best at SQL)
But I am open to suggestions of better ways to do this. I am using c# visual studios 2010 and sql server 2008.
I have been stuck on this for over a week now so really any practical help would be welcome.
Write One Stored Procedure and Pass DropDownList values as Parameters like this:
CREATE PROC CUST_Details
(
#CustomerID INT,
#CompanyID INT
)
AS
BEGIN
SELECT
Customer.CustomerName,
Company.CompanyName
FROM
Customer INNER JOIN
Company ON Customer.CompanyID = Company.CompanyID
WHERE
(#CompanyID = -1 OR Customer.CompanyID = #CompanyID) AND
(#CustomerID = -1 OR Customer.CustomerID = #CustomerID)
END
Before that, in your DropDownList add item such as "<-----Select----->" as DataTextField and "-1" as DataValueField.
In Both DropDownList SelectedIndexChanged Event, pass DropDownList's SelectedValue as parameters and once again call the database and databind it with the Grid.
If you are not good in writing SP's then you can directly filter your SQL DataSource by using the FilterExpression property.
sql.FilterExpression = "Filteration Expression";
GridView1.DataBind();
Edit: Something that will work for you:
if (DropDownList1.SelectedItem.Text != "All")
{
SqlDataSource1.FilterExpression = "Title like '" + textbox1.Text + "' and Category like " + DropDownList1.SelectedValue;
}
else
{
SqlDataSource1.FilterExpression = "Title like '" + textbox1.Text + "'";
}
GridView1.DataBind();
Below might give you idea how this works, please check:
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>ASP.NET Example</title>
</head>
<body>
<form id="FORM1" runat="server">
<p>Show all employees with the following title:
<asp:DropDownList
id="DropDownList1"
runat="server"
AutoPostBack="True">
<asp:ListItem>Sales Representative</asp:ListItem>
<asp:ListItem>Sales Manager</asp:ListItem>
<asp:ListItem>Vice President, Sales</asp:ListItem>
</asp:DropDownList></p>
<asp:SqlDataSource
id="SqlDataSource1"
runat="server"
ConnectionString="<%$ ConnectionStrings:NorthwindConnection %>"
SelectCommand="SELECT EmployeeID,FirstName,LastName,Title FROM Employees"
FilterExpression="Title='{0}'" OnFiltering="SqlDataSource1_Filtering">
<FilterParameters>
<asp:ControlParameter Name="Title" ControlId="DropDownList1" PropertyName="SelectedValue"/>
</FilterParameters>
</asp:SqlDataSource><br />
<asp:GridView
id="GridView1"
runat="server"
DataSourceID="SqlDataSource1"
AutoGenerateColumns="False">
<columns>
<asp:BoundField Visible="False" DataField="EmployeeID" />
<asp:BoundField HeaderText="First Name" DataField="FirstName" />
<asp:BoundField HeaderText="Last Name" DataField="LastName" />
</columns>
</asp:GridView>
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
</form>
</body>
</html>
Server Side:
protected void SqlDataSource1_Filtering(object sender, SqlDataSourceFilteringEventArgs e)
{
Label1.Text = e.ParameterValues[0].ToString();
}
Your stored procedure would declare all your parameters like so:
CREATE PROCEDURE GetData
#parameter1 varchar(50),
#parameter2 int
etc...
Then you would call your stored procedure with the parameters like:
GetData(dropdownlist1.SelectedItem.Value, dropdownlist2.SelectedItem.Value);
Is that the sort of thing you mean?
UPDATE:
For a situation where the 'All' option was chosen, you could still pass the value as a null parameter, and in the stored procedure you would declare it as 'optional':
CREATE PROCEDURE GetData
#parameter1 varchar(50) = NULL,
#parameter2 int
So the query in your stored procedure would look something like this:
SELECT *
FROM Table
WHERE ((#parameter1 IS NULL) OR (column1 = #parameter1 ))
AND column2 = #parameter2
Related
SQL Server stored procedure accepts the parameters, current company name, new company name and whether it already exists which has a default value. When the edit button is clicked on the front end UI, the grid view allows me to edit the company name. This shows an 'Update' button - when this is clicked - the code parses however nothing updates and company name does not update either.
Breakpoint is set and stepped through and #CurrentCompanyName is returned as null. Not sure how to fix this.
Aspx:
<asp:GridView ID="CompanyTable" runat="server"
OnRowEditing="CompanyTable_RowEditing"
OnRowCancelingEdit="CompanyTable_RowCancelingEdit"
OnRowUpdating="CompanyTable_RowUpdating"
OnPageIndexChanging="CompanyTable_PageIndexChanging"
PageSize="20" Font-Underline="False" AllowPaging="True">
<HeaderStyle Width="150px" />
<Columns>
<asp:TemplateField>
<HeaderStyle Width="200px" />
<ControlStyle CssClass="ButtonDesigntwo" />
<ItemTemplate>
<asp:LinkButton ID="Edit" ButtonType="Button" runat="server" CommandName="Edit" Text="Edit" />
<asp:LinkButton ID="Delete" ButtonType="Button" runat="server" CommandName="Delete" Text="Delete" />
</ItemTemplate>
<EditItemTemplate>
<asp:Button ID="Update" ButtonType="Button" runat="server" Text="Update" CommandName="Update"/>
<asp:Button ID="Cancel" ButtonType="Button" runat="server" Text="Cancel" CommandName="Cancel"/>
</EditItemTemplate>
</asp:TemplateField>
</Columns>
<HeaderStyle CssClass="tableHeaderStyle" />
<PagerSettings Mode="NumericFirstLast" />
<PagerStyle CssClass="pager" BorderColor="Black" ForeColor="White" Font-Underline="False" />
<RowStyle CssClass="tableRowStyle" />
</asp:GridView>
Method code:
protected void CompanyTable_RowUpdating(object sender, System.Web.UI.WebControls.GridViewUpdateEventArgs e)
{
string connectionString = ConfigurationManager.ConnectionStrings["DBConnection"].ConnectionString;
SqlConnection cn = new SqlConnection(connectionString);
using (SqlCommand cmd = new SqlCommand("[updateCompanyName]", cn))
{
TextBox name = CompanyTable.Rows[e.RowIndex].FindControl("CompanyTable") as TextBox;
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#CurrentCompanyName", name);
cmd.Parameters.AddWithValue("#NewCompanyName", CompanyInputTextBox.Text).Direction = ParameterDirection.Input;
SqlParameter objisExists = new SqlParameter("#isExists", SqlDbType.Int);
objisExists.Direction = ParameterDirection.Output;
cmd.Parameters.Add(objisExists);
cn.Open();
cmd.ExecuteNonQuery();
cn.Close();
int isExists = Convert.ToInt32(cmd.Parameters["#isExists"].Value.ToString());
if (isExists == 0)
{
Page.ClientScript.RegisterStartupScript(this.GetType(), "111", "AddCompanyUpdating();", true);
}
else if (isExists == 1)
{
Page.ClientScript.RegisterStartupScript(this.GetType(), "111", "CompanyNotUpdatedValidation();", true);
}
}
// Setting the EditIndex property to -1 to cancel the Edit mode in Gridview
CompanyTable.EditIndex = -1;
// Call ShowData method for displaying updated data
BindData();
}
Stored procedure:
ALTER PROCEDURE [dbo].[updateCompanyName]
#CurrentCompanyName VARCHAR(50),
#NewCompanyName VARCHAR(50),
#IsExists INT = 0 OUT
AS
BEGIN
DECLARE #CompanyID INT
SELECT #CompanyID = CompanyID
FROM company
WHERE companyname = #CurrentCompanyName
BEGIN
IF EXISTS (SELECT CompanyName
FROM company
WHERE companyname = #NewCompanyName )
BEGIN
SET #IsExists = 1
END
ELSE
BEGIN
UPDATE COMPANY
SET CompanyName = #NewCompanyName
WHERE companyid = #CompanyID
SET #IsExists = 0
END
END
PRINT #isexists
END
You are defining name as a textbox in this line:
TextBox name = CompanyTable.Rows[e.RowIndex].FindControl("CompanyTable") as TextBox;
Then you try to set the value of your parameter to the textbox in this line:
cmd.Parameters.AddWithValue("#CurrentCompanyName", name);
When what you SHOULD be doing, is setting the parameter value to the TEXT that is IN the textbox:
cmd.Parameters.AddWithValue("#CurrentCompanyName", name.Text);
EDIT:
Since name itself is NULL when you are hovering over it, that means that you have not correctly defined it in this line:
TextBox name = CompanyTable.Rows[e.RowIndex].FindControl("CompanyTable") as TextBox;
Stop the code in the debugger and open a quick view into CompanyTable, and see if you can figure out the correct way to define the textbox you are looking for.
EDIT 2: In defining your TextBox, you are doing FindControl("CompanyTable"), but according to your markup, "CompanyTable" is the ID of your GridView, not a textbox. In fact, I don't see any markup anywhere for a textbox in the first code sample you posted.
I want to be able to delete a row when I click on the delete button on that gridview. I have the aspx page and the code behind as well as the app code. The DeletePaymentCondition runs the store procedure to delete the row. But somehow the overall code doesnt work
aspx
<asp:GridView ID="gridview1" runat="server" HorizontalAlign="left" AutoGenerateColumns="false" CssClass="table table-bordered " GridLines="None"
AllowSorting="True" OnRowDeleting="OnRowDeleting">
<Columns>
<asp:TemplateField ItemStyle-HorizontalAlign="left" HeaderText="Payment Condition" HeaderStyle-CssClass="OGColor" HeaderStyle-ForeColor="white" SortExpression="monthToQuarters">
<ItemTemplate>
<span style="font-size:12px; color: #2980b9; text-align:left">
<asp:Label ID="lblUserId" runat="server" Visible="true" Text="<%# bind('payConditionId')%>"/>
</span>
</ItemTemplate>
</asp:TemplateField>
<asp:CommandField ButtonType="Link" ShowEditButton="true" ShowDeleteButton="true" ItemStyle-Width="150"/>
</Columns>
</asp:GridView>
cs
protected void OnRowDeleting(object sender, GridViewDeleteEventArgs e)
{
Label lblEmpID = (Label)gridPayment.Rows[e.RowIndex].FindControl("lblUserId"); //This is Table Id load on Label1
int id = Convert.ToInt32(lblEmpID.Text.ToString());
dsPayment = objcommission.Delete(id);
gridPayment.DataSource = dsPayment.Tables[0];
gridPayment.DataBind();
}
app code
public DataSet DeletePayment(int id)
{
DataSet dsGetAllPayment;
dsGetAllPaymentCondition = SqlHelper.ExecuteDataset(OGconnection, CommandType.Text, "Delete FROM tblPay where pay ='" + id + "'");
return dsGetAllPayment;
}
You shoul execute two different SQL, one for the delete and a new select one to retreive the new data.
The DELETE should be executed using in a NonQuery because it does not return rows (only the number of rows affected).
public DataSet DeletePaymentCondition(int ids)
{
int rowsAffected = SqlHelper.ExecuteNonQuery(OGconnection, CommandType.Text, "Delete FROM [Accounting].[dbo].[tblPayConditions] where payConditionId ='" + ids + "'");
DataSet dsGetAllPaymentCondition = SqlHelper.ExecuteDataSet(OGconnection, CommandType.Text, "Select * FROM [Accounting].[dbo].[tblPayConditions]");
return dsGetAllPaymentCondition;
}
As a good praxys, you should consider changing it into parametrized queries. In this case it is safe because of the integer conversion, but in similar code with string parameters you would be prone to SQL Injection attacks
I got the solution. I've made changes to the cs file and as well as the code provided by bradbury9.
protected void OnRowDeleting(object sender, GridViewDeleteEventArgs e)
{
int index = Convert.ToInt32(gridPaymentCondition.DataKeys[e.RowIndex].Value.ToString());
dsPaymentCondition = objcommission.DeletePaymentCondition(index);
gridPaymentCondition.DataSource = dsPaymentCondition.Tables[0];
updatePaymentConditionsWithoutRefresh();
}
I am using 3 tier architecture to develop website. I need to develop search functionality to show products based on what user type in search bar. When I debug, I see search value is not passing to ProductBL's GetProductInfo page.
Here is code:
protected void Search(object sender, EventArgs e)
{
string searchString = Request.QueryString["ProductName"];
Product product = new Product();
product.ProductName = txtSearch.Text.Trim();
ProductBL.GetProductInfo(searchString);
}
ProductBL Code for GetProductInfo method:
public static DataTable GetProductInfo(string searchString)
{
string query = "SELECT * FROM [Products] where ProductName like #SearchString and Visible = 1";
SqlCommand cmd = new SqlCommand(query);
cmd.Parameters.AddWithValue("#SearchString", SqlDbType.Text).Value = searchString;
return DbUtility.GetRecordsInDataTable(cmd);
}
Gridview page:
Search:
<asp:TextBox ID="txtSearch" runat="server" />
<asp:Button Text="Search" runat="server" OnClick="Search" />
<hr />
<br />
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="ProductID" CssClass="footable"
OnRowDeleting="DeleteRecord" EmptyDataText="There are no data records to display."
CellPadding="4" ForeColor="#333333" GridLines="None">
<AlternatingRowStyle BackColor="White" />
Kindly Help me with this
Change
string searchString = Request.QueryString["ProductName"];
to
string searchString = txtSearch.Text.Trim();
Because you are sending searchString to function as:
GridView1.DataSource = ProductBL.GetProductInfo(searchString);
GridView1.DataBind();
You have not set your query properly. First try checking your query in SQL editor.
The issue lies here.
like #SearchString
Change it to something like below
SELECT * FROM [Products] where ProductName like '%SearchString%' and Visible = 1
IF there will be records in the Products table then it will fetch through the query.
Also have a look at how to use Wildcards
https://support.microsoft.com/en-in/kb/98434
Hope that helps.
Here seems like your wildcard condition is wrong:
Has per comment you've to change your query like following.
string query = "SELECT * FROM [Products] where ProductName like where name like '%' + replace(SearchString, '%', '[%]') + '%' and Visible = 1";
Here your query seems like : select * from tablename where Column like '%[%]%'
It'll give you more appropriate result.
SELECT
LeagueTable.P,
LeagueTable.W,
LeagueTable.D,
LeagueTable.L,
LeagueTable.GF,
LeagueTable.GA,
LeagueTable.GD,
LeagueTable.Pts,
Team.Team_name,
LeagueTable.Team_ID
FROM LeagueTable
INNER JOIN Team
ON LeagueTable.Team_ID = Team.Team_ID
I've got the user to enter a team name on start up that is entered into the Team table, which redirects to a webpage with a league table. The league table initially contains no data but it should be displaying a row with the users input once the user has gotten to this page.
However this query shows the GridView as blank. What's wrong with it?
asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataSourceID="SqlDataSource1" EmptyDataText="No teams entered into the table.">
<Columns>
<asp:BoundField DataField="P" HeaderText="P" SortExpression="P" />
<asp:BoundField DataField="W" HeaderText="W" SortExpression="W" />
<asp:BoundField DataField="D" HeaderText="D" SortExpression="D" />
<asp:BoundField DataField="L" HeaderText="L" SortExpression="L" />
<asp:BoundField DataField="GF" HeaderText="GF" SortExpression="GF" />
<asp:BoundField DataField="GA" HeaderText="GA" SortExpression="GA" />
<asp:BoundField DataField="GD" HeaderText="GD" SortExpression="GD" />
<asp:BoundField DataField="Pts" HeaderText="Pts" SortExpression="Pts" />
<asp:BoundField DataField="Team_name" HeaderText="Team_name" SortExpression="Team_name" />
<asp:BoundField DataField="Team_ID" HeaderText="Team_ID" SortExpression="Team_ID" />
</Columns>
</asp:GridView>
protected void NewTeamBtn_Click(object sender, EventArgs e)
{
string qry1 = "INSERT into Team (Team_name) VALUES (#Team_name)";
using (SqlCommand cmd = new SqlCommand(qry1, con))
{
cmd.Parameters.Add(("#Team_name"), SqlDbType.VarChar).Value = NewTeamTxtBox.Text;
cmd.CommandType = CommandType.Text;
con.Open();
cmd.ExecuteNonQuery();
con.Close();
}
Response.Redirect("EnterData.aspx");
}
<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:SportsData2ConnectionString %>" SelectCommand="SELECT LeagueTable.League_ID, LeagueTable.Team_ID, LeagueTable.P, LeagueTable.W, LeagueTable.D, LeagueTable.L, LeagueTable.GF, LeagueTable.GA, LeagueTable.GD, LeagueTable.Pts, Team.Team_name FROM LeagueTable INNER JOIN Team ON LeagueTable.Team_ID = Team.Team_ID"></asp:SqlDataSource>
Based on your comments it appears you may be inserting data into your Team table, but when you run the select statement you have in your SQL Data Source you will notice you have an Inner Join. That Inner Join means that if the team Id is not in either one of the 2 tables you are joining then no results will be returned.
I don't see your sql data source code, but another possible point of failure is the TeamID you pass into that control. There are 3 questions that come to my mind for making sure you get valid data.
1) Where are you getting it from?
2) Is it valid and in both tables?
3) Are you rebinding the gridview after setting that value?
Edit
What you want to do does not at all match your question at this point. You should edit your title and question.
I would use something like this for your insert.
DECLARE #TeamID as INT
INSERT into Team (Team_name) VALUES (#Team_name)
SELECT #TeamID = SCOPE_IDENTITY();
INSERT into LeagueTable Team_ID VALUES #TeamID
this post will help Scope_Identity vs ##Identity
this stack question will help too.
I have a simple GridView that uses 3 session variables; CoName that is captured when the user logs in and PurchaseOrderDate, and HeatNumber that are captured in text boxes (both of these are optional) as input parameters for a stored procedure on a SQLServer 2012 database. I have a CustomerLanding.aspx page that has a search button on it that, when clicked, redirects the user to a TestReportLanding.aspx page that currently has the GridView on it. Everything works as it should in this scenario.
I want to move the GridView to CustomerLanding.aspx so I can display the search results on the same page that has the search parameters and the search button. Eventually I want to use AJAX for the update, but for now I'm just putting the GridView in a different div. When I use this setup, the query only returns results when the optional parameters (PurchaseOrderDate and HeatNumber) are provided. My stored procedure only requires CoName for it's search, so I should get a lot more rows returned with the optional parameters left empty.
Being somewhat new to .NET, I'm hoping that I'm missing something simple here.
Here is my GridView code in CustomerLanding along with the SqlDataSource:
<div class="col-xs-12 col-lg-10">
<asp:Label ID="NoRecordsFound" runat="server" Visible ="false" Text="No records found."></asp:Label>
<asp:GridView ID="GridView1" runat="server" BorderColor="#999999" BorderStyle="Solid" BorderWidth="1px" CellPadding="3" GridLines="Vertical" BackColor="White" ForeColor="Black" AllowSorting="True" AutoGenerateColumns="False" DataSourceID="SqlDataSource1">
<AlternatingRowStyle BackColor="#CCCCCC" />
<Columns>
<asp:BoundField DataField="doc" HeaderText="doc" SortExpression="doc" />
<asp:BoundField DataField="Date" HeaderText="Date" SortExpression="Date" />
<asp:BoundField DataField="Heat" HeaderText="Heat" SortExpression="Heat" />
<asp:BoundField DataField="Dir" HeaderText="Dir" SortExpression="Dir" />
</Columns>
</asp:GridView>
<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:iiConnectionString %>" SelectCommand="sp_test_reports" SelectCommandType="StoredProcedure">
<SelectParameters>
<asp:SessionParameter Name="CustomerName" SessionField="CoName" Type="String" />
<asp:SessionParameter DbType="Date" Name="Date" SessionField="PurchaseOrderDate" />
<asp:SessionParameter Name="Heat" SessionField="HeatNumber" Type="String" />
</SelectParameters>
</asp:SqlDataSource>
</div>
And for what it's worth here is my stored procedure (I'm certain this is not the problem because it works when the DataGrid is on a seperate page:
CREATE PROCEDURE [dbo].[sp_test_reports]
-- Add the parameters for the stored procedure here
#CustomerName varchar(50),
#Date date,
#Heat varchar(50)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
IF #Heat IS NULL AND #Date IS NULL
SELECT DISTINCT TOP 1000 d.doc, d.Date, dl.Heat, d.Dir
FROM documents d
INNER JOIN Documents_Line_Items dl ON d.Doc = dl.Doc
WHERE d.type = 2 and d.Customer = #CustomerName;
ELSE IF #Heat IS NOT NULL AND #Date IS NULL
SELECT DISTINCT(d.doc), d.Date, dl.Heat, d.Dir
FROM documents d
INNER JOIN Documents_Line_Items dl ON d.Doc = dl.Doc
WHERE d.type = 2 AND d.Customer = #CustomerName AND dl.Heat = #Heat;
ELSE IF #Heat IS NULL AND #Date IS NOT NULL
SELECT DISTINCT(d.doc), d.Date, dl.Heat, d.Dir
FROM documents d
INNER JOIN Documents_Line_Items dl ON d.Doc = dl.Doc
WHERE d.type = 2 AND d.Customer = #CustomerName AND d.Date = #Date;
ELSE IF #Heat IS NOT NULL AND #Date IS NOT NULL
SELECT DISTINCT(d.doc), d.Date, dl.Heat, d.Dir
FROM documents d
INNER JOIN Documents_Line_Items dl ON d.Doc = dl.Doc
WHERE d.type = 2 AND d.Customer = #CustomerName AND d.Date = #Date AND dl.Heat = #Heat;
END
And here is the code behind my search button:
Note that if I uncomment the Response.Redirect here, the GridView works like it should.
protected void TestReports_Click(object sender, EventArgs e)
{
Session["PurchaseOrderDate"] = DatePurchaseOrder.Text;
Session["HeatNumber"] = HeatText.Text;
GridView1.Visible = true;
MessageBox.Show(Session["CoName"].ToString());
MessageBox.Show(Session["HeatNumber"].ToString());
if (GridView1.Rows.Count == 0)
{
NoRecordsFound.Visible = true;
}
else
{
NoRecordsFound.Visible = false;
}
//Response.Redirect("TestReportLanding.aspx", false);
}
Thanks in advance for the help.
In your stored procedure, initialize your two optional parameters to NULL.
#CustomerName varchar(50),
#Date date = NULL,
#Heat varchar(50) = NULL
Parameters for a stored procedure aren't really "optional" unless they've been initialized to something.
Finally found an answer here:
empty gridview although the sqldatasource has values
Basically set CancelSelectOnNullParameter="false" on the SqlDatasource.