ListItems text not showing in Listbox - c#

The strangest thing happened to me in my asp.net application with a Listbox -- the ListItems are not showing their text. I know they are there because I can see them when I set breakpoints, and on top of that I am using almost the exact same code as I am on another page where they show up just fine. My listbox is on a panel that is called by a modal pop-up that looks like this:
<asp:ModalPopupExtender ID="ModalPopupExtender1" runat="server"
DynamicServicePath="" Enabled="True" TargetControlID="Button5"
BackgroundCssClass="modalBackground"
DropShadow="True"
PopupControlID="Panel2" CancelControlID="Button5" OkControlID="Button5">
</asp:ModalPopupExtender>
<asp:Panel ID = "Panel2" runat="server" CssClass="modalPopup">
<table>
<tr>
<td class="style3">
<asp:Label ID="Label5" runat="server" Text="The following users are queued front of you. Select 'OK' to add your name to the queue and 'Cancel' to cancel."></asp:Label>
</td>
</tr>
</table>
<asp:ListBox ID="ListBox6" runat="server" Width="100%"></asp:ListBox>
<center>
<asp:Button ID="reqOk" runat="server" Text="OK" onclick="reqOk_Clk" />
<asp:Button ID="reqCncl" runat="server" Text="Cancel" onclick="reqCncl_Clk" />
</center>
</asp:Panel>
The listbox (ListBox6) is populated like in the code behind page like this:
SqlConnection sqlconn = new SqlConnection(ConfigurationManager.ConnectionStrings
["something"].ConnectionString);
SqlCommand sqlcommand = new SqlCommand();
sqlcommand.Connection = sqlconn;
string cmd = "";
cmd = " SELECT devices.requestQueue, devices.invnumber FROM devices WHERE devices.invnumber='" + str + "'";
sqlcommand.CommandText = cmd;
SqlDataAdapter da = new SqlDataAdapter(sqlcommand);
DataSet ds = new DataSet();
da.Fill(ds);
DataTable dt = ds.Tables[0];
object[] obj = dt.Rows[0].ItemArray;
sqlconn.Close();
hasRequest = true;
int i2 = 0;
if (!obj[0].Equals(System.DBNull.Value))
{
string see = (string)obj[0];
string[] words = see.Split(',');
foreach (string word in words)
{
i2++;
if (word.Contains(getname(HttpContext.Current.User.Identity.Name)))
{
showStuff = false;
ListItem item = new ListItem(word);
ListBox6.Items.Add(item);
ModalPopupExtender1.Show();
Label5.Text = "You have already requested " + (string)ViewState["inventory"] + ". Please press cancel and request a different device.";
reqOk.Visible = false;
}
else
{
ListItem item = new ListItem(word);
ListBox6.Items.Add(item);
}
}
}
/*foreach (object o in ListBox6.Items)
{
Label4.Text += o.ToString() + " ";
}*/
if (showStuff == true)
{
ListBox6.DataBind();
if (obj[0].Equals(System.DBNull.Value) || (string)obj[0] == "")
i2 = 0;
Label5.Text = "The following " + i2 + " user(s) are queued in front of you for device " + str + ". Select 'OK' to add your name to the queue and 'Cancel' to cancel. Your name will not be added to the queue if you select 'Cancel'.";
ModalPopupExtender1.Show();
What makes this super frustrating is that when I uncomment this peice of code from above:
/*foreach (object o in ListBox6.Items)
{
Label4.Text += o.ToString() + " ";
}*/
then Label 4 properly shows each of the items in the ListBox that I want my ListBox to be showing! So, I know the ListItems are being added to the ListBox correctly; I just cannot understand why they are not showing any text in the listbox. Any ideas?? Thanks

From your code, the problem is stemming showStuff being true. You are adding items manually to your ListBox, then calling ListBox.DataBind on a non-databound list box, which will empty it's contents (since AppendDataBoundItems is not set to true). Either set the DataSource, DataValueField, and DataTextField, or stop databinding and your ListBox should function as expected.

Ok, I am going to assume this is just some weird bug that happened. To resolve this I just made a new modal popup extender, a new panel and changed the name on the listbox and the modal popup extender. Now it works just fine... Really weird but it works now.

Related

Add new data to gridview without refreshing entire gridview

I know the title might make my question look like a duplicate so please read the complete question first.
I have 3 dropdowns in my webform and based on those parameters the data is retrieved from the database and my gridview is populated. What I need is that once a result is displayed, if the user changes the parameters, the new retrieved data should be displayed below the old data. But currently my gridview is refreshing entirely and only the data based on new parameters is displayed.
I have read that one way is to use viewstate but I dont understand what it is. Can someone please help? Thank you.
Ok, so this is a difficult question. It is rather easy to filter, and have a cumulative filter.
So, say we have this screen:
And lots more rows.
So, I can say lets filter by a city.
So this:
Note how we do allow multiple city in the multi-select drop down.
So, I now have this:
Now, lets select those ONLY with a description.
So this:
And then say only active ones. So, this:
So, above is quite easy to setup. Note how any option NOT selected is left out of the critera.
but, a BIG problem exists in the above.
What happens if I want Active from say B.C. but NOT active from Alberta???
I can't do that, and hence your problem.
What we could do however is add a button to above to SAVE the resulting filter, and put the "list" of filters say into a list box or collection.
we then have a search button to search on our collection of filters.
Let me see if this can work - I'll add to above a "box" or collection of each filter.
I would think a union query with distinct row for each filter would do the trick.
So, above example is not too hard - a "cumulative" filter. In fact, the code patter for 2 or 15 filters is quite easy to do here.
However, adding up separate filter requests and combine them? That is somewhat difficult to do.
Edit: Multiple filters
so, while in above, I could say filter by city and get all active, but THEN I want to filter by another city, and get all NON active!!!
That's the problem here.
So, we would have to add code to SAVE the filter. And the HUGE problem with that is how then do we save each filter to "add up" each filter set we want?
We could try and save the raw SQL, but such SQL would be subject to sql injection, and we want to always use parameters.
So, we can and could adopt a design in which we SAVE the resulting SqlCommand object. And then merge the results.
So, now our UI becomes like this:
Lets grab and filter all those from city Edmonton, but Active,
so, this:
We now hit save filter and this:
And now we filter by say City = Banff, but don't care about active or not.
So we have this:
We then save that filter - and now we have this:
I now hit the filter button below the list of filters, and we get this:
So, how does this code work?
Well, I simple saved the Sqlcommand object to a collection (list), and thus combine the results.
So, first our markup at the top for the filter stuff.
<h4>Filters</h4>
<div style="float:left">
<asp:Label ID="Label1" runat="server" Text="Search Hotel"></asp:Label>
<br />
<asp:TextBox ID="txtHotel" runat="server"></asp:TextBox>
</div>
<div style="float:left;margin-left:20px">
<asp:Label ID="Label2" runat="server" Text="Search City"></asp:Label>
<br />
<asp:TextBox ID="txtCity" runat="server"></asp:TextBox>
</div>
<div style="float:left;margin-left:20px">
<asp:Label ID="Label3" runat="server" Text="Must Have Description"></asp:Label>
<br />
<asp:CheckBox ID="chkDescripiton" runat="server" />
</div>
<div style="float:left;margin-left:20px">
<asp:Label ID="Label4" runat="server" Text="Show only Active Hotels"></asp:Label>
<br />
<asp:CheckBox ID="chkActiveOnly" runat="server" />
</div>
<div style="float:left;margin-left:20px">
<asp:Button ID="cmdSearch" runat="server" Text="Search" CssClass="btn" OnClick="cmdSearch_Click"/>
</div>
<div style="float:left;margin-left:20px">
<asp:Button ID="cmdClear" runat="server" Text="Clear Fitler" CssClass="btn" OnClick="cmdClear_Click"/>
</div>
<div style="float:left;margin-left:20px">
<asp:Button ID="cmdTest" runat="server" Text="Save Filter"
CssClass="btn" OnClick="cmdTest_Click"
OnClientClick="return myfilterprompt()"
/>
<asp:HiddenField ID="HFilterName" runat="server" ClientIDMode="Static"/>
<script>
function myfilterprompt() {
sFilter = ""
sFilter = prompt('Enter name for filter ')
if ( (sFilter === null) || (sFilter === "") ){
return false
}
$('#HFilterName').val(sFilter)
return true
}
</script>
</div>
<div style="float:left;margin-left:30px;width:190px">
<asp:ListBox ID="lstFilters" runat="server" Width="100%" Height="100px"
DataTextField="sFilterName" >
</asp:ListBox>
<asp:Button ID="cmdMultiFilter" runat="server" Text="Filter"
CssClass="btn" OnClick="cmdMultiFilter_Click" style="float:left" />
<asp:Button ID="cmdMultiClear" runat="server" Text="Clear"
CssClass="btn" OnClick="cmdMultiClear_Click" style="float:right"/>
</div>
then below above is our grid:
<asp:GridView ID="GridView1" runat="server"
AutoGenerateColumns="False" DataKeyNames="ID"
CssClass="table" Width="60%" ShowHeaderWhenEmpty="true">
<Columns>
<asp:BoundField DataField="FirstName" HeaderText="FirstName" />
<asp:BoundField DataField="LastName" HeaderText="LastName" />
<asp:BoundField DataField="HotelName" HeaderText="HotelName" />
<asp:BoundField DataField="City" HeaderText="City" />
<asp:BoundField DataField="Province" HeaderText="Province" />
<asp:BoundField DataField="Description" HeaderText="Description" />
<asp:BoundField DataField="Active" HeaderText="Active" />
</Columns>
</asp:GridView>
So, code to load:
List<MyFilter> MyFilters = new List<MyFilter>();
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack == false)
{
SqlCommand cmdSQL = new
SqlCommand("SELECT * FROM tblHotels WHERE ID = 0");
LoadGrid(cmdSQL);
Session["MyFilters"] = MyFilters;
}
else
MyFilters = (List<MyFilter>)Session["MyFilters"];
}
public void LoadGrid(SqlCommand cmdSQL)
{
DataTable rstData = MyRstP(cmdSQL);
GridView1.DataSource = rstData;
GridView1.DataBind();
}
And now our search button:
protected void cmdSearch_Click(object sender, EventArgs e)
{
SqlCommand cmdSQL = GetMyCommand();
LoadGrid(cmdSQL);
}
SqlCommand GetMyCommand()
{
string strSQL = "SELECT * FROM tblHotels ";
string strORDER = " ORDER BY HotelName";
string strFilter = "";
SqlCommand cmdSQL = new SqlCommand();
if (txtHotel.Text != "")
{
strFilter = "(HotelName like #HotelName + '%')";
cmdSQL.Parameters.Add("#HotelName", SqlDbType.NVarChar).Value = txtHotel.Text;
}
if (txtCity.Text != "")
{
if (strFilter != "") strFilter += " AND ";
strFilter += "(City Like #City + '%') ";
cmdSQL.Parameters.Add("#City", SqlDbType.NVarChar).Value = txtCity.Text;
}
if (chkActiveOnly.Checked)
{
if (strFilter != "") strFilter += " AND ";
strFilter += "(Active = 1)";
}
if (chkDescripiton.Checked)
{
if (strFilter != "") strFilter += " AND ";
strFilter += "(Description is not null)";
}
if (strFilter != "") strSQL += " WHERE " + strFilter;
strSQL += strORDER;
cmdSQL.CommandText = strSQL;
return cmdSQL;
}
And now our save the filter button code:
protected void cmdTest_Click(object sender, EventArgs e)
{
MyFilter OneFilter = new MyFilter();
OneFilter.sFilterName = HFilterName.Value;
OneFilter.cmdSQL = GetMyCommand();
MyFilters.Add(OneFilter);
lstFilters.DataSource = MyFilters;
lstFilters.DataBind();
}
public class MyFilter
{
public string sFilterName { get; set; }
public SqlCommand cmdSQL = new SqlCommand();
}
And our multi-filter code button.
Now, for large data sets - not a great idea, but a start:
protected void cmdMultiFilter_Click(object sender, EventArgs e)
{
List<DataTable> MyTables = new List<DataTable>();
foreach (MyFilter OneFilter in MyFilters)
{
DataTable rstDT = MyRstP(OneFilter.cmdSQL);
MyTables.Add(rstDT);
}
DataTable rstData = MyTables[0];
for (int i = 1;i < MyTables.Count;i++)
{
rstData.Merge(MyTables[i]);
}
GridView1.DataSource = rstData;
GridView1.DataBind();
}
so, you can build list up of "filters" and display them in a listbox and then have a filter button that merges all of the filtering.
And one more helper routine I used:
public DataTable MyRstP(SqlCommand cmdSQL)
{
DataTable rstData = new DataTable();
using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
{
using (cmdSQL)
{
cmdSQL.Connection = conn;
conn.Open();
rstData.Load(cmdSQL.ExecuteReader());
}
}
return rstData;
}
These systems can be really nice. Often a group of managers will say, lets grab all customers from west coast. Yuk - too many. Ok, only those with purchases in last 2 months - ah, that's nice.
then they say, lets get all customers who never purchased anything, but from the south - and add those to the list - but only active on our mailing list.
So, this type of slice and dice - get some of those, and then get some of these, and then combine them?
This type of business query system and being able to combine these, and those, and them, and then toss in a few more? Often they will keep going say until such time they get say 10,000 results (which happens to be how many catalogs they have left they would like to send out).
So, I solved my problem by using a little outside the box thinking. I am posting it here for anyone visiting this question or having a same problem in the future could see this:
So what I did is that I extracted the data from the database based on the parameters selected by the user from the dropdowns. In the database, I had created a temp table to store the extracted temporarily. So I inserted the data into that temporary table and used that table to populate the gridview. I had to add a reset button, when the user clicked it the all the data is deleted from the temp table and also the page reset to its default with gridview not visible and dropdowns having no selection.

