I'm adding a series of dropdown lists populated from a database to a page from code behind. Because I need a variable number of sections with each containing a variable number of dropdown lists, I'm having to run my queries and then put build and place the HTML straight onto the page. I'm sure there's a better way to do this (nested repeaters, possibly) but it is working. My HTML is:
Question
<input type='hidden' id='h100' />
<select id='q100'>
<option>Answer 1</option>
<option>Answer 2</option>
<option>Answer 3</option>
</select>
However, when the page POSTs back, I'm not getting these fields in the form collection. It's really odd because they seemed to be there yesterday, but then I come back to the page and can't find them.
Why would these not be appearing in the form collection after POST?
I'm using C# for code behind, any help is very appreciated.
Edit: Here is my code behind (please don't hurt me, I'm learning ASP.NET as I go):
if (!Page.IsPostBack)
{
// Much stuff that works fine, connecting to database, etc.
// Get matching questions - variables
ArrayList matchingSections = new ArrayList();
int matchingSectionCount;
// Get count of matching sections
OracleCommand cmdMatchSectCount = new OracleCommand("Select Count(distinct matching_section) From graphite.question Join graphite.q_matching Using(q_id) Where t_id = " + Session["TestTaking"].ToString(), conn);
OracleDataReader drMatchSectCount = cmdMatchSectCount.ExecuteReader();
drMatchSectCount.Read();
matchingSectionCount = (int)drMatchSectCount.GetOracleNumber(0).Value;
Session["MatchingSectionCount"] = matchingSectionCount;
// Get matching sections
OracleCommand cmdMatchSects = new OracleCommand("Select Distinct matching_section From graphite.question Join graphite.q_matching Using(q_id) Where t_id = " + Session["TestTaking"].ToString() + " Order By matching_Section", conn);
OracleDataReader drMatchSects = cmdMatchSects.ExecuteReader();
for(int i = 0; i < matchingSectionCount; i++)
{
drMatchSects.Read();
matchingSections.Add(drMatchSects.GetOracleString(0).Value);
}
foreach (String s in matchingSections)
{
string row = string.Empty;
int questionCount;
ArrayList answers = new ArrayList();
matchManual.InnerHtml += "\n<h2>Matching Section - " + s + "</h2>";
matchManual.InnerHtml += "\n<table>";
OracleCommand cmdQuestionCount = new OracleCommand("Select Count(correct_answer) From graphite.question Join graphite.q_matching Using(q_id) Where t_id = " + Session["TestTaking"].ToString() + " and matching_section = '" + s + "'", conn);
OracleDataReader drQuestionCount = cmdQuestionCount.ExecuteReader();
drQuestionCount.Read();
questionCount = int.Parse(drQuestionCount.GetOracleNumber(0).Value.ToString());
OracleCommand cmdMatchAnswers = new OracleCommand("Select correct_answer From graphite.question Join graphite.q_matching Using(q_id) Where t_id = " + Session["TestTaking"].ToString() + " and matching_section = '" + s + "' Order By correct_answer", conn);
OracleDataReader drMatchAnswers = cmdMatchAnswers.ExecuteReader();
for (int i = 0; i < questionCount; i++)
{
drMatchAnswers.Read();
answers.Add(drMatchAnswers.GetOracleString(0).Value.ToString());
}
OracleCommand cmdMatchLoop = new OracleCommand("Select q_phrase, q_id From graphite.question Join graphite.q_matching Using(q_id) Where t_id = " + Session["TestTaking"].ToString() + " and matching_section = '" + s + "'", conn);
OracleDataReader drMatchLoop = cmdMatchLoop.ExecuteReader();
for (int i = 0; i < questionCount; i++)
{
drMatchLoop.Read();
row += "\n <tr>";
row += "\n <td>" + drMatchLoop.GetOracleString(0).Value ;
row += "<input type='hidden' id='h" + drMatchLoop.GetOracleNumber(1).Value.ToString() + "' />";
row += "\n </td>";
row += "\n <td>";
row += "\n <select id='q" + drMatchLoop.GetOracleNumber(1).Value.ToString() + "' runat='server'>";
foreach(string answer in answers)
{
row += "\n <option>" + answer + "</option>";
}
row += "\n </select>";
row += "\n </td>";
row += "\n </tr>";
}
matchManual.InnerHtml += row;
matchManual.InnerHtml += "\n</table>\n\n";
}
Wow. Just...wow. With <select>, you have to include a name='value', not id='value'. Moral: know your HTML. And try harder to find ways to avoid spewing raw HTML onto a page.
If they are not present in the formcollection when submiting, I think the problem is they are not within a form tag that is submited, or you have to create the form tag and place the select tag in it.
#edited
Aha - so it was within a form, see now that the reason was the missing name attribute in the select tag!
The form collection uses the attribute name values as keys when posted.
I think that your Page.IsPostBack condition is source of problems. Because you are generating elements only on !IsPostback => only 'first' time, not after the post => they are missing after the post.
Related
So I'm stumped on this problem.
I need to get all the column values of another table (tbladdbenefit) and add them to another table (payrolltable) and insert all the values of the first table into a single cell.
In this case, I'm trying to insert all of the values of column "benefit" to a single cell of "benefit" on the new table, the same thing for "BenefitAmount".
So far I am using Parameters.AddWithValue but to no avail. I have 2 data from the column benefit from the first table but it only shows the record I highlighted. Which is not what I want to do. I want to display and add all the records of my parent table
Any suggestions?
cmd = new SqlCommand("INSERT INTO payrolltable " +
"(Name, " +
"Position, " +
"Honoraria, " +
"Total, " +
"Benefit, " +
"BenefitAmount, " +
"Deduction, " +
"DeductionAmount) " +
"VALUES " +
"(#name, " +
"#position, " +
"#honoraria, " +
"#total, " +
"#benefit, " +
"#benefitamount, " +
"#deduction, " +
"#deductionamount)", con);
cmd.Parameters.AddWithValue("#name", txtfname.Text + " " + txtlname.Text);
cmd.Parameters.AddWithValue("#position" , txtposition.Text);
cmd.Parameters.AddWithValue("#honoraria", txtsalary.Text);
cmd.Parameters.AddWithValue("#total", 323232);
cmd.Parameters.AddWithValue("#benefit", SqlDbType.VarChar);
cmd.Parameters.AddWithValue("#benefitamount", SqlDbType.BigInt);
cmd.Parameters.AddWithValue("#deduction", " ");
cmd.Parameters.AddWithValue("#deductionamount", " ");
for (int i = 0; i < tbladdbenefit.Rows.Count - 1; i++)
{
cmd.Parameters["#benefit"].Value = tbladdbenefit.Rows[i].Cells[1].Value;
cmd.Parameters["#benefitamount"].Value = tbladdbenefit.Rows[i].Cells[2].Value;
}
There are a couple of ways to store multiple values in a column of a database table.
You can store it as CSV (comma separated values) or JSON or XML, But it will have its downside when you want to update this column values or want to query on this table.
Also just refer to this as well.
Sample as requested:
Please follow the sample to help you to understand the concept.
List<string> ls = new List<string>();
for (int i = 0; i < tbladdbenefit.Rows.Count - 1; i++)
{
ls.Add(tbladdbenefit.Rows[i].Cells[1].Value);
}
string csv = string.Join(",", ls);
cmd.Parameters["#benefit"].Value = csv;
Currently, I am grabbing an unknown number of rows from a database and writing to a table. Each table cell is given a unique ID from the database.
Is there a way I can access these IDs to apply a certain CSS attribute to them, i.e:
reader.GetString("id").Attributes.CssStyle.Add("background-color", "#e1e1e1");
Sorry, still new to this - for example:
string sql = "select * from test";
MySqlConnection conn = new MySqlConnection(connString);
MySqlCommand cmd = new MySqlCommand(sql, conn);
conn.open
MySqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
q += "<tr><td id='" + reader.GetString("id") + "'>" + reader.GetString("name") + "</td></tr>\r\n";
if (reader.GetString("name") == "test")
{
// This will not work - I need to reference the actual ID - how can I get this to work?
reader.GetString("id").Attributes.CssStyle.Add("background-color", "#e1e1e1");
}
}
You are building HTML in the string q, so you also have to add the color definition inside q. The simplest way is something like this:
while (reader.Read())
{
var id = reader.GetString("id");
var name = reader.GetString("name");
// define style using the ? ... : ... operator
var style = name == "test" ? "background-color: #e1e1e1" : "";
q += "<tr><td id='" + id + "' style='" + style + "'>" + name + "</td></tr>\r\n";
}
Note that building long strings tends to get slow, because each new addition will repeatedly make a copy of all text you had thus far + the new text.
A usually more efficient way is using a StringBuilder:
var sb = new System.Text.StringBuilder();
while (reader.Read())
{
var id = reader.GetString("id");
var name = reader.GetString("name");
var style = name == "test" ? "background-color: #e1e1e1" : "";
sb.AppendLine("<tr><td id='" + id + "' style='" + style + "'>" + name + "</td></tr>");
}
// use sb.ToString() for the result
I have a small problem regarding the Access Database when it has data inserted.
I have a button that inserts data when it's clicked. Here it is the code:
string[] read = File.ReadAllLines("Harta_Distantelor.txt");
string[] orase = { "Constanta", "Varna", "Burgas", "Istambul", "Kozlu", "Samsun", "Batumi", "Sokhumi", "Soci", "Anapa", "Yalta", "Sevastopol", "Odessa" };
OleDbCommand cmd;
for (int i = 0; i < read.Length; i++)
{
int j = 0;
string[] numbers = read[i].Split(' ');
while (j < read.Length)
{
//cmd = new OleDbCommand("UPDATE Distante SET ID_Port='" + (i + 1) + "', ID_Port_Destinatie='" + (j + 1) + "', Nume_Port_Destinatie='" + orase[j] + "' WHERE Distanta='" + numbers[j] + "' ", conn);
cmd = new OleDbCommand("INSERT INTO [Distante]([ID_Port], [ID_Port_Destinatie], [Nume_Port_Destinatie], [Distanta]) VALUES ('" + (i + 1).ToString() + "', '" + (j + 1).ToString() + "', '" + orase[j] + "', '" + numbers[j] + "')", conn);
cmd.ExecuteNonQuery();
j++;
}
}
The problem is that instead of having something like ID_Port=1, ID_Port_Destinatie=1, Nume_Port_Destinatie="Constanta", ID_Port=1, ID_Port_Destinatie=2, Nume_Port_Destinatie="Varna" and so on, I get this...
https://i.stack.imgur.com/OjMQm.png
The file "Harta_Distantelor.txt" is a matrix that has the distances, so that's why I tried to split every number from a line(string[] numbers = read[i].Split(' ');). I have to mention that [Distanta] data is correctly inserted, but the rest of the data is totally randomly inserted. I tried to figure out where the problem is, but I have no clue. Where is the mistake? What should I try to do in order to have the data showed correctly?
1.) Create a table called HartaDistantelor with columns for ID_Port, ID_Port_Destinatie, and Distanta
2.) Fill the table HartaDistantelor with your matrix values. You may be able to copy and paste directly into Access
3.) Create a table called Orase with columns for ID_Port and Nume_Port
4.) Fill the table Orase with the 13 values from your array. It should look like this:
1 Constanta
2 Varna
3 Burgas
4 ...
5.) Change your code:
OleDbCommand cmd;
for (int i = 0; i < 12; i++)
{
for (int j = 0; j < 12; j++)
{
cmd = new OleDbCommand("INSERT INTO Distante (ID_Port, ID_Port_Destinatie, Nume_Port_Destinatie, Distanta) SELECT " + (i + 1).ToString() + ", " + (j + 1).ToString() + ", o.Nume_Port, h.Distanta FROM Orase o JOIN HartaDistantelor h ON h.ID_Port = o.ID_Port WHERE h.ID_Port = i AND h.ID_Port_Destinatie = j", conn);
cmd.ExecuteNonQuery();
}
}
My approach joins records from two tables using ID values that match. I don't think you made any mistake, but used a method with more complexity than was necessary.
I have a Multiple Select DROPDOWNLIST to select items. See the Dropdownlist below
[![dropdownlist][1]][1]
What I am doing is, I am selecting 2 items from the list. One of PROCESSED and another of PENDING
So what's happening wrong here is, when the condition is PROCESSED it works properly and goes in IF condition but second time it is PENDING but still it goes in the IF condition.
using (SqlConnection conn = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["ConnectionString"].ToString()))
{
using (SqlCommand sqcmd = new SqlCommand("select month(a.dt_of_leave)month, year(a.dt_of_leave)year " +
"from emp_mst a where month(a.dt_of_leave) >= month(getdate())-1 and " +
"year(a.dt_of_leave)= case when month(getdate())=1 " +
"then year(getdate())-1 else year(getdate()) end " +
"and emp_card_no IN (" + str_emp_sel + ") order by emp_name", conn))
{
SqlDataAdapter damonthyear = new SqlDataAdapter(sqcmd);
damonthyear.Fill(dtspmonthyear);
for (i = 0; i < dtspmonthyear.Rows.Count; i++)
{
if (cmbEmp_Name.SelectedItem.Text.Contains("PROCESSED") == true)
{
//CF.ExecuteQuerry("exec Emp_Resign_Allocate_Leave '" + str_emp_sel + "','" + dtspmonthyear.Rows[0]["month"].ToString() + "', '" + dtspmonthyear.Rows[0]["year"].ToString() + "'");
}
else
{
// not going in else for `PENDING`
}
}
}
}
This is the markup:
<asp:DropDownCheckBoxes ID="cmbEmp_Name" AddJQueryReference="true" Width="60%" runat="server"
DataTextField="Employee Name" DataValueField="User_ID" UseSelectAllNode="false">
<Style DropDownBoxBoxWidth="500px" DropDownBoxBoxHeight="45%" SelectBoxWidth="55%" />
</asp:DropDownCheckBoxes>
try something similar to:
for (i = 0; i < dtspmonthyear.Rows.Count; i++)
{
foreach (var item in cmbEmp_Name.Items)
{
if (item.Selected)
{
if (item.Text.Contains("PROCESSED"))
{
//CF.ExecuteQuerry("exec Emp_Resign_Allocate_Leave '" + str_emp_sel + "','" + dtspmonthyear.Rows[0]["month"].ToString() + "', '" + dtspmonthyear.Rows[0]["year"].ToString() + "'");
}
else
{
// not going in else for `PENDING`
}
}
}
}
You apparently downloaded some control from the web. Its documentation states:
DropDownCheckBoxes is an ASP.NET server control directly inheriting from standard ASP.NET CheckBoxList control.
Cool, so we can just search the web for what we want to do: "ASP.NET CheckBoxList get selected items", which yields Q&As like How can I get the CheckBoxList selected values, what I have doesn't seem to work C#.NET/VisualWebPart, How to get values of selected items in CheckBoxList with foreach in ASP.NET C#? and so on:
foreach (ListItem item in dropDownCheckBoxList.Items)
{
if (item.Selected)
{
// Do what you want to do
}
}
I'm currently working on a project using MySql in combination with C#.
The Data for the DataGridView is provided by a join from multiple tables in the DB. To show the data I use the following, working, code:
adapter.SelectCommand = new MySqlCommand(
" SELECT" +
" l.lot AS Lot, "+
" m.comment AS Bemerkungen," +
... (multiple columns from different tables) ...
" FROM m " +
" JOIN m2p ON m.m2p_id = m2p.id" +
... (more joins) ...
, this._mySqlConnection);
dataGridView1.DataSource = data;
adapter.Fill(data);
Now the user of the GUI is allowed to modify a certain column (the "comment" column). So I assigned an eventHandler to the CellEndEdit event and when the user modified the allowed column the adapter.Update(data) is called. Now this doesn't perform the correct action.
To define my updatecommand I used the following code:
adapter.UpdateCommand = new MySqlCommand(
" UPDATE m" +
" JOIN l ON m.l_id = l.id" +
" SET m.comment = #comment" +
" WHERE l.lot = #lot"
, this._mySqlConnection);
adapter.UpdateCommand.Parameters.Add("#comment", MySqlDbType.Text, 256, "Bemerkungen");
adapter.UpdateCommand.Parameters.Add("#lot", MySqlDbType.Text, 256, "Lot");
Could you explain me how I fix my code to automatically Update the database?
EDIT:
added further source code:
private MySqlDataAdapter warenlagerMySqlDataAdapter, kundenMySqlDataAdapter;
private DataTable warenlagerData, kundenData;
private DataGridView warenlagerGridView;
private void updateWarenlagerView(object sender, EventArgs e) {
warenlagerMySqlDataAdapter.Update(warenlagerData);
}
private void initialzeFields() {
warenlagerGridView.CellEndEdit += new DataGridViewCellEventHandler(this.updateWarenlagerView);
warenlagerMySqlDataAdapter = new MySqlDataAdapter();
warenlagerData = new DataTable();
}
private void initializeWarenlagerView() {
warenlagerMySqlDataAdapter.SelectCommand = new MySqlCommand(
" SELECT" +
" c.name AS Ursprung, " +
" m2p.art_nr AS ArtNr," +
" m.delivery_date AS Eingangsdatum," +
" CONCAT(FORMAT(m.delivery_amount / 100, 2), 'kg') AS Eingangsmenge, " +
" l.lot AS Lot," +
" m.quality AS Qualität," +
" m.comment AS Bemerkungen," +
" CONCAT(m.units, 'kg') AS Units," +
" CONCAT(FORMAT(s.amount / 100, 2), 'kg') AS Lagermenge, " +
" FORMAT(m.base_price / 100, 2) AS Einkaufspreis," +
" FORMAT(s.amount/10000 * m.base_price, 2) AS Wert" +
" FROM mushrooms AS m " +
" JOIN mushroom2path AS m2p ON m.mushroom2path_id = m2p.id" +
" JOIN countries AS c ON m.origin_id = c.id" +
" JOIN lots AS l ON m.lot_id = l.id" +
" JOIN stock AS s ON s.mushrooms_id = m.id"
, this._mySqlConnection);
warenlagerGridView.DataSource = warenlagerData;
warenlagerMySqlDataAdapter.Fill(warenlagerData);
warenlagerMySqlDataAdapter.UpdateCommand = new MySqlCommand(
" UPDATE mushrooms AS m" +
" JOIN lots AS l ON m.lot_id = l.id" +
" SET m.comment = #comment" +
" WHERE l.lot = #lot"
, this._mySqlConnection);
warenlagerMySqlDataAdapter.UpdateCommand.Parameters.Add("#comment", MySqlDbType.Text, 256, "Bemerkungen");
warenlagerMySqlDataAdapter.UpdateCommand.Parameters.Add("#lot", MySqlDbType.Text, 256, "Lot");
}
This is the whole code concerning this problem. I'm 100% sure the adapter.Update(data) method is called (debugging). And the data which is passed to the adapter.Update() method contains the new data.
Please try this update query it works.
UPDATE mushrooms
SET comment = #comment
WHERE
l_id=(select id from l where lot=#lot)
Your update statement is incorrect. It should be:
"UPDATE m FROM mushrooms m JOIN lots l ON m.lot_id = l.id SET m.comment = #comment WHERE l.lot = #lot"
Did you forget to execute the warenlagerMySqlDataAdapter.UpdateCommand?
You are just setting the command and the parameters but not executing it.
What I see is that you are calling the update when the info is updated, but your update command is not loaded.
You just call updateWarenlagerView when you update the row, but where are you calling initialzeFields?
Or am I missing code?
Try moving your update code from the CellEndEdit event to the CellValueChanged event and see if this works.
Try this example out:
public void UpdateAllFromDgv(DataGridView dataGridView1)
{
string query = "Update List set ColumnName1=#Value1" +
",ColumnName2=#Value2" +
",ColumnName3=#Value3" +
",ColumnName4=#Value4" +
",ColumnName5=#Value5" +
",ColumnName6=#Value6 where ColumnName0=#Value0";
try
{
foreach (DataGridViewRow row in dataGridView1.Rows)
{
using (MySqlConnection con = new MySqlConnection(ConnectionString))
{
using (MySqlCommand cmd = new MySqlCommand(query, con))
{
cmd.Parameters.AddWithValue("#Value0", row.Cells[0].Value);
cmd.Parameters.AddWithValue("#Value1", row.Cells[1].Value);
cmd.Parameters.AddWithValue("#Value2", row.Cells[2].Value);
cmd.Parameters.AddWithValue("#Value3", row.Cells[3].Value);
cmd.Parameters.AddWithValue("#Value4", row.Cells[4].Value);
cmd.Parameters.AddWithValue("#Value5", row.Cells[5].Value);
cmd.Parameters.AddWithValue("#Value6", row.Cells[6].Value);
con.Open();
cmd.ExecuteNonQuery();
dataGridView1.ResetBindings();
con.Close();
}
}
}
}
catch (MySqlException MsE)
{
MessageBox.Show(MsE.Message.ToString());
}
}