简体   繁体   English

如何通过 php 将数据发送到 csv 文件,表格单元格为 javascript 制作的文本区域?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM