I have a jqgrid (ver 4.6.0.0), I show a grant total on footer of a amount column. If user insert a new row or delete a row, it should recalculate the total amount, and show it on footer. It works fine until the grid is empty(no any rows), I mean if user delete the last row on grid, the code still calculate the correct amount ( 0 ), but the footer still show the total amount it was, not 0.
Here is my code:
protected void Jqgrid1_DataRequested(object sender, JQGridDataRequestedEventArgs e)
{
DataSet _ds = (DataSet)Session["myApplicationForm"];
DataTable dt1 = _ds.Tables[1] as DataTable;
CalcVoucherAmt(dt1);
}
private void CalcVoucherAmt(DataTable _dt)
{
decimal amtSum = 0;
foreach (DataRow dr in _dt.Rows)
{
amtSum += obj2decimal(dr["DETAIL_AMT"]);
}
Jqgrid1.Columns.FromDataField("DETAIL_AMT").FooterValue = amtSum.ToString();
}
protected void Jqgrid1_RowAdding(object sender, Trirand.Web.UI.WebControls.JQGridRowAddEventArgs e)
{
DataSet _ds = (DataSet)Session["myApplicationForm"];
DataTable dt1 = _ds.Tables[1] as DataTable;
dt1.PrimaryKey = new DataColumn[] { dt1.Columns["DATA_SEQ"] };
DataRow row = dt1.NewRow();
row["UNIQ_KEY"] = System.Guid.NewGuid().ToString();
row["DETAIL_AMT"] = amt; //user input
dt1.Rows.InsertAt(row, dt1.Rows.Count);
Session["myApplicationForm"] = _ds;
Jqgrid1.DataSource = dt1;
Jqgrid1.DataBind();
}
protected void Jqgrid1_RowEditing(object sender, Trirand.Web.UI.WebControls.JQGridRowEditEventArgs e)
{
DataSet _ds = (DataSet)Session["myApplicationForm"];
DataTable dt1=_ds.Tables[1] as DataTable;
dt1.PrimaryKey = new DataColumn[] { dt1.Columns["DATA_SEQ"] };
DataRow rowEdited = dt1.Rows.Find(e.RowKey);
rowEdited["DETAIL_AMT"] = amt; //user input
Session["myApplicationForm"] = _ds;
Jqgrid1.DataSource = dt1;
Jqgrid1.DataBind();
}
protected void Jqgrid1_RowDeleting(object sender, JQGridRowDeleteEventArgs e)
{
DataSet _ds = (DataSet)Session["myApplicationForm"];
DataTable dt1 = _ds.Tables[1] as DataTable;
dt1.PrimaryKey = new DataColumn[] { dt1.Columns["DATA_SEQ"] };
DataRow rowToDelete = dt1.Rows.Find(e.RowKey);
if (rowToDelete != null)
dt1.Rows.Remove(rowToDelete);
}
and in aspx, the code is
<cc1:JQGrid ID="Jqgrid1" runat="server" Height="100%" Width="100%" AutoWidth="true" PagerSettings-PageSizeOptions="[]"
OnRowAdding="Jqgrid1_RowAdding"
OnRowEditing="Jqgrid1_RowEditing"
OnDataRequested="Jqgrid1_DataRequested"
OnRowDeleting="Jqgrid1_RowDeleting">
</cc1:JQGrid>
any idea?
Why you decide that jqGrid "should recalculate the total amount" automatically? If you insert a row using or delete a row you can specify callback which will be called at the end of Add/Delete operation. Inside of the callback you can use getCol to recalculate the total amount and to use footerData to set new value in the footer.
Alternatively you can trigger reloadGrid which will sort new data correctly, recalculate the total amount and to place it on the footer row. Both ways will work.
The code which you posted seems to have mo relation to jqGrid. It don't show which editing mode and how you use to Add/Delete rows. So I can't give you more detailed implementation tips.
Related
private void GridViewBind()
{
SqlConnection Dbcon = new SqlConnection();
Dbcon.ConnectionString = ConfigurationManager.ConnectionStrings[
"ConnectionString"].ConnectionString;
Dbcon.Open();
string expSql = "SELECT [dName],[item],[cnt] FROM [Test1].[dbo].[Test3]
ORDER BY [dName], [cnt] desc";
SqlDataAdapter adAdapter = new SqlDataAdapter(expSql, Dbcon);
DataSet ds = new DataSet();
adAdapter.Fill(ds);
GridView.DataSource = ds.Tables[0];
GridView.DataBind();
ViewState["dt"] = ds.Tables[0];
ViewState["sort"] = "Desc";
}
I drew a table using gridview(asp:gridview) And I made a db for test and bound it
Then, in order to merge cells with the same subject, cells were merged using OnDataBound.
I want to sort by merged subject when cnt is clicked
However, my sort code sorts the entire cnt column, and the merged cells are unraveled.
I need a way to keep the merged cells and do ASC/DESC sorting within them!
protected void OnDataBound(object sender, EventArgs e)
{
for (int i = GridView2.Rows.Count - 1; i > 0; i--)
{
GridViewRow row = GridView2.Rows[i];
GridViewRow previousRow = GridView2.Rows[i - 1];
int j = 0;
if (row.Cells[j].Text == previousRow.Cells[j].Text)
{
if (previousRow.Cells[j].RowSpan == 0)
{
if (row.Cells[j].RowSpan == 0)
{
previousRow.Cells[j].RowSpan += 2;
}
else
{
previousRow.Cells[j].RowSpan = row.Cells[j].RowSpan + 1;
}
row.Cells[j].Visible = false;
}
}
}
}
I don't have reputation to comment, so i comment here in answer.
Can you add your OnDataBound code where your merged subject?
Also can you make your select query with merged subject as column, then you just need to bind data directly to gridview.
For sorting you can follow below link:
https://www.c-sharpcorner.com/UploadFile/b8e86c/paging-and-sorting-in-Asp-Net-gridview/
https://codepedia.info/gridview-sorting-header-click
Hi Friends wish you all Happy New Year 2017!
I am displaying records in grid and i have code to select the row and display records in text boxes as per selected row.
I have Edit Button to edit records in grid row but when i click on text box (edit mode) to enter value it is showing error because the "select row" event is still active.
Any help how to remove the select row action when edit button is clicked.
// click on the row to select and display records in text boxes
protected void gvUsrEdit_SelectedIndexChanged(object sender, EventArgs e)
{
GridViewRow row = gvUsrEdit.SelectedRow;
Label l1 = row.FindControl("Label1") as Label;
Label l2 = row.FindControl("Label2") as Label;
i_TranInputID.Text = l1.Text;
tReason.Text = l11.Text;
gvUsrEdit.Visible = false;
}
protected void gvUsrEdit_RowEditing(object sender, GridViewEditEventArgs e)
{
gvUsrEdit.EditIndex = e.NewEditIndex;
show1();
}
public void show1()
{
string strquery = "select * from btaprs2 where vEmpID=#d1 and vQuarter=#d2 and vyear1=#d3 and tKRA=#d4 and v10='Active' ";
con.Open();
SqlCommand cmd = new SqlCommand(strquery, con);
try
{
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataSet ds = new DataSet();
da.Fill(ds);
gvUsrEdit.DataSource = ds;
gvUsrEdit.DataBind();
con.Close();
}
catch (Exception ex)
{
Response.Write(ex);
Label46.Text = "Error in page please check!";
}
}
You need to change the RowIndex.
protected void gvUsrEdit_RowEditing(object sender, GridViewEditEventArgs e)
{
gvUsrEdit.EditIndex = -1;
show1();
}
I would suggest to Edit the rows this way:
You may want to use RowUpdating method like this:
protected void gvUsrEdit_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
i_TranInputID.Text = ((Label)gvUsrEdit.Rows[e.RowIndex].FindControl("Label1") ).Text;
tReason.Text = ((Label)gvUsrEdit.Rows[e.RowIndex].FindControl("Label2")).Text;
tReason.Text = l11.Text;
gvUsrEdit.EditIndex = -1;
show1();
}
this code display total of column in each page of grid view footer I want to display total of all columns in all pages footer
if (e.Row.RowType == DataControlRowType.DataRow)
{
string deb = ((Label)e.Row.FindControl("debit")).Text;
string cred = ((Label)e.Row.FindControl("credit")).Text;
decimal totalvalue = Convert.ToDecimal(deb) - Convert.ToDecimal(cred);
amount += totalvalue;
Label lbl = (Label)e.Row.FindControl("lblTotal");
lbl.Text = amount.ToString();
Label lblDebAmount = (Label)e.Row.FindControl("debit");
Label lblCredamount = (Label)e.Row.FindControl("credit");
float debtotal = (float)Decimal.Parse(lblDebAmount.Text);
float credtotal = (float)Decimal.Parse(lblCredamount.Text);
totalPriced += debtotal;
totalPricec += credtotal;
}
if (e.Row.RowType == DataControlRowType.Footer)
{
Label totallblCAmount = (Label)e.Row.FindControl("totallblDebAmount");
Label totallblCredAmount = (Label)e.Row.FindControl("totallblCredAmount");
totallblCAmount.Text = totalPriced.ToString("###,###.000");
totallblCredAmount.Text = totalPricec.ToString("###,###.000");
}
}
Why do it when the row is data bound? Why not do it when you originally bind the data?
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostBack)
{
DataTable dt = Database.GetData();
GridView1.DataSource = dt;
GridView1.DataBind();
//calculate here by manually adding up the debit/credit column from dt
//or do a separate database call that calculates the sum, ex: select sum(debits), sum(credits) from general_ledger
}
}
It makes sense to let the database do the math calculation for you. You wouldn't need to write your own custom calculation code. Just let the database's sum function handle it.
Here's a little more detail.
//Executes a SqlCommand and returns a DataTable
public class GetDataTable(SqlCommand command)
{
var dt = new DataTable();
using (var connection = new SqlConnection("connectionstring"))
{
command.Connection = connection;
connection.Open();
dt.Load(command.ExecuteReader());
}
return dt;
}
//Executes a SqlCommand and returns a scalar of type T
public static T GetScalar<T>(SqlCommand command)
{
using (var connection = new SqlConnection ("connectionstring"))
{
command.Connection = connection;
connection.Open();
var result = command.ExecuteScalar();
if (result is T)
{
return (T)result;
}
else
{
return (T)Convert.ChangeType(result, typeof(T));
}
}
}
//Load the data into the GridView, then get the credit amount and put the value in a label.
//You'll need to adjust the queries to match your schema
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostBack)
{
var tableCommand = new SqlCommand("select columns from table");
GridView1.DataSource = GetDataTable(tableCommand);
GridView1.DataBind();
var creditCommand = new SqlCommand("select sum(stat_amount) from tablename where stat_flag='c'");
var credits = GetScalar<decimal>(creditCommand);
Label1.Text = credits;
}
}
I have a gridview with paging (page size 10), which contains Course details. when i am saving gridview data into database it save only 10 record (according to page).
is there any to get all gridview all rows.
e.g. if my gridview contains 25 rows with paging and when i save data into database then all 25 rows data insert into database?
please help...
Here is my code
DataTable dt = new DataTable();
dt.Columns.Add("row_index");
dt.Columns.Add("edited_value");
IList<int?> SeqNos = new List<int?>();
foreach (GridViewRow gvr in gvViolationCodes.Rows)
{
TextBox tb = (TextBox)gvr.FindControl("txtSeqNo");
Label lblSysid = (Label)gvr.FindControl("lblSysID");
HiddenField hf = (HiddenField)gvr.FindControl("HiddenField1");
if (tb.Text != hf.Value)
{
DataRow dr = dt.NewRow();
SeqNos.Add(Convert.ToInt32(tb.Text));
dr["row_index"] = lblSysid.Text;
dr["edited_value"] = tb.Text;
dt.Rows.Add(dr);
}
}
You need to save the data in temporary storage in PageIndexChanging event of GrIdView. On final save send the datatable to Sql Server Procedure or loop through the datatable and save it in database. Follow the steps:
protected void grdView_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
fnStoreGridData();
}
private void fnStoreGridData()
{
DataTable TempDataTable = new DataTable();
if(Session["Data"]!=null){
TempDataTable = Session["Data"] as DataTable;
}
else{
TempDataTable.Columns.Add("exCourse", typeof(string)) ;
TempDataTable.Columns.Add("exUniversityCourse", typeof(string)) ;
}
foreach (GridViewRow row in gvExportCourse.Rows)
{
Label exCourse = (Label)row.FindControl("gvlblCourseName");
Label exUniversityCourse = (Label)row.FindControl("gvlblUniversityCourseName");
if (exCourse != null)
{
if (!string.IsNullOrEmpty(exCourse.Text))
{
TempDataTable.Rows.Add(exCourse.Text, exUniversityCourse.Text);
//TempDataTable is your datatable object. Make sure that datatable contains these columns
}
}
}
}
In Final Save:
protected void button_Click(object s, EventArg e)
{
fnStoreGridData(); //Here this will bind the data of current page
DataTable TempDataTable = new DataTable();
if(Session["Data"]!=null){
TempDataTable = Session["Data"] as DataTable;
}
//Now loop through datatable and store the values
foreach(DataRow in TempDataTable.Rows)
{
CourseInformation course = new CourseInformation();
course.AddCourseMaster(dr["exCourse"].ToString(), dr["exUniversityCourse"].ToString());
}
label1.Text = "Course saved successfully.";
}
I am using link button to display a pdf report for selected Report Id from Grid view. On page load I am binding the datasource with Gridview. By clicking the link button it fetches the correct report id from column 0 and displays the report. After sorting the grid the grid view shows the sorted data. Now if i click the link button it is not picking the changed value from column 0. instead it is picking the value before sorted.
Say: Column 0 has values 1, 2, 3, 4, 5 before sorting. If i click link button of Row 3 before sorting it is picking value 3 from column 0. After sorting it is 3,4,5,2,1. Now if i click link button of row 3 it is still picking value 3 instead of 5. Can you please help me.
Below is my code:
aspx:
CS:
protected void Page_Load(object sender, EventArgs e)
{
bindGrid();
}
protected void GvStockTakingReport_Sort(object sender, GridViewSortEventArgs e)
{
GvStockTakingReport.DataSource = null;
GvStockTakingReport.DataBind();
GvStockTakingReport.Dispose();
DataSet ds = StockTakingList.BindStocktakingReportGrid();
DataTable dtSortTable = ds.Tables[0];
if (dtSortTable != null)
{
DataView dv = new DataView(ds.Tables[0]);
dv.Sort = e.SortExpression + " " + getSortDirectionString();
//ViewState["sortExpression"] = e.SortExpression;
//Session["sortExpression"] = e.SortExpression;
GvStockTakingReport.DataSource = dv;
GvStockTakingReport.DataBind();
}
}
protected void PrintReport(object sender, CommandEventArgs e)
{
LinkButton lkButton = (LinkButton)sender;
GridViewRow item = (GridViewRow)lkButton.NamingContainer;
string Id = (item.FindControl("lblstk_id") as Label).Text;
//Getting value for Id
string Id1 = e.CommandArgument.ToString();
int rowIndex = Convert.ToInt32((string)e.CommandArgument);
//string Id1 = Convert.ToString(GvStockTakingReport.Rows[rowIndex].Cells[0].Text);
string Id2 = ((Label)(GvStockTakingReport.Rows[rowIndex].FindControl("lblstk_id"))).Text;
//Getting value for Id
string virtualPath = string.Format("~/{0}/{1}{2}", Portal.Business, Portal.Core.Profile.ReportsDirectory, "General/RPT_03002_StockTakinReport.rpt");
string physicalPath = Server.MapPath(virtualPath);
using (ReportDocument report = new ReportDocument())
{
report.Load(physicalPath);
Core.Security.CrystalReportLogOn(report, (SqlConnectionStringBuilder)Portal.Core.Profile.ConnectionStrings["MTServer"]);
report.SetParameterValue("#STK_Id", Id);
report.ExportToHttpResponse(ExportFormatType.PortableDocFormat, Page.Response, true, "Stock Taking report");
}
}
the issue was whenever i click the link button the page load calls
bindgrid method which resets the gridview to original sorting before the printreport method invokes.
I have included the sorting logic in bindgrid method as well as below which resolved the issue.
public void bindGrid()
{
try
{
DataSet ds = StockTakingList.BindStocktakingReportGrid();
GvStockTakingReport.DataSource = ds;
GvStockTakingReport.DataBind();
//To make sure the grid remains with sorting order while pageload method invokes otherwise it will reset to original order
DataView dv = new DataView(ds.Tables[0]);
if (dv != null)
{
if (ViewState["sortExpression"] == null)
{
ViewState["sortExpression"] = "STK_Id"; //First time it will sort by STK_ID i.e on first time page loading
}
if (ViewState["sortDirection"] == null)
{
ViewState["sortDirection"] = "ASC";//First time it will sort ascending i.e on first time page loading
}
dv.Sort = ViewState["sortExpression"].ToString() + " " + ViewState["sortDirection"].ToString();
GvStockTakingReport.DataSource = dv;
GvStockTakingReport.DataBind();
}
}
catch (Exception ex)
{
error.Visible = true;
error.Text = ex.Message.ToString();
}
}