Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to dynamically create and populate text fields in jQuery?

Tags:

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...

like image 659
rixter Avatar asked Jan 02 '26 03:01

rixter


1 Answers

My first thought: use pg_affected_rows to find out whethaer you got one or more records.

My second thought: why not pg_fetch_object ? 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);
   });
}
like image 124
V-Light Avatar answered Jan 04 '26 08:01

V-Light



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!