英文:
Javascript for several elements in a PHP loop
问题
<div class="container">
<h2>活动</h2>
<table class="table table-striped">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">日期</th>
<th scope="col">位置</th>
<th scope="col">活动类型</th>
<th scope="col">编辑</th>
</tr>
</thead>
<tbody>
<?php
$incremental=0;
while($selRow=$res_selPostData->fetch_assoc()) {
$incremental +=1;
$filepath='.\outputs\\' . 'verbale' . $selRow['IDIntervento'] . '.pdf';
?>
<tr>
<td><?php echo $selRow['IDActivity']; ?></td>
<td><?php echo $selRow['DateActivity']; ?></td>
<td><?php echo $selRow['Position']; ?></td>
<td><div id=<?php echo "TypeAct" . $incremental; ?>><?php echo $selRow['Activity_type']; ?></div></td>
<td><div id=<?php echo "button" . $incremental; ?>><span id='edit'>编辑</span></div></td>
</tr>
<?php
}
?>
</tbody>
</table>
</div>
英文:
I have created a HTML table where every row retrieves data from an sql database table.
?>
<div class="container">
<h2>Activities</h2>
<table class="table table-striped">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Date</th>
<th scope="col">Position</th>
<th scope="col">Activity Type</th>
<th scope="col">Edit</th>
</tr>
</thead>
<tbody>
<?php
$incremental=0;
while($selRow=$res_selPostData->fetch_assoc()) {
$incremental +=1;
$filepath='.\outputs\\' . 'verbale' . $selRow['IDIntervento'] . '.pdf';
?>
<tr>
<td><?php echo $selRow['IDActivity']; ?></td>
<td><?php echo $selRow['DateActivity']; ?></td>
<td><?php echo $selRow['Position']; ?></td>
<td><div id=<?php echo "TypeAct" . $incremental; ?>><?php echo $selRow['Activity_type']; ?></div></td>
<td><div id=<?php echo "button" . $incremental; ?>><span id='edit'>EDIT</span></div></td>
</tr>
<?php
}
?>
</tbody>
</table>
</div>
The last column of the HTML table contains for each row a 'button' which is connected to the following javascript function.
<script>
window.onload = function() {
var maximum=parseInt(<?php echo $incremental; ?>);
for (let i = 1; i<maximum; i++) {
var makeMod = document.getElementById('TypeAct' + 'i');
var div = document.getElementById('button' + 'i');
div.onclick = function(e) {
makeMod.contentEditable = true;
makeMod.focus();
makeMod.style.backgroundColor = '#E0E0E0';
makeMod.style.border = '1px dotted black';
}
}
}
</script>
I had tried using the script without the for loop with
<td><div id=<?php echo "button"; ?>><span id='edit'>EDIT</span></div></td>
and
var makeMod = document.getElementById('TypeAct')` and `var div = document.getElementById('button')
but in that case the function works only for one row.
Changing 'i' to i solved the problem with the 'button' but when i click the button in different rows only the activity_type in the last row becomes editable and not the one in the same row as the button; as if the function only acts on the last generated row in the while loop of the table. Can you guess why?
答案1
得分: 2
在这一行:
var div = document.getElementById('button' + i);
最好在单词 "button" 和递增变量之间使用连字符,如下所示:
id="button-1" id="button-2" 等。
英文:
On this line:
var div = document.getElementById('button' + 'i');
the 'i' is in quotes, thus not getting the calculated value but literally the letter "i". Instead, try:
var div = document.getElementById('button' + i);
and ideally use a hyphen between the word button and the increment variable like:
id="button-1" id="button-2" etc.
答案2
得分: 0
makeMod = document.getElementById('TypeAct-' + i);
<span id='edit-<?php echo $incremental; ?>'>EDIT</span>
for (let i = 1; i <= maximum; i++) {
let makeMod;
addEventListener("click", function(e) {
Replace all occurrences of var
with let
or const
.
英文:
Im using a sample HTML with sample data I made just to test the code, since PHP can't be reproduced in here so.
-
First thing first, replace the string
i
with the variable (which you already did)makeMod = document.getElementById('TypeAct-' + i);
-
This line of code is inside a loop.
<span id='edit'>EDIT</span>
which means you will have multiple elements with theedit
id. Can't have that so change it like you did with the other ids. You can concatenate your php variable$incremental
like you did with the others. -
Change your loop to this
for (let i = 1; i <= maximum; i++) {
if you leave it toi < maximum
then it won't add the event to your last button. -
It is much better to use
let
andconst
instead ofvar
now. More info here -
Use
addEventListener
instead ofonclick
. Why? read more about it here addEventListener-vs-onclick
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
window.onload = function() {
let maximum = 3;//sample value, leave this line like in your original code
let makeMod;
for (let i = 1; i <= maximum; i++) {
document.getElementById('button-' + i).addEventListener("click", function(e) {
makeMod = document.getElementById('TypeAct-' + i);
makeMod.contentEditable = true;
makeMod.focus();
makeMod.style.backgroundColor = '#E0E0E0';
makeMod.style.border = '1px dotted black';
});
}
}
<!-- language: lang-html -->
<div class="container">
<h2>Activities</h2>
<table class="table table-striped">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Date</th>
<th scope="col">Position</th>
<th scope="col">Activity Type</th>
<th scope="col">Edit</th>
</tr>
</thead>
<tbody>
<tr>
<td>some data</td>
<td>some data</td>
<td>some data</td>
<td>
<div id="TypeAct-1">act 1</div>
</td>
<td>
<div id="button-1"><span id='edit-1'>EDIT</span></div>
</td>
</tr>
<tr>
<td>some data</td>
<td>some data</td>
<td>some data</td>
<td>
<div id="TypeAct-2">act 2</div>
</td>
<td>
<div id="button-2"><span id='edit-2'>EDIT</span></div>
</td>
</tr>
<tr>
<td>some data</td>
<td>some data</td>
<td>some data</td>
<td>
<div id="TypeAct-3">act 3</div>
</td>
<td>
<div id="button-3"><span id='edit-3'>EDIT</span></div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end snippet -->
答案3
得分: 0
删除ID属性,如果需要使用数字后缀来标识元素,请依赖于其他更灵活的方式来识别DOM元素,比如 querySelector
、querySelectorAll
以及其他父/子/兄弟类型的属性和方法。在上述代码中,PHP变量 $incremental
的唯一作用是作为数字后缀,它在实际的编辑操作(表单提交/ajax等)中不起任何作用,因此可以删除。表格是从数据库中获取内容生成的,因此有一个 IDActivity
,在编辑操作中会很有用,因此将其分配为 data-id
值!
可以使用“委托事件监听器”而不是为每个“button”分配事件监听器来识别“click”事件。
还添加了一个blur
事件处理程序到contentEditable
DIV元素,当不再使用时将它们返回到正常状态。该blur
处理程序可以用于触发编辑数据库中记录的ajax请求。
英文:
It would be better, IMO, to remove the ID attributes entirely if you need to use a numerical suffix to help identify elements and rely on other, more flexible means of identifying DOM elements, such as querySelector
, querySelectorAll
and other parent/child/sibling type properties & methods. In the above the only use that the PHP variable $incremental
has is as that numeric suffix - it would play no part in whatever actual edit
operation (Form submission/ ajax etc) when the record is to be edited so could be removed. The table is generated with content from a database so you have an IDActivity
which will be useful in an edit operation so assign that as the data-id value!
The identifying of click
events can be done using a delegated event listener
rather than assigning an event listener to each button
.
I also added a blur
event handler to the contentEditable DIV elements that returns them to their normal state when no longer used. That blur
handler could be used to fire off the ajax request to edit the record in db.
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
const d=document;
const CN='editable';
d.querySelector('.container table').addEventListener('click', e=>{
if( e.target instanceof HTMLSpanElement && e.target.dataset.type == 'edit' ) {
let id=e.target.parentNode.dataset.id;
let content = e.target.parentNode.closest('tr').querySelector('div[data-type="content"]');
content.contentEditable=true;
content.focus();
content.classList.add( CN );
console.log( ' -> Id=%s',id )
}
});
d.querySelectorAll('[data-type="content"]').forEach(n=>n.addEventListener('blur',e=>{
if( e.target.classList.contains( CN ) ){
e.target.classList.remove( CN );
e.target.contentEditable=false;
// update using ajax?
console.log(e.target.dataset.id,e.target.textContent);
}
}));
<!-- language: lang-css -->
.editable{
background:#E0E0E0;
border:1px dotted black
}
<!-- language: lang-html -->
<div class="container">
<h2>Activities</h2>
<table class="table table-striped">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Date</th>
<th scope="col">Position</th>
<th scope="col">Activity Type</th>
<th scope="col">Edit</th>
</tr>
</thead>
<tbody>
<!-- emulated content -->
<!--
The `IDActivity` value is what would be assigned
to the `data-id` attribute below. That `data-id`
is easily accessible in Javascript and can be used
for whatever EDIT operation you wish.
ie:
<td>
<div data-id="<?=$selRow['IDActivity'];?>">
<?=$selRow['Activity_type'];?>
</div>
</td>
-->
<tr>
<td>1</td>
<td>2023/04/15</td>
<td>Midfield</td>
<td><div data-id=1 data-type='content'>Banana Bouncing</div></td>
<td><div data-id=1><span data-type='edit'>EDIT</span></div></td>
</tr>
<tr>
<td>2</td>
<td>2023/04/17</td>
<td>Ground-Level</td>
<td><div data-id=2 data-type='content'>Hedgehog Juggling</div></td>
<td><div data-id=2><span data-type='edit'>EDIT</span></div></td>
</tr>
<tr>
<td>3</td>
<td>2023/04/18</td>
<td>Upstairs</td>
<td><div data-id=3 data-type='content'>Dwarf Tossing</div></td>
<td><div data-id=3><span data-type='edit'>EDIT</span></div></td>
</tr>
<!-- end emulated content -->
</tbody>
</table>
</div>
<!-- end snippet -->
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论