【问题标题】:Get THIS value from multiple input with same name IN INLINE-EDITING table从在线编辑表中具有相同名称的多个输入中获取此值
【发布时间】:2019-06-14 07:04:31
【问题描述】:

我有这种情况。 我创建了一个带有内联编辑的表(使用 jQ),每一行都有它的编辑按钮。因此,例如,如果我想编辑第一行,我单击编辑按钮,它会打开他的输入字段。每个打开的编辑行都有其保存按钮,其 id 与行中该属性的 id 连接。 现在,如何使用 php 获取输入值?我不得不提到每个输入都具有相同的属性名称 - >它们都是动态创建的。

php

$new_tname = $_POST['edit_team']; ?????????????????????????????????

if (isset($_GET['save_tid'])) {
$tid = $_GET['save_tid'];
$team = Team::getById($tid);

if ($tid == $team->team_id) {


  $team->name = $new_tname;
  $team->save();
}

}

html/php

<?php 
                  $teams = Team::getAll();
                  foreach ($teams as $team) {
                    $tname = $team->name;
                    $tid = $team->team_id;


                    echo "<tr>
                    <td>
                    <a href='#' class='editable' style='margin-left: 2px;'>".$tname."</a><form method='POST' action=''><input type='text' class='editshow form-control col-sm-3' aria-label='Sizing example input' aria-describedby='inputGroup-sizing-sm' name='edit_teams' value='".$tname."'></form><a href='teams.php?save_tid={$tid}' style='margin-left: 2px; margin-top:3px;' class='btn btn-success btn-sm editshow'>Save</a>
                    </td>";

                    echo "<td>
                    <button  class='btn btn-primary btn-sm btnEdit'".$tid."'>Edit</button> | <a href='teams.php?delete_tid={$tid}' class='btn btn-danger btn-sm'>Delete</a>
                    </td>
                    </tr>";
                  }

var_dump($new_tname) throws me a NOTICE: Undefined variable: edit_team

我假设 php 找不到哪个 edit_team(因为它们是多个), isset($_POST['edit_team']) 不是解决方案,因为它会将我抛出 NULL,

这里是用于内联编辑的 jQ

jQ

<script type="text/javascript">
$(".editshow").hide();
  $(".btnEdit").click(function(){
    let btnEdit = $(this),
    containerEl = btnEdit.closest("tr");
    containerEl.find(".editshow").toggle();
  });
</script>

php 有什么解决方法吗?我希望有一个人可以帮助我。谢谢。

【问题讨论】:

  • 所以您点击了“保存”链接 (&lt;a href='teams.php?save_tid={$tid}' style='margin-left: 2px; margin-top:3px;' class='btn btn-success btn-sm editshow'&gt;Save&lt;/a&gt;),但希望/希望通过 $_POST 传递之前的表单值?
  • 当然我应该先获取数据,然后保存它:D 但它仍然是一样的......注意未定义的变量
  • 这里需要一些前端和脚本,所以当点击保存链接时,您可以获取编辑的字段并创建表单正文。
  • 好的,但是怎么做?你能给我一些例子,或指导...我会非常感谢..

标签: php jquery ajax


【解决方案1】:

所以问题是这样的:当您单击这些链接(保存或删除)时,您实际上并没有告诉服务器您正在更新什么。该链接本身无法知道它正在发送哪些字段,或者它们是否已更新,或任何其他信息。您正在页面上进行动态操作,在这种情况下,这将意味着脚本。

这比您使用切换功能所做的要复杂一个数量级,因此请注意 - 您刚刚跳入了最深的一端。我已经开始构建一些可以向您展示可以如何完成的东西,但这绝不是完整或准确的。通过您给我们的快照,我们不知道您的 php 到底在做什么。

这是我构建的代码块,只是作为原型。我将在下面更详细地描述它:

