1

I am creating a data entry/timing web app using Python and Flask. When the user goes to the log page, they enter in the "session ID" for their task, and the time of form submission and user ID are automatically input to the database as well.

Now I am trying to use Javascript to record when the page is loaded for a task so I have a start time and an end time. I first attempted to POST the javascript variable via AJAX to the back end, but I couldn't seem to get it to work. Now I am trying to have the javascript variable be sent alongside the session ID as part of a "HiddenField". I am not yet at the point of configuring the page load time script, I am just trying to get the Javascript to talk to WTForms to talk to my database commit. Here is my code currently:

views.py

@app.route('/logpage', methods=['GET', 'POST'])
@login_required
def logpage():
    form = LogForm()

    if form.validate_on_submit():
        timer = request.get_data("timer")
        entry = LogData(sessionid=form.sessionid.data, user_id=current_user.get_id(), starttime=form.testvar.data, endtime=datetime.utcnow())
        db.session.add(entry)
        db.session.commit()

        return redirect(url_for('home'))

    return render_template('logpage.html', form=form)

models.py

class LogForm(FlaskForm):
    sessionid = StringField('sessionid', validators=[InputRequired(), Length(min=16, max=16)])
    testvar = HiddenField('testvar')

logpage.html

{% extends "base.html" %}
{% import "bootstrap/wtf.html" as wtf %}

{% block title %}Active Log Page{% endblock %}
{% block head %}
    <!-- Custom styles for this template -->
    <link href="static/css/starter-template.css" rel="stylesheet">
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
    <script>window.jQuery || document.write('<script src="{{ url_for('static', filename='jquery.js') }}">\x3C/script>')</script>
    <script src="static/js/timer.js?version=25"></script>
{% endblock %}

{% block body %}

    <div class="container">

    <div class="form-group">
    <form class="form-logpage", method="POST" action="/logpage", id="jsinput">
      {{ form.hidden_tag() }}
      {{ wtf.form_field(form.sessionid) }}
      <div id="jsinput">
      {{ wtf.form_field(form.testvar) }}
      </div>
<button class="btn btn-lg btn-primary btn-block" type="submit">Finish Job</button>
</form>
  </div>
</div>
{% endblock %}

timer.js

var myData = "dataVariable";
document.getElementById("jsinput").value = "myData";

As you can see, I tried to use document.getElementById to put the variable in logpage.html, but when I hit submit, the starttime field is empty. I've looked around the documentation for a way to put a variable in the WTForm, but I can't find anything relevant.

Before, during some other issues it's showed as null and /x and ''b but I've done a good bit of tinkering since then and the database entry is just ''.

If there is a more elegant way to record page load datetime and record simultaneously to the database with the rest of the data, I would love to hear suggestions. Previous SO post here: Python/Flask: How to tell how long a user spends on a page? (Data entry/time log app)

  • I think figuring this out would be much more straightforward if you were looking at the resultant HTML rather than this pre processed file. – 0x11 Sep 22 '17 at 19:51
  • According to `timer.js`, you're attempting to set the `
    `'s value, which doesn't exist. You need to set the ``'s value.
    –  Sep 22 '17 at 19:51
  • @ChrisG That's what I'm having issues with, I don't know how to set the input value when I'm using WTForms. – reflects_ark Sep 22 '17 at 19:55
  • If I was to send the data in a regular form, like from this answer https://stackoverflow.com/questions/7764154/pass-a-javascript-variable-value-into-input-type-hidden-value , how do I call that to be input into the database? I can't find the syntax to call the value. – reflects_ark Sep 22 '17 at 20:05
  • Usually, `` elements have a `name` attribute; this is used on the server-side to access the value. If you want to set the value, you can reference the input by `formElement.name` or by assigning it an `id`. Can you show us the actual HTML of logpage.html? –  Sep 22 '17 at 21:57

1 Answers1

1

Here's the solution I came up with for this problem:

  1. Add a hidden field to the form with an id.
  2. Grab the ID in your script and assign a value to it.

In your form.py:

from flask_wtf import FlaskForm
from wtforms import SubmitField
from wtforms import HiddenField

class MyForm(FlaskForm):
    
    my_data = HiddenField(
        'my_data',
        render_kw={'id':'my_data'}
    )
    
    save = SubmitField(
        'Save',
        render_kw={'id':'save'}
    )

create and pass your form in your view and then render the save and my_data fields in your html template using {{ form.save }} and {{ form.my_data }}

Add the following to your javascript:

var saveButton = document.getElementById('save');

saveButton.addEventListener('click', function() {
    document.getElementById('my_data').value = 'MY DATA IS HERE!!';
});

you can now access your data in your python view using:

from flask import request

...some code...

request.form['my_data']

It's a late answer, but hopefully useful to someone out there...