A few questions about gridviews - asp.net

I need to have a grid on one of my webpages that will be used to enter budget information. I was planning on using a gridview, but I am open to other ideas if something else will fit my needs better. I need the following functionality in my grid:
All cells are in edit mode as soon as the page loads
Need a footer row at the bottom to
calculate totals for particular columns
I looked around for this functionality in the gridview for a bit but didn't have any luck. Any links or suggestions on how to do the two items above in a gridview would be greatly appreciated.
NOTE: I'm using Visual Studio 2008

IMO you are going to be much better off coding this yourself using a ListView. You can look into the DataBound() and ItemDataBound() events. The GridView does not come with the functionality built in.
OTOH, Matt Dotson has a blog post describing how to build a GridView with all rows in edit mode.

Totals in the footer can be applied using a combination of javascript executed on each data change and form load AND dynamically adding textboxes or labels to the footer via the GridView's RowDataBound event. For example,
// Create textboxes in footer to hold hours totals
if (e.Row.RowType == DataControlRowType.Footer)
{
e.Row.CssClass = "wgv-ft";
for (int i = 0; i < NumHoursTextBoxes; ++i)
{
var tb = new TextBox();
tb.ID = String.Format("Hours{0}TotalTextBox", i);
tb.CssClass = "total";
tb.Enabled = false;
e.Row.Cells[FirstHoursTextBoxIndex + i].Controls.Add(tb);
}
}
Rather than using the built-in edit functionality (EditItemTemplates) which the GridView offers, you might want to just use the ItemTemplates and always show an editable textboxes or other controls. I've used this technique. You can still take advantage of validators and the core ASP.NET control set, but you do have to write quite a bit of javascript to manage updates to the totals.
I hope this helps. Best of luck.

Related

Linking HTML Table with sql database

I am new to html tables in vb.net.
i have an html table with all functionality i need (Expanding and collapsing row on click etc) ,how can i link that table with sql database.
I can show database details in grid view..
But My table have functions such as on click of row ,the row having 4 fields must expand down with 10 text boxes (other than shown on row) must be displayed together with few buttons.Hence i used javascript for expand/collapse row
As told how can i make the rendered grid view row clickable and expandable
You will want to use an asp.net control called a GridView. When rendered, it becomes an HTML table. It can then be manipulated by CSS and Javascript.
http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.gridview.aspx
GridView not being an option, try using a Literal:
<asp:Literal ID="LiteralTable" runat="server"></asp:Literal>
Codebehind:
StringBuilder sb = new StringBuilder();
sb.Append("<table>");
for (int i = 1; i < 15; i++)
{
sb.Append("<tr class=\"clickable\"><td>" + FirstColumn[i] + "</td>" + "<td>" + SecondColumn[i] + "</td></tr>");
sb.Append("<tr class=\"expandable\"><td>Edit</td>" + "<td>More Info</td></tr>");
}
sb.Append("</table>");
LiteralTable.Text = sb.ToString();
And then work your javascript (or jquery) magic:
$(".clickable").click().next().show();
And in this case just load your database into the array before calling the stringbuilder!
If you are using ASP.NET WebForms, it's actually really easy to make GridView to suit your needs.
You can either use Visual Studio's built-in toolkit, and just drag to your WebForm, set your SQLDataSource, and set to selectable, and then to editable. I think VS 2010 and up have a quick code generated one by using toolkit, but here's what the code might look like:
<asp:GridView ID="gvPreview" runat="server" CssClass="gvPreview" AutoGenerateEditButton="true">
</asp:GridView>
I don't have SQL on my machine at the moment so I can't use the GUI Wizard exactly to show you what it would look like, but I can.

ASP.NET treeview performance issue with IE7,8

