How to add and update rows in gridview asp.net - asp.net

I am doing an online ordering system. I want to check if the item exist in the gridview so it will not add another row or have multiple lines (It will update the qty and the price). The gridview is updating using dgvOrder.Rows[i].Cells[2].Text but my problem is how to update the datatable.
bool isExist = false;
if (Session["dtInSession"] != null)
dt = (DataTable)Session["dtInSession"]; //Getting datatable from session
for (int i = 0; i < dgvOrder.Rows.Count; i++)
{
if (dgvOrder.Rows[i].Cells[0].Text == b.ID)
{
isExist = true;
dgvOrder.Rows[i].Cells[2].Text = Convert.ToString(Convert.ToInt32(dgvOrder.Rows[i].Cells[2].Text) + 1);
dgvOrder.Rows[i].Cells[3].Text = Convert.ToString(Convert.ToInt32(dgvOrder.Rows[i].Cells[2].Text) * price);
}
}
if (!isExist)
{
DataRow dr = dt.NewRow();
dr["pCode"] = b.ID;
dr["desc"] = description;
dr["qty"] = "1";
dr["price"] = price;
dt.Rows.Add(dr);
dgvOrder.DataSource = dt;
dgvOrder.DataBind();
}
Because I am planning to pass the datatable using the session variable.
Session["orders"] = dt;
Response.Redirect("FinalizeOrder.aspx");
after passing the data, the code is working but only 1 qty for each item is passing.
Can anyone help me in this issue?

The problem is that you reload the DataSource of the GridView only if !isExist. Otherwise you are changing the datatable, but you are not assigning it to the GridView again, so the values are coming from the ViewState.
So this should work:
// update the table
// ...
if (!isExist)
{
// ...
}
// reassign the updated DataTable and DataBind the grid always
dgvOrder.DataSource = dt;
dgvOrder.DataBind();

Related

can't add all the selected rows to the dataset

I have added records chosen (checkbox) in a datatable shown below, records have been displaying in a datagrid populated using stored procedure. Then on the button click I save all the selected (added) records to the ds in database.
public DataSet getMain()
{
DataSet ds = CFObj.GetSchemaRequest();
DataRow dr;
dr = ds.Tables[0].NewRow();
for (int i = 0; i < dgAvailableCandidates.Items.Count; i++)
{
CheckBox saveChkBoxItem = (CheckBox)dgAvailableCandidates.Items[i].FindControl("chkbox_SelectCandidate");
if (saveChkBoxItem.Checked)
{
//ds.Tables[0].Columns["pk_scrndRecId"].ReadOnly = false;
dr["pk_scrndRecId"] = "0";
dr["fk_jobId"] = ddl_jobList.SelectedValue.ToString();
obj._fkjob_Id = ddl_jobList.SelectedValue.ToString();
dr["fk_recId"] = dgAvailableCandidates.DataKeys[i].ToString();
obj._fk_recId = dgAvailableCandidates.DataKeys[i].ToString();
}
}
ds.Tables[0].Rows.Add(dr);
return ds;
}
here my issue is when ds.Tables[0].Rows.Add(dr); i put outside of loop, it adds only one last selected record to ds, and when I put this inside loop, it throws following exception
[pk_scrndRecId] column is read only
and when I have placed this inside if block, it throws following exception:
This row already belongs to this table.
I am not able to understand why this code doesn't add all the selected rows of datagrid to the ds.
please help. thanks!
You have to create a new row and add it to datatable inside the loop and so each time it will create a new instance and add it to your datatable.
Check updated code.
public DataSet getMain()
{
DataSet ds = CFObj.GetSchemaRequest();
DataRow dr;
for (int i = 0; i < dgAvailableCandidates.Items.Count; i++)
{
CheckBox saveChkBoxItem = (CheckBox)dgAvailableCandidates.Items[i].FindControl("chkbox_SelectCandidate");
if (saveChkBoxItem.Checked)
{
dr = ds.Tables[0].NewRow();
//ds.Tables[0].Columns["pk_scrndRecId"].ReadOnly = false;
dr["pk_scrndRecId"] = "0";
dr["fk_jobId"] = ddl_jobList.SelectedValue.ToString();
obj._fkjob_Id = ddl_jobList.SelectedValue.ToString();
dr["fk_recId"] = dgAvailableCandidates.DataKeys[i].ToString();
obj._fk_recId = dgAvailableCandidates.DataKeys[i].ToString();
ds.Tables[0].Rows.Add(dr);
}
}
return ds;
}

Add Session data to ListBox

I didn't write all code. It just a part of sessions which has already data inside. I just want to get all data from sessiosn by which Session["sepet"] to add Listbox but I couldn't do that. There is no any error message. Actually the code purpose is, I wanted to add all data to Listbox after that I want to send all data what include the Listbox to SQL Database. I don't know is there any different way to do.
private void SepetGetir1()
{
List<string> lst = new List<string>();
if (Session["sepet"] != null)
{
DataTable dt = new DataTable();
dt = (DataTable)Session["sepet"];
foreach (DataRow r in dt.Rows)
{
lst.Add(r["ID"].ToString());
lst.Add(r["productName"].ToString());
}
ListBox1.DataSource = lst;
}
}
You can bind the data table to the ListBox, and specify which field is used for Text and wihch one is used for Value:
DataTable dt = Session["sepet"] as DataTable;
ListBox1.DataSource = dt;
ListBox1.DataTextField = "productname";
ListBox1.DataValueField = "ID";
ListBox1.DataBind();

Add To The Top in the DataList

