I have a snippet of html containing the first part of a post code and the region it is in. An example of two rows:
<tr height="17">
<td class="xl66" height="17">Channel Islands</td>
<td class="xl66">GY - (Guernsey)</td>
</tr>
<tr height="17">
<td class="xl66" height="17">Channel Islands</td>
<td class="xl66">JE - (Jersey)</td>
</tr>
How/what can I use to extract the region and the part of the postcode minus the name of the location.
From the example data, I would like to retrieve ('Channel Islands', 'GY'), ('Channel Islands', 'JE') so I can enter them into a database.
USING GAWK
Using gawk scripting language can prove worthwhile
create a file name gawkscript and add the following:
#Test to see if the line matches the region, if it does, use regex to get your region
$0~/<td class="xl66" height="17">Channel Islands<\/td>/{printf gensub(/ *<td.*>(.+)<\/td>/,"\\1,",$0)};
#Test to see if the line matches the cose, if it does, use regex to get your code
$0~/<td class="xl66">(.+)<\/td>/{print gensub(/ *<td.*>(.+) *- \(.+\)<\/td>/,"\\1",$0)}
using your shell you can run the script
gawk -f gawkscript my_html_file
Since this is html codes we are dealing with, I would use a powerful html webscraping module in python call BeautifulSoup
USING PYTHON
Assuming you know some python
import re #import regex
from bs4 import BeautifulSoup #import beautifulsoup
soup=BeautifulSoup(
#add your html string
"""<tr height="17">
<td class="xl66" height="17">Channel Islands</td>
<td class="xl66">GY - (Guernsey)</td>
</tr>
<tr height="17">
<td class="xl66" height="17">Channel Islands</td>
<td class="xl66">JE - (Jersey)</td>
</tr>""")
#find all tr tags in your html string
find_all_tr=soup.find_all("tr")
for i in find_all_tr: #loop through all tr tags
all_td=BeautifulSoup(str(i)).find_all("td") #find all td tags
for j in all_td:
#check to see if your td tages matches 'td class="xl66" height="17"' and print
if re.search('<td class="xl66" height="17"',str(j)):
print(j.text.strip(),end=" ")
#check to see if your td tag matches ONLY <td class="xl66" and use regex to obtain your country code
elif re.search('<td class="xl66">',str(j)):
print(","+re.sub(".*-","",j.text.strip()))
NOTE: I use strip() function here because html to eliminate the unwanted newline characters in html codes when extracting information
You can use regex
/<td.*?>(.*?)<\/td.*?>\s+<td.*?>(.*?)\s-.*?<\/td>/gi
Regex explanation here
I can make your work with the help of javascript as i have less knowledge in regex.
Here the JS code :
var array = [];
var table = document.getElementById('myTable');
var rowLength = table.rows.length;
for (i = 0; i < rowLength; i++) {
var collect = [];
var col = table.rows.item(i).cells;
var colLength = col.length;
for (var j = 0; j < colLength; j++) {
var value = col.item(j).innerHTML;
collect.push(value);
}
array.push(collect);
}
Here is the working link
http://plnkr.co/edit/8e67Il0u5dmr6NZX3FWJ?p=preview
Hope it helps you :)
Without knowing server-side specifics like languages (PHP/ASP) and database (MySQL/NoSQL), I cannot show you how to handle the code in the back-end.
That being said, the code below shows you how to handle and prepare the data client-side and make an asynchronous (POST) request via JavaScript to your server.
Related Information:
Here is a well documented guide for the -- FormData( ) object
Here is a well documented guide for the -- XMLHttpRequest( ) object
Screenshot:
//HTML (index.html)
<!DOCTYPE html>
<html>
<head>
<script src="index.js"></script>
<link rel="stylesheet" href="index.css">
</head>
<body>
<button onclick="submitTable();">Click Me</button>
<table>
<thead>
<tr>
<th>Region</th>
<th>Postcode</th>
</tr>
</thead>
<tbody>
<tr class="data-row">
<td>Channel Islands</td>
<td>GY - (Guernsey)</td>
</tr>
<tr class="data-row">
<td>Channel Islands</td>
<td>JE - (Jersey)</td>
</tr>
</tbody>
</table>
</body>
</html>
//JS (index.js)
function submitTable(){
//OBJECT INITIALIZATION
if (window.XMLHttpRequest){
var request = new XMLHttpRequest(); // IE7+, Firefox, Chrome, Opera, Safari
}
else{
var request = new ActiveXObject("Microsoft.XMLHTTP"); // IE 6 and older
}
var formData = new FormData();
//LOOP THROUGH DATA and APPEND to FormData(object)
var dataRows = document.getElementsByClassName("data-row");
for(var i=0; i < dataRows.length; i++){
var data = dataRows[i].children;
for(var x=0; x < data.length; x++){
if(x === 1){
var postcode = data[x].innerHTML.substr(0, 2);
formData.append("postcode", data[x].innerHTML);
}
else{
formData.append("region", data[x].innerHTML);
}
}
}
//OPEN
request.open("POST", "/path/to/post/the/data");
//SEND
request.send(formData);
//RESPONSE
request.onreadystatechange = function(){
if(request.readyState == 4){
console.log(request.response);
}
}
}
//CSS (index.css)
table, th, td {
border: 1px solid black;
}
Related
I have a large table in WordPress, I need to change the order of the columns, but I have to do it manually every time, when I need. Is there any plugin out there, in which all table loads up and I drag and drop the whole column from there as my choice?
The website is here
Based on your question, i can give you a demo to show you how to move forward with your requirements.
Please check this UPDATED FIDDLE. As you requested we are using Dragtable js.
Once sorting is completed we checks each row of the table finds each column of the respective row and create a json tree structure.
Html
<table id="sort_table">
<thead>
<tr>
<th></th>
<th class="draggable">Col1</th>
<th class="draggable">Col2</th>
<th class="draggable">Col3</th>
<th class="draggable">Col4</th>
</tr>
</thead>
<tbody>
<tr>
<td>Row1</td>
<td>Data11</td>
<td>Data12</td>
<td>Data13</td>
<td>Data14</td>
</tr>
<tr>
<td>Row2</td>
<td>Data21</td>
<td>Data22</td>
<td>Data23</td>
<td>Data24</td>
</tr>
<tr>
<td>Row3</td>
<td>Data31</td>
<td>Data32</td>
<td>Data33</td>
<td>Data34</td>
</tr>
<tr>
<td>Row4</td>
<td>Data41</td>
<td>Data42</td>
<td>Data43</td>
<td>Data44</td>
</tr>
</tbody>
</table>
JS (UPDATED)
$(document).ready(function() {
$('#sort_table').dragtable({
dragaccept: '.draggable',
beforeStop: function() {
var tree = {};
var rows = [];
$('#sort_table tr').each(function() {
var col_count = 0;
var cols = [];
$(this).children().each(function() {
cols[col_count] = $(this).html();
col_count++;
});
rows.push(cols);
});
tree.data = rows;
var tree_json = JSON.stringify(tree); // use the variable to save to DB
console.log(tree_json);
}
});
});
You can save the variable tree_json to database (Call ajax to php and save to DB)
On each page load you could take the value from database to a variable and using json_decode to make the string a json object
$table_structure = ; // Code to take from db
$table_structure = json_decode($table_structure);
You can copy and paste json from console to check if its valid using JSONLint
first of all I've been dealing with this problem for the past 2 days and I thought I may finally ask it since I've not found any working solution. First let me introduce the problem then I'll explain what I've tried.
As the title introduces, I'm trying to convert HTML to PDF using iTextSharp, the HTML includes gridview as well.
using (StringWriter sw = new StringWriter())
{
using (HtmlTextWriter hw = new HtmlTextWriter(sw))
{
System.Text.Encoding Enc = System.Text.Encoding.GetEncoding("UTF-8");
iTextSharp.text.pdf.BaseFont STF_Helvetica_Turkish = iTextSharp.text.pdf.BaseFont.CreateFont("Helvetica", "CP1254", iTextSharp.text.pdf.BaseFont.NOT_EMBEDDED);
iTextSharp.text.Font fontNormal = new iTextSharp.text.Font(STF_Helvetica_Turkish, 12, iTextSharp.text.Font.NORMAL);
StringReader sr = new StringReader(sw.ToString());
string contentHtml = PrintElem();
contentHtml = contentHtml.Replace("Ş", "S");
contentHtml = contentHtml.Replace("İ", "I");
contentHtml = contentHtml.Replace("ı", "i");
contentHtml = contentHtml.Replace("Ğ", "G");
contentHtml = contentHtml.Replace("Ü", "U");
contentHtml = contentHtml.Replace("ğ", "g");
contentHtml = contentHtml.Replace("ş", "s");
StringReader srHtml = new StringReader(contentHtml);
Stream denemeStream = GenerateStreamFromString(srHtml.ToString());
iTextSharp.text.Document pdfDoc = new iTextSharp.text.Document(iTextSharp.text.PageSize.A4, 10f, 10f, 10f, 0f);
MemoryStream ms = new MemoryStream();
iTextSharp.text.pdf.PdfWriter writer = iTextSharp.text.pdf.PdfWriter.GetInstance(pdfDoc, ms);
pdfDoc.Open();
using (var msCss = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(PrintElem().ToString())))
{
using (var msHtml = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(PrintElem().ToString())))
{
//iTextSharp.tool.xml.XMLWorkerFontProvider fontProvider = new iTextSharp.tool.xml.XMLWorkerFontProvider();
//Parse the HTML
iTextSharp.tool.xml.XMLWorkerHelper.GetInstance().ParseXHtml(writer, pdfDoc, msHtml, (Stream)null);
}
}
//iTextSharp.tool.xml.XMLWorkerHelper.GetInstance().ParseXHtml(writer, pdfDoc, denemeStream,null,Encoding.UTF8);
pdfDoc.Close();
MemoryStream ret = new MemoryStream(ms.ToArray());
return ret;
}
}
As you can see last solution I tried was to change all turkish characters to english ones yet the pdf output still did not display them.
So far I've tried changing encoding to everything offered on the internet. I tried to add the font yet I've failed to do it as you can see I'm not using that overloaded function of ParseXHtml (if you know how to add this fontNormal to the parsing I'll gladly try that out as well).
the PrintElem function returns the following HTML content (or similar ones that contain turkish characters inside)
<html>
<head>
<h3 align='center'>ABG SİGORTA ALACAK/VERECEK MUTABAKAT EKSTRESİ</h3>
<style>#ContentPlaceHolder1_vaultsListGridview{width: 100%;} td:nth-child(3) {text-align: right;}td:nth-child(4) {text-align: right;}.netWorthClass{text-align: right;}</style>
</head>
<body >
<br/>
<div>Kasa Adı = 1</div>
<div>Devir = 56 TL</div>
<br/>
<div>
\r\n\t
<table class=\"table table-hover table-striped\" cellspacing=\"0\" rules=\"all\" border=\"1\" id=\"ContentPlaceHolder1_vaultsListGridview\" style=\"border-collapse:collapse;\">
\r\n\t\t
<thead>
\r\n\t\t\t
<tr>
\r\n\t\t\t\t
<th scope=\"col\">Tarih</th>
<th scope=\"col\">Açıklama</th>
<th scope=\"col\">Giren</th>
<th scope=\"col\">Çıkan</th>
\r\n\t\t\t
</tr>
\r\n\t\t
</thead>
<tbody>
\r\n\t\t\t
<tr>
\r\n\t\t\t\t
<td>\r\n <span id=\"ContentPlaceHolder1_vaultsListGridview_fullDateLabel_0\">26/05/2017</span>\r\n </td>
<td>\r\n <span id=\"ContentPlaceHolder1_vaultsListGridview_detailLabel_0\">MART AYI KALAN VE NİSAYIN AYI SSK ÖDEMESİ</span>\r\n </td>
<td>\r\n 0\r\n </td>
<td>\r\n 1,295.00\r\n </td>
\r\n\t\t\t
</tr>
<tr>
\r\n\t\t\t\t
<td>\r\n <span id=\"ContentPlaceHolder1_vaultsListGridview_fullDateLabel_1\">31/05/2017</span>\r\n </td>
<td>\r\n <span id=\"ContentPlaceHolder1_vaultsListGridview_detailLabel_1\">NİSAN AYI KOMİSYON</span>\r\n </td>
<td>\r\n 1,351.00\r\n </td>
<td>\r\n 0\r\n </td>
\r\n\t\t\t
</tr>
\r\n\t\t
</tbody>
\r\n\t
</table>
\r\n
</div>
<br/>
<div class='netWorthClass'>Giren Miktar = 1351 TL</div>
<div class='netWorthClass'>Çıkan Miktar = 1295 TL</div>
<br/>
</body>
</html>
I've taken the above html part from debugger sorry for the mess, but you see the problematic characters above.
I'll gladly try out everything you may offer. Thanks in advance.
i was able to break string to chars array and surround each char in <span></span> but when im trying to pass this array to table the html wont render.
breaking the string:
//parse cron_format and edit each digit individually
$scope.parse = function (cron_format){
var parsed = cron_format.split('');
for(var i = 0; i < parsed.length; i++) {
parsed[i] = '<span>' + parsed[i] + '</span>';
}
return parsed;
}
when i try to create the table like this:
<table class="table table-bordered table-hover">
<thead>
<td>user name</td>
<td>script name</td>
<td>cron format</td>
</thead>
<tbody ng-repeat="(user_id,script_id) in data | filter: test">
<tr ng-repeat="(script_id, cron_format) in script_id">
<td>{{user(user_id)}}</td>
<td>{{script(script_id)}}</td>
<td ng-bind-html-unsafe="{{parse(cron_format)}}"></td>
</tr>
</tbody>
</table>
there are no values in cron_format:
without trying to render -> <td>{{parse(cron_format)}}</td>
the table looks like this:
what am i doing wrong?
UPDATE:
i changed function's two last rows :
$scope.parsed.htmlSafe = $sce.trustAsHtml(parsed.html);
return parsed;
and i get this error:
Can't interpolate: {{parse(cron_format)}}
TypeError: Cannot set property 'htmlSafe' of undefined
can someone explain whats the mistake im doing here?
I am working on developing a multi-column multi-word filtering search and have difficulties with two problems:
I am only able to partially filter the first column; partial because typing apple it shows apple and oranges in the first column.
I am struggling with finding a way to make this a multi-word search over both columns.
I found a table filtering techniques on SO and adjusted them in this fiddle. But this code will only filter over all the columns with one word. Typing more than one word to narrow the result (find A and B) does not work.
The code below is my attempt to perform a multi-column multi-word search in a single box see my fiddle.
How can I achieve filtering over multiple columns that combines the search phrases?
Meaning show only rows where searchphrase-1 and searchphrase-2 are present.
JS
var $orig_rows1 = $('#table tbody tr td[class = "col1"]');
var $orig_rows2 = $('#table tbody tr td[class = "col2"]');
$('#search').keyup(function() {
var $rows1 = $orig_rows1;
var $rows2 = $orig_rows2;
var val = '^(?=.*\\b' + $.trim($(this).val()).split(/\s+/).join('\\b)(?=.*\\b') + ').*$',
reg = RegExp(val, 'i'),
text;
$("tr:hidden").show();
$rows1.show().filter(function() {
text = $(this).text().replace(/\s+/g, ' ');
return !reg.test(text);
}).parent("tr").hide();
});
HTML
<input type="text" id="search" placeholder="Type to search title 1">
<table class="table-striped" id="table">
<thead>
<th>Title 1</th>
<th>Title 2</th>
</thead>
<tbody>
<tr>
<td class="col1">Apple</td>
<td class="col2">Green</td>
</tr>
<tr>
<td class="col1">Grapes</td>
<td class="col2">Green</td>
</tr>
</tbody>
<tr>
<td>Orange</td>
<td>Orange</td>
</tr>
</table>
Any advice would be great.
Mistake in your code </tbody> is placed wrong, it must be
<tbody>
<tr>
<td class="col1">Apple</td>
<td class="col2">Green</td>
</tr>
<tr>
<td class="col1">Grapes</td>
<td class="col2">Green</td>
</tr>
<tr>
<td>Orange</td>
<td>Orange</td>
</tr>
</tbody>
Not a perfect solution, suggestions would be greatly appreciated
Try this Demo Fiddle it has multiple words search capability made using Tag-it! plugin.
Update search for both AND and OR
Demo Fiddle with a check box to perform both operations
Edit: pieces of linked fiddle added
This is a part of the code from the linked fiddle
var search = function () {
if ($('.tagit-label').length) {
$("#table tbody tr").hide();
var toShow = [];
$('.tagit-label').each(function () {
filter = $(this).text();
$("#table tbody tr").each(function () {
if ($(this).text().search(new RegExp(filter, "i")) > 0) {
toShow.push($("#table tbody tr").index(this));
}
});
});
if ($('#chkBoth').prop("checked") && $('.tagit-label').length > 1) {
var filterShow = [];
var outputArray = [];
$(toShow).each(function (i, value) {
if (($.inArray(value, outputArray)) == -1) {
outputArray.push(value);
}
});
$(outputArray).each(function (i, value) {
var index = toShow.indexOf(value);
toShow.splice(index, 1);
});
}
$(toShow).each(function (i, value) {
$("#table tbody tr").eq(value).fadeIn();
});
} else {
$("#table tbody tr").fadeIn();
}
}
This is the result of my linked fiddle below:
Hope it helps..!!
I have HTML table and the table contains 100 Rows and 2 columns (200 cells). I would like the cells to be rearranged randomly with respect to it's original row AND/OR it's original column.
This is how I would represent 4 pieces of data.
<table>
<tr>
<td> Data1 </td>
<td> Data2 </td>
</tr>
<tr>
<td> Data 3 </td>
<td> Data 4 </td>
</tr>
</table>
I'm using HTML and CSS only. I intend on enter the contents of each cell manually Initially.
The Data's represent Images for a gallery which I'm working on. Kindly suggest another opinion if I shouldn't be using tables for such an arrangement.
There's no need to be using a table for this kind of goal. However, to do anything randomly without you sitting at your computer rolling a dice and typing in the result, you will need to use some JavaScript. At the bottom of your page, put something like this:
<script>
var images = document.getElementsByTagName('img');
var randomArrangement = [];
for (var i=0; i < images.length; i++)
{
if (Math.random() > 0.5) {
randomArrangement.push(images.src);
} else {
randomArrangement.unshift(images.src);
}
}
for (var j=0; j < images.length; j++)
{
images[i].src = randomArrangement[i];
}
</script>
That will give you an array of your image URLs in a random order, and fill each one into the existing images. However, this will be much more effective and efficient if done server-side before the page load.