I am using treeview in my asp.net application which have 2000 nodes in it. The treeview takes 40 sec to load on IE7,8 while same page takes 1/10th time on Firefox and chrome. Is there any solution to this problem. Tried searching for this but found only unanswered questions. If this is a limitation of IE 7,8 then what is the reason for it. Is it because of the rendering engine. Is there any solution to the problem ? I mean i tried using the jquery treeview but again it hangs the IE and alert popups up for slow script.
Please help.
Have you tried this jQuery plugin? http://www.jstree.com/
It supports AJAX loading, which is great for a 2000 node tree.
When you open the rendered html generated from the tree view, you will find that the control generate a hell of html table, tr and td which I think is taking a very long time to be rendered on IE so I suggest that you create a new custom web control that inhertis from the treeview control and update the "Render Method" to write Div's instead of HTML and this will require a professional developer and HTML designer to do this.
I think you can after that share this new control with the community and we can enhance on it with you to get rid of this dummy asp.net gridview.
There must be something else going on. I did some performance testing on TreeView and was able to render a complex tree structure containing 5000 nodes in far less time then 40 seconds. A 2000 node complex tree rendered in about 3 seconds in IE8. If you can provide some more details about your tree maybe I can provide more assistance.
I've read that the amount of rendered HTML is one of the biggest factors when it comes to rendering time on a big tree. Even simple things such as reducing the length of a URL string by shortening a page name (if your nodes link directly to pages) or replacing CSS classes with more advanced style sheet usage techniques can make it considerably faster.
Below is my code for generating a random complex tree of _nodeCount size:
ASPX Page has a TreeView named tv:
<asp:TreeView ID="tv" runat="server"></asp:TreeView>
Code Behind looks like the following:
private Random _rand = new Random();
private int _nodeCount = 2000;
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
//create a big tree
var itemCount = 0;
while (itemCount < _nodeCount)
{
//create a parent item
var n = new TreeNode("Node " + itemCount.ToString(), itemCount.ToString());
itemCount++;
tv.Nodes.Add(n);
CreateSubItem(n, ref itemCount);
}
}
}
protected void CreateSubItem(TreeNode parent, ref int itemCount)
{
//chance that we won't create a sub item
if (_rand.Next(2) == 1 || itemCount > _nodeCount)
{
return;
}
var n = new TreeNode("Child Node " + itemCount.ToString(), itemCount.ToString());
itemCount++;
parent.ChildNodes.Add(n);
CreateSubItem(n, ref itemCount);
CreateSubItem(parent, ref itemCount);
}
Update 7/20
Perhaps you could take the logic in your javascript for setting icons and move it into .NET code, this should greatly reduce the page load time. This page, http://weblogs.asp.net/dannychen/archive/2006/01/25/436454.aspx, shows how to customize the rendering of a TreeNode; maybe it could be a good starting place for you.
It is always good to use AJAX in your application and load the treeview dynamically via AJAX. Here is a link...
http://www.codeproject.com/KB/ajax/selfloadelement.aspx
Setting the attribute HoverNodeStyle-CssClass="nh" makes the rendering of the TreeView slow in IE9. I removed the attribute and the performance restored.

Dynamic data population like stackoverflow comments?

I'm trying to create a comment system just like SO has, but first, I'd like to show first 5 comments for a post and show rest if "display all comments" is clicked for the desired reply.
What is the best way of doing this? I really couldn't found a good way for doing what I want. I must be missing something.
For info, comments datasource is a nested repeater in my page. The outer repeater is replies and inner repeater is comments. Currently I'm binding all comments for all results (even if it has 10000 replies.). Also, I don't want to do paging for comments. I just want it to work the same way as SO.
Any ideas?
EDIT: Now I'm thinking of having 2 tables for comments which are:
A table which only has 5 rows of data and will be visible by default. I need filtering to do this. Linq filtering code would be great!
A table which has all the results. No filtering. I have no problems with this one.
So here is what I have for the data:
DataRowView dv = e.Item.DataItem as DataRowView;
if (dv != null)
{
Repeater commentRepeater = e.Item.FindControl("childRepeater") as Repeater;
if (commentRepeater != null)
{
commentRepeater.DataSource = dv.CreateChildView("myrelation");
commentRepeater.DataBind();
}
}
As you can see, I have created a relation between tables in my dataset and I'm binding that datarow to my repeater. I need to do top 5 filtering on the datarow.
Thank you
I suggest to use JSON returned from ASP.NET Web Services with jQuery.
http://www.mikesdotnetting.com/Article/96/Handling-JSON-Arrays-returned-from-ASP.NET-Web-Services-with-jQuery
http://www.electrictoolbox.com/json-data-jquery-php-mysql/
If you want to append the left over items to the current repeater item you could have a button at the end of the coments that is attached to a jquery function that will fetch the rest of the comments for you. Then once the data is recieved your function would just append the comments to the list of other comments mimicing what the repeater was doing and replacing the 'show all' button.
If you don't want to use any ajax to do this then you will probably need to rebind the comments Repeater with a new set of data that is not limited to just the first 5 results.
EDIT: Based on your comment and changes you have editted, I would go with one table with all comments and in the DataBinding of each comment set the row style to visible with a global counter. Once your have more than 5 set the style to a hidden style for each item. When they click the show all button, just switch the style from hidden to visible for the rest comments that are hidden. This will save you duplicating the data for the first 5 items which could turn into a lot of extra rows if there are a lot of answers with comments.

