Im sorry if this has been asked before, but i have searched the forums for quite some time and have not been able to find a solution to my problem.
I am currently developing a web application where users are able to donate bottle deposit. When users have uploaded the bottles they will be shown in the following table:
Snippet of the table
The data is shown in a gridview with a SqlDataSource. The code:
<div class="table-responsive col-8">
<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:WeCANConnectionString %>"
SelectCommand="SELECT [creator], [amount], [details],
[imageurl], [pickup], [available_from] FROM [deposit] ORDER BY [id] DESC"></asp:SqlDataSource>
<asp:GridView id="GridView1" class="table table-hover table-striped table-bordered" runat="server" AutoGenerateColumns="False" DataSourceID="SqlDataSource1">
<Columns>
<asp:BoundField DataField="creator" HeaderText="Uploaded By" SortExpression="creator" />
<asp:BoundField DataField="amount" HeaderText="Amount" SortExpression="amount" />
<asp:BoundField DataField="details" HeaderText="Details" SortExpression="details" />
<asp:BoundField DataField="imageurl" HeaderText="Image" SortExpression="imageurl" />
<asp:BoundField DataField="pickup" HeaderText="Location of the bottles" SortExpression="pickup" />
<asp:BoundField DataField="available_from" HeaderText="Available from" SortExpression="available_from" />
</Columns>
</asp:GridView>
I would like to be able to click on each individual post and create dynamic pages where more data from the database is shown. I read somewhere that i was possible to create these page with the ID of each post but i couldnt find anything that showed how it works.
Be free to ask any follow questions. This is my first post so im not sure if i have covered everything.
Thanks a lot in advance.
One way to do this is with a link in each row. First, you need to add "id" to the SELECT in your DataSource, so the data is accessible at the time the table is bound.
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString="<%$ ConnectionStrings:WeCANConnectionString %>"
SelectCommand="SELECT [id], [creator], [amount], [details], [imageurl],
[pickup], [available_from] FROM [deposit] ORDER BY [id] DESC">
</asp:SqlDataSource>
Then in your GridView, make a template column with a HyperLink, and have the NavigateUrl of that HyperLink open a new page with the ID on the query string. If you don't want the ID to be exposed in the URL, you may need to obfuscate it in some way, or use perhaps a GUID column in the DataBase for each record. As long as you can identify it. Your NavigateUrl can be whichever page you want, but in this example I used DetailPage.aspx.
<asp:GridView id="GridView1" class="table table-hover table-striped table-bordered" runat="server" AutoGenerateColumns="False" DataSourceID="SqlDataSource1">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:HyperLink ID="DetailsLink" runat="server"
NavigateUrl="DetailPage.aspx?id=<%# Eval("id")%>"
Text="Details" Target="_blank">
</asp:HyperLink>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="creator" HeaderText="Uploaded By" SortExpression="creator" />
<asp:BoundField DataField="amount" HeaderText="Amount" SortExpression="amount" />
<asp:BoundField DataField="details" HeaderText="Details" SortExpression="details" />
<asp:BoundField DataField="imageurl" HeaderText="Image" SortExpression="imageurl" />
<asp:BoundField DataField="pickup" HeaderText="Location of the bottles" SortExpression="pickup" />
<asp:BoundField DataField="available_from" HeaderText="Available from" SortExpression="available_from" />
</Columns>
</asp:GridView>
The <## Eval('id')#> will render the ID for each row as a query string in the URL.
If I understand you well, You can use Template Field
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton Text="text" runat="server" />
</ItemTemplate>
</asp:TemplateField>
Related
I'm connecting to an access database using the AccessDataSource for a course listing. I'm primarily relying on the prebuilt controls - GridView.
<asp:GridView ID="GridView1" runat="server" AllowSorting="True" AutoGenerateColumns="False" DataSourceID="AccessDataSource1" EmptyDataText="There are no data records to display.">
<Columns>
<asp:BoundField DataField="title" HeaderText="title" SortExpression="title" />
<asp:BoundField DataField="category" HeaderText="category" SortExpression="category" />
</Columns>
</asp:GridView>
My problem is I want to filter the data based on the Category through a dropdown list. The dropdown list does not show non-distinct though.
<asp:DropDownList ID="DropDownList2" runat="server" DataSourceID="AccessDataSource1" DataTextField="category" DataValueField="category">
</asp:DropDownList>
<asp:AccessDataSource ID="AccessDataSource1" runat="server" DataFile="C:\Users\x\Documents\Visual Studio 2013\WebSites\WebSite2\courses.mdb" SelectCommand="SELECT [title], [category] FROM [mainclasslist]"></asp:AccessDataSource>
I need to be able to create a view that show this:
Couse Category1
Course 1
Course 2
Course Category 2
course 1
so etc...
Should I be using 2 datasources? The gridview should be filtered based on the dropdown. But on the initial load I need all the courses to be visible.
I have the following GridView:
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="SysInvoiceID" DataSourceID="SqlDataSource1">
<Columns>
<asp:BoundField DataField="InvoiceID" HeaderText="SysInvoiceID" ReadOnly="True" SortExpression="SysInvoiceID" />
<asp:BoundField DataField="BillMonth" HeaderText="BillMonth" SortExpression="BillMonth" />
<asp:BoundField DataField="InvoiceDate" HeaderText="InvoiceDate" ReadOnly="True" SortExpression="InvoiceDate" />
<asp:BoundField DataField="InvoiceNumber" HeaderText="InvoiceNumber" SortExpression="InvoiceNumber" />
<asp:BoundField DataField="Net" HeaderText="Net" SortExpression="Net" />
<asp:BoundField DataField="VAT" HeaderText="VAT" SortExpression="VAT" />
<asp:BoundField DataField="Gross" HeaderText="Gross" SortExpression="Gross" />
<asp:ButtonField CommandName="ViewInvoice" HeaderText=" " ShowHeader="True" Text="View" />
</Columns>
</asp:GridView>
The very last column (ButtonField) is one I created myself just to include the text 'View' on each row, which when clicked, will bring up a PDF invoice.
I'm not sure if this is even possible, but I was wondering if it was possible to add some sort of validation for that column or something, so that if the 'InvoiceID' column is blank, the 'View' link on the corresponding row won't show up.
I felt close to doing this by going on split view in Visual Studio and then the 'Edit Columns' button on GridView tasks, but like I said I'm not sure if it's possible to do it this way and may have to resort to simply coding it.
Thanks for any help!
Use a <TemplateField> instead of a <ButtonField>
<asp:TemplateField>
<ItemTemplate>
<asp:Button runat="server" Text="View"
Visible='<%# Eval("IsEmpty(InvoiceID)") %>' CommandName="ViewInvoice" />
</ItemTemplate>
</asp:TemplateField>
And add a method to your page that is IsEmpty(string id) or whatever type your id is, and just check to see if it's empty first.
You can also add a CommandArgument attribute to the Button that will let you specify what the argument to it will be.
Use a placeholder...
<asp:Placeholder runat="server" ID="plView" Visible="<%# Convert.ToBoolean(InvoiceID == null) ? false : true %>">
<asp:ButtonField CommandName="ViewInvoice" HeaderText=" " ShowHeader="True" Text="View" />
</asp:Placeholder>
I am setting up HealthMonitoring and I am writing a couple of pages to manage the event logs.
I have one page which has a GridView and another that has a DetailsView. The GridView has a template button on each row with an onClick event that loads the second page with the DetailsView on it.
What I would like to do is; when I click the template button on the GridView it then loads the second page with the DetailsView and inserts that particular record from the GridView into the DetailsView table.
The DetailsView must have paging enabled. I am stuck trying to find out which page index to load with the right record from the GridView. Currently it will just load up the first page index, then I have to click next to the record I need.
Without the paging enabled, I can read my 2 global variables and then load the correct record into the DetailsView table, but with paging enabled I'm not sure how to do it.
On the GridView page:
protected void Details1_ButtonClick(object sender, EventArgs e)
{
//I set 2 global variables here of the selected EventId and
//Details to read when the next page loads
Response.Redirect("ErrorDetails.aspx");
}
On the DetailsView page.
protected void Page_Load(object sender, EventArgs e)
{
//without paging I can set the SqlDataSource1.SelectCommand to select
//the correct record using one of the global variables
}
I have tried to use DetailsView1_PageIndexChanged, DetailsView1_Load and Page_Load to get the value in the first row, but for some reason it is allways a page behind. The variable always shows the ID of the previous page when it loads. I was going to try and keep track of the page for deleting records, but it will not work either.
This is the DataSource and DetailsView in ErrorDetails.aspx:
<asp:SqlDataSource
ID="SqlDataSource1"
runat="server"
ConnectionString="<%$ ConnectionStrings:DefaultConnection %>"
ProviderName="<%$ ConnectionStrings:DefaultConnection.ProviderName %>">
<DeleteParameters>
<asp:Parameter Name="EventId" />
</DeleteParameters>
</asp:SqlDataSource>
<asp:DetailsView ID="DetailsView1" runat="server" Height="50px" Width="125px" DataSourceID="SqlDataSource1" DataKeyNames="EventId" AutoGenerateRows="False" OnItemDeleted="DetailsView1_ItemDeleted" OnItemDeleting="DetailsView1_ItemDeleting" AllowPaging="True" OnLoad="DetailsView1_Load" OnPageIndexChanged="DetailsView1_PageIndexChanged" OnPageIndexChanging="DetailsView1_PageIndexChanging">
<AlternatingRowStyle CssClass="alt" />
<Fields>
<asp:CommandField ShowDeleteButton="True" />
<asp:BoundField DataField="EventId" HeaderText="EventId" />
<asp:BoundField DataField="EventTimeUtc" HeaderText="EventTimeUtc" />
<asp:BoundField DataField="EventTime" HeaderText="EventTime" />
<asp:BoundField DataField="EventType" HeaderText="EventType" />
<asp:BoundField DataField="EventSequence" HeaderText="EventSequence" />
<asp:BoundField DataField="EventOccurrence" HeaderText="EventOccurrence" />
<asp:BoundField DataField="EventCode" HeaderText="EventCode" />
<asp:BoundField DataField="EventDetailCode" HeaderText="EventDetailCode" />
<asp:BoundField DataField="Message" HeaderText="Message" />
<asp:BoundField DataField="ApplicationPath" HeaderText="ApplicationPath" />
<asp:BoundField DataField="ApplicationVirtualPath" HeaderText="ApplicationVirtualPath" />
<asp:BoundField DataField="MachineName" HeaderText="MachineName" />
<asp:BoundField DataField="RequestUrl" HeaderText="RequestUrl" />
<asp:BoundField DataField="ExceptionType" HeaderText="ExceptionType" />
<asp:TemplateField HeaderText="Details">
<ItemTemplate>
<asp:Label ID="Label1" runat="server">
<%= EventVariables.EventDetails %>
</asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:CommandField ShowDeleteButton="True" />
</Fields>
<PagerSettings Mode="NextPreviousFirstLast" />
<PagerStyle CssClass="pager" />
</asp:DetailsView>
This is the DataSource and GirdView from the parent form:
<asp:GridView
ID="ErrorGrid"
runat="server"
AutoGenerateColumns="False"
DataSourceID="SqlDataSource1"
DataKeyNames="EventId"
OnRowDeleting="ErrorGrid_RowDeleting"
AllowPaging="True"
AllowSorting="True"
Font-Size="Small"
CellPadding="10"
CellSpacing="1" >
<Columns>
<asp:TemplateField ShowHeader="False">
<ItemTemplate>
<asp:LinkButton ID="LinkButton1" runat="server" CausesValidation="False" CommandName="Delete" OnClientClick="return confirm('Are you sure you want to delete this record?');" Text="Delete"></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField ShowHeader="False">
<ItemTemplate>
<asp:LinkButton ID="Details1" Text="Details" runat="server" AutoPostBack="true" OnClick="Details1_ButtonClick" />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="EventId" HeaderText="EventId" SortExpression="EventId" />
<asp:BoundField DataField="EventTime" HeaderText="EventTime" SortExpression="EventTime" />
<asp:BoundField DataField="RequestUrl" HeaderText="RequestUrl" SortExpression="RequestUrl" />
<asp:BoundField DataField="ExceptionType" HeaderText="ExceptionType" SortExpression="ExceptionType" />
</Columns>
</asp:GridView>
<asp:SqlDataSource
ID="SqlDataSource1"
runat="server"
ConnectionString="<%$ ConnectionStrings:DefaultConnection %>"
SelectCommand="SELECT * FROM [aspnet_WebEvent_Events]"
DeleteCommand="DELETE FROM [aspnet_WebEvent_Events] WHERE [EventId]=#EventId">
<DeleteParameters>
<asp:Parameter Name="EventId" />
</DeleteParameters>
</asp:SqlDataSource>
I managed to solve this by doing a calculation. As there is 10 rows per page in the GridView I'm able to calculate the page by doing this:
EventVariables.EventPage = ((((ErrorGrid.PageIndex + 1) * 10) - 10) + Row.RowIndex);
And then loading the page in the DetailsView from the variable when it loads.
Well it so happens that I am kind of a novice to asp.net and trying to create a Grid whose source is declared programmatically.
In the process, I came across 2 tags Fields and Columns. Can anyone please tell me how they are different?
EDIT: I went through some sample MSDN examples, and for all I can tell it seems to me they can be used interchangeably(though I have a feeling thats not true!).
Check this out:
<asp:GridView ID="GridView1" runat="server"
AutoGenerateColumns="False" DataKeyNames="EmployeeID" DataSourceID="ObjectDataSource1">
<Columns>
<asp:BoundField DataField="LastName" HeaderText="LastName"
SortExpression="LastName" />
<asp:BoundField DataField="FirstName" HeaderText="FirstName"
SortExpression="FirstName" />
<asp:BoundField DataField="Title" HeaderText="Title"
SortExpression="Title" />
<asp:BoundField DataField="HireDate" HeaderText="HireDate"
SortExpression="HireDate" />
</Columns>
</asp:GridView>
And then there is:
<asp:GridView ID="GridView1" runat="server" AllowPaging="True"
AutoGenerateRows="False" DataKeyNames="ProductID"
DataSourceID="ObjectDataSource1" EnableViewState="False">
<Fields>
<asp:BoundField DataField="ProductName" HeaderText="Product"
SortExpression="ProductName" />
<asp:BoundField DataField="CategoryName"
HeaderText="Category"
ReadOnly="True" SortExpression="CategoryName" />
<asp:BoundField DataField="SupplierName"
HeaderText="Supplier"
ReadOnly="True" SortExpression="SupplierName" />
<asp:BoundField DataField="QuantityPerUnit"
HeaderText="Qty/Unit" SortExpression="QuantityPerUnit" />
<asp:BoundField DataField="UnitPrice"
DataFormatString="{0:c}"
HeaderText="Price"
HtmlEncode="False" SortExpression="UnitPrice" />
</Fields>
</asp:GridView>
Seem similar or is it just me??!
Thanks for helping.
Columns is just the surrounding tag for the fields which are
TemplateFields with any controls you want or
BoundFields which are created automatically
So Columns enclose the list of fields in the GridView.
<Columns>
<asp:Boundfield datafield="StudentID"
readonly="true"
headertext="Student ID"/>
<asp:TemplateField HeaderText="Student" HeaderStyle-HorizontalAlign="Left">
<ItemTemplate>
<asp:label runat="server" Font-Bold="true" ID="LblStudent" Text='<%# Bind("Student") %>'></asp:label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Inner Grid">
<ItemTemplate>
<asp:GridView ID="Grid2" AutoGenerateColumns="false" runat="server" GridLines="None" Width="300">
<RowStyle CssClass="GridViewRowStyle" />
<AlternatingRowStyle CssClass="GridViewAlternatingRowStyle" />
<HeaderStyle CssClass="GridViewHeaderStyle" />
<SelectedRowStyle BackColor="Aqua" />
<Columns>
<asp:TemplateField HeaderText="Student" HeaderStyle-HorizontalAlign="Left">
<ItemTemplate>
<asp:label runat="server" Font-Bold="true" ID="LblStudent" Text='<%# Bind("Student") %>'></asp:label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</ItemTemplate>
</asp:TemplateField>
</Columns>
As you can see, a TemplateField could also contain another nested GridView.
Am I blind or wat!
After I posted this question I went back to my drawingboard and as it turns out, there is no Fields tag in asp:GridView, right?!
Please do let me know if this is true people(and prove me silly!)
Putting aside this particular control for a moment, it might be helpful to look at this from a general computer science point of view.
In classic programming (ANY LANGUAGE), a FIELD would be the INTERSECTION of a row and a column -- a discrete piece of data. For example, if a table has 20 rows of data containing first and last names, if you went to the 19th row and looked in the "first name" column, you've got a FIELD. Perhaps it contains the discrete data "JOHN".
COLUMNS then would be collections of like data -- in this example, you have the two columns "first name" and "last name". Columns would have attributes such as a data type, maximum length, constraints (are nulls OK?, etc.) and so forth.
Some may quibble with my definitions and say that individual cells in a COLUMN would be called a FIELD. It's not uncommon to hear that. I would reply that for a table with a single column, it'd be especially true :-) But the takeaway point is this: COLUMNS are generally containers for smaller, more discrete items such as FIELDS. FIELDS typically refer to a single piece of data, such as you'd find at the intersection of a row and column in a database table.
I want here that user can see the answer under the question by selecting its heading. The question should be a hyperlink to redirect me on the page Answer.aspx. I mean to say that when user take cursor over the How to do this? it should redirect the user to the desired page. How can I do that?
here is the code
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataSourceID="SqlDataSource1" Width="100%" BorderStyle="None">
<Columns>
<asp:BoundField DataField="QuestionHEAD" HeaderText="Question"
SortExpression="QuestionHEAD" HeaderStyle-ForeColor="white" HeaderStyle-BackColor="Brown"/>
<asp:BoundField DataField="Problem" HeaderText="Problem"
SortExpression="Problem" HeaderStyle-ForeColor="white" HeaderStyle-BackColor="Brown" />
<asp:BoundField DataField="Forum" HeaderText="Forum" SortExpression="Forum" HeaderStyle-ForeColor="white" HeaderStyle-BackColor="Brown"/>
<asp:BoundField DataField="Username" HeaderText="Asked By"
SortExpression="Username" HeaderStyle-ForeColor="white" HeaderStyle-BackColor="Brown" />
</Columns>
</asp:GridView>
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString="<%$ ConnectionStrings:connectionstring %>"
SelectCommand="SELECT [QuestionHEAD], [Problem], [Forum], [Username] FROM [Question]">
</asp:SqlDataSource>
You can use a HyperLinkField for this:
<asp:HyperLinkField DataNavigateUrlFormatString="/somepage.aspx?a={0}&b={1}" DataNavigateUrlFields="Column1, Column2" />
Try something like this
Eval("id") should be the question id and Eval("Question") should be the question field in your database
<asp:TemplateField HeaderText="Question" HeaderStyle-HorizontalAlign="Center" ItemStyle-HorizontalAlign="Center">
<ItemTemplate>
<%#Eval("Question")%>
</ItemTemplate>
</asp:TemplateField>