Eogcloud
Eogcloud

Reputation: 1365

Accessing posted form data in javascript

I'm trying to post form data in another view in my node/express application. I'm using Jade as the view engine.

My question is how do I access this res.body object? How to I get at the data? I'm trying to use user input to draw some graphs.

Code below

barchartEntry.jade

form(method="POST")
        #dynamicInput
            input(type="button" value="Add New Bar" onClick="addInput('append');")
            input(type="button" value="Remove Last Bar" onClick="removeInput();")
            br
            label(class="barTitle") Bar 1
            label(class="bartTtle") Value
                input(type="text" name="myInputs[]")
            label Label
                input(type="text" name="myLabel[]")
            br
            #append
            input(type="submit" value="Submit")
    include copyright

Route Handler

exports.postBarchartentry = function postBarchartentry(req, res){
    res.body = req.body;
    res.render('barchart');
};

local JS on new view

$( document ).ready(function() {

        var values = ?
        var labels = ?

        var canvas = document.getElementById("canvas").getContext("2d");
        var Width = canvas.canvas.clientWidth;
        var Height = canvas.canvas.clientHeight;
        var padding = 30;



        function fillBackground(color){
            canvas.fillStyle=color;
            canvas.fillRect(0,0,Width,Height);
        }

        function fillAxes(){
            canvas.beginPath();
            canvas.moveTo(padding, padding);
            canvas.lineTo(padding, Height-padding);
            canvas.lineTo(Width-padding, Height-padding);
            canvas.lineWidth = "3"
            canvas.strokeStyle="black";
            canvas.stroke();
        }

        function draw(){
            fillAxes();
        }

        draw();
});

As you can see, I'm trying to get the inputted form data to be accessable in my last script

Upvotes: 1

Views: 1467

Answers (2)

juanpaco
juanpaco

Reputation: 6433

Hector is correct in that the view only has access to what you pass directly into it. So the question remains what do you want to pass into it?

req.body is indeed a JavaScript object, and your markup gives a really nice way to get at the contents.

I put together a little test project where I used your markup:

label(class="barTitle") Bar 1
label(class="bartTtle") Value
  input(type="text" name="myInputs[]")
label Label
  input(type="text" name="myLabel[]")

When I submitted that form, in my post handler I had something like this:

 app.post('/arraytest', function(req,res) {
   console.log(req.body)
   res.send(req.body)
 })

(We'll ignore for now the ugliness of putting the actual handler inline with the routing call). When that form submits, I get this object for req.body:

{ myInputs: [ '3' ], myLabel: [ 'asdf' ] }

For fun, I added a second input box and pluralized myLabel, so that my form looked like this:

label(class="barTitle") Bar 1
label(class="bartTtle") Value
  input(type="text" name="myInputs[]")
label Label
  input(type="text" name="myLabels[]")
label(class="barTitle") Bar 2
label(class="bartTtle") Value
  input(type="text" name="myInputs[]")
label Label
  input(type="text" name="myLabels[]")

Notice that I didn't change any of the names. I left them with the array brackets at the end. Submitting this form gave me the following object:

{ myInputs: [ '3', '4' ], myLabels: [ 'asdf', 'asdfasfsdf' ] }

So the interaction between the browser and body parsing gives you two arrays with all of your values. Arrays are easy enough to loop over. If you modify your render call to look like:

res.render('barchart', {inputs: req.body.myInputs, labels: req.body.myLabels})

then in your view you can have something like:

- each input, i in inputs
  = input
  = myLabels[i]

But since you want this accessible in your JS, you can use this in your Jade:

script.
  var inputs = !{JSON.stringify(inputs)}
    , labels = !{JSON.stringify(labels)}

  alert(inputs)
  alert(labels)

You'll likely not need the alert calls, but I put them there to convince me that it worked.

Many thanks to this SO question and answer for the dynamic JS portion: How can I render inline JavaScript with Jade?

Upvotes: 2

Hector Correa
Hector Correa

Reputation: 26680

My question is how do I access this res.body object? How to I get at the data?

You'll have access to this data in your controller as you indicated. If you want to pass this data to another view you need to explicitly pass it to the next view.

exports.postBarchartentry = function postBarchartentry(req, res){
    res.render('barchart', {data1: req.body.field1, data2: req.body.field2});
};

In your barchart view you have two options. (1) you can render HTML directly (via Jade) with the new data. For example, add a div if data1 has data. (2) you can also render JavaScript on the page (again via Jade) so that those values will be available when the browser execute the onReady which I think is what you are trying to do.

Also, make sure you are using Express' bodyParser middleware somewhere in your application so that req.body.X has the actual data:

app.use(express.bodyParser())

Upvotes: 2

Related Questions