How to implement the calendar layout logic in ASP.NET and C# with MS SQL Database

I have this project at school and I have created a project with homePage, member signUp, member Login, member profile, and Admin Login pages I want to implement this layout on my homepage when the user is logged in and be able to select dates when an employee is working from home should choose a date and insert into a database for the employer to see who is working from home on this specific date or day.
Well, if we break this down?
We need a listbox on the left side to display the Employee's
So, drop in a listbox, say like this:
<div style="float:left">
<asp:ListBox ID="lstEmployee" runat="server"
DataValueField="ID"
DataTextField="EmpName" Height="270px" Width="125px"
AutoPostBack="True"
OnSelectedIndexChanged="lstEmployee_SelectedIndexChanged" >
</asp:ListBox>
</div>
And our code to load is thus this:
DateTime dtStart, dtEnd; // start and end of this month
DateTime CalStart, CalEnd; // start and end of the whole cal display
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
LoadEmployee();
LoadCal();
}
}
void LoadEmployee()
{
// load up employee listbox
SqlCommand cmdSQL = new SqlCommand(
"SELECT ID,(FirstName + ' ' + LastName) as EmpName " +
"FROM Employee ORDER BY FirstName");
lstEmployee.DataSource = MyRstP(cmdSQL);
lstEmployee.DataBind();
}
And now we have this:
Ok, now we need a calendar. Hum, ok, looking at outlook, we see that we need 6 rows of a "thing".
I think a simple Listview, and for each row (6 of them), we need a data table, with 1-7 days of data.
So, a simple list view, one row - but we spit out 6 of them.
and we want the calendar to be clickable, so each day will be a button - a LinkButton should work fine.
So, a list view could be like this:
<div style="float:left;margin-left:25px">
<asp:ListView ID="ListView1" runat="server" OnItemDataBound="ListView1_ItemDataBound1" >
<ItemTemplate>
<tr id="OneRow" runat="server">
<td>
<asp:Linkbutton ID="L1" runat="server" Text='<%# Eval("Sun", "{0:dd}") %>'
bDate = '<%# Eval("Sun") %>' OnClick="L1_Click" />
</td>
<td>
<asp:Linkbutton ID="L2" runat="server" Text='<%# Eval("Mon", "{0:dd}") %>'
bDate = '<%# Eval("Mon") %>' OnClick="L1_Click" />
</td>
<td>
<asp:Linkbutton ID="L3" runat="server" Text='<%# Eval("Tue", "{0:dd}") %>'
bDate = '<%# Eval("Tue") %>' OnClick="L1_Click" />
</td>
<td>
<asp:Linkbutton ID="L4" runat="server" Text='<%# Eval("Wed", "{0:dd}") %>'
bDate = '<%# Eval("Wed") %>' OnClick="L1_Click" />
</td>
<td>
<asp:Linkbutton ID="L5" runat="server" Text='<%# Eval("Thu", "{0:dd}") %>'
bDate = '<%# Eval("Thu") %>' OnClick="L1_Click" />
</td>
<td>
<asp:Linkbutton ID="L6" runat="server" Text='<%# Eval("Fri", "{0:dd}") %>'
bDate = '<%# Eval("Fri") %>' OnClick="L1_Click" />
</td>
<td>
<asp:Linkbutton ID="L7" runat="server" Text='<%# Eval("Sat", "{0:dd}") %>'
bDate = '<%# Eval("Sat") %>' OnClick="L1_Click" />
</td>
</tr>
</ItemTemplate>
<LayoutTemplate>
<table id="itemPlaceholderContainer" runat="server" border="0" style="">
<tr runat="server" style="">
<th runat="server" style="text-align:center" >Sun</th>
<th runat="server" style="text-align:center">Mon</th>
<th runat="server" style="text-align:center">Tue</th>
<th runat="server" style="text-align:center">Wed</th>
<th runat="server" style="text-align:center">Thr</th>
<th runat="server" style="text-align:center">Fri</th>
<th runat="server" style="text-align:center">Sat</th>
</tr>
<tr id="itemPlaceholder" runat="server"></tr>
</table>
</LayoutTemplate>
</asp:ListView>
Not a lot of markup.
Now, we need to load up the data, so we have this:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
LoadEmployee();
LoadCal();
}
}
And the code to load up the calendar? A data table of 6 rows, and 7 columns, say like this code:
void LoadCal()
{
SetupDates();
DataTable OneMonth = new DataTable();
// add heading colums to table (Sun->Sat)
for (int i = 0; i <= 6; i++)
{
DateTime d = CalStart.AddDays(i);
string strCol = d.ToString("ddd"); // gets day of week as text (sun->sat)
OneMonth.Columns.Add(new DataColumn(strCol, typeof(DateTime)));
}
DateTime dtPtr = CalStart; // start a simple date counter - upper left
// add 6 rows for calendar
for (int i = 1; i <= 6; i++)
{
DataRow OneRow = OneMonth.Rows.Add();
for (int wDay = 0; wDay <= 6; wDay++) // put date in each colum 1 - 7
{
OneRow[wDay] = dtPtr; // shove date into cal square
dtPtr = DateAndTime.DateAdd(DateInterval.Day, 1, dtPtr);
}
ListView1.DataSource = OneMonth;
ListView1.DataBind();
}
}
And we now have this:
Now, I did want to "gray" out the dates off this month, so in the Listview databound event (a great event for formatting grids or listview), then I put in this code
If the date ptr is outside of this month, we grey out the linkbutton.
so, this:
protected void ListView1_ItemDataBound1(object sender, ListViewItemEventArgs e)
{
if (e.Item.ItemType == ListViewItemType.DataItem)
{
ListViewDataItem lvRow = e.Item as ListViewDataItem;
for (int MyDay = 1; MyDay <= 7;MyDay++)
{
LinkButton LDate = lvRow.FindControl("L" + MyDay) as LinkButton;
DateTime BoxDate = Convert.ToDateTime(LDate.Attributes["bDate"]);
if ( (BoxDate < dtStart) | (BoxDate > dtEnd))
LDate.BackColor = System.Drawing.Color.LightGray;
// this sets the size for ALL squares
LDate.Attributes.Add("style", "float:right;height:70px;width:60px;text-align:right");
}
}
}
Ok, so now we have to add some code to highlight a square if this is a work at home date.
We have this data table:
So, after we load the Grid, then we click on a list view item.
That code is this:
protected void lstEmployee_SelectedIndexChanged(object sender, EventArgs e)
{
int EmployeeID = 0;
EmployeeID = Convert.ToInt32(lstEmployee.SelectedValue);
ShowOffDays(EmployeeID);
}
So, we need a routine to now display (highlight) any record in the table based on employee id and the given date.
So this:
void ShowOffDays(int EmpID)
{
SetupDates();
var cmdSQL = new SqlCommand(
"SELECT * FROM AtHome WHERE EmployeeID = #EmpID " +
"AND AtHomeDate BETWEEN #dtSTart AND #dtEnd");
cmdSQL.Parameters.Add("#EmpID", SqlDbType.Int).Value = EmpID;
cmdSQL.Parameters.Add("#dtStart", SqlDbType.Date).Value = dtStart;
cmdSQL.Parameters.Add("#dtEnd", SqlDbType.Date).Value = dtEnd;
DataTable rstAtHome = new DataTable();
rstAtHome = MyRstP(cmdSQL);
DateTime dtPtr = CalStart;
for(int i = 0;i<=5;i++)
{
ListViewItem lvRow = ListView1.Items[i];
for (int wDay = 1;wDay <= 7;wDay++)
{
if ((dtPtr >= dtStart) & (dtPtr <= dtEnd)) // only highlit this month
{
LinkButton LDate = lvRow.FindControl("L" + wDay) as LinkButton;
DataRow[] tView = rstAtHome.Select("AtHomeDate = #" + dtPtr + "#");
if (tView.Length == 0)
// no at home date
LDate.BackColor = System.Drawing.Color.White;
else
// found a date - blue the square0
LDate.BackColor = System.Drawing.Color.LightBlue;
}
dtPtr = DateAndTime.DateAdd(DateInterval.Day, 1, dtPtr);
}
}
}
Now, that was a bit of code - but not too bad.
So, now we get this:
Ok, so now we need a click event for the square. If you click a empty square, we add a single row to the table, and if already highliged, we delete it.
So, that click event can be this:
protected void L1_Click(object sender, EventArgs e)
{
LinkButton btn = sender as LinkButton;
DateTime dtDateV = Convert.ToDateTime(btn.Attributes["bDate"]);
int EmpID = Convert.ToInt32(lstEmployee.SelectedItem.Value);
DataTable rstDayOff = new DataTable();
using (var conn = new SqlConnection(Properties.Settings.Default.TEST4))
{
using (var cmdSQL = new SqlCommand(
"SELECT * FROM AtHome WHERE EmployeeID = #EmpID " +
"AND AtHomeDate = #Date", conn))
{
cmdSQL.Parameters.Add("#EmpID", SqlDbType.Int).Value = EmpID;
cmdSQL.Parameters.Add("#Date", SqlDbType.Date).Value = dtDateV;
conn.Open();
rstDayOff.Load(cmdSQL.ExecuteReader());
if (rstDayOff.Rows.Count == 0 )
{
// add this day off to table
DataRow OneDay = rstDayOff.Rows.Add();
OneDay["EmployeeID"] = EmpID;
OneDay["AtHomeDate"] = dtDateV;
btn.BackColor = System.Drawing.Color.LightBlue;
}
else
{
// delete the at home day
rstDayOff.Rows[0].Delete();
btn.BackColor = System.Drawing.Color.White;
}
SqlDataAdapter da = new SqlDataAdapter(cmdSQL);
SqlCommandBuilder daU = new SqlCommandBuilder(da);
da.Update(rstDayOff);
}
}
}
Not bad! So, now you can click to highlight, or un-highlight a day. (it toggles the given square).
So, above should give you some ideas.
And the two helper routines I used was to get a data table.
And the other to setup the dates.
These:
void SetupDates()
{
DateTime dt = DateTime.Today;
dtStart = DateAndTime.DateSerial(DateAndTime.Year(dt), DateAndTime.Month(dt), 1);
int DaysInMonth = DateTime.DaysInMonth(DateAndTime.Year(dt),DateAndTime.Month(dt));
// end of month = DaysInmonth less one
dtEnd = DateAndTime.DateAdd(DateInterval.Day, DaysInMonth - 1, dtStart);
// now with date end/start - get display start/end (subtract day of week)
CalStart = DateAndTime.DateAdd(DateInterval.Day, 1 - (DateAndTime.Weekday(dtStart)), dtStart);
CalEnd = DateAndTime.DateAdd(DateInterval.Day, 41, CalStart);
}
and
DataTable MyRstP(SqlCommand cmdSQL)
{
DataTable rstData = new DataTable();
using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
{
using (cmdSQL)
{
cmdSQL.Connection = conn;
conn.Open();
rstData.Load(cmdSQL.ExecuteReader());
}
}
return rstData;
}
So, it was a bit of code, but breaking down each part - into smaller bits and sizes? It was not really that hard.
Edit: the connection string
Well, the connection string is generally placed in the web.config file. However you can get visual studio to do that for you and it tends to be a whole lot easier.
So, from Visual studio, go project->"my project settings".
Say like this:
So, for things like maybe the welcome message, company name, perhaps to use some tax rate, or a bunch of typical settings that just about any and every applcation has?
Well, you can use the settings tab from above. so, say like this:
So, in above, I have My Cool Company name, and in code I can thus reference that setting. And note how I have multiple conneciton strings.
Using the above is nice, since if you choose to add a connection string, it not only means ONE PLACE in your whole application, but you can use the connection string builder to help you out.
Say, like this:
when you click on the [...], then you get this:
so, you get the connection wizard, and that makes setting up a connection a whole lot less hassile.
So, now in code, to get that string, you can use this:
using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
Now, at the end of the day, if you go look at web.config, you see the settings in web.config, but that can be extra work, so using the above project settings is a just a great handy place to use and place all of the many settings you will have in any typical applcation.

