How to create text fields dynamically?

How to dynamically create and populate text fields in jQuery?

  • This is a problem (or design pattern?) which I would think is pretty common, so I hope this post might help others with a similar problem.... I have the not uncommon situation where a complex form needs to dynamically allow users to edit data that depends on other choices the user makes. I'm using Ajax, jQuery with PHP and postgres as the backend database. I have figured out how to return the data for a single record, based on two values picked by the user, using a jQuery Ajax technique (Ajax is sooo much slicker than php for this); usually the return value will be one record, which my HTML form can handle. But sometimes the return value will be two or three records. In that case, I need to dynamically add input fields and populate them with the returned data. Here is the code in my form; the Fetch button takes the Selected Marker value and the Selected LabID value to lookup the dependant record, which contains Allele_1, Allele_2 and Run date: <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> This is the javascript code linked to Fetch button: 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; } Here is the separate PHP script that is the Ajax part that looks up the related data: // 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); ?> } This part works, I know, for the single value case; but when the return value is an array of multiple records, my jQuery code in my javascript section of my form has incorrect syntax. I get an error in the line a1='allele1_'||i.toString(); Any jQuery gurus who can set me straight would be much appreciated...

  • Answer:

    My first thought: use http://php.net/manual/en/function.pg-affected-rows.php to find out whethaer you got one or more records. My second thought: why not http://www.php.net/manual/en/function.pg-fetch-object.php ? I think you'll get much better (readable) json. My third thought : you should unify the JSON output. Pretty common practice is - JSON response should look like an Array of Objects. If DB return only one record -> JSON-response is an Array with ONLY item in it. If DB returns more than one -> JSON-response is an Array with more than one items in it Example of 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 you get result like this, you can easier create INPUT-field dynamically. First of all, you can easy check if you recieved one or more records if(response.totalItems === 1 ) { // handle single record }else if (response.totalItems > 1) { // handle multiple records } in case of multiple records, you can iterate through with jQuery.each() & jQuery.map() and generate inputfields 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); }); }

rixter at Stack Overflow Visit the source

Was this solution helpful to you?

Just Added Q & A:

Find solution

For every problem there is a solution! Proved by Solucija.

  • Got an issue and looking for advice?

  • Ask Solucija to search every corner of the Web for help.

  • Get workable solutions and helpful tips in a moment.

Just ask Solucija about an issue you face and immediately get a list of ready solutions, answers and tips from other Internet users. We always provide the most suitable and complete answer to your question at the top, along with a few good alternatives below.