I have written a code for button click that should retrieve data from the database and display the data row wise as required. It is working Fine for the first two clicks and it is not firing for the third time... I really don't understand why Please any help.
thank you in advance
The button code
protected void NextButton_Click(object sender, EventArgs e)
{
c++; //integer created to iterate through rows of datatable
qno++; //just counts the rows begining from 1 and displays on page
SqlCommand lque = new SqlCommand("select * from questions where course='" + cour + "' and [group]='" + gr + "' and semester='" + sem + "'", con);
IDataReader rque = lque.ExecuteReader();
if (rque.Read())
{
DataTable dt = new DataTable();
dt.Load(rque);
QuestionNo.Text = Convert.ToString(qno);
Question.Text = dt.Rows[c].Field<string>(4);// only displaying the required columns.
RadioButton1.Text = dt.Rows[c].Field<string>(5);
RadioButton2.Text = dt.Rows[c].Field<string>(6);
RadioButton3.Text = dt.Rows[c].Field<string>(7);
RadioButton4.Text = dt.Rows[c].Field<string>(8);
}
}
source code for the button
<asp:Button ID="NextButton" runat="server" Text="Next" Width="111px" OnClick="NextButton_Click" />
i also checked the data is loaded without any errors into the datatable by passing the datatable as a source to the gridview, it shows all the rows in gridview but in the labels the first 2 rows only displaying. I also chekced the counting varible is only increasing 2 times.enter image description here
a few rows from the table that i am retrieving
Your variables(c for example) will be reset to 0 on every request(button-click). Http is stateless. So you need to persist this value somewhere else(i.e. Session, ViewState, Hiddenfield, etc).
For example with Session, which you should only use if this site has not too much traffic:
private int CurrentRowIndex
{
get
{
if (Session["CurrentRowIndex"] == null)
Session["CurrentRowIndex"] = 0;
return (int)Session["CurrentRowIndex"];
}
set => Session["CurrentRowIndex"] = value;
}
protected void NextButton_Click(object sender, EventArgs e)
{
int currentRowIndex = ++CurrentRowIndex;
// maybe you need this also for your other variables
// ...
}
You should also not read all rows if you only want one, you should modify your sql query. If you use MS SQL-Server you could use ROW_NUMBER function to select only the required row from DB.
Related
I am currently trying to create a website that dynamically displays items when a certain Make, Model, Year is chosen using dropdown lists. The item information was retrieved using web crawling which utilized the HtmlAgilityPack.
So I currently have a database table that is full of thousands of items which contain the columns: id, Make, Model, Year, PartCategory, PartUrl, ImageUrl, PartBrand, PartName, PartPrice.
What I'm attempting to do is separate each site into divs so the user can easily tell which site the item they are looking at is from. Example:
<div id="siteOne">
<table>
<tr>
<td>
<img url="ImageUrl">
PartBrand & PartName & PartPrice
</td>
</tr>
<tr>
<td>
<img url="ImageUrl">
PartBrand & PartName & PartPrice
</td>
</tr>
</table>
</div>
<div id="siteTwo">
.............
</div>
<div id=""siteThree>
.............
</div>
I am currently only using three sites total, and I can easily pull the data into a DataTable and then see how many rows were returned, so that number will be how many dynamic instances I need to create. I'm pretty sure Jquery can handle this job, however I cannot find any examples of people using a DataTable's DataRows to control the dynamic part, usually it is with a button event or something of the sort.
I imagine the code will look something like this:
//this foreach statement will be in the last dropdown list's SelectedIndexChanged event
//when the last dropdown is chosen, a datatable will be returned with all the items that match that particular make/model/year
foreach (DataRow tempRow in tempDataTable)
{
//this should pull data from each column one at a time
//column: 0 = id, 1 = Make, 2 = Model, 3 = Year, don't think I'll need these right now
string partCategory = tempRow[4].ToString();
string partUrl = tempRow[5].ToString();
string imageUrl = tempRow[6].ToString();
string partBrand = tempRow[7].ToString();
string partName = tempRow[8].ToString();
string partPrice = tempRow[9].ToString();
//this is where the jquery would generate the dynamic elements in the table.
//three main divs can be hard coded for now, only using 3 sites currently
//this means the <table></table> in each will most likely be hard coded as well
//the <tr></tr>, <td></td>, <img>, and <a></a> will need to be generated dynamically each loop iteration
}
I've been working on this one step for a while so I figured I would post to see if anyone had any tips or similar examples while I continue to try and solve it myself. Anything would be greatly appreciated. Cheers!
I figured it out, and its quite easy.
heres how my function is setup
protected void drpdwnYear_SelectedIndexChanged(object sender, EventArgs e)
{
//get the data for the specific make/model/year from the database
DataTable dt = new DataTable();
string tempYear = drpdwnYear.SelectedItem.ToString();
string tempManufacturer = Globals.myManufacturer;
string tempModel = Globals.myModel;
Globals.myQuery = "SELECT * FROM CrawlerInfo WHERE Model = '" + tempModel + "' AND Year ='" + tempYear + "'";
try
{
using (SqlConnection con = new SqlConnection(Globals.myConStr))
{
using (SqlCommand cmd = new SqlCommand(Globals.myQuery, con))
{
using (SqlDataAdapter da = new SqlDataAdapter(cmd))
{
da.Fill(dt);
}
}
}
}
catch (Exception ex)
{
handleTheError(ex);
}
//put the data into HTML elements
try
{
int tempflag = 0;
foreach (DataRow tempRow in dt.Rows)
{
string tempCategory = tempRow[4].ToString();
string tempPartUrl = tempRow[5].ToString();
string tempImageUrl = tempRow[6].ToString();
string tempPartBrand = tempRow[7].ToString();
string tempPartName = tempRow[8].ToString();
string tempPrice = tempRow[9].ToString();
string tempStoreName = tempRow[10].ToString();
Image tpImg = new Image();
tpImg.ID = "id_img_" + tempflag;
tpImg.ImageUrl = tempImageUrl;
Page.Controls.Add(tpImg);
HyperLink hyp = new HyperLink();
hyp.ID = "id_link_" + tempflag;
hyp.NavigateUrl = tempPartUrl;
hyp.Text = tempPartBrand + " " + tempPartName + ": " + tempPrice + "\n\n";
Page.Controls.Add(hyp);
tempflag++;
}
}
catch (Exception ex)
{
handleTheError(ex);
}
}
and here hows it displays currently, I just need to figure out how to put them into <div>s so I can style them.
Currently, I have a working code that selects and transfers gridview row data in a textbox. Here's the code
protected void grdRP_SelectedIndexChanged(object sender, EventArgs e)
{
GridViewRow row = grdLocation.SelectedRow;
hdnSearchedLoc.Value = grdLocation.Rows[grdLocation.SelectedIndex].Cells[1].Text;
txtSearchedLoc.Text = HttpUtility.HtmlDecode(row.Cells[2].Text);
}
It works well functionality and performance (speed) wise when it is local. I have seen the difference in speed when I upload it to the web server. it takes 5 seconds and more before it transfer the row data to textbox.
Now, I am thinking of alternative way to make it faster by using javascript since it is on client-side. I have seen a sample code but it is only on selection method but the transfer of row data is still the same speed. Here's the code
javascript
function setMouseOverColor(element)
{
oldgridSelectedColor = element.style.backgroundColor;
element.style.backgroundColor='#C0C0C0';
element.style.cursor='hand';
//element.style.textDecoration='underline';
}
function setMouseOutColor(element)
{
element.style.backgroundColor=oldgridSelectedColor;
element.style.textDecoration='none';
}
aspx.cs
protected void grdRP_RowDataBound(object sender, GridViewRowEventArgs e)
{
e.Row.Cells[0].Style["display"] = "none";
if (e.Row.RowType == DataControlRowType.DataRow)
{
e.Row.Attributes["onmouseover"] =
"javascript:setMouseOverColor(this);";
e.Row.Attributes["onmouseout"] =
"javascript:setMouseOutColor(this);";
e.Row.Attributes["onclick"] =
Page.ClientScript.GetPostBackClientHyperlink
(this.grdRP, "Select$" + e.Row.RowIndex);
}
}
is there other javascript way of doing that?
I have a grid view that I want to use with JavaScript to calculate values entered in the textboxes.
I was adding onkeyup to the textboxes in the onrowcreated function and it was working fine.
Then I put the gridview in a multiview, and it stopped working.
This is my JavaScript function:
function margin1(rowIndex, price, gridId) {
var grid = document.getElementById(gridId);
var volumeQuota = grid.rows[rowIndex].cells[2].innerText;
alert(volumeQuota);
var coef = grid.rows[rowIndex].cells[5].childNodes.item(1).value;
alert(coef);
var prevSites = grid.rows[rowIndex].cells[4].innerText;;
grid.rows[rowIndex].cells[6].childNodes.item(1).value = parseFloat(coef) * (parseFloat(volumeQuota) - parseFloat(prevSites));
grid.rows[rowIndex].cells[7].childNodes.item(1).value = price;
}
and in the code behind this is how im adding it.
if (e.Row.RowType == DataControlRowType.DataRow)
{
TextBox t1 = (TextBox)e.Row.FindControl("p98Margin1");
t1.Attributes.Add("onkeyup",
string.Format("javascript:margin1('{0}', {1}, {2})", e.Row.RowIndex + 2, a98.Text , GridView1.ClientID));
when I alert Gridview1.clientId in the JavaScript function I'm getting [objectHTMLTableElement]
use this
t1.Attributes.Add("onkeyup",
string.Format("javascript:margin1('{0}', '{1}', '{2})'", e.Row.RowIndex + 2, a98.Text , GridView1.ClientID));
I think this should work.
I think the value should go in single quotes ' mark.
Like you said you put your grid in a multiview and everything stopped working,which means your gridview has been buried and you need to drill down a bit further to expose it.
Do this
GridView myGridView=(GridView)(MultiView1.FindControl("GridView1"));
Now you have located it gracefully reference its ID
if (e.Row.RowType == DataControlRowType.DataRow)
{
TextBox t1 = (TextBox)e.Row.FindControl("p98Margin1");
t1.Attributes.Add("onkeyup",
string.Format("javascript:margin1('{0}', {1}, {2})", e.Row.RowIndex + 2, a98.Text ,myGridView.ClientID));
}
Hope this helps.
I have a ListBox that contains all the online users.
The users are loaded from a MySQL database and loaded into the ListBox every second.
When I add an Item to the ListBox the ListBox scrolls up, I do not want this to happen.
<asp:UpdatePanel ID="usersPanel" UpdateMode="Conditional" runat="server">
<ContentTemplate>
<asp:ListBox ID="lstUsers" runat="server" ViewStateMode="Enabled" AutoPostBack="True"></asp:ListBox>
<asp:Timer ID="mainTimer" runat="server" ontick="Timer1_Tick" Interval="1000"></asp:Timer>
</ContentTemplate>
</asp:UpdatePanel>
Timer Code:
protected void Timer1_Tick(object sender, EventArgs e)
{
...
MySqlDataReader datareader = command.ExecuteReader();
if (datareader.HasRows) {
lstUsers.Items.Clear();
while (datareader.Read()) {
lstUsers.Items.Add(new ListItem(datareader.GetString(1), datareader.GetInt32(0).ToString()));}
}
}
I've tried to do it with javascript but I was unable to get/set the scrollbar position on the listbox
What is done here is to save the current selected on list on client side, and set it back after the panel have been updated with the new values.
<script type="text/javascript" language="javascript" >
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_beginRequest(beighnloadinf);
prm.add_endRequest(EndRequest);
var selected = "";
//get selected index and store in variable
function beighnloadinf() {
var sel = document.getElementbyId('<%=lstUsers.ClientID%>');
var listLength = sel.options.length;
for(var i=0;i<listLength;i++){
if(sel.options[i].selected){
selected =sel.options[i].value;
break;
}
}
}
// set selected index back afrer update finished
function EndRequest(sender, args) {
var sel = document.getElementbyId('<%=lstUsers.ClientID%>');
sel.value = selected;
}
</script>
You can do the same thing and on code behind, you get the selected one, and place it after the new update of your list.
You shouldn't be clearing the control every second. This is your problem:
lstUsers.Items.Clear();
Simplest solution would be to compare you ListBox items with your data source using the Except method on IEnumerable.
You'll have to convert your data source to IEnumerable manually. See this post as to how to do that.
NOTE: You'll have to change the type for the extension method.
After that, you can loop through your difference set (the returned object for .Except()) and add them to your list box like this:
lstUsers.Items.Add("a new list item");
I have a webservice that gets a ProductName and I need the Products that are dropped down from the AutoExtender to be links to each product's individual page.
Right now the URL gets filled with the ProductName, and not the ID:
Default.aspx?id=Test%20Product
needs to be
Default.aspx?id=519
*Note - this site is for internal use only, so we are not worried about getting hacked right now. We want the site to work.
I have been told that what I want to do is not possible by people on the forum for asp.net so I came here hoping for some help. I think it is the javascript that is getting the ProductName from the webservice, and I need it to get the ProductID. I tried rewriting the For Each loop to include ProductID instead of ProductName, but then the AutoCompleteExtender only shows IDs in the results instead of the ProductNames.
Javascript:
<script type="text/javascript">
function AutoCompleteClientMethod(source, eventArgs) {
var value = eventArgs.get_value();
window.location = ("/Product/Default.aspx?id=" + value)
}
</script>
Here is the code for my autoCompleteExtender and the webservice:
<asp:TextBox ID="Search" runat="server" AutoComplete="off"></asp:TextBox>
<asp:AutoCompleteExtender ID="AutoCompleteExtender1" runat="server" TargetControlID="Search" ServicePath="~/ProductSearch.asmx" ServiceMethod="GetProducts" MinimumPrefixLength="1" CompletionSetCount="120" EnableCaching="true" OnClientItemSelected="AutoCompleteClientMethod">
</asp:AutoCompleteExtender>
' To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
<System.Web.Script.Services.ScriptService()> _
<WebService(Namespace:="http://tempuri.org/")> _
<WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1)> _
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Public Class ProductSearch
Inherits System.Web.Services.WebService
<WebMethod()> _
Public Function GetProducts(ByVal prefixText As String, ByVal count As Integer) As String()
Dim ProductSql As String = "Select DISTINCT ProductID, ProductName FROM Product WHERE ProductName LIKE '%" & prefixText & "%' ORDER BY ProductName ASC"
Dim sqlConn As New SqlConnection
sqlConn.Open()
Dim myCommand As New SqlCommand(ProductSql, sqlConn)
Dim myReader As SqlDataReader = myCommand.ExecuteReader()
Dim myTable As New DataTable
myTable.TableName = "ProductSearch"
myTable.Load(myReader)
sqlConn.Close()
Dim items As String() = New String(myTable.Rows.Count - 1) {}
Dim i As Integer = 0
For Each dr As DataRow In myTable.Rows
items.SetValue(dr("ProductName").ToString(), i)
i += 1
Next
Return items
End Function
End Class
Edit: Adding the way the search results used to show up before the switch to the AutoCompleteExtender. I have tried to incorporate this into what I have now, but I can't get anything to work right. Please note that this is the OLD code, what is above is all the code I am using NOW.
<div class="hiddenResults">
<ul id="hiddenResults" style="display:none;">
<asp:ListView ID="lvProducts" runat="server" DataSourceID="dsProducts">
<ItemTemplate>
<li><span class="title"><%# eval("ProductName") %></span></li>
</ItemTemplate>
</asp:ListView>
</ul>
</div>
I tried
<ul style="list-style:none;"><li><a href='/Product/Default.aspx?id=<%# eval("ProductID") %>'>
<asp:AutoCompleteExtender ID="AutoCompleteExtender1" runat="server" TargetControlID="Search" ServicePath="~/ProductSearch.asmx" ServiceMethod="GetProducts" MinimumPrefixLength="1" CompletionSetCount="120" EnableCaching="true" OnClientItemSelected="AutoCompleteClientMethod">
</asp:AutoCompleteExtender></a></li></ul>
but having the autocomplete extender in a list keeps the results of the query from showing.
Edit: Working code:
For Each dr As DataRow In myTable.Rows
Dim id As String = dr("ProductID").ToString()
Dim name As String = dr("ProductName").ToString()
Dim item As String = AjaxControlToolkit.AutoCompleteExtender.CreateAutoCompleteItem(name, id)
items.SetValue(item, i)
i += 1
Next
See this article, or this one.
In short, create your list items using CreateAutoCompleteItem(). Modify the loop in GetProducts to use CreateAutoCompleteItem():
For Each dr As DataRow In myTable.Rows
dim id as String = dr("ProductId").ToString()
dim name as String = dr("ProductName").ToString()
dim item as String = AutoCompleteExtender.CreateAutoCompleteItem(name, id)
items.SetValue(item, i)
i += 1
Next
That sends both the name and the id to the client. That step is crucial. (If there are syntax errors above, forgive me... It's been a long time since I coded much VB - mostly C# these days.)
Then modify your OnClientItemSelected handler to use get_key() instead of get_value() for the url:
function AutoCompleteClientMethod(source, eventArgs) {
var value = eventArgs.get_key();
window.location = ("/Product/Default.aspx?id=" + value)
}
You need to wrap the href in single quotes, like this:
<a href='/Product/Default.aspx?id=<%# eval("ProductID") %>'>
Now, what are you trying to do with the autocomplete extender? Are you trying to load the results with JavaScript?