Searching between 2 column numbers

I want to validate in my webform i have 1 textbox and i want to search number and if the number i search is between the range of 2 numbers in my 2 column i want to show the data in the row of my table.
select * from SSPRequest where StartingSeries = '" + TxtSearch.Text + "' BETWEEN EndingSeries= '"+TxtSearch2.Text+"'"
Well, drop a grid view, and then say have this code:
protected void cmdSearch_Click(object sender, EventArgs e)
{
string strSQL = "select * from SSPRequest where StartingSeries >= #Start " +
" AND EndingSeries <= #End";
using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST3))
{
using (SqlCommand cmdSQL = new SqlCommand(strSQL, conn))
{
cmdSQL.Parameters.Add("#Start", SqlDbType.Int).Value = txtSearch.Text;
cmdSQL.Parameters.Add("#End", SqlDbType.Int).Value = txtSearch2.Text;
conn.Open();
GridView1.DataSource = cmdSQL.ExecuteReader();
GridView1.DataBind();
}
}
}
So whatever the sql matches, the grid will display. Your markup could be say this:
Enter Start Number:
<asp:TextBox ID="txtSearch" runat="server" Style="width:25px;padding-right:25px"></asp:TextBox>
Enter End Number:
<asp:TextBox ID="txtSearch2" runat="server" Style="width:25px;padding-right:25px"></asp:TextBox>
<asp:Button ID="cmdSearch" runat="server" Text="Search" style="padding-left:25px;" CssClass="btn" OnClick="cmdSearch_Click" />
<br />
<br />
<asp:GridView ID="GridView1" runat="server"></asp:GridView>
Looking at your sql posted, it seems a bit wonkey, and does not make sense. I would fire up sql studio, and hand code the sql with two range values and get the sql working, THEN AND ONLY THEN would I attempt the above code.
So FIRST get a working sql statement BEFORE YOU WRITE ONE line of code.

