1

I'm using flask and sqlalchemy inside sublime text to create a simple web application. In 'studentscreen.html', there are multiple html elements (post-it notes/sticky notes) made up of a title and some text. These are created using a for loop. Like so:

<ul id='postlist'>

        {% for post in posts %}

            {% if loggedIn == True: %}


                {% if post[3] == True: %}

                  <li>
                    <a>
                        <h2 onkeypress="return (this.innerText.length <= 15)" contenteditable="true" onblur="saveText()">{{post[1]}}</h2>
                        <p onkeypress="return (this.innerText.length <= 60)" contenteditable="true" onblur="saveText()">{{post[2]}}</p>
                    </a>
                  </li>

    <!-- etc... -->

Using 'onblur', the Javascript function named saveText() is called.

This function is supposed to retrieve the "h2" text as well as the "p" text for any notes that have been created and send it to my 'routes.py' document using an http post request. (I'm unsure about how to do an ajax request.)

Now, I retrieve the contents for each post like so:

function saveText(){
    
            let postsRef  = document.getElementById('postlist').getElementsByTagName('li');
    
            var text = [];
            var title = [];
    
            for (let i = 0; i < postsRef.length; i++) {
                text.push([postsRef.item(i).getElementsByTagName('p')[0].innerHTML]);
            }
    
            for (let i = 0; i < postsRef.length; i++) {
                title.push([postsRef.item(i).getElementsByTagName('h2').[0].innerHTML]);
            }
    
    /* etc... */

This creates two arrays; text and title holding all texts' and titles'. I'm trying to send this information to 'routes.py' like so:

var http = new XMLHttpRequest();
var url = "/newtext";
http.open ("POST", url, true);
http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
http.send(/* something! */);

I don't know what to pass in to .send(). Furthermore I don't know how to receive the information to be sent. Now I have the following:

@app.route("/newtext", methods = ["POST", "GET"])
    def newText():

        if request.method == "POST":
            data = request.form


    # etc... #

I have tried different alternatives like request.form.get(), request.value and request.form.get('name') (creating a dictionary with a key named 'name' in 'studentscreen.html').

Sometimes it returns stuff like this:

'None', 
{}, 
ImmutableMultiDict([]), 
CombinedMultiDict([ImmutableMultiDict([]), 
ImmutableMultiDict([('object Object', '')])])

Please let me know how to format the content and perform the post request and receive it in python.

Thank you! /William

1 Answers1

0

In the send function you need to send xml form.

http.send(`title=${title}&text=${text}`); 

The one inside ${} are the lists.

In flask you can access it using

request.form.get("title")
request.form.get("text")

Edit : ajax version

Include jquery in your html

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>


$.ajax({
    type: "POST",
    url: url,
    data: JSON.stringify({titles: title, contents: text}),
    contentType: "application/json; charset=utf-8"
    success: function(response){
     
    }
  });

When accessing this in python you need to use getlist

request.get_json()['titles']
request.get_json()["text"]
charchit
  • 1,492
  • 2
  • 6
  • 17
  • What do you mean by more than one title and text. You are storing all the title and text in a list. You can't have two variable with same name. – charchit Jul 21 '21 at 11:51
  • I tried using your solution but `request.form.get("title")`returns a string that looks like a list; Title1,Title2,Title3. I need it to return an actual list. – William O'Brien Jul 21 '21 at 11:54
  • You can covert the string to list by list.split(","), but that would not be a good idea, you can use ajax jquery for the same which is easy, if you want I can edit my answer to include it. – charchit Jul 21 '21 at 12:02
  • Yes, please add the ajax version. It would be very helpful! – William O'Brien Jul 21 '21 at 12:12
  • Thanks! I just tried it but nothing happens. No console log or request. Where do I have to put the link to google apis? Can it be anywhere in the html? The $.ajax function is supposed to be in the saveText() function right? – William O'Brien Jul 21 '21 at 14:25
  • I found it. It's a typo in your code. `data:{"title":title,"text",text}`. The colon : is missing. But now when I try, the POST request works but `data = request.form.get("title")`returns None. Any suggestions? Thanks a lot! – William O'Brien Jul 21 '21 at 14:45
  • Sorry my bad, I was confused in javascript object and python dict. You don't have to make key as string, I have edited the answer now check it will work. – charchit Jul 21 '21 at 14:57
  • `data = request.form.get("title") still returns 'None' but `data = request.form` returns: ImmutableMultiDict([('title[0][]', 'lorem ipsum'), ('title[1][]', 'bla bla'), ('title[2][]', 'hello'), ('text[0][]', 'some text'), ('text[1][]', 'some more text'), ('text[2][]', 'Lorem ipsum dolor sit amet')]) **I think the answer is close. Any ideas on this?** – William O'Brien Jul 21 '21 at 15:57
  • You need to use `request.form.getlist("title[]")` and same for text. – charchit Jul 21 '21 at 16:07
  • I'm afraid this returns `[]`. Just an empty list on client side. – William O'Brien Jul 21 '21 at 16:52
  • What about server side, and can you try without those brackets. Also can you move this automatically this conversation to chat because it is not showing in my device. – charchit Jul 21 '21 at 16:54
  • Sorry, I don't have enough reputation points to automatically move it to chat. It still returns `[]`without the brackets like so: `request.form.getlist("title")`. On server side, the following returns [object Object]: `let data = {title:title,text:text} alert(data)` – William O'Brien Jul 21 '21 at 17:09
  • I think you are confused in client and server side, the flask python side is your server and the html,css,is is your client side. Check this answer. https://stackoverflow.com/a/23889195/15011621 – charchit Jul 21 '21 at 17:15
  • Thank you so much! It's working now. I had to encode the data to JSON. `data: JSON.stringify({titles: title, contents: text}),`and then add a content type: `contentType: "application/json; charset=utf-8",`. The lists are accessed through this: `data = request.get_json() titles = data['titles']`on the sever side. Thanks again! – William O'Brien Jul 22 '21 at 07:27
  • ok thanks for telling I will edit my question and include this so it helps other's too. – charchit Jul 22 '21 at 07:33