One part of my application uses nested GridViews in order to display data. I have clients' orders, and each order consists of 1-or-more products. Now, in order to present data to the user, I used the order data GridView with a button in each row, which allows you to expand/collapse the child Gridview.
When designing this I followed the tutorial presented on this page:
https://www.aspsnippets.com/Articles/ASPNet-Nested-GridViews-GridView-inside-GridView-with-Expand-and-Collapse-feature.aspx
with some modifications, since my situation is a little bit different (E.g. I don't use a database since data is imported from the external API).
However, the problem is that in the original code the child GridView data is only displayed, while in my solution it has some DropDownLists that allows user to edit the data:
<asp:GridView ID="MainTable" runat="server" OnDataBound="MainTable_DataBound" AutoGenerateColumns="false" OnRowCommand="MainTable_RowCommand" class="w3-table w3-centered">
<HeaderStyle CssClass="w3-blue" />
<Columns>
<asp:TemplateField>
<ItemTemplate>
<a class="w3-btn w3-blue button" id="plus">+</a>
<asp:Panel ID="pnlOrders" runat="server" Style="display: none">
<asp:GridView ID="ProductsTable" runat="server" OnRowDataBound="ProductsTable_RowDataBound" AutoGenerateColumns="false" class="w3-table w3-striped">
<Columns>
<asp:BoundField DataField="Name" HeaderText="Nazwa" />
<asp:BoundField DataField="Indexer" Visible="false" />
<asp:TemplateField HeaderText="Parametr 1">
<ItemTemplate>
<asp:DropDownList ID="DropDownList1" runat="server" class="w3-select w3-border"></asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Parametr 2">
<ItemTemplate>
<asp:DropDownList ID="DropDownList2" runat="server" class="w3-select w3-border"></asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Parametr 3">
<ItemTemplate>
<asp:DropDownList ID="DropDownList3" runat="server" class="w3-select w3-border"></asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Usuń">
<ItemTemplate>
<a class="w3-btn w3-blue verify">V</a>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</asp:Panel>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="ID" HeaderText="ID" />
<asp:BoundField DataField="Client" HeaderText="Klient" />
<asp:BoundField DataField="Phone" HeaderText="Telefon" />
<asp:BoundField DataField="Comment" HeaderText="Komentarz" />
<asp:TemplateField HeaderText="Zatwierdź">
<ItemTemplate>
<asp:Button class="w3-btn w3-blue" Text="Zatwierdź" runat="server" CommandName="Verify" CommandArgument="<%# Container.DataItemIndex %>" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Now, the JQuery used in the original code creates a copy of child GridView, which is removed when the user clicks the "-" button. Because of that, I can't access DropDownLists in the code and the changes made by user are not saved. I also found out that the buttons in the child GridView (class .verify) aren't working properly (This, however, might be my fault since I'm not really fluent in JQuery).
$(document).ready(function () {
$(".button").on("click", function () {
if ($(this).attr('id') == "plus") {
$(this).closest("tr").after("<tr><td></td><td colspan = '999'>" + $(this).next().html() + "</td></tr>");
$(this).html("-");
$(this).attr('id', 'minus');
}
else {
$(this).html("+");
$(this).closest("tr").next().remove();
$(this).attr('id', 'plus');
}
});
$(".verify").on("click", function () {
$(this).closest("tr").css("background-color", "#ffffff");
});
});
So my question is - how to maintain the current look and page design of the application (opening child GridView outside of the cell), while still being able to access DropDownLists in the code behind? is it possible to do it with JQuery? If not, do you have any other ideas on how to resolve this?
[EDIT] Here are some pics of how it looks:
You can also use hide() instead of remove(). Like so:
$(this).html("+");
$(this).closest("tr").next().hide();
$(this).attr('id', 'plus');
Related
I have a problem in gridview, as per requirement i have set No of Records per page = 4 in gridview. I have to select Checkbox against every complaint but problem is then when i got to next pge in gridview and e.g fro 1 to 2 then when i come back to page 1 then it doesn't show TICK in check boxes . It doesn't remember my selection when i browse to and back to page.
<asp:GridView ID="GridViewSmsComplaints" AllowPaging="True" PageSize="4" runat="server" AutoGenerateColumns="False" CssClass="mGrid" BorderColor="#333333" Width="550px" OnPageIndexChanging="GridViewSmsComplaints_PageIndexChanging" >
<Columns>
<asp:BoundField HeaderText="ID" DataField="ID" />
<asp:BoundField HeaderText="Recieving Date" DataField="RecievingDate" />
<%--<asp:BoundField HeaderText="ToMobileNo" DataField="ToMobileNo" /> --%>
<asp:BoundField HeaderText="FromMobileNo" DataField="FromMobileNo" />
<asp:BoundField HeaderText="Message" DataField="Message" >
<ItemStyle Wrap="True" />
</asp:BoundField>
<asp:TemplateField HeaderText="IsComplaint">
<ItemTemplate>
<asp:CheckBox ID="ckboxIsComplaint" runat="server" Checked='<%# Convert.ToBoolean(Eval("IsComplaint").ToString()) %>' />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
please check the above link.here your problem was clearly explained here.i think so it may be helpfull
As per comments...
If you do not update the underlying database by processing the OnCheckChanged event of the check box, then it will simply be reading the same data all the time.
From How to add event for Checkbox click in Asp.net Gridview Column, I have extracted the required information and tried to modify to fit your initial question.
<asp:TemplateField HeaderText="IsComplaint">
<ItemTemplate>
<asp:CheckBox ID="ckboxIsComplaint" runat="server" Checked='<%# Convert.ToBoolean(Eval("IsComplaint").ToString()) %>' OnCheckedChanged="chk_CheckedChanged" AutoPostBack="true/>
</ItemTemplate>
</asp:TemplateField>
add checkbox change event in aspx.cs page
protected void chk_CheckedChanged(object sender, EventArgs e)
{
GridViewRow row = ((GridViewRow)((CheckBox)sender).NamingContainer);
<your data source>.Rows[row.DataItemIndex]["B"] = ((CheckBox)GridViewSmsComplaints.Rows[row.RowIndex].FindControl("ckboxIsComplaint")).Checked;
}
How can I fix the width for each column in GridView. My GridView keeps extend along with data in the cell. I need it to skip to new line when it reach the right side of the cell. This is my code in .aspx file:
<asp:GridView ID="GridView1" runat="server"
AutoGenerateColumns="False" DataKeyNames="Emp_ID" DataSourceID="LinqDataSource1"
AllowPaging="True" AllowSorting="True" Width="900px" HorizontalAlign="Center" >
<Columns>
<asp:BoundField DataField="Emp_ID" HeaderText="ID"
InsertVisible="False" ReadOnly="True" SortExpression="Emp_ID"/>
<asp:BoundField DataField="Emp_Username"
HeaderText="Username" SortExpression="Emp_Username" />
<asp:BoundField DataField="Emp_Password"
HeaderText="Password" SortExpression="Emp_Password" />
<asp:BoundField DataField="Emp_Name"
HeaderText="ชื่อพนักงาน" SortExpression="Emp_Name" />
<asp:BoundField DataField="Emp_Address"
HeaderText="ที่อยู่" SortExpression="Emp_Address" />
<asp:BoundField DataField="Emp_Tel"
HeaderText="เบอร์โทรศัพท์" SortExpression="Emp_Tel" />
<asp:TemplateField HeaderText="รูปพนักงาน" SortExpression="Emp_Picture">
<EditItemTemplate>
<asp:TextBox ID="TextBox1" runat="server" Text='<%# Bind("Emp_Picture") %>'></asp:TextBox>
</EditItemTemplate>
<ItemTemplate>
<asp:Image ID="Image2" runat="server" Height="70px"
ImageUrl='<%# Eval("Emp_Picture", "{0}") %>' Width="50px" />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="Status" HeaderText="สถานะ"
SortExpression="Status" />
<asp:HyperLinkField DataNavigateUrlFields="Emp_ID"
DataNavigateUrlFormatString="AdminUpdate.aspx?Emp_ID={0}" Text="Edit" />
<asp:TemplateField>
<HeaderTemplate>
<asp:CheckBox ID="ChkSelectAll" runat="server"
AutoPostBack="True" oncheckedchanged="ChkSelectAll_CheckedChanged" />
</HeaderTemplate>
<ItemTemplate>
<asp:CheckBox ID="Chk" runat="server" AutoPostBack="True" oncheckedchanged="Chk_CheckedChanged" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Here's my design view:
As you can see, the first 4 columns has no problem with that until column 5. It keeps extend cause all GridView extend out of the page
Set itemstyle width of every column.For example.
<asp:BoundField DataField="Emp_Address"
HeaderText="ที่อยู่" SortExpression="Emp_Address">
<ItemStyle Width="200px" HorizontalAlign="Left" />
</asp:BoundField>
Wrapping is done based on words so that any single word is not broken in two lines.
So won't work for you if your data has long string without space.
The problem is that you can't insert spaces on your own because that may change the meaning of data.
While showing in grid we show only that long string which can be accommodated in column and then add "..." (only if string is more than what is showing) and then add a tooltip to show the full string.
That way the grid formatting is not compromised and if user wants he can hover his mouse and see the whole string.
hope this helps Example
Try setting the property RowStyle-Wrap of the GridView to True.
You can use ItemStyle-Width to fix the column width ,but in case you enter characters which can not be enclosed in given width (As seen in your image) ,column will expand as per the inputs so you can use RowStyle-Wrap property of gridview
<asp:GridView ID="grdVwtrial" runat="server" RowStyle-Wrap="true">
RowStyle-Wrap==true should work I guess. For more clarifications refer this:
http://forums.asp.net/t/1263769.aspx
I'm trying to add a delete column to my gridview, however when I press the delete button on a row, it calls the function I assigned to onRowDeleting infinitely or so it seems.
Here's my code:
<asp:GridView ID="GridView1" runat="server" CssClass="yep" AutoGenerateColumns="False" OnRowDeleting="dismissClick">
<Columns>
<asp:TemplateField HeaderText="Create Incident">
<ItemTemplate>
<asp:CheckBox ID="Selections" runat="server" ViewStateMode = "Enabled" OnCheckedChanged="CheckBox1_CheckedChanged" />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="case#" HeaderText="Case #" SortExpression="case#" />
<asp:BoundField DataField="Unit #" HeaderText="Unit #" SortExpression="Unit #" />
<asp:BoundField DataField="date" HeaderText="date" SortExpression="date" />
<asp:BoundField DataField="typeOfCall" HeaderText="typeOfCall" SortExpression="typeOfCall" />
<asp:BoundField DataField="Primary Impression" HeaderText="Primary Impression" SortExpression="Primary Impression" />
<asp:TemplateField HeaderText="View PCR">
<ItemTemplate>
<asp:Button ID="ViewPCR" Text="View PCR" runat="server" OnClick="viewPCRClick" CssClass="btn em" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Dismiss">
<ItemTemplate>
<asp:Button ID="dismiss" Text="Dismiss" runat="server" CommandName="Delete" CssClass="btn em" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
and my simple deletion function:
protected void dismissClick(object sender, GridViewDeleteEventArgs e)
{
int index = Convert.ToInt32(e.RowIndex);
GridView1.DeleteRow(index);
}
Calling GridView1.DeleteRow(index) is causing an event loop, because calling that method also raises the RowDeleted and RowDeleting events again, as described in the MSDN documentation for GridView.DeleteRow Method:
Calling this method also raises the RowDeleted and RowDeleting events.
Instead you want to either remove it from the binding source (i.e. DataSet, DataTable, List<T> or whatever you are binding to) or persist your delete to the database or whatever is ultimately holding your data and then re-bind the grid.
I have a gridview in which i have two textboxes. The senarios is such that the value I enter in one (txtCharges) should come as * 10 in the other textbox (txtTotalCharges). How to achieve this using javascript ? Markup code for gridview is as follows:
<asp:GridView ID="grdFixedMontlhy" CssClass="gridview" runat="server" AutoGenerateColumns="False"
Width="100%">
<RowStyle CssClass="gridviewItemStyle" HorizontalAlign="center" />
<Columns>
<asp:CheckBoxField Text="Select" />
<asp:BoundField DataField="Bill_HeadName" HeaderText="Head" />
<asp:BoundField DataField="Applicable_Charges_Category_Text" HeaderText="Type" />
<asp:TemplateField HeaderText="Charges" ItemStyle-CssClass="gridviewColumnControls">
<ItemTemplate>
<asp:TextBox ID="txtCharges" runat="server" Text='<%# Bind("Charges") %>'></asp:TextBox>
<asp:FilteredTextBoxExtender ID="txtCharges_FilteredTextBoxExtender" runat="server"
Enabled="True" TargetControlID="txtCharges" ValidChars="0123456789.">
</asp:FilteredTextBoxExtender>
</ItemTemplate>
<ItemStyle CssClass="gridviewColumnControls" />
</asp:TemplateField>
<asp:TemplateField HeaderText="Days" ItemStyle-CssClass="gridviewColumnControls">
<asp:TemplateField HeaderText="Total Charges" ItemStyle-CssClass="gridviewColumnControls">
<itemtemplate>
<asp:TextBox ID="txtTotalCharges" runat="server" Text=""></asp:TextBox>
<asp:FilteredTextBoxExtender ID="txtTotalCharges_FilteredTextBoxExtender"
runat="server" Enabled="True" TargetControlID="txtTotalCharges"
ValidChars="0123456789.">
</asp:FilteredTextBoxExtender>
</itemtemplate>
<itemstyle cssclass="gridviewColumnControls" />
</asp:TemplateField>
</Columns>
</asp:GridView>
Thanks in advance.
You can add onKeyUp javascript event for the txtCharges as below
<asp:TextBox ID="txtCharges" runat="server" Text='<%# Bind("Charges")%>' onkeyup="calculateTotalCharge(this);"></asp:TextBox>
Now the Javascript as below
<script type="text/javascript">
function calculateTotalCharge(elem)
{
var totChargeid = $(elem).attr("id").replace('_txtCharges', '_txtTotalCharges');
$('#' + totChargeid).val(parseInt($(elem).val())*10);
}
</script>
Also you must do the required checkups for NAN. Hope this is helpful to you.
fail ... lack of understanding above ...
put the script on the page that suryakiran suggests (with a slight alteration) ...
<script type="text/javascript">
function calculateTotalCharge(charge, total)
{
$(total).val(parseInt($(charge).val())*10);
}
</script>
// in grid template
<asp:Textbox onkeyup='calculateTotalCharge(this, <%= totalchargestextbox.clientid %>)' ... />
as an attribute for the txtCharges box.
that way each rows dynamic id for the total box is passed in to the js on the client when it's called.
You can do this on the server side also
<asp:TextBox ID="txtTotalCharges" runat="server" Text='<%# Convert.ToString(Convert.ToInt32(DataBinder.Eval(Container.DataItem, "Charges"))*10 )></asp:TextBox>
Merged with GridView sorting works once only.
Please help me, I set Allowsorting="true" but sorting is not working in my GridView. I want automatic sorting i.e. sorting without handling its event.
Here is code of aspx page:
<asp:GridView ID="gdvSignatureLines" runat="server" CssClass="Grid1" AutoGenerateColumns="False"
SkinID="PagedGridView" AllowPaging="True" AllowSorting="True" DataKeyNames="Id"
onrowcommand="gdvSignatureLines_RowCommand"
onrowdeleting="gdvSignatureLines_RowDeleting"
onrowediting="gdvSignatureLines_RowEditing">
<PagerStyle CssClass="gridPager" HorizontalAlign="Right" />
<Columns>
<ucc:commandfieldcontrol headertext="Actions" showdeletebutton="true" buttontype="Image"
deleteimageurl="~/App_Themes/Default/images/delete.png" showeditbutton="true"
editimageurl="~/App_Themes/Default/images/edit.png" deleteconfirmationtext="Are you sure you want to delete?">
<ItemStyle HorizontalAlign="Center" Width="60px" />
</ucc:commandfieldcontrol>
<asp:BoundField DataField="SortOrder" HeaderText="Line" SortExpression="SortOrder" />
<asp:TemplateField HeaderText="Type">
<ItemTemplate>
<asp:Label ID="lblglTypeId" runat="server" Text='<%# Eval("GeneralLookup.LookupItem") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Label">
<ItemTemplate>
<asp:Label ID="lblglLabelId" runat="server" Text='<%# Eval("GeneralLookup1.LookupItem") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="Caption" HeaderText="Caption" SortExpression="Caption" />
</Columns>
<EmptyDataTemplate>
<div class="divEmptyListingGrid">
--- No Signature Line Exists ---
</div>
</EmptyDataTemplate>
</asp:GridView>
Here is the code of CS file:
protected void LoadSignatureList(int reportId, string reportName)
{
lblHeading.Text = "Signature Line for " + reportName;
ReportOptionsBO reportOptionsBO = new ReportOptionsBO();
this.gdvSignatureLines.DataSource = reportOptionsBO.GetReportSignatureLineByReportId(reportId);
this.gdvSignatureLines.DataBind();
}
When I click on the Header of column "Line" or "Caption", nothing happens.
I have one more grid that is working fine. The difference between both is, data is bound to this grid on runtime. But the other grid's datasource is preset.
My current grid has not these options of Enable Paging and Enable Sorting.
Please help as soon as possible.