I'm working on sending an email for order confirmation and I need to loop every items that the user order from my website. So, I use the foreach to load very items in the email but it return a html code.
string body = string.Empty;
using (StreamReader reader = new StreamReader(Server.MapPath(templatePath)))
{
body = reader.ReadToEnd();
}
var items = "";
foreach (var itemList in orderProducts)
{
items += "<tbody style=\"border: 0; border - bottom: 1px dashed #ccc;\"><tr>< td style = \"text-align:center;\" width = \"200\" >{ Image}</ td >< td style = \"text-align:left\" width = \"250\" >"+ itemList.Name + "</ td >< td style = \" text-align:center\" width = \"100\" >" + itemList.Quantity + "</ td >< td style = \" text-align:center\" width = \"100\" >" + itemList.Price +"</ td ></ tr ></ tbody > ";
}
body = body.Replace("{Items}", items);
System.Net.Mail.AlternateView htmlView = System.Net.Mail.AlternateView.CreateAlternateViewFromString(body, null, "text/html");
mailMessage.AlternateViews.Add(htmlView);
//Send message
System.Net.Mail.SmtpClient smtpClient = new
System.Net.Mail.SmtpClient(mailServer);
smtpClient.Port = 587;
smtpClient.Credentials = new
System.Net.NetworkCredential(senderMail,senderPassword);
smtpClient.EnableSsl = true;
smtpClient.Send(mailMessage);
my email template
<table cellpadding="0" cellspacing="0" width="100%" style="border-collapse: collapse;margin-top:-20px;">
<thead style="border: 0;border-bottom: 1px dashed #ccc;">
<tr>
<td style=" text-align:center" width="200"><b>ITEMS ORDERED</b></td>
<td style=" text-align:center" width="250">NAME</td>
<td style=" text-align:center" width="100">QTY</td>
<td style=" text-align:center" width="100">PRICE</td>
</tr>
</thead>
{Items}
</table>
and here's the result in my email. How to read the html code? Thank you for helping me.
You are adding multiple <tbody> elements to your table but that isn't the main problem. You need to remove the extra spaces from your < tr and < td elements. See snippet below for example with and without spaces.
You should also use StringBuilder when manipulating strings like this as it's more efficient.
var sb = new StringBuilder();
foreach (var itemList in orderProducts)
{
sb.AppendLine("<tbody style=\"border: 0; border-bottom: 1px dashed #ccc;\">");
sb.AppendLine("<tr>");
sb.AppendLine("<td style=\"text-align:center;\" width=\"200\">{Image}</td>");
sb.AppendLine("<td style=\"text-align:left\" width=\"250\">"+ itemList.Name + "</td>");
sb.AppendLine("<td style=\"text-align:center\" width=\"100\">" + itemList.Quantity + "</td>");
sb.AppendLine("<td style=\"text-align:center\" width=\"100\">" + itemList.Price +"</td>");
sb.AppendLine("</tr>");
sb.AppendLine("</tbody>");
}
var items = sb.ToString();
<h1>Without Spaces</h1>
<table cellpadding="0" cellspacing="0" width="100%" style="border-collapse: collapse;">
<thead style="border: 0;border-bottom: 1px dashed #ccc;">
<tr>
<td style=" text-align:center" width="200"><b>ITEMS ORDERED</b></td>
<td style=" text-align:center" width="250">NAME</td>
<td style=" text-align:center" width="100">QTY</td>
<td style=" text-align:center" width="100">PRICE</td>
</tr>
</thead>
</table>
<h1>With Spaces</h1>
<table cellpadding="0" cellspacing="0" width="100%" style="border-collapse: collapse;">
< thead style="border: 0;border-bottom: 1px dashed #ccc;">
< tr>
< td style=" text-align:center" width="200"><b>ITEMS ORDERED</b></td>
< td style=" text-align:center" width="250">NAME</td>
< td style=" text-align:center" width="100">QTY</td>
< td style=" text-align:center" width="100">PRICE</td>
</ tr>
</ thead>
</ table>
My model have List products which get from database.
When index view loaded, i get the variable from input of user, then model get varible, and return view OutputTableAsync. After view loaded, i click link "Export Excel", in debug mode, List products is null.
My view:
<body>
#if (Model != null)
{
var products = Model.products.Products;
Export Excel
<table border="1" style="width: 100%">
<thead>
<tr>
<th>Model</th>
<th>Price</th>
<th>Link</th>
<th>ImageUrl</th>
</tr>
</thead>
<tbody>
#foreach (var product in Model.products.SortProduct())
{
<tr id="i">
<td align="center">#product.Model</td>
<td align="center">#product.FormatPrice()</td>
<td align="center">#product.Link</td>
<td align="center"><img src="#product.ImageUrl" style="width : 200px; height:200px ;" id="#product.ImageUrl" /></td>
</tr>
}
</tbody>
</table>
}
</body>
ExportToExcel method in controller:
public void ExportToExcel(List<Product> products)
{
ExcelPackage pck = new ExcelPackage();
ExcelWorksheet ws = pck.Workbook.Worksheets.Add("Products");
ws.Cells["A1"].Value = "Model";
ws.Cells["B1"].Value = "Price";
ws.Cells["C1"].Value = "Link";
ws.Cells["D1"].Value = "ImageLink";
int rowstart = 2;
foreach(var item in products)
{
ws.Cells[string.Format("A{0}", rowstart)].Value = item.Model;
ws.Cells[string.Format("B{0}", rowstart)].Value = item.Price;
ws.Cells[string.Format("C{0}", rowstart)].Value = item.Link;
ws.Cells[string.Format("D{0}", rowstart)].Value = item.ImageUrl;
rowstart++;
}
ws.Cells["A:AZ"].AutoFitColumns();
Response.Clear();
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Response.AddHeader("content-disposition", "attachment: filename=" + "ExcelFile.xlsx");
Response.BinaryWrite(pck.GetAsByteArray());
Response.End();
}
According to accepted answer here you can not pass complex type through Url.Action
I would pass serialized version of object in this situation.
I am developing a C# application in which I need to parse a specific row from a table and compare its different values to a given string.
The URL I want to parse is
http://wsrpg.com/clans/57
<table cellspacing="0" cellpadding="0" border="0" class="table">
<thead>
<tr>
<th width="100">Rank</th>
<th width="150">Nick</th>
<th width="100">RCASH</th>
<th width="150">Activity in December</th>
<th width="100">Comportment</th>
<th width="100">Online</th>
<th width="150">Last Login</th>
</tr>
</thead>
<tr><td>Leader</td><td>robbie_william</td><td>351</td><td>1024</td><td>1195</td><td class='offline'><span class="label label-danger">Offline</span></td><td>03/01/2016</td></tr><tr><td>Boss</td><td>Alloy_</td><td>1418</td><td>1043</td><td>354</td><td class='offline'><span class="label label-danger">Offline</span></td><td>26/12/2015</td></tr><tr><td>Boss</td><td>AnonYmous_</td><td>32976</td><td>5142</td><td>937</td><td class='offline'><span class="label label-danger">Offline</span></td><td>04/01/2016</td></tr><tr><td>Boss</td><td>dJones</td><td>2739</td><td>6152</td><td>1044</td><td class='online'><span class="label label-success">Online</span></td><td>04/01/2016</td></tr><tr><td>Boss</td><td>SHARP</td><td>9015</td><td>1216</td><td>32</td><td class='offline'><span class="label label-danger">Offline</span></td><td>04/01/2016</td></tr><tr><td>Boss</td><td>Steffie</td><td>7888</td><td>6043</td><td>887</td><td class='online'><span class="label label-success">Online</span></td><td>04/01/2016</td></tr><tr><td>Boss</td><td>YOLOvsYODO</td><td>10950</td><td>2703</td><td>385</td><td class='offline'><span class="label label-danger">Offline</span></td><td>04/01/2016</td></tr><tr><td>Member</td><td>Angel_</td><td>8629</td><td>3256</td><td>167</td><td class='offline'><span class="label label-danger">Offline</span></td><td>04/01/2016</td></tr><tr><td>Member</td><td>asad</td><td>2452</td><td>3938</td><td>183</td><td class='offline'><span class="label label-danger">Offline</span></td><td>03/01/2016</td></tr><tr><td>Member</td><td>D3nim</td><td>1285</td><td>3217</td><td>31</td><td class='offline'><span class="label label-danger">Offline</span></td><td>03/01/2016</td></tr><tr><td>Member</td><td>Dell</td><td>5025</td><td>3305</td><td>182</td><td class='offline'><span class="label label-danger">Offline</span></td><td>01/01/2016</td></tr><tr><td>Member</td><td>Habib</td><td>1650</td><td>3860</td><td>36</td><td class='offline'><span class="label label-danger">Offline</span></td><td>04/01/2016</td></tr><tr><td>Member</td><td>Iron_MiXx</td><td>2569</td><td>485</td><td>525</td><td class='offline'><span class="label label-danger">Offline</span></td><td>03/01/2016</td></tr><tr><td>Member</td><td>MCool</td><td>4960</td><td>12739</td><td>290</td><td class='online'><span class="label label-success">Online</span></td><td>04/01/2016</td></tr><tr><td>Member</td><td>PREXEN</td><td>127</td><td>3873</td><td>1547</td><td class='offline'><span class="label label-danger">Offline</span></td><td>04/01/2016</td></tr><tr><td>Member</td><td>Sensation_</td><td>2733</td><td>1944</td><td>338</td><td class='offline'><span class="label label-danger">Offline</span></td><td>03/01/2016</td></tr><tr><td>Member</td><td>Wizard_</td><td>2081</td><td>2578</td><td>46</td><td class='offline'><span class="label label-danger">Offline</span></td><td>03/01/2016</td></tr>
</table>
I only want the nick's to be stored in a string or a string array, so that I can use it compare to an already given string.
What I want to achieve, is to check whether the nick entered by the user exists in this table or not.
I am going to use a bool method to achieve that.
Solution:
I used Tim Schmelter's code, and here is how I used it:
private bool Authenticate(string nick)
{
using (WebClient client = new WebClient())
{
string html = client.DownloadString("http://wsrpg.com/clans/57");
DataTable table = GetTable(html, "table", true);
string[] nicks = table.AsEnumerable().Select(r => r.Field<string>("nick")).ToArray();
if(nicks.Contains(nick))
{
return true;
}
else
{
return false;
}
}
}
And then called it by
bool Authenticated = Authenticate(Player.GetName());
You could use this method that parses HTML and fills a DataTable with the first table that contains a given class name:
public static DataTable GetTable(string html, string tableClass, bool firstRowContainsHeader = false)
{
var doc = new HtmlAgilityPack.HtmlDocument();
doc.LoadHtml(html);
string xpath = string.Format("//table[contains(#class,'{0}')]", tableClass);
var firstTable = doc.DocumentNode.SelectSingleNode(xpath);
if (firstTable == null) return null;
DataTable table = new DataTable();
var tableRows = firstTable.Descendants("tr");
var tableData = tableRows.Skip(firstRowContainsHeader ? 1 : 0)
.Select(row => row.Descendants("td")
.Select((cell, index) => new { row, cell, index, cell.InnerText })
.ToList());
var headerCells = tableRows.First().Descendants()
.Where(n => n.Name == "td" || n.Name == "th");
int columnIndex = 0;
foreach (HtmlNode cell in headerCells)
{
string colName = firstRowContainsHeader
? cell.InnerText
: String.Format("Column {0}", (++columnIndex).ToString());
table.Columns.Add(colName, typeof(string));
}
foreach (var rowCells in tableData)
{
DataRow row = table.Rows.Add();
for (int i = 0; i < Math.Min(rowCells.Count, table.Columns.Count); i++)
{
row.SetField(i, rowCells[i].InnerText);
}
}
return table;
}
Then you can use LINQ-To-DataTable to check if it contains the given nick:
string html = File.ReadAllText("C:\\Temp\\html.txt"); // loading your sample from file
DataTable table = GetTable(html, "table", true);
string nick = "robbie_william"; // input example
bool isContained = table.AsEnumerable()
.Any(r => nick.Equals(r.Field<string>("nick"), StringComparison.InvariantCultureIgnoreCase));
if you just want to fill a string[] or List<string>:
string[] nicks = table.AsEnumerable().Select(r => r.Field<string>("nick")).ToArray(); // or ToList()
Easiest way to do this is with the XPath of the element so from an application I have that parses a different table I have:
string tableResult = htmlDocument.DocumentNode.SelectSingleNode("//table[#class='output']/tr[3]/td[3]").InnerText;
I currently have table that displays a list of all of the issues. I added PagedList.MVC to the application as well as a jquery filterTable the issue is that when I click on a different page using the PagedListPager it loses all of the sort options at the top of the page. I believe I just need to add the parameters to the pagedlistpager but I am not sure how to get the value of the textbox. I was thinking about trying to use jquery and using the val() of the element but not sure if that is the best/easiest way to do this.
Here is my View:
#model PagedList.IPagedList<ApIssues.Models.AP_Tasks>
#using System.Data.SqlClient
#using PagedList.Mvc;
#{
ViewBag.Title = "Index";
}
<div class="search-sort-section">
<h2>Search and Sort</h2>
#using (Html.BeginForm("Index","ApIssues"))
{
<p>
#Html.Label("Company: ")
#Html.DropDownList("company", (SelectList)ViewBag.CompanyList, " ")
#Html.Label("Warehouse: ")
#Html.DropDownList("warehouse", (SelectList)ViewBag.WarehouseList, " ")
#Html.Label("Past Due Only: ")
#Html.DropDownList("pastDue", (SelectList)ViewBag.PastDueList, " ")
#Html.Label("Assigned To/By: ")
#Html.DropDownList("assignedToBy", (SelectList)ViewBag.UsersList, " ")
</p>
<p>
#Html.Label("Open / Completed: ")
#Html.DropDownList("openco", (SelectList)ViewBag.OpenCompList, " ")
#Html.Label("Sort By: ")
#Html.DropDownList("sortBy", (SelectList)ViewBag.SortByList, " ")
#Html.Label("PO #: ")
#Html.TextBox("poNumber")
#Html.Label("Freight #: ")
#Html.TextBox("freightNumber")
#Html.Label("Vendor Name: ")
#Html.TextBox("vendorName")
</p>
<p>
#Html.Label("Issue Date")
#Html.TextBox("beginIssueDate") - #Html.TextBox("endIssueDate")
#Html.Label("Invoice Date")
#Html.TextBox("beginInvoiceDate") - #Html.TextBox("endInvoiceDate")
#Html.Label("Completed Date")
#Html.TextBox("beginCompletedDate") - #Html.TextBox("endCompletedDate")
#Html.Label("Quick Filter: ")
#Html.TextBox("quickFilter")
</p>
<p>
<input type="submit" value="Go" />
<input type="button" value="Printable View" onclick=" location.href = '#Url.Action("PrintablePdf", "ApIssues")' " />
<input type="button" value="Add New Task" onclick=" location.href = '#Url.Action("Create", "ApIssues")' " />
<input type="button" value="Reporting" />
</p>
}
</div>
<div class="issue-table">
<h2>A/P Issues</h2>
<table id="data-table">
<tr>
<th style="border: 2px solid black; text-align: center; width: 12%">
#Html.ActionLink("Task ID", "Index",
new { sortOrder = "TaskID", CurrentSort = ViewBag.CurrentSort })
</th>
<th style="border: 2px solid black; text-align: center; width: 12%">
#Html.ActionLink("Task Date", "Index",
new { sortOrder = "TaskDate", CurrentSort = ViewBag.CurrentSort })
</th>
<th style="border: 2px solid black; text-align: center; width: 12%">
#Html.ActionLink("Invoice Date", "Index",
new { sortOrder = "InvDate", CurrentSort = ViewBag.CurrentSort })
</th>
<th style="border: 2px solid black; text-align: center; width: 12%">
#Html.ActionLink("Assigned To", "Index",
new { sortOrder = "AssignedTo", CurrentSort = ViewBag.CurrentSort })
</th>
<th style="border: 2px solid black; text-align: center; width: 12%">
#Html.ActionLink("CC", "Index",
new { sortOrder = "CC", CurrentSort = ViewBag.CurrentSort })
</th>
<th style="border: 2px solid black; text-align: center; width: 12%">
#Html.ActionLink("WHSE", "Index",
new { sortOrder = "Whse", CurrentSort = ViewBag.CurrentSort })
</th>
<th style="border: 2px solid black; text-align: center; width: 12%">
#Html.ActionLink("PO #", "Index",
new { sortOrder = "PO", CurrentSort = ViewBag.CurrentSort })
</th>
<th style="border: 2px solid black; text-align: center; width: 12%">
#Html.ActionLink("Freight #", "Index",
new { sortOrder = "FreightNo", CurrentSort = ViewBag.CurrentSort })
</th>
<th style="border: 2px solid black; text-align: center; width: 12%">
#Html.ActionLink("Vendor Name", "Index",
new { sortOrder = "VendName", CurrentSort = ViewBag.CurrentSort })
</th>
<th style="border: 2px solid black; text-align: center; width: 12%">
#Html.ActionLink("Req. Completion Date", "Index",
new { sortOrder = "ReqCompDate", CurrentSort = ViewBag.CurrentSort })
</th>
<th style="border: 2px solid black; text-align: center; width: 12%">
#Html.ActionLink("Task Type", "Index",
new { sortOrder = "TaskType", CurrentSort = ViewBag.CurrentSort })
</th>
<th></th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.ActionLink(item.TaskID.ToString(), "Task", new { id = item.TaskID })
</td>
<td>
#Html.DisplayFor(modelItem => item.TaskDate)
</td>
<td>
#Html.DisplayFor(modelItem => item.InvDate)
</td>
<td>
#Html.DisplayFor(modelItem => item.AssignedTo)
</td>
<td>
#Html.DisplayFor(modelItem => item.CC)
</td>
<td>
#Html.DisplayFor(modelItem => item.Whse)
</td>
<td>
#Html.DisplayFor(modelItem => item.PO)
</td>
<td>
#Html.DisplayFor(modelItem => item.FreightNo)
</td>
<td>
#Html.DisplayFor(modelItem => item.VendName)
</td>
<td>
#Html.DisplayFor(modelItem => item.ReqCompDate)
</td>
<td>
#Html.DisplayFor(modelItem => item.TaskType)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id = item.TaskID })
</td>
</tr>
}
</table>
<br />
<div id='Paging' style="text-align:center">
Page #(Model.PageCount < Model.PageNumber ? 0 : Model.PageNumber)
of #Model.PageCount
#Html.PagedListPager(Model, page => Url.Action("Index", new {page}))
</div>
</div>
<head>
<title></title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="http://sunnywalker.github.io/jQuery.FilterTable/jquery.filtertable.min.js"></script>
<script src="~/Scripts/Additional JS/jquery.tablesorter.js"></script>
<script type="text/javascript">
$(document).ready(function () {
$('table').filterTable(
{
minRows: 1,
label: "Search :",
inputSelector: "#quickFilter" ,
placeholder: "Keyword"
});
});
</script>
</head>
Here is my action:
public ActionResult Index(string sortOrder,string currentSort, int? page, string company, string warehouse,
string pastDue, string assignedToBy, string openco, string sortBy, string poNumber, string freightNumber,
string vendorName, string beginIssueDate, string endIssueDate, string beginInvoiceDate, string endInvoiceDate,
string beginCompletedDate, string endCompletedDate)
{
//Variable Definitions
const int pageSize = 20;
var pageIndex = 1;
pageIndex = page.HasValue ? Convert.ToInt32(page) : 1;
IPagedList<AP_Tasks> tasks = null;
// Instantiate the Entities
var nxtDb = new nxtSQLEntities();
var db = new Accounting_AaronTestEntities();
var usersDb = new PDDAEntities1();
//Query that gets the warehouses, companys, and users from the nxtDB and the PPP DB
var whses = from w in nxtDb.icsds select w.whse;
var coNames = from c in nxtDb.icsds select c.name;
var userDb = new PDDAEntities1();
var query1 = from u in userDb.Users where u.Cono == 1 select new { u.UserName, u.FirstName, u.LastName };
var query2 = from gm in userDb.GroupMembers
join ug in userDb.UserGroups on gm.GroupID equals ug.GroupID
join u in userDb.Users on gm.UserName equals u.UserName
where ug.GroupName == "AP Department" || ug.GroupName == "MIS"
orderby new { u.LastName, u.FirstName }
select new { UserName = u.UserName, FirstName = u.FirstName, LastName = u.LastName };
var query3 = query1.Concat(query2);
var users = new List<string> { };
users.AddRange(query3.Select(entry => entry.UserName));
//Dropdown lists being created and using a viewbag to setup and communication line between the the conroller and view
var warehouseList = new SelectList(whses);
ViewBag.WarehouseList = warehouseList;
var companyList = new SelectList(coNames);
ViewBag.CompanyList = companyList;
var pastDueList = new SelectList(new[]{"Yes", "No"});
ViewBag.PastDueList = pastDueList;
var usersList = new SelectList(users);
ViewBag.UsersList = usersList;
var openCompList = new SelectList(new[] { "Open", "Completed" });
ViewBag.OpenCompList = openCompList;
var sortByList = new SelectList(new[] { "Task ID", "Warehouse", "Assigned To", "PO Number", "Task Date" });
ViewBag.SortByList = sortByList;
tasks = GetFilteredSortedTasks(db,company, warehouse, pastDue, assignedToBy, openco, sortBy, poNumber,
freightNumber, vendorName, beginIssueDate, endIssueDate, beginInvoiceDate, endInvoiceDate,
beginCompletedDate, endCompletedDate).ToPagedList(pageIndex, pageSize);
return View(tasks);
}
Html.PagedListPager can take an additional parameter that is an expression that tells it how to generate the URL for the next page:
#Html.PagedListPager((IPagedList)ViewBag.OnePageOfItems, page => SomeMethodToGetUrlFor(page))
What you need to do basically is keep the current URL of the page (with all the appropriate querystring params for the filters and such) and add or update a page parameter. The "add or update" part makes this tricky, though: for example, you can't just tack on &page=N to the end of the URL as page may already be present in the querystring. I created a UrlHelper extension for just this purpose:
public static string ModifyQueryString(this UrlHelper helper, string url, NameValueCollection updates, IEnumerable<string> removes)
{
NameValueCollection query;
var request = helper.RequestContext.HttpContext.Request;
if (string.IsNullOrWhiteSpace(url))
{
url = request.Url.AbsolutePath;
query = HttpUtility.ParseQueryString(request.QueryString.ToString());
}
else
{
var urlParts = url.Split('?');
url = urlParts[0];
if (urlParts.Length > 1)
{
query = HttpUtility.ParseQueryString(urlParts[1]);
}
else
{
query = new NameValueCollection();
}
}
updates = updates ?? new NameValueCollection();
foreach (string key in updates.Keys)
{
query.Set(key, updates[key]);
}
removes = removes ?? new List<string>();
foreach (string param in removes)
{
query.Remove(param);
}
if (query.HasKeys())
{
return string.Format("{0}?{1}", url, query.ToString());
}
else
{
return url;
}
}
What this does is essentially let you pass in a NameValueCollection of parameters you want to add or update and/or a list of parameters you want to remove from the querystring. By default, it uses the current request URL, but if you pass in a URL it will do the transformation on that instead. Finally, it returns the modified URL back to the view.
I also added some additional methods to make working with this a little easier such as:
public static string UpdateQueryParam(this UrlHelper helper, string param, object value)
{
return ModifyQueryString(helper, new NameValueCollection { { param, value.ToString() } }, null);
}
public static string UpdateQueryParam(this UrlHelper helper, string url, string param, object value)
{
return ModifyQueryString(helper, url, new NameValueCollection { { param, value.ToString() } }, null);
}
So, if I just need to add/update one parameter, I don't need to actually instantiate a new NameValueCollection in my view.
Using these extensions, then, you can modify the URL appropriately with:
Url.UpdateQueryParam("page", page)
Which makes your pager line:
#Html.PagedListPager((IPagedList)ViewBag.OnePageOfItems, page => Url.UpdateQueryParam("page", page))
I am creating a page that will display log files on a page dynamically as they are created. Here is my front end:
<div id="container">
<asp:UpdatePanel UpdateMode="Conditional" runat="server" ID="ServerUpdates">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="Timer" />
</Triggers>
</asp:UpdatePanel>
</div>
</div>
Here is my css:
#container {
width:100%;
display: inline-block;
height:100%;
}
.textboxStatus
{
/*background-image:url('http://placehold.it/15/15');*/
background-repeat:no-repeat;
/* background-position:3px 3px;*/
border:solid 1px black;
padding:20px;
width:600px;
height:500px;
float:left;
clear:left;
/*position:relative;*/
}
/*.textbox input
{
border:none;
background:transparent;
width:100%;
outline: none;
}*/
.textboxURL
{
/*background-image:url('http://placehold.it/15/15');*/
background-repeat:no-repeat;
/* background-position:3px 3px;*/
border:solid 1px black;
padding:20px;
width:575px;
height:475px;
float:right;
/*clear: right;
position:relative;*/
display:inline;
}
Here is my code behind:
protected void CreateDiv(object sender, EventArgs e)
{
string path = #"\\server\d$\websites\Updates\Product\Production\Logs";
//int rowCount = 0;
DirectoryInfo dir = new DirectoryInfo(path);
List<FileInfo> FileList = dir.GetFiles().ToList();
ServerUpdates.ContentTemplateContainer.Controls.Add(new LiteralControl("<asp:GridView runat='server' ID='Grid' AutoGenerateColumns='false'>"));
ServerUpdates.ContentTemplateContainer.Controls.Add(new LiteralControl("<Columns>"));
foreach (FileInfo file in FileList)
{
StreamReader sr = new StreamReader(new FileStream(file.FullName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite));
// string[] findStatus = System.IO.Directory.Exists(path, "codepush.log.*", System.IO.SearchOption.TopDirectoryOnly);
// string[] findURL = System.IO.Directory.GetFiles(path, "sql.output.log.*", System.IO.SearchOption.TopDirectoryOnly);
bool findStatus = (file.Name.Contains("codepush.log.")) ? true : false;//File.Exists(Path.Combine(path, ".txt"));
bool findURL = (file.Name.Contains("sql.output.")) ? true : false;
if (findStatus == true)
{
//ServerUpdates.ContentTemplateContainer.Controls.Add(new LiteralControl(String.Format("<br /><div class=\"statusLog\"><asp:TextBox runat=\"server\" id=\"tbStatus{0}\"/> </div><div class=\"urlLog\"></div>", count)));
//(TextBox)ServerUpdates.ContentTemplateContainer.FindControl("tbStatus" + count.ToString());
ServerUpdates.ContentTemplateContainer.Controls.Add(new LiteralControl(string.Format("<asp:BoundField Datafield={0} /><div class='textboxStatus'>", rowCount)));
TextBox txt = new TextBox();
txt.TextMode = TextBoxMode.MultiLine;
txt.Wrap = false;
txt.Width = 600;
txt.Height = 500;
while (!sr.EndOfStream)
txt.Text = txt.Text + sr.ReadLine() + "\r\n";
//Panel txt = new Panel();
//txt.ScrollBars = ScrollBars.Vertical;
//txt.Wrap = true;
ServerUpdates.ContentTemplateContainer.Controls.Add(txt);
ServerUpdates.ContentTemplateContainer.Controls.Add(new LiteralControl("</div>"));
ServerUpdates.ContentTemplateContainer.Controls.Add(new LiteralControl("</Columns>"));
}
if (findURL == true)
{
//ServerUpdates.ContentTemplateContainer.Controls.Add(new LiteralControl(String.Format("<br /><div class=\"statusLog\"><asp:TextBox runat=\"server\" id=\"tbStatus{0}\"/> </div><div class=\"urlLog\"></div>", count)));
//(TextBox)ServerUpdates.ContentTemplateContainer.FindControl("tbStatus" + count.ToString());
ServerUpdates.ContentTemplateContainer.Controls.Add(new LiteralControl("<Columns>"));
ServerUpdates.ContentTemplateContainer.Controls.Add(new LiteralControl(string.Format("<asp:BoundField Datafield={0} /><div class='textboxURL'>", rowCount)));
TextBox txt = new TextBox();
txt.TextMode = TextBoxMode.MultiLine;
txt.Wrap = false;
txt.Width = 575;
txt.Height = 475;
while (!sr.EndOfStream)
txt.Text = txt.Text + sr.ReadLine() + "\r\n";
//Panel txt = new Panel();
//txt.ScrollBars = ScrollBars.Vertical;
//txt.Wrap = true;
ServerUpdates.ContentTemplateContainer.Controls.Add(txt);
ServerUpdates.ContentTemplateContainer.Controls.Add(new LiteralControl("</div>"));
ServerUpdates.ContentTemplateContainer.Controls.Add(new LiteralControl("</Columns>"));
}
//rowCount++;
}
ServerUpdates.ContentTemplateContainer.Controls.Add(new LiteralControl("</asp:GridView>"));
}
My issue is that it is not displaying the URL div next to the first Status div and so fourth. The URL div displays last.
I need it to display the URL div next to the Status div for each div (file).
I have been trying GridView so any suggestions would be helpful.
I am not sure I understand the problem, but to your issue " it is not displaying the URL div next to the first Status div and so fourth. The URL div displays last," I recommend the following:
<div class="row">
<div class="textboxStatus">
</div>
<div class="textboxURL">
</div>
</div>
Apply float: left; to both textboxStatus and textboxURL. I understand, this is dynamically generated, but instead, why not AJAX to fetch the content and then simply fill it?
You can easily use AJAX with webforms like so:
http://encosia.com/using-jquery-to-directly-call-aspnet-ajax-page-methods/
In your ".textboxStatus" css-class you have defined a "float:left" and are clearing the float at the same time with "clear:left".
Remove both attributes and in ".textboxURL" replace "float:right" with "float:left" and you should be fine.
first we will define the main div or body in which other will be contained for that div the style will be
#maindiv{
width: 100%;
font-size: 12px;
overflow: hidden;
background: #ccc
}
in your case it will be "container"
now when you are adding the divs as
then first div style will be
#leftdiv {
float: left;
width: 33%;
background-color: #bbb;
}
after that set the width of each div and put the width to the style of that d
#nextdiv {
float: left;
background-color: #eee;
width: 33%;
}
and so on..
You should generate a <TABLE> with one line <TR> and multiple columns <td> instead of generating an Asp.net Gridview control by Literal controls.
Remember to write Html tags when you use Literal controls
Example of final html:
<Table>
<tr>
<td>First div inside</td>
<td>Second div inside</td>
...
</tr>
</Table>