Diskuze: Edit položky v tabulce
V předchozím kvízu, Online test znalostí JavaScript, jsme si ověřili nabyté zkušenosti z kurzu.


:11.6.2018 16:19
A čo editovať priamo v tabuľke s contenteditable, strážiť zmeny v bunke s oninput a na save postnúť tieto zmeny?
Ja bych na table navazal onclick. Z event.target zjistil, zda se jedna o
nodeName TD nebo INPUT a podle toho tam input pridal nebo z inputu presunul
value do td.innerHTML.
Asi kod na 50 radku. Ale mozna to contenteditable resi. To by mel byt parametr
te tabulky tusm html5.
O neco podobneho, slozitejsiho se prave u jednoho programu pokousim. Ale budes si muset z toho kodu sam vytahnout a prepsat, co potrebujes. Ja to mam organizovane v classu a je tam tam 70%, co je ti na nic. Blbinky, kdy tam treba delam ramecek kolem td a pod.
function $(id,win) {var win = win || window;
//if (!win.document.getElementById(id)) alert(id)
return win.document.getElementById(id);}
this.event = {};
this.event.func = {};
this.event.func.read = function (event)
{
SCREEN.func.log('---event---');
return {
'event' : event || window.event,
'target': event.target || event.srcElement
};
}
this.edit.func.open = function(event)
{
root.edit.func.log('open');
var ev_data, el;
ev_data = root.event.func.read(event);
el = ev_data.target; // td or input
if (el.nodeName=='TH')
{
root.edit.func.insertRowClick(el);
}
//root.func.log('.func.open node '+el.nodeName);
xy = root.edit.func.getXY(el.parentNode,false);
if (xy!=="" && root.edit.input_id==xy)
{
// root.func.log('.func.open input_id==xy');
return;
}
root.edit.func.close();
if (isExist(el) && el.nodeName=='TD')
{
root.edit.func.inputCreate(el);
}
// root.func.log('.func.open END');
}
this.edit.func.inputCreate = function(el) // el = TD
{
root.edit.func.log('inputCreate');
var xy, xy1,x,y;
xy = root.edit.func.getXY(el,false);
//alert(['xy',xy,typeof xy])
if (xy!=="")
{
//alert([7,el.nodeName,el.className])
HTML.func.classAdd(el,'edit')
xy1 = root.edit.func.getXY(el,true);
x = xy1[1];
y = xy1[0] - 1;
//alert([x,y])
HTML.func.classAdd(root.edit.func.getTdByXY(el,x ,y-1),'edit1');
HTML.func.classAdd(root.edit.func.getTdByXY(el,x-1,y ),'edit2');
//alert([8,el.nodeName,el.className])
//111 el.
el.innerHTML = '<input class="edit" value="'+el.innerHTML+'" onpaste="APPEDIT.edit.func.inputOnPaste(event);">';
el = el.getElementsByTagName('INPUT')[0];
el.focus();
el.value = el.value;
el.selectionStart = el.selectionEnd = el.value.length;
root.edit.input = el;
root.edit.input_id = xy;
}
}
$('table').onclick = root.edit.func.open;
Dost spatne se to hleda. V google je to az na druhe strance
http://doodles.tev.net/…enteditable/
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset=utf-8 />
<meta name="viewport" content="width=620" />
<title>HTML5 contenteditable on a table</title>
<link rel="stylesheet" href="css/style.css" type="text/css" />
<body>
<section id="wrapper">
<header>
<h1>HTML5 contenteditable table</h1>
</header>
<article>
<section contenteditable="true">
<table>
<tr><th> </th><th>A</th><th>B</th><th>C</th><th>D</th><th>E</th><th>F</th><th>G</th><th>H</th><th>I</th><th>J</th></tr>
<tr><th>1</th><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
<tr><th>2</th><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
<tr><th>3</th><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
<tr><th>4</th><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
<tr><th>5</th><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
<tr><th>6</th><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
<tr><th>7</th><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
<tr><th>8</th><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
<tr><th>9</th><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
<tr><th>10</th><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
</table>
</section>
</article>
</section>
</body>
</html>
:12.6.2018 11:19
Tu máš príklad ako to dosiahnúť s Vue - možeš ho použiť prakticky tak ako je napísaný. Veď tak ako s jQuery. A kód by mal byť pomerne samovysvetľujúci, myslím, že ho netreba moc komentovať.
<div id="ediTable">
<table>
<thead>
<tr>
<th>Username</th>
<th>Name</th>
<th>Email</th>
</tr>
</thead>
<tbody>
<tr v-for="({id, name, username, email}, idx) in users">
<td
@click="makeCellEditable({idx: idx, key: 'username', val: username}, $event)"
@blur="saveNewValue"
>{{ username }}</td>
<td
@click="makeCellEditable({idx: idx, key: 'name', val: name}, $event)"
@blur="saveNewValue"
>{{ name }}</td>
<td
@click="makeCellEditable({idx: idx, key: 'email', val: email}, $event)"
@blur="saveNewValue"
>{{ email }}</td>
</tr>
</tbody>
</table>
<button @click="loadData('users')">Load data</button>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.min.js"></script>
<script>
const api = axios.create({
baseURL: 'https://jsonplaceholder.typicode.com'
})
new Vue({
el: '#ediTable',
data: _ => ({
users: [],
processed: {}
}),
methods: {
async loadData (table) {
let { data } = await api.get(table)
console.log(JSON.stringify(data))
this.users = data
},
makeCellEditable (cell, evt) {
evt.target.setAttribute("contenteditable", true)
evt.target.focus()
this.processed = cell
},
saveNewValue (evt) {
evt.target.setAttribute("contenteditable", false)
if (evt.target.textContent === this.processed.val) return // nothing to save, exit
this.processed.val = evt.target.textContent // update value
alert(`Changed cell: ${JSON.stringify(this.processed)}`) // and save here
}
}
})
</script>
PS: Ak budeš editovať ten príklad, rob to nasledovným spôsobom: pokús sa o zmysluplné názvy premenných a funkcií a píš veľa krátkych funkcií, nie menej dlhých. Hovorí sa, že funkcia nad 4 riadky už je príliš dlhá.
Tu je upravený (aj opravený, finálny) príklad ako to písať, meniť či rozširovať:
<style>
table {
width: 100%;
border: 1px solid #ddd;
border-collapse: collapse;
}
th, td {
border: 1px solid #ddd
}
<style>
<div id="ediTable">
<table>
<thead>
<tr>
<th>Username</th>
<th>Name</th>
<th>Email</th>
</tr>
</thead>
<tbody>
<tr v-for="({id, name, username, email}, index) in userList">
<td
@click="makeEditable({index: index, key: 'username', value: username}, $event)"
@blur="checkForChanges"
>{{ username }}</td>
<td
@click="makeEditable({index: index, key: 'name', value: name}, $event)"
@blur="checkForChanges"
>{{ name }}</td>
<td
@click="makeEditable({index: index, key: 'email', value: email}, $event)"
@blur="checkForChanges"
>{{ email }}</td>
</tr>
</tbody>
</table>
<button @click="loadData('users')">Load data</button>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.min.js"></script>
<script>
const api = axios.create({
baseURL: 'https://jsonplaceholder.typicode.com'
})
new Vue({
el: '#ediTable',
data: _ => ({
userList: [],
processedCell: {}
}),
methods: {
async loadData (table) {
let { data } = await api.get(table)
this.userList = data
},
switchEditability (element, value) {
element.setAttribute("contenteditable", value)
element.focus()
},
makeEditable (currentCell, event) {
this.switchEditability(event.target, true)
this.processedCell = currentCell
},
checkForChanges (event) {
this.switchEditability(event.target, false)
event.target.textContent !== this.processedCell.value && this.updateData(event.target.textContent)
},
updateData (newValue) {
this.saveData(Vue.set(this.processedCell, 'value', newValue))
this.userList[this.processedCell.index][this.processedCell.key] = this.processedCell.value
},
saveData (newData) {
alert(`Changed cell: ${JSON.stringify(newData)}`) // your save logic here
}
}
})
</script>
Zobrazeno 11 zpráv z 11.