[英]How to send data to a csv file via php with table cell as textarea made by javascript?
I've managed to read and display the contents of a csv file in an html table and even managed to change cells into text-area on-click but when I try to save new data of the cells into the csv files, it does'nt work.我已经设法在 html 表中读取并显示 csv 文件的内容,甚至设法将单元格更改为文本区域,但是当我尝试将单元格的新数据保存到 Z628CB5675FF524F3E719B7AA2 文件中时,它确实如此nt工作。 Id like to save the new data to be save in the csv when I click the "OK" button.当我单击“确定”按钮时,我想保存要保存在 csv 中的新数据。
my codes:我的代码:
<?php
// configuration
$file = 'sales.csv';
// check if form has been submitted
if (isset($_POST['text']))
{
// save the text contents
file_put_contents($file, $_POST['text']);
}
// read the textfile
$text = file_get_contents($file);
echo "<html><body><table border='1' id='sales'>";
$f = fopen("sales.csv", "r");
while (($line = fgetcsv($f)) !== false) {
echo "<tr>";
foreach ($line as $cell) {
echo "<form action='' method='post'><td width='100'>".htmlspecialchars($cell)."</td></form>";
}
echo "</tr>";
}
fclose($f);
echo "</table></body></html>";
?>
<script>
let table = document.getElementById('sales');
let editingTd;
table.onclick = function(event) {
let target = event.target.closest('.edit-cancel,.edit-ok,td');
if (!table.contains(target)) return;
if (target.className == 'edit-cancel') {
finishTdEdit(editingTd.elem, false);
} else if (target.className == 'edit-ok') {
finishTdEdit(editingTd.elem, true);
} else if (target.nodeName == 'TD') {
if (editingTd) return; // already editing
makeTdEditable(target);
}
};
function makeTdEditable(td) {
editingTd = {
elem: td,
data: td.innerHTML
};
td.classList.add('edit-td'); // td is in edit state, CSS also styles the area inside
let textArea = document.createElement('textarea');
textArea.style.width = td.clientWidth + 'px';
textArea.style.height = td.clientHeight;
textArea.className = 'edit-area';
textArea.tagName = 'text';
textArea.value = td.innerHTML;
td.innerHTML = '';
td.appendChild(textArea);
textArea.focus();
td.insertAdjacentHTML("beforeEnd",
'<div class="edit-controls"><button type="submit" class="edit-ok">OK</button><button class="edit-cancel">CANCEL</button></div>'
);
}
function finishTdEdit(td, isOk) {
if (isOk) {
td.innerHTML = td.firstChild.value;
} else {
td.innerHTML = editingTd.data;
}
td.classList.remove('edit-td');
editingTd = null;
}
</script>
I could not determine if what you have shown above is the entire page or pieces of code pasted together here for the question.我无法确定您上面显示的内容是整个页面还是粘贴在一起的代码片段。 The HTML generated using PHP is invalid as you have omitted the head
completely and the Javascript code appears after the closing html
tag.使用 PHP 生成的 HTML 无效,因为您完全省略了head
,并且 Javascript 代码出现在关闭标签之后html
。
I mentioned that you could perhaps use contentEditable
so that the table-cells themselves become, in effect, input elements.我提到您也许可以使用contentEditable
以便表格单元格本身实际上成为输入元素。 I cobbled together a demo of how you might use contentEditable
to display & edit your csv file.我拼凑了一个演示,说明如何使用contentEditable
来显示和编辑 csv 文件。
As you are/were heavily relying upon Javascript there really is no need to actually use a form
in the HTML - you can accomplish all that you are trying to do in other ways, notably AJAX.由于您现在/正在严重依赖 Javascript,因此实际上没有必要在 HTML 中实际使用form
- 您可以通过其他方式完成您尝试做的所有事情,特别是 ZA34A6659BCEAE779F28185E757ABFCA55
Given a basic CSV file:给定一个基本的 CSV 文件:
sales.csv
"John Vials",902,9214,927,9433,494
"Helen Crew",81,83552,93,847,855
"Ben Gunn III"," 1268",5369,4562,74,77
"Gemima Puddleduck",13,273,38,42,52
The script:剧本:
<?php
error_reporting( E_ALL );
$filename = __DIR__ . '/sales.csv';
if( $_SERVER['REQUEST_METHOD']=='POST' ){
ob_clean();
/*
Save the new data back to the source csv file
*/
if( isset( $_POST['text'] ) ){
$json=json_decode( $_POST['text'] );
// open the csv file in write mode
$file = new SplFileObject( $filename, 'w' );
// process each line
foreach( $json as $line => $arr ) $file->fputcsv( $arr );
}
exit( sprintf( 'The file %s has been updated', basename( $filename ) ) );
}
?>
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='utf-8' />
<title></title>
<style>
table{background:whitesmoke;font-family:monospace;font-size:1rem}
th{background:gray;color:white}
[type='button']{margin:0.25rem; padding:0.25rem; display:inline-block;}
td{background:white}
[contenteditable]{background:rgba(0,255,0,0.1)}
</style>
</head>
<body>
<table border=1 cellpadding='15px' cellspacing='5px' id='sales'>
<tr>
<th>Name</th>
<th>Sales - 1</th>
<th>Sales - 2</th>
<th>Sales - 3</th>
<th>Sales - 4</th>
<th>Sales - 5</th>
</tr>
<?php
$csv = new SplFileObject( $filename );
$csv->setFlags( SplFileObject::READ_CSV | SplFileObject::SKIP_EMPTY | SplFileObject::DROP_NEW_LINE );
foreach( $csv as $index => $row ) {
if( !empty( $row ) ){
list( $name, $sale1, $sale2, $sale3, $sale4, $sale5 )=$row;
printf('
<tr class="data">
<td>%s</td>
<td>%s</td>
<td>%s</td>
<td>%s</td>
<td>%s</td>
<td>%s</td>
</tr>', $name, $sale1, $sale2, $sale3, $sale4, $sale5 );
}
}
?>
</table>
<script>
/*
helper to add a new button and assign the
callback defined below - "bttnclickhandler"
*/
const createbttn=(v)=>{
let bttn=document.createElement('input');
bttn.onclick=bttnclickhandler;
bttn.className='edit-'+v.toLowerCase();
bttn.type='button';
bttn.value=v;
bttn.name=v;
return bttn;
};
/*
If no buttons already exist in current cell, add
*/
const addbttn=(e,v)=>{
if( !e.target.querySelector( 'input[type="button"][name="'+v+'"]' ) ) {
e.target.append( createbttn( v ) );
}
};
/*
If the "OK" button is clicked scan the entire
table and collate text values into object that
will be sent, via ajax, to the backend script
and thus will be used to update the source csv.
*/
const bttnclickhandler=function(e){
e.preventDefault();
switch( this.value.toLowerCase() ){
case 'ok':
let tmp={};
// find all rows in table and add to output object
tbl.querySelectorAll('tr.data').forEach( ( tr, i )=>{
tmp[i]=[];
// find all table-cells in current row - add text content to output object
tr.querySelectorAll('td').forEach( td => tmp[i].push( td.textContent ) )
});
// prepare data for sending
let fd=new FormData();
fd.append('text', JSON.stringify( tmp ) );
// send data to backend script
fetch( location.href, { method:'post',body:fd })
.then( r=>r.text() )
.then( text=>{
console.log( text );
removebttns(e);
e.target.blur();
});
break;
case 'cancel':
removebttns(e);
break;
}
};
/*
scan the entire table and remove any/all
buttons added in the process of making
"contentEditable"
*/
const removebttns=function(e){
tbl.querySelectorAll('[type="button"]').forEach( bttn => {
bttn.parentNode.removeAttribute('contenteditable');
bttn.parentNode.removeChild( bttn );
});
};
/*
Assign an event listener to the table but delegate
control when the clicked target is a table-cell element.
When clicked the table-cell is made "contentEditable"
and 2 buttons are added.
*/
let tbl=document.getElementById('sales');
tbl.addEventListener('click',e=>{
if( e.target.tagName.toLowerCase()=='td' ){
e.target.contentEditable=true;
addbttn(e,'OK');
addbttn(e,'Cancel');
e.target.focus();
}
})
</script>
</body>
</html>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.