Custom ListView to show EmptyDataTemplate and InsertItemTemplate at the same time

It is known that the ListView control can't display both an EmptyDataTemplate and a InsertItemTemplate at the same time.
For my design style I need to be able to show both. I want to be able to show that no data exist and at the same time show a form to add new data.
I've already implemented various solutions, such as putting a PlaceHolder in my LayoutTemplate and then manually showing or hiding this PlaceHolder in the code-behind, depending on if there is data or not.
However, I would like a control that has this built-in capability in order to keep my code-behind light.
I believe there are only two ways to achieve what I want:
First way (preferred) is to write that custom control myself. I was thinking of deriving from ListView and overriding the function responsible for disabling the EmptyDataTemplate, but I have no experience with custom controls. And I'm not even sure it will work in the end.
Second way is to use a custom control found or purchased somewhere. I have not been able to find such control that has the same base capabilities as the ListView.
Has anybody any idea how to solve #1 and maybe #2?
Thank you.
Here is what I ended up doing:
public class MyListView : ListView
{
protected override int CreateChildControls(IEnumerable dataSource, bool dataBinding)
{
int itemCount = base.CreateChildControls(dataSource, dataBinding);
if (this.InsertItemPosition != InsertItemPosition.None && itemCount == 0)
{
CreateEmptyDataItem();
}
return itemCount;
}
}
Works great!
I would go for your option 1: Create a custom control
Because you haven't specified a programming language I made one in VB.NET:
Public Class CustomListView
Inherits ListView
Public Sub CheckEmptyData() Handles Me.PreRender
If Me.Items.Count = 0 Then
Dim label As New Label
label.Text = "No data found <br/>"
Me.Controls.AddAt(0, label)
End If
End Sub
End Class
Just tested it and works perfectly, it can just replace an existing ListView.
As you can see it checks if there is any data and if not it inserts a label with the text "No data found". I haven't found an easy way to use the EmptyDataTemplate for this, that would be a better option but this might already work for you.
Another option is to hide the InsertItem (InsertItemPosition.None) if there is no data, and add a Button "Insert" to the EmptyDataTemplate that enables the InsertItemTemplate and therefore hides the EmptyDataTemplate.
I don't understand much of your requirement without a screen shot of what you are actually trying to achieve. Anyway, you may be able to achieve this interface with a combination of ListView+FormView or ListView+ a User Control. If you can provide any more info I may help further.

Advanced ASP.NET Gridview Layout

So i had a feature request to add fields to a second table row for a single data row on a GridView. At first, I looked at extending the functionality of the GridView but soon realized this would be a huge task and since I consider this request a shim for a larger future feature decided against it. Also want to move to MVC in the near future and this would be throw away code.
So instead I created a little jquery script to move the cell to the next row in the table.
$(document).ready(function() {
$(".fieldAttributesNextRow").each(function() {
var parent = $(this).parent();
var newRow = $("<tr></tr>");
newRow.attr("class", $(parent).attr("class"));
var headerRow = $(parent).parent().find(":first");
var cellCount = headerRow.children().length - headerRow.children().find(".hide").length;
newRow.append($(this).attr("colspan", cellCount));
$(parent).after(newRow);
})
});
What do you think of this? Is this a poor design decision? I am actually quite pleased with the ease of this solution. Please provide your thoughts.
This is client side code, as long as users are not going to play with the gridview after it is loaded, it should be fine. However, if you want to do anything with postbacks, this might need some refactoring.
What are you trying to achieve with the gridview? Remmber that you can hook into the Row bind event and modify the current row however you need to.

Resources