$(function(){
  let updateTeamUrl = "SET_THIS_TO_THE_UPDATE_URL";

  // We'll also save these as references to all the action buttons.
  let actionItems = {
    editBtn: $(".btnEdit"),
    saveBtn: $(".save-btn"),
    deleteBtn: $(".btnDelete")
  }
  $(".editshow").hide();
  // Here we assign the actions to the various buttons/anchors
  actionItems.editBtn.on("click", toggleEdit);
  actionItems.saveBtn.on("click", saveTeam);
  actionItems.deleteBtn.on("click", confirmDelete)

  // Below are the actions we assign above, or support functions for them

  /**
   * toggleEdit() is triggered when the "Edit" button is clicked. This
   *   hides the team name text element, and displays the editable field.
   **/
  function toggleEdit(event){
    let teamContainer = $(this).closest("tr");
    teamContainer.find(".editshow").toggle();
    teamContainer.find(".editable").toggle();
  }

  /**
   * saveTeam() crawls up the DOM tree to the closest "tr" node, and gets
   *  the custom "data-teamid" attribute there. Using that, we can create
   *  a JSON object that we will send to the backend.
   **/
  function saveTeam(event){
    event.preventDefault();

    let clickedEl = $(this),
        teamContainer = clickedEl.closest("tr"),
        teamNameEl = teamContainer.find(".editshow");
    let payloadToSend = {
      // We need a mechanism to identify what team we're updating
      teamId: teamContainer.data("teamid"),
      // This will eventually hold any and all updates.
      updates: {
        /* We'll create this empty, and fill it as we need.*/
      }
    };

    // I created a data attribute on the input, "data-original", and
    //  set it to the same value as the input. By comparing these, we
    //  can see if an input has, in fact, been updated.
    if(teamNameEl.data("original") !== teamNameEl.val() ){
      /**
       * The only thing we are updating in this pass is the team name.
       *  So we can update our "payload", then simply send the post request.
       **/
      payloadToSend.updates.name = teamNameEl.val();

      /**
       * When we POST, we need a URL and a string we'll send. 
       *  What we'll do is take the payload, and run it through
       *  JSON.stringify() to convert it to a string.
       *  Then, when we call $.post(), we can also add a .done() and
       *  .fail() handler. These will run when the save is complete,
       *  or when it fails.
       * 
       **/
      let postRequest = $.post(UpdateTeamUrl, JSON.stringify(payloadToSend) )
              .done(function(returnedData){
                console.log("Update succeeded: "+returnedData)
              })
              .fail(function(error){
                console.error("Update had an error: "+error)
              })
              .always(function(){
                teamContainer.find(".editshow").toggle();
                teamContainer.find("editable").toggle();
              });
    }
  } // end saveTeam();

  function confirmDelete(event){
    event.preventDefault();
    let clickedEl = $(this),
        teamContainer = clickedEl.closest("tr"),
        teamId = teamContainer.data("teamid"),
        teamName = teamContainer.find("[name='edit_teams']").val();


    if(confirm("are you sure you want to delete the team "+teamId+": "+teamName+"?") ){
      console.log("Deleting!")
    } else {
      console.log("false alarm.")
    }
  }
})

此外,支持此功能的 HTML 需要稍作更改:&lt;tr&gt; 获取数据属性 data-teamid&lt;input&gt; 获取数据属性 data-original,包装输入的表单元素已删除。这是 HTML(没有 PHP 来构建它):

    <tr data-teamid="1">
      <td>
        <a href='#' class='editable' style='margin-left: 2px;'>Team Name</a>: <input type='text' class='editshow form-control col-sm-3' aria-label='Sizing example input' aria-describedby='inputGroup-sizing-sm' name='edit_teams' data-original='Team Name' value='Team Name'> <a href='teams.php?save_tid={$tid}' style='margin-left: 2px; margin-top:3px;' class='btn btn-success btn-sm editshow save-btn'>Save</a>
      </td>
      <td>
        <button  class='btn btn-primary btn-sm btnEdit team-1'>Edit</button> | <a href='#' class='btn btn-danger btn-sm btnDelete'>Delete</a>
      </td>
    </tr>

正如我所说,这变得相当复杂。

首先,我将您所有的“操作”移到了一个 javascript 对象中。如果我添加其他操作,我只需在那里更新它们。然后,我使用.on(...) 为我要处理的每个操作附加侦听器:编辑、保存和删除。对于其中的每一个,我编写了一个函数来处理操作本身:toggleEdit(...) 用于编辑,saveTeam(...) 用于保存,confirmDelete 用于删除。每个动作都是独立的,使编辑更容易。

toggleEdit(...) 几乎与您之前的完全一样。我不认为我在那个方面有太大变化,所以看起来应该很熟悉。

saveTeam(...) 是您现在要询问的那个,它是复杂的位。首先,我们爬回 DOM 树到 &lt;tr&gt;,并使用 .data("teamid") 获取我们正在编辑的团队的 id。然后我们开始创建一个javascript 对象,我称之为payloadToSend。在此,我们有一个属性teamId,和一个嵌套对象updates。接下来,我们检查文本输入是否已更新(通过将其值与我添加的 data-original 属性进行比较)。如果它没有改变,我们不需要更新。如果它,那么我们通过将name 添加到payloadToSend.updates 对象来更新payloadToSend,并且我们使用$.post(...) 来实际发送POST 请求。 $.post() 接受一个 URL 和一些数据。我们将发送payloadToSend 对象作为该数据,它应该在php 中显示为$_REQUEST$_POST。此外,$.post(...) 包括两个条件回调,.done(...).fail(...),以及一个“绝对”回调,.always(...)

.done(...) 在服务器端请求返回成功完成时运行,.fail(...) 处理后端失败并显示错误消息。不过,无论哪种情况,我们.always(...) 都希望隐藏可编辑项并再次显示团队名称。

此时,confirmDelete 操作除了获取相同的 teamId 并弹出一个基本的确认对话框之外没有做任何其他事情。删除操作远不止于此,超出了您最初问题的范围。

【讨论】:

    【解决方案2】:

    您将需要一些额外的处理和过滤以确保数据的安全性,但一个简单的解决方案是将字段名称更改为 edit_teams_{$tid} 并在您的 php 循环中通过传递表单域:

        <?php
            foreach($_POST as $field_name => $field_value){
               if(substr($field_name,"edit_teams") !== false){
                  $edit_teams = $field_value;
                  $team_id = str_replace("edit_teams_","",$field_name);
               }
        }
    ?>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-12-30
      • 1970-01-01
      • 2020-03-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-11
      • 1970-01-01
      相关资源
      最近更新 更多