Hide entire datalist item based on a property

I have a datalist which is populated with values from a database. When the user clicks a checkbox, I want to loop through all of the datalist items and hide all of the items that have the property isActive = false (which is displayed as "Disabled" in a text label). The item template consists of a table that contains multiple other items, buttons etc, which have not been included below. I therefore want to hide all elements that are found under the itemtemplate of a specific item.
My idea was to just hide the entire table by accessing its id, and then setting the table's visible property to false. This is currently not doing anything when I run the code. Any help will
appreciated!
<asp:CheckBox runat="server" Text="Filter by active postings" OnCheckedChanged="filterByActive"/>
<asp:DataList ID="postingsDataList" runat="server" OnItemCommand="itemCommand" >
<ItemTemplate>
<div class="postingRow">
<table class="postingTable" id="posting">
<tr>
<td>
<asp:Label ID="lblActive" runat="server" Text=<%#Eval("isActive").ToString().Equals("True") ? "Active &#9989" : "Disabled &#10060"%>/>
</td>
</tr>
</table>
</div>
</ItemTemplate>
</asp:DataList>
Code Behind:
protected void filterByActive (object sender, EventArgs e)
{
int count = postingsDataList.Items.Count;
CheckBox check = (CheckBox)sender;
if (check.Checked == true)
{
for (int i = 0; i < count; i++)
{
Label lblActive = postingsDataList.Items[i].FindControl("lblActive") as Label;
string isActive = lblActive.Text.ToString();
if (isActive.Equals("Disabled &#10060"))
{
Table tbl = postingsDataList.Items[i].FindControl("posting") as Table;
tbl.Visible = false;
}
}
}
else
{
for (int i = 0; i < count; i++)
{
Label lblActive = postingsDataList.Items[i].FindControl("lblActive") as Label;
string isActive = lblActive.Text.ToString();
if (isActive.Equals("Active &#9989"))
{
Table tbl = postingsDataList.Items[i].FindControl("posting") as Table;
tbl.Visible = true;
}
}
}
}
}
Ok, I suggest you do this:
Persist your table - thus you don't have to hit sql server again. (but, you could - not the end of the world).
I don't have your data, but I have a simple list of hotels - and there is a Active column for the Hotel. So, lets filter the data based on checking the check box, not have to hit the database server again. And EVEN BETTER is if we un-check the box, we can display all records we had.
We assume of course this is not a lot of data.
Ok, so we have this for our markup:
(really does not matter a whole lot)
<asp:DataList ID="DataList1" runat="server" DataKeyField="ID" RepeatColumns="4" RepeatDirection="Horizontal" >
<ItemTemplate>
<div style="border-style:solid;color:black;width:300px;">
<div style="padding:5px;text-align:right">
<p>Hotel Name: <asp:TextBox ID="HotelName" runat="server" Text ='<%# Eval("HotelName") %>' /></p>
<p>First Name: <asp:TextBox ID="FirstName" runat="server" Text ='<%# Eval("FirstName") %>' /></p>
<p>Last Name: <asp:TextBox ID="LastName" runat="server" Text ='<%# Eval("LastName") %>' /></p>
<p>City: <asp:TextBox ID="City" runat="server" Text ='<%# Eval("City") %>' /></p>
<p>Province: <asp:TextBox ID="Province" runat="server" Text ='<%# Eval("Province") %>' /></p>
Active: <asp:CheckBox ID="Active" runat="server" Checked = '<%# Eval("Active") %>'/>
</div>
</div>
</ItemTemplate>
</asp:DataList>
Now, our code to load could be this:
DataTable rstData = new DataTable();
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
LoadData();
ViewState["MyData"] = rstData;
}
else
rstData = (DataTable)ViewState["MyData"];
}
void LoadData()
{
using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
{
string strSQL = "SELECT top 10 * from tblHotels ORDER BY HotelName";
using (SqlCommand cmdSQL = new SqlCommand(strSQL, conn))
{
conn.Open();
rstData.Load(cmdSQL.ExecuteReader());
DataList1.DataSource = rstData;
DataList1.DataBind();
}
}
}
And now we have this:
Now, our filter show/hide becomes JUST this:
protected void ckFilter_CheckedChanged(object sender, EventArgs e)
{
// filter based on check box
if (ckFilter.Checked)
rstData.DefaultView.RowFilter = "Active = 1";
else
rstData.DefaultView.RowFilter = "";
DataList1.DataSource = rstData;
DataList1.DataBind();
}
And BETTER is if I un-check the check box, all the data is re-displayed. And we don't have to re-hit the database to do this!!!
Now, we COULD also just hide/show each row, and then un-hide if for some reason you don't want to persist the data table as I did per above.
Checking on the box filters to this:
As noted, if I un-check the box, then I get all the data back - all without hitting the database again.
Edit:=========================================
Note that if you NOT using the above horizontal across, but just rows down?
Then you can just as well format to hide/show the rows, and you do NOT have to persist the data table.
You can apply formatting say by doing this:
protected void ckFilter_CheckedChanged(object sender, EventArgs e)
{
foreach (DataListItem gRow in DataList1.Items)
{
// get checkbox
CheckBox ckActive = (CheckBox)gRow.FindControl("Active");
// get div
HtmlGenericControl Myiv = (HtmlGenericControl)gRow.FindControl("myrow");
string MyFormat = "normal";
if (ckFilter2.Checked)
{
// only show active ones
if (ckActive.Checked)
MyFormat = "normal";
else
MyFormat = "none";
}
Myiv.Style["display"] = MyFormat;
}
}
So the above does work fine. BUT the restriction is that you can't have a set of horizontal across data items like my original screen shot
(it actually still works but in fact hide each panel with a blank space).
So, if your as noted using vertical layout (and it looks to be that you are).
Note for above, I added a simple ID to the "div", and runat server like this:
<ItemTemplate>
<div id="myrow" runat="server"
style="border-style:solid;color:black;width:300px;">
Then skip my first example. You can loop the data list rows, and hide, or un-hide. And even more amazing is that if you un-hide - then the rows all do re-appear and persist correct.
I had pulled a working example - but I was trying to figure out why I had to persist the data - the reason was the "horizontail" across settings.
But, as above shows, no real need to persist the data source table - you can process the data list rows, and hide/show each one conditionals, and you can do this without a data re-bind.

