I am attempting to Dynamically generate an HTML Table. What I am after is to have a header row and a second row of textboxes under the header row (all aligned horizontally across the page). I attempted this syntax - however it ignores the values that are selected in the checkboxlist, and the textboxes for input are stacked on top of each other instead of horizontal.
Can someone right the errors in my ways?
protected void btnBullDozer_Click(object sender, EventArgs e)
{
StringBuilder sb = new StringBuilder(string.Empty);
var columnname = string.Empty;
foreach (System.Web.UI.WebControls.ListItem item in checkboxtest.Items)
{
columnname = item.Text;
sb.Append("<table>");
sb.Append("<tr>");
sb.Append("<th>Sponsor Level</th>");
sb.Append("<th>" + item.Selected + "</th>");
}
sb.Append("</tr>");
var cm = string.Empty;
int z = 1;
foreach (System.Web.UI.WebControls.ListItem item in checkboxtest.Items)
{
cm = item.Text;
sb.Append("<tr>");
sb.Append("<td><input type=\"text\" name=\"field " + z + "\"></td>");
z = z + 1;
}
sb.Append("</tr>");
sb.Append("</table>");
mask.InnerHtml = sb.ToString();
}
Hypothetical of what my desired grid should look like - let's say that the user selected 4 options from the checkboxlist then I would want 5 headers (Sponsor Level, and the names selected) then one row with 5 empty textboxes underneath for the data entry
Think about the logic of HTML.
<table>
<tr>
<th>Text</th>
<th>Text</th>
<th>Text</th>
</tr>
<tr>
<td>Text</td>
<td>Text</td>
<td>Text</td>
</tr>
</table>
So you want to:
<table>
<tr>
First foreach loop for the headings
<th>
Text
</th>
End Loop
</tr>
<tr>
Second foreach loop for the values
<td>
Value
</td>
End loop
</tr>
</table>
That is how I understand your comments. I know others have provided actual code but I wanted to go back to basics of HTML construct. When you have that clear in your mind you can convert it to logic to create it dynamically with loops.
You need to move tr and table out of for loop
Also, since you need following:
Input from you
I need header row going horizontal across the page (based off the selections from the checkboxlist) then for each header I need an input box under the header, only one row.
Changed your logic as follows:
protected void btnBullDozer_Click(object sender, EventArgs e)
{
StringBuilder sb = new StringBuilder(string.Empty);
var columnname = string.Empty;
sb.Append("<table>");
sb.Append("<tr>");
sb.Append("<th>Sponsor Level</th>");
foreach (System.Web.UI.WebControls.ListItem item in checkboxtest.Items)
{
//This loop will genrate a horizontal header for all checkbox items
columnname = item.Text;
sb.Append("<th>" + item.Selected + "</th>");
}
sb.Append("</tr>"); //empty td for Sponsor Level header
var cm = string.Empty;
int z = 1;
sb.Append("<tr><td></td>");
foreach (System.Web.UI.WebControls.ListItem item in checkboxtest.Items)
{
//This will generate a item under each header
cm = item.Text;
//if you want input for only selected items in checkbox uncomment following line
/*if(!item.Selected)
{
sb.Append("<td></td>");
}
else
{*/
sb.Append("<td><input type=\"text\" name=\"field " + z + "\"></td>");
// }
z = z + 1;
}
sb.Append("</tr>");
sb.Append("</table>");
mask.InnerHtml = sb.ToString();
Note: First forLoop will generate headers for all checkbox items. Second for loop will generate inputbox for all checkbox items. Its not very good logic though, we can refactor it a little to use only one loop
protected void btnBullDozer_Click(object sender, EventArgs e)
{
StringBuilder sb = new StringBuilder(string.Empty);
var columnname = string.Empty;
sb.Append("<table>");
sb.Append("<tr>");
foreach (System.Web.UI.WebControls.ListItem item in checkboxtest.Items)
{
columnname = item.Text;
sb.Append("<th>Sponsor Level</th>");
sb.Append("<th>" + item.Selected + "</th>");
}
sb.Append("</tr>");
var cm = string.Empty;
int z = 1;
sb.Append("<tr>");
foreach (System.Web.UI.WebControls.ListItem item in checkboxtest.Items)
{
cm = item.Text;
sb.Append("<td colspan="2"><input type=\"text\" name=\"field " + z + "\"></td>");
z = z + 1;
}
sb.Append("</tr>");
sb.Append("</table>");
mask.InnerHtml = sb.ToString();
}
Related
Please i have the below code that upon button click event, i create a delimited string from a gridview and display it in a textbox. Currently the loop creates the delimited string using all the columns available in the gridview. How do i specify only the columns that is needed to create the delimited string.
Per the image below i don't want the storeid column to be part of the delimeted string
This code is what am using to create the delimeted string
protected void CreatePOEntryString2()
{
{
string MyResults = "";
foreach (GridViewRow gRow in griditem.Rows)
{
if (MyResults != "")
MyResults += "|";
string MyRow = "";
foreach (TableCell tCell in gRow.Cells)
{
if (MyRow != "")
MyRow += ",";
MyRow += tCell.Text;
}
MyResults += MyResults;
}
txtPODetails.Text = MyResults + ItemPipe;
}
}
Thank you all
you can simply filter out storeid from the inner foreach (if you want to go with this approach)
foreach (TableCell tCell in gRow.Cells.where (x=>x.Text!="storeid"))
{
if (MyRow != "")
MyRow += ",";
MyRow += tCell.Text;
}
Please i have the below code that upon button click event, i create a delimited string from a gridview and display it in a textbox. Currently the loop creates the delimited string using all the columns available in the gridview. How do i specify only the columns that is needed to create the delimited string.
Per the image below i don't want the storeid column to be part of the delimeted string
This code is what am using to create the delimeted string
protected void CreatePOEntryString2()
{
{
string MyResults = "";
foreach (GridViewRow gRow in griditem.Rows)
{
if (MyResults != "")
MyResults += "|";
string MyRow = "";
foreach (TableCell tCell in gRow.Cells)
{
if (MyRow != "")
MyRow += ",";
MyRow += tCell.Text;
}
MyResults += MyResults;
}
txtPODetails.Text = MyResults + ItemPipe;
}
}
Thank you all
you can simply filter out storeid from the inner foreach (if you want to go with this approach)
foreach (TableCell tCell in gRow.Cells.where (x=>x.Text!="storeid"))
{
if (MyRow != "")
MyRow += ",";
MyRow += tCell.Text;
}
I have two string lists:
currentRow = contains the info that the row should have
currentCol = contains the names of the columns that data from currentRow should go in.
each List contains 25(0-24) items, and is ordered in the same way as the dataRow it should be written to.
I am filling the Lists here, from labels and textboxes on a form:
List<string> currentRow = new List<string>();
List<string> currentCol = new List<string>();
foreach (var c in form11.Controls)
{
if (c.GetType() == typeof(TextBox))
{
var str = c.ToString();
var str1 = str.Substring(35);
currentRow.Add(str1);
}
if (c.GetType() == typeof(Label))
{
var str = c.ToString();
var str1 = str.Substring(34);
currentCol.Add(str1);
}
}
I then select the row in the dataTable that needs to be updated from the 3rd item in currentRow, which is a unique identifier.
var updateRow = arraysDt.Select("SERIAL =" + "'" + currentRow.ElementAtOrDefault(2) + "'");
Now i try to update the row from the items in the Lists here:
for (int i = 0; i < currentRow.Count; i++)
{
//MessageBox.Show(currentCol.ElementAtOrDefault(i).ToString() + " " + currentRow.ElementAtOrDefault(i).ToString());
updateRow[0][currentCol.ElementAtOrDefault(i)] = currentRow.ElementAtOrDefault(i);
}
As soon as it gets inside the for loop i throws a "index was out of bounds of the array" error.
As i said, currentCol contains column names and currentRow is the value.
So when it get here i expect it to find the column name and then update it with the value.
updateRow[0][currentCol.ElementAtOrDefault(i)] = currentRow.ElementAtOrDefault(i);
What am i doing wrong?
I have found out the issue:
"SERIAL =" + "'" + currentRow.ElementAtOrDefault(2) + "'"
will give me this:
SERIAL=' XXXXX'
What i need is:
SERIAL='XXXXX'
so to fix it i did:
string SMnum = currentRow.ElementAt(2).ToString().Replace(" ", string.Empty);
string query = string.Format("SERIAL='{0}'", SMnum.Replace(#"'", "''"));
var updateRow = arraysDt.Select(query);
This removes any white space in the string that i am looking for.
I a subtotal for each item in a list Box, but I want to create a running subtotal in a text Box when I press a button, "Add to Order"
I'm not sure what kind of coding I would need, if it is an "if" statement or for statement
Loop through the values in the listbox.
string value = "The items you selected are:\r\n\r\n";
foreach (var item in ListBox1.Items)
{
value += "," + item.ToString();
}
TextBox1.Text = value;
foreach (var item in ListBox1.Items)
{
value += "," + item.ToString();
}
txtTotal.Text = value;
I am having trouble displayin the values of list itmes in the proper order. The following are the fields in the list (with their actual system names):
-Title
-Category
-NominatedWon
-Logo
The "Title" field contains year values eg, "2011", "2010", etc.
//getting the awards list and extracting correct values from the necesary fields
//asp running with elevated privilegs
SPSecurity.RunWithElevatedPrivileges(delegate()
{
using (SPSite site = new SPSite(webUrl))
{
using (SPWeb web = site.OpenWeb())
{
try
{
SPList awardsList = web.Lists["Awards"];
SPListItemCollection listItemCollection = awardsList.Items;
//Creating the table
Table tbl = new Table();
//foreach (SPListItem oListItem in listItemCollection)
int x = listItemCollectionI.Count;
for(int i = 0; (i * 2) < x; i++) // divide total item collection by two, each loop
iteration, add two awards to a row (left cell, right cell)
{
// get listItemCollection[i];
//Create table rows, table cells
int leftIndexer = i * 2;
int rightIndexer = (i * 2) + 1;
if (leftIndexer == x)
{
break;
}
TableRow tblRow = new TableRow();
TableCell tblCellLeft = new TableCell(); //for the awards in the first column
TableCell tblCellRight = new TableCell(); //for the awards in the second column
tblCellLeft.VerticalAlign = VerticalAlign.Top;
tblCellLeft.HorizontalAlign = HorizontalAlign.Center;
tblCellLeft.CssClass = ("style5");
tblCellRight.VerticalAlign = VerticalAlign.Top;
tblCellRight.HorizontalAlign = HorizontalAlign.Center;
// get the values
awardYear = listItemCollection[leftIndexer]["Title"].ToString();
awardCategory = listItemCollection[leftIndexer]["Category"].ToString();
awardNomWon = listItemCollection[leftIndexer]["NominatedWon"].ToString();
if(listItemCollection[leftIndexer]["Logo"] != null)
awardLogo = (string)listItemCollection[leftIndexer]["Logo"];
// add to left cell
//values for the left column
tblCellLeft.Controls.Add(new LiteralControl("<div class=\"style1\">" + awardYear +
"</div>"));
tblCellLeft.Controls.Add(new LiteralControl("<div class=\"style2\">" + awardCategory
+ "</div>"));
tblCellLeft.Controls.Add(new LiteralControl("<div class=\"style3\">" + awardNomWon +
"</div>"));
tblCellLeft.Controls.Add(new LiteralControl("<div class=\"style4\">" + "<img src=" +
awardLogo.Replace(",", "") + "</div>"));
// add left cell to row
tblRow.Cells.Add(tblCellLeft);
if (rightIndexer < x) // if this item exists in the collection (prevent bug with odd
number of awards)
{
// get the values
awardYear = listItemCollection[rightIndexer]["Title"].ToString();
awardCategory = listItemCollection[rightIndexer]["Category"].ToString();
awardNomWon = listItemCollection[rightIndexer]["NominatedWon"].ToString();
if (listItemCollection[rightIndexer]["Logo"] != null)
awardLogo = (string)listItemCollection[rightIndexer]["Logo"];
// add to right cell
//Values for the right column
tblCellRight.Controls.Add(new LiteralControl("<div class=\"style1\">" + awardYear +
"</div>"));
tblCellRight.Controls.Add(new LiteralControl("<div class=\"style2\">" + awardCategory
+ "</div>"));
tblCellRight.Controls.Add(new LiteralControl("<div class=\"style3\">" + awardNomWon +
"</div>"));
tblCellRight.Controls.Add(new LiteralControl("<div class=\"style4\">" + "<img src=" +
awardLogo.Replace(",", "") + "</div>"));
// add right cell to row
tblRow.Cells.Add(tblCellRight);
}
// add row to table
tbl.Rows.Add(tblRow);
}
PlaceHolder6.Controls.Add(tbl); // add table outside of loop
}
catch (Exception err)
{
PlaceHolder3.Controls.Add(new LiteralControl(err.ToString()));
}
}
}
});
So the output for some reason seems to show the two latest lists items eg list item "2012", and list item "2011" are displayed at the bottom. In theory these should be displayed at the top followed by the rest of the list items.
Any sugestions on this will be greatly appreciated!
Thanks
There's nothing in your code to indicate the order, use something along the lines of:
SPList awardsList = web.Lists["Awards"];
SPQuery q = new SPQuery();
q.Query="<OrderBy><FieldRef Name='Title' /></OrderBy>";
SPListItemCollection listItemCollection = awardsList.Items.GetItems(q);
Don't you have to use something like:
listItemCollection.OrderBy(i=>i.Title).ThenBy(i=>i.Category).ThenBy(i=>i.NominatedWon).ThenBy(i=>i.Logo)