This My code For binding My DataList ,and every item in datalist have a different button ,
the items sorted correctly by date but the index for each item not sorted with it ,
ex:
when insert a new data in employees table the data shows correct(sorted by date),the last employee was insert into employee table shows in the first item and take the index 0.
I want to know how i can to make his index The Last Index in my old data + 1 ?
private void bind()
{
da2 = new SqlDataAdapter("select * from employees order by insert_date desc", m_SqlConnection);
DataSet dataSet2 = new DataSet();
da2.Fill(dataSet2, "det");
DataList1.DataSource = dataSet2.Tables["det"];
DataList1.DataBind();
}
protected void DataList1_ItemDataBound(object sender, DataListItemEventArgs e)
{
Button btn = (Button)e.Item.FindControl("button4");
Button btn2 = (Button)e.Item.FindControl("button1");
da2 = new SqlDataAdapter("select insert_stat from insert_detail where user_id='" + int.Parse(Session["id"].ToString()) + "'", m_SqlConnection);
DataSet dataSet2 = new DataSet();
da2.Fill(dataSet2, "chk");
if (dataSet2.Tables["chk"].Rows[e.Item.ItemIndex]["insert_stat"].ToString() == "accept")
{
btn.Visible = true;
btn2.Visible = true;
}
else
{
if (dataSet2.Tables["chk"].Rows[e.Item.ItemIndex]["insert_stat"].ToString() == "reject")
{
btn.Visible = false;
btn2.Visible = false;
}
}
}
This is more a SQL problem than a DataList issue.
I recommend that you rewrite your SQL in the bind() method to do a JOIN on the insert_detail table to get the accept or reject value out of the table and into the bound data set for the data list. This serves two benefits:
It eliminates the database call in the DataList1_ItemDataBound() method, which if you have dozens or hundreds of rows, then that is dozens or hundreds less database calls.
It allows you to put the insert_stat value into a HiddenField control in your DataList and then check the value in the DataList1_ItemDataBound event, like this:
HiddenField theHiddenField = e.Item.FindControl("HiddenField1") as HiddenField;
// Make sure we found the control, because the as operator
// returns null for a failed cast
if(theHiddenField != null)
{
if(theHiddenField.Value.ToLower() == "accept")
{
btn.Visible = true;
btn2.Visible = true;
}
else
{
btn.Visible = false;
btn2.Visible = false;
}
}

create custom gridview template fields for a List<>

I have a List of Lists of string . I want to show it to user using a gridview . as number of columns are not known I decided to create gridview fields dynamically . I found some tutorials but all of them use DataTable . I tried to use the same but I have problem with databinding event's "_columnName" :
void field_DataBinding(object sender, EventArgs e)
{
TextBox txtdata = (TextBox)sender;
GridViewRow container = (GridViewRow)txtdata.NamingContainer;
object dataValue = DataBinder.Eval(container.DataItem, _columnName);
if (dataValue != DBNull.Value)
{
txtdata.Text = dataValue.ToString();
}
}
as there is no column in list . any suggestion is appreciated .
A much easier way would be to set AutoGenerateColumns to true and use a DataTable as DataSource.
For example ( the aspx can be an empty GridView ):
List<List<String>> data = new List<List<String>>() {
new List<String>(){"Row1_Col1", "Row1_Col2", "Row1_Col3"},
new List<String>(){"Row2_Col1", "Row2_Col2", "Row2_Col3"},
new List<String>(){"Row3_Col1", "Row3_Col2", "Row3_Col3"},
new List<String>(){"Row4_Col1", "Row4_Col2", "Row4_Col3"},
new List<String>(){"Row5_Col1", "Row5_Col2", "Row5_Col3"},
};
var tbl = new DataTable();
int maxFieldCount = data.Max(l => l.Count);
for (int i = 1; i <= maxFieldCount; i++)
tbl.Columns.Add("Column" + i);
foreach (var list in data)
{
DataRow newRow = tbl.Rows.Add();
newRow.ItemArray = list.ToArray();
}
now it can be used as DataSource of the GridView:
GridView1.DataSource = tbl;
GridView1.DataBind();

Drop Down List values in databind

My dropdownlist is set to databine like this...
dt = dal.FillDataTable(SqlConnectionString, "SELECT SQL Query Statement")
dropdownlist1.datasource = dt
dropdownlist1.datatextfield = dt.columns.item(0).tostring
dropdownlist1.databind()
This is turn populates my dropdownlist, when a user selects a value, it is then populated to the remaining textboxes on the remaining forms with a session call...
dropdownlist2.add(ctype(session.item("valOne"), String))
Through this session it populates the one value, is it possible to display the selected value but also include all other dropdownlist items in case they want to change thier selection? Any suggestions would really help?
I didnt understand adding one value at a time. Just show them all the associated values and let them select or change their decision.
Sample code
public DataSet GetmTest_Filter()
{
try
{
DataSet oDS = new DataSet();
SqlParameter[] oParam = new SqlParameter[1];
oParam[0] = new SqlParameter("#col_Id", _scolidvalue);
oDS = SqlHelper.ExecuteDataset(DataConnectionString, CommandType.StoredProcedure, "your_stored_procedure_here", oParam);
return oDS;
}
catch (Exception e)
{
ErrorMessage = e.Message;
return null;
}
}
public void ddlFill_Test(DropDownList ddl)
{
DataSet oDSddlmTest = new DataSet();
oDSddlmTest = GetmTest_Filter();
if (oDSddlmTest.Tables[0].Rows.Count > 0)
{
ddl.DataSource = oDSddlmTest.Tables[0].DefaultView;
ddl.DataTextField = "col_desc";
ddl.DataValueField = "col_id";
ddl.DataBind();
}
else
{
ddl.Enabled = false;
}
}
May this help you.

Resources