Code Not Preventing Duplicate E-mail Addresses in Database

The code I have is allowing duplicate e-mails to be added to the database. I added a line of code before allowing entry into the database to prevent duplicate e-mail addresses to be added, however with this code I am still getting duplicate e-mails. I have provided both the form code in asp.net & the c# code. Please help.
Originally I was getting an error & I debugged the code in VS & realized that I actually had the wrong specification for the email entry, that has been corrected. In the VS debugger I see values for TextBox1.Text & TextBox2.Text, i also see the e-mail address passing through the string query = the issue however is that even if the e-mail is already in the database, it still gets added again. Any improvements to fix this issue with my code? Is my logic wrong perhaps?
c# code:
protected void Button1_Click(object sender, EventArgs e)
{
OleDbConnection con = new OleDbConnection();
con.ConnectionString = ConfigurationManager.ConnectionStrings["northwind"].ToString();
con.Open();
string query = "SELECT COUNT(ID) FROM Table1 WHERE pEmail= '" + TextBox2.Text +"'";
OleDbCommand cmd = new OleDbCommand(query, con);
var count = cmd.ExecuteNonQuery();
if (count > 0)
{
Label1.Text = "email is already in use";
}
else {
cmd.CommandText = "insert into[Table1](pName, pEmail)values(#nm,#em)";
cmd.Parameters.AddWithValue("#nm", TextBox1.Text);
cmd.Parameters.AddWithValue("#em", TextBox2.Text);
cmd.Connection = con;
int a = cmd.ExecuteNonQuery();
if (a>0)
{
Label1.Text = "Inserted Sucessfully!";
}
}
}
}
Form Code:
<form id="form1" runat="server">
<div style="height: 138px">
Enter Name:<asp:TextBox ID="TextBox1" runat="server" style="margin-left: 12px"></asp:TextBox>
<asp:RequiredFieldValidator
id="reqName"
ControlToValidate="TextBox1"
Style="color:Red"
ErrorMessage="Please enter your name!"
runat="server" />
<br />
Enter Email:
<asp:TextBox ID="TextBox2" runat="server"></asp:TextBox>
<asp:RegularExpressionValidator
id="ValidEmail"
ControlToValidate="TextBox2"
Style="color:Red"
ValidationExpression="^([a-zA-Z0-9_\-\.]+)#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$"
ErrorMessage="Invalid Email Entry"
runat="server" />
<br />
<asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Submit" />
<br />
<asp:Label ID="Label1" runat="server"></asp:Label>
</div>
</form>
You should use ExecuteScalar instead of ExecuteNonQuery to get the row count
Original:
var count = cmd.ExecuteNonQuery();
Suggest to change:
var count = cmd.ExecuteScalar();
Refer to https://stackoverflow.com/a/4269651/1050927
The ExecuteNonQuery Method returns the number of row(s) affected by either an INSERT, an UPDATE or a DELETE. This method is to be used to perform DML (data manipulation language) statements as stated previously.
The ExecuteScalar Method will return a single value in the first row, first column from a SELECT statement. This method is to be used when you expect only one value from the query to be returned.
Use ExecuteScalar and Convert the result to int. I also recommend you to change the sql query concatenation to parameters, and if you are using ASP.NET Validators, you must check the property IsValid of the page as it will tell you if the controls has passed validation (remember that users can disable javascript and post the form).
protected void Button1_Click(object sender, EventArgs e)
{
if (IsValid)
{
using (var con = new OleDbConnection())
{
con.ConnectionString = ConfigurationManager.ConnectionStrings["northwind"].ToString();
con.Open();
using (var cmd = con.CreateCommand())
{
cmd.CommandText = "SELECT COUNT(ID) FROM Table1 WHERE pEmail= #em";
cmd.Parameters.AddWithValue("#em", TextBox2.Text);
int count = Convert.ToInt32(cmd.ExecutScalar());
if (count > 0)
{
Label1.Text = "email is already in use";
}
else
{
cmd.CommandText = "insert into[Table1](pName, pEmail)values(#nm, #em)";
cmd.Parameters.AddWithValue("#nm", TextBox1.Text);
// not need to add #em parameter, it was added previously
int insertedRows = cmd.ExecuteNonQuery();
if (insertedRows > 0)
{
Label1.Text = "Inserted Sucessfully!";
}
}
}
}
}
}

Categories