I have a loop on the server ( C# ) that does this:
for(i=0;i<=Request.Files.Count - 1; i++)
{
// tell the client that the upload is about to happen
// and report useful information
Update(percent, message, i, 0);
System.Threading.Thread.Sleep(1000);
// tell the client that upload succeeded
// and report useful information
Update(percent, message, i, 1);
}
The function "Update" writes to the client-side javascript function "PublishUpdate".
The row parameter is the row in the table containing the uploading file. The 'status' tells us if the file is about to be uploaded (0) or completed (1).
THE PROBLEM is that I can't seem to get the count correct. The loop seems to
start 2 or 3 rows into the table or (after playing with the row value) it ends before the
final row. I am very new to jQuery. Does anything look obviously wrong to you?
function PublishUpdate(percent, message, row, status)
{
var bodyRows = $("#picTableDisplay tbody tr");
bodyRows.each(function(index){
if (index == row && status == 0)
$('#status'+index).html("<img alt='inproc' src='images/loading.gif' />");
else if (index == row && status == 1)
$('#status'+index).html("complete");
});
}
Finally, the table looks like this:
<table width="100%" cellspacing="0" cellpadding="3" border="0" align="center" id="picTableDisplay" summary="" class="x-pinfo-table">
<tbody id="files_list" class="scrollContent">
<tr class="evenRow">
<td class="numCol" id="num0">
</td>
<td class="fnameCol" id="fname0">
</td>
<td class="statusCol" nowrap="" id="status0">
</td>
<td class="remCol" id="rem0">
</td>
</tr>
<tr class="oddRow">
<td class="numCol" id="num1">
</td>
<td class="fnameCol" id="fname1">
</td>
<td class="statusCol" nowrap="" id="status1">
</td>
<td class="remCol" id="rem1">
</td>
</tr>
<tr class="evenRow">
<td class="numCol" id="num2">
</td>
<td class="fnameCol" id="fname2">
</td>
<td class="statusCol" nowrap="" id="status2">
</td>
<td class="remCol" id="rem2">
</td>
</tr>
AND SO ON ...
Thanks in advance.
The C# is using zero indexing, and typically HTML authors use indexing starting from one. Check to see if you need to correct the index from 0 to 1-based, like this:
$('#status' + (index + 1))
Also refactoring your code to something simpler can often fix hidden errors, or at least make the error more obvious. I'd suggest something along these lines:
if (index == row)
{
if (status == 0) {
html = "<img alt='inproc' src='images/loading.gif' />";
} else {
html = "complete";
}
$('#status'+index).html(html);
}
You should also use C# idiom for looping, < x not <= x - 1:
for(i=0; i < Request.Files.Count; i++)
I'm not entirely sure what you're trying to do as it's not clear where the #status elements are. However, assuming they're cells within the row it might be better to give them a class "status" and then write something like
function PublishUpdate(percent, message, row, status) {
$('#picTableDisplay tbody tr:eq('+row+') .status').html(
status==0 ? '<img alt="inproc" src="images/loading.gif"/>' : 'complete'
);
}
Related
I have a bootstrap table with 4 rows. Each of those rows can be clicked, revealing child rows which are unique to each of the four parent rows.
All works fine as long as I collapse a row before un-collapsing another, but if I un-collapse a row and then un-collapse another, only one child row will show inside this newly un-collapsed parent row, even if there are supposed to be more child rows than just the one inside that parent row. Then, if I click on the parent row again, it will show all of the child rows inside that parent row, apart from the one that was just showing.
How do I fix this glitchy behavior? I should be able to click a parent row without collapsing the previous one first. Ideally the previous row would be collapsed automatically upon un-collapsing a new row.
Razor Page table:
<table id="accordionTable" class="table" style="border-collapse:collapse;">
<thead style="color:white;">
<th>DATABASE</th>
<th>STATUS</th>
</thead>
#for (var i = 0; i < Model.statusList.Count; i++)
{
<tr data-toggle="collapse" data-target="#("#innerTable" + i)">
<td>#Model.Databases[i]["DATABASE_NAME"].ToString().ToUpper()</td>
<td #*class="#Model.StatusAll[i]"*#>#Model.StatusAll[i]</td>
</tr>
foreach (var number in Model.statusList[i])
{
<tbody>
<tr #if (number.ToString() == "Running...") { #: style="background-color: #ccffc4;"
} else if (number.ToString() == "Scheduled") { #: style="background-color: #d1f3fc;"
} else if (number.ToString() == "Failed") { #: style="background-color:#ffe4e4;"
}
style="cursor:default; background-color: white;" data-parent="#accordionTable" id="#("innerTable" + i)">
<td> #number.ToString()</td>
<td #if (number == "Running...") { #: class="fas fa-spinner"
} else if (number == "Scheduled") { #: class="far fa-clock"
} else if (number == "Failed") { #: class="fas fa-exclamation-triangle"
}>
</td>
</tr>
</tbody>
}
}
</table>
As suggested by #Nan Yu above, this is how I fixed it:
You can try to remove attribute data-parent="#accordionTable" in the child tr tags, then add class ="collapse" in the child tr tags. Like style="cursor:default; background-color: white;" class="collapse" id="#("innerTable" + i)"> – Nan Yu
I want to parse a HTML table into a CSV file, but keeping the right number of colspan and rowpspan.
I'm using ";" as delimiter cell. Thus, when there colspan of 2 columns, for example, instead of having only one, ";", it will have 2.
I can extract the content of the table and make line breaks where tr indicators ends, but don't know how to treat colspan and rowspan.
HtmlNodeCollection rows = tables[0].SelectNodes("tr");
// Aux vars
int i;
// ncolspan
// For each row...
for (i = 0; i < rows.Count; ++i)
{
// For each cell in the col...
foreach (HtmlNode cell in rows[i].SelectNodes("th|td"))
{
/* Unsuccessful attempt to treat colspan
foreach (HtmlNode n_cell in rows[i].SelectNodes("//td[#colspan]"))
{
ncolspan = n_cell.Attributes["colspan"].Value;
}
*/
text.Write(System.Text.RegularExpressions.Regex.Replace(cell.InnerText, #"\s\s+", ""));
text.Write(";");
/*
for (int x = 0; x <= int.Parse(ncolspan); x++)
{
text.Write(";");
}
*/
}
text.WriteLine();
ncolspan = "0";
}
Any help, please? Thank you!
UPDATE: Here a simple example table to use:
<table id="T123" border="1">
<tr>
<td colspan="3"><center><font color="red">Title</font></center></td>
</tr>
<tr>
<th>R1 C1</th>
<th>R1 C2</th>
<th>R1 C3</th>
</tr>
<tr>
<td>R2 C1</td>
<td>R2 C2</td>
<td>R2 C3</td>
</tr>
<tr>
<td colspan="2">R3 C1 e C2 with "</td>
<td>R3 C3</td>
</tr>
<tr>
<td>R4 C1</td>
<td colspan=2>R4 C2 e C3 without "</td>
</tr>
<tr>
<td>R5 C1</td>
<td>R5 C2</td>
<td>R5 C3</td>
</tr>
<tr>
<td rowspan ="2">R6/R7 C1: Two lines rowspan. Must leave the second line blank.</td>
<td>R6 C2</td>
<td>R6 C3</td>
</tr>
<tr>
<td>R7 C2</td>
<td>R7 C3</td>
</tr>
<tr>
<td>End</td>
</tr>
</table>
CSV doesn't handle rowspan or colspan values - it's a very simple format that has no concept of columns or rows beyond it's delimiter and the end of line character.
If you want to try preserve the rowspan and colspan you will need to use an intermediate object model which you can use to store the specific contents of a cell and it's location, for example, before exporting the model to CSV. And even then, the CSV format will not preserve the colspan and rowspan as you may be hoping (i.e. like an Excel sheet would).
is true, that you can not put a rowspan or colspan in the csv format, what worked for me is to put blank spaces where the span should exist
It is not the best option, but aesthetically it looks similar
"";SEPTIEMBRE;;OCTUBRE;;NOVIEMBRE;;TOTAL;
PRODUCTOS;cantidad;monto;cantidad;monto;cantidad;monto;cantidad;monto
I want to retrieve data from HTML document.
I am scraping data from a web site I almost done but get issue when tried to retrieve data from the table.
Here is HTML code
<div id="middle_column">
<form action="url?" method="post" name="inquirydetail">
<input type="hidden" name="ServiceName" value="SurgeWebService">
<input type="hidden" name="TemplateName" value="Inpat_AvailableResponses.htm">
<input type="hidden" name="CurrentPage" value="inquirydetail">
<form method="post" action="url" name="ResponseSel" onSubmit="return EditPage(document.forms[3])">
<TABLE
<tBody
<table
....
</table
<table
....
</table
<table border="0" width="90%">
<tr>
<td width="10%" valign="bottom" class="content"> Service Number</td>
<td width="30%" valign="bottom" class="content"> Status</td>
<td width="50%" valign="bottom" class="content"> Status Date</td>
</tr>
<tr>
<td width="20%" bgcolor="white" class="subtitle">1</td>
<td width="40%" bgcolor="white" class="subtitle">Approved</td>
<td width="40%" bgcolor="white" class="subtitle">03042014</td>
</tr>
<tr>
<td></td>
</tr>
</table>
</tbody>
</TABle>
</div>
I have to retrieve data for Status field It is Approved and write it in SQL DB
There are many tables in the form tag.Tables do not have IDs.How I can get correct table,row and cell
Here is my code
HtmlElement tBody = WB.Document.GetElementById("middle_column");
if (tBody != null)
{
string sURL = WB.Url.ToString();
int iTableCount = tBody.GetElementsByTagName("table").Count;
}
for (int i = 0; i <= iTableCount; i++)
{
HtmlElement tb=tBody.GetElementsByTagName("table")[i];
}
Something is wrong here
Please help with this.
Don't you have any control over the page being displayed within the Webbrowser control? If you do it's better you add an id field for status TD. Then your life would be much easier.
Anyway, here's how you could search a value within a table.
HtmlElementCollection tables = this.WB.Document.GetElementsByTagName("table");
foreach (HtmlElement TBL in tables)
{
foreach (HtmlElement ROW in TBL.All)
{
foreach (HtmlElement CELL in ROW.All)
{
// Now you are looping through all cells in each table
// Here you could use CELL.InnerText to search for "Status" or "Approved"
}
}
}
But, this is not a good approach as you are looping through each table and each cell within each table to find your text. Keep this as the last option.
Hope this helps you to get an idea.
I prefer using the dynamic type and the DomElement property, but you must be using .net 4+.
For tables, the main advantage here is that you don't have to loop through everything. If you know the row and column that you are looking for, then you can just target the important data by row and column numbers instead of looping through the whole table.
The other big advantage is that you can basically use the entire DOM, reading more than just the contents of the table. Make sure you use lowercase properties as required in javascript, even though you are in c#.
HtmlElement myTableElement;
//Set myTableElement using any GetElement... method.
//Use a loop or square bracket index if the method returns an HtmlElementCollection.
dynamic myTable = myTableElement.DomElement;
for (int i = 0; i < myTable.rows.length; i++)
{
for (int j = 0; j < myTable.rows[i].cells.length; j++)
{
string CellContents = myTable.rows[i].cells[j].innerText;
//You are not limited to innerText; you have the whole DOM available.
//Do something with the CellContents.
}
}
In the past I've used jQuery/Ajax to capture the key press of an end user, and build up a WHERE clause to filter data on a Web form.
I'm now taking advantage of the strongly type facilitates in ASP.NET 4.5. I was wondering if anyone has a way of performing real-time filtering/searching on a Gridview.
Basically, I have three grids, all showing different information. I want the end-user to key in or select from a drop down list (generic searching) and all girds reflect those changes.
I'm not adverse to resorting back to the old method, just didn't; know if there was anything new I could use?
So you can look at this. I hope this help you.
Here is the HTML:
<input id="searchInput" value="Type To Filter">
<br/>
<table>
<thead>
<tr>
<th>Column1</th>
<th>Column2</th>
</tr>
</thead>
<tbody id="fbody">
<tr>
<td>cat</td>
<td>one</td>
</tr>
<tr>
<td>dog</td>
<td>two</td>
</tr>
<tr>
<td>cat</td>
<td>three</td>
</tr>
<tr>
<td>moose</td>
<td>four</td>
</tr>
<tr>
<td>mouse</td>
<td>five</td>
</tr>
<tr>
<td>dog</td>
<td>six</td>
</tr>
</tbody>
</table>
And here is the JavaScript code:
$("#searchInput").keyup(function () {
// Split the current value of searchInput
var data = this.value.split(" ");
// Create a jQuery object of the rows
var jo = $("#fbody").find("tr");
if (this.value == "") {
jo.show();
return;
}
// Hide all the rows
jo.hide();
// Recusively filter the jquery object to get results.
jo.filter(function (i, v) {
var $t = $(this);
for (var d = 0; d < data.length; ++d) {
if ($t.is(":contains('" + data[d] + "')")) {
return true;
}
}
return false;
})
// Show the rows that match.
.show();
}).focus(function () {
this.value = "";
$(this).css({
"color": "black"
});
$(this).unbind('focus');
}).css({
"color": "#C0C0C0"
});
Enter link description here
I have a dynamically created table with id called "editTable" that looks as follows:
<tbody>
#{var i = 0;}
#foreach (var item in Model)
{
<tr>
<td width="25%">
#Html.DisplayFor(modelItem => item.Product.Name)
</td>
<td width="25%">
#Html.DisplayFor(modelItem => item.Quantity)
</td>
<td width="25%">
<div class="editor-field">
#Html.EditorFor(modelItem => item.UnitPrice)
#Html.ValidationMessageFor(model => item.UnitPrice)
</div>
</td>
<td width="25%" id="total"></td>
</td>
</tr>
}
</tbody>
The 3th td-element consists of a C# textbox that is turned into a element in html.
Now I want to multiply the quantity by the unit price to display this value in the 4th td element next to it. This value should update every time the value in the textbox is adjusted. I am a newbie at JQuery / JavaScript and came up with the following code:
// Calculating quantity*unitprice
$('#editTable tr td:nth-child(3) input').each( function (event) {
var $quant = $('#editTable tr td:nth-child(2)', this).val();
var $unitPrice = $('#editTable tr td:nth-child(3) input', this).val();
$('#editTable tr td:nth-child(4)').text($quant * $unitPrice);
});
This doesn't work and only displays NaN in the 4th element. Can anyone help me updating this code to a working version? Any help would be very much appreciated.
I geussed you accidentally switched units and price because it has more logic to change the number of units then the price. I took your html and javascript and tried to change as little as possible to make it work (I'm not saying the solution is perfect, I just don't want to give you a totaly different example of how to do it).
The html (The C# is irrelevant for this problem):
<table id="editTable">
<tbody>
<tr>
<td width="25%">
Product name
</td>
<td width="25%">
5
</td>
<td width="25%">
<div class="editor-field">
<input id="UnitPrice" name="UnitPrice" type="number" value="2" style="width:40px" />
</div>
</td>
<td width="25%" id="total"></td>
</tr>
</tbody>
</table>
The javascript/jquery (which should run on load):
$('#editTable tr td:nth-child(3) input').each(updateTotal);
$('#editTable tr td:nth-child(3) input').change(updateTotal);
var element;
function updateTotal(element)
{
var quantity = $(this).closest('tr').find('td:nth-child(2)').text();
var price = $(this).closest('tr').find('td:nth-child(3) input').val();
$(this).closest('tr').find('td:nth-child(4)').text(quantity * price);
}
The problem you had were with jquery. I've created a function that recieves an element (in our case it's your UnitPrice input), then it grabs the closest ancestor of type tr (the row it's in) and from there it does what you've tried to do.
You've used jquery selector to get all 2nd cells in all table rows, the closest('tr').find limits it to the current row.
You've tried to use .val() on a td element, you should use either .text() or .html(). Instead, You can also add a data-val="<%=value%>" on the td and then use .data('val').
It will be better to take the units directly from $(element).val() and no going to the tr and then back into the td and the input.
To see it working: http://jsfiddle.net/Ynsgf/1/
I hope I didn't caused you any confusion with my explanation and the options I gave you.
Here is another way to write the jquery part.
$('#editTable tr').each(function (i, row) {
var $quant = $(row).find('.editor-field input').val();
var $unitPrice = $(row).find('.editor-field input').val();
$(row).find('td:nth-child(4)').text($quant * $unitPrice);
});