如何使用jQuery动态创建和填充文本字段?

3

这是一个我认为相当常见的问题(或设计模式?),因此我希望这篇文章可以帮助其他遇到类似问题的人......

我有一个不太常见的情况,需要动态地允许用户编辑依赖于用户做出的其他选择的数据的复杂表单。我正在使用Ajax、jQuery与PHP以及后端数据库postgres。

我已经想出了如何基于用户选择的两个值返回单个记录的数据,使用了jQuery Ajax技术(对于这种情况,Ajax比php更加出色);通常返回值将是一个记录,我的HTML表单可以处理。但有时返回值将是两个或三个记录。在这种情况下,我需要动态添加输入字段并用返回的数据填充它们。

这是我的表单中的代码;Fetch按钮获取所选标记值和所选LabID值来查找相关记录,其中包含Allele_1、Allele_2和Run日期:

<fieldset>
      <LEGEND><b>Edit Genotype</b></LEGEND>
      <p>
    <boldlabel>Selected Marker</boldlabel><input name=sel_marker length=15 DISABLED>
    <boldlabel>Selected LabID</boldlabel><input name=sel_labid length=10 DISABLED><br>
    <boldlabel>Allele_1</boldlabel><input id=allele1 name=allele_1 size=5 >
    <boldlabel>Allele_2</boldlabel><input id=allele2 name=allele_2 size=5 >
    <boldlabel>Run date</boldlabel><input id=run_date name=run_date size=10 >
    <br>
      </p>              
    <input type="button" name="fetch" id="fetchbutton" value="Fetch" sclass="btn">
    <input type="button" name="save"  value="Save" onclick="savegenotype()" class="btn">
    <br>
    </fieldset>

这是与“获取”按钮相关联的JavaScript代码:

  function fetchgenotype() {
    // here's where we use an Ajax function to fetch the allele values without reloading the page.
    // Get the index number of the genotype record to retrieve; retrieve it; populate the alleles.

    var mndx = document.EditGenotype.marker.options[document.EditGenotype.marker.selectedIndex].value;
    var sndx = document.EditGenotype.labid.options[document.EditGenotype.labid.selectedIndex].value;

    $.post("fetchAlleles.php", {mndx: mndx, sndx: sndx},
    function(result) {        
      i=0;
      result.each(
        a1='allele1_'||i.toString();
        a2='allele2_'||i.toString();
        r='rundate_'||i.toString();

        $("#run_date").after(a1);
        $("#run_date").after(a2);
        $("#run_date").after(r);
      )
    }, "json");

    return false;
  }

这里是单独的 PHP 脚本,即 Ajax 部分,用于查找相关数据:
   // query the database.
    $dbconnect = pg_pconnect("host=".$hostname." user=".$dbuser." dbname=".$dbname);    
    if (!$dbconnect)    {
        showerror(0,"Failed to connect to database",'fetchAlleles',16,"username=".$dbuser.", dbname=".$dbname);
        exit;
    }
    $sql = "SELECT allele1, allele2, run_date FROM geno.genotypes WHERE markers_id=".$mndx." AND gsamples_id=".$sndx;

    $fetchresult = pg_exec($dbconnect, $sql);
    if ($fetchresult) {
        $arr = pg_fetch_array($fetchresult, 0, PGSQL_NUM);
        // for debugging
        //print_r($arr);
    } else {
        echo "(25) Failed to retrieve results.<BR>SQL: ".$sql."</br>";
    }

    // It appears necessary to return the array as json encapsulated.
    echo json_encode($arr);
?>
}

我知道,对于单一数值情况,这部分代码是有效的;但是当返回值为多条记录的数组时,我的javascript表单中jQuery代码的语法不正确。我在以下这行代码中遇到了错误 a1='allele1_'||i.toString();

希望有jQuery高手能够帮我解决这个问题,非常感谢...


你能否也发布JSON输出(使用Firebug或Chrom Dev-tool)以便我们可以看到你的响应结构是什么样子的。 - V-Light
1个回答

2
我的第一个想法是:使用pg_affected_rows来查找是否有一个或多个记录。
我的第二个想法是:为什么不使用pg_fetch_object?我认为你会得到更好(可读性更高的)JSON。
我的第三个想法是:您应该统一JSON输出。常见做法是-JSON响应应类似于对象数组。如果DB仅返回一条记录-> JSON响应是仅包含其中一项的数组。如果DB返回多条记录-> JSON响应是包含多个项的数组。
JSON-Response示例
//DB return only ONE record
    {
      "items": [
            { 
                "allele1" : "the-value",
                "allele2" : "the-value",
                "run_date" : "the-date"
            }
        ],
      "totalItems : 1
    }

//DB returns more than one records
{
  "items": [
        { 
            "allele1" : "the-value_1",
            "allele2" : "the-value_1",
            "run_date" : "the-date_1"
        },
        { 
            "allele1" : "the-value_2",
            "allele2" : "the-value_2",
            "run_date" : "the-date_2"
        },
        ...
        { 
            "allele1" : "the-value_n",
            "allele2" : "the-value_n",
            "run_date" : "the-date_n"
        }
    ],
  "totalItems : n
}

如果您得到这样的结果,您可以更容易地动态创建输入字段。首先,您可以轻松检查是否收到了一个或多个记录。
if(response.totalItems === 1 ) {
    // handle single record
}else if (response.totalItems > 1) {
    // handle multiple records
}

如果有多个记录,您可以使用jQuery.each()和jQuery.map()进行迭代,并生成输入字段。

if (response.totalItems > 0) {
    //iterate through all items in JSON-response
    $.each(response.items, function(index, object) {
        // create FIELDSET element
        var $fieldset = $('<fieldset>', {'html' : '<legend>#'+(index+1)+'</legend>'});

        $.map(object, function(value ,key) {
           //create LABEL element and appendInto FIELDSET
           $fieldset.append($('<label>', {'text' : key, 'for' : key}));
           //create INPUT element and appendInto FIELDSET
           $fieldset.append($('<input>', {'id': key, 'name': key, 'value' : value}));
           //create LineBreak
          $fieldset.append('<br />');
        });
        // Append whole FIELDSET with LABEL, INPUT and BR to body (or whatever your placeholder is)
        $('body').append($fieldset);
   });
}

谢谢V-Light!这正是我需要的。我会试一试并让你知道结果... - rixter

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接