5

I am building a Django app and on one of my HTML sheets, I have a button that should first run a js function(ocr()) and then another function in the .py.

I've tried the first solution to this post. And now it runs the javascript function but it doesn't go on to the function in the .py.

UPDATE: I added the onsubmit event and the function returns true now. But it still doesn't work.

This is the js script:

<div>
        
        <script>
            var ocr = function(event){
                event.preventDefault();

                Tesseract.recognize(
                    document.getElementById('imgde').src,
                    'deu',
                    { logger: m => console.log(m) }
                ).then(({ data: {text}}) => {
                    console.log(text);
                    document.getElementById('txt_voc_de').innerHTML = ['<input type="hidden" name="txt_voc_de" id="txt_voc_de" value="',text, '"/>'].join('');
                })

                Tesseract.recognize(
                    document.getElementById('imgen').src,
                    'eng',
                    { logger: m => console.log(m) }
                ).then(({ data: {text}}) => {
                    console.log(text);
                    document.getElementById('txt_voc_en').innerHTML = ['<input type="hidden" name="txt_voc_en" id="txt_voc_en" value="',text, '"/>'].join('');
                })
                
                
   
                
            };

            var form = document.getElementById("imgForm");
            form.addEventListener("submit", ocr, true);
        </script>
        <input type="submit" onsubmit="ocr();" id="senden" class="inputfiles" />
        <button for="senden" class="button" id="weiter_btn" >WEITER</button>
        {% csrf_token %}
        </div>

UPDATE 2:

I am now trying to send a request to a URL in the JS function and have it be picked up by a view. But it only returns the previous html sheet.

This is the updated script:

<div>
        
        <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js">
            $(document).ready(function () {
                $("#imgForm").submit(function (event) {
                    event.preventDefault();
                    $.ajax({
                    type: "POST",
                    beforeSend: function() {
                        Tesseract.recognize(
                            document.getElementById('imgde').src,
                            'deu',
                            { logger: m => console.log(m) }
                        ).then(({ data: {text}}) => {
                            console.log(text);
                            document.getElementById('txt_voc_de').innerHTML = ['<input type="hidden" name="txt_voc_de" id="txt_voc_de" value="',text, '"/>'].join('');
                        })

                        Tesseract.recognize(
                            document.getElementById('imgen').src,
                            'eng',
                            { logger: m => console.log(m) }
                        ).then(({ data: {text}}) => {
                            console.log(text);
                            document.getElementById('txt_voc_en').innerHTML = ['<input type="hidden" name="txt_voc_en" id="txt_voc_en" value="',text, '"/>'].join('');
                        })
                    } ,
                    url: "/upload/",
                    success: function () {
                        $('#message').html("<h2>Contact Form Submitted!</h2>")
                    }
                    });
                    return false;
                });
                });
            
        </script>
       <input type="submit" id="senden" class="inputfiles"/>
       <button for="senden" class="button" id="weiter_btn" >WEITER</button>
        {% csrf_token %}
        </div>

The problem probably is that the beforesend function is in javascript right? But is there a way I can run that function in javascript before the ajax request?

And this is my function in views.py

def upload(request):
    if request.is_ajax():
        message = "Yes"
        txt_voc_en = request.POST.get("txt_voc_en")
        txt_voc_de = request.POST.get("txt_voc_de")
        print(txt_voc_de)
        print(txt_voc_en)

        vocsde = ocr_core(txt_voc_de)
        vocsen = ocr_core(txt_voc_en)
        
        messages.success(request, vocsde, extra_tags="de")
        messages.success(request, vocsen, extra_tags="en")
        context = {'vocsen': vocsen,
                    'vocsde': vocsde}
        return render(request, 'success.html', context)
     else:
        message = "Not ajax"
     return HttpResponse(message)



anonimostilton
  • 170
  • 1
  • 16

2 Answers2

2

As per your question, you first want to process some form data via JavaScript, embedding the results in hidden input types. Finally you want to send those hidden input's data to views.py for further process. In the updated script, you mixed javascript with AJAX. You can update you script as followed -

<script>
    var ocr = function(event) {
        event.preventDefault();

        Tesseract.recognize(
            document.getElementById('imgde').src,
            'deu', {
                logger: m => console.log(m)
            }
        ).then(({
            data: {
                text
            }
        }) => {
            console.log(text);
            Tesseract2(text);
        })
    };

function Tesseract2(text_de) {
    Tesseract.recognize(
        document.getElementById('imgen').src,
        'eng', {
            logger: m => console.log(m)
        }
    ).then(({
        data: {
            text
        }
    }) => {
        console.log(text);
        AjaxCall(text_de, text);
    })

}

function AjaxCall(text_de, text_en) {
    $.ajax({
        type: 'POST',
        url: "/upload/",
        data: {
            csrfmiddlewaretoken: $('input[name=csrfmiddlewaretoken]').val(), // to avois csrf error
            txt_voc_en: text_en,
            txt_voc_de: text_de
        },
        success: function(json) {
            //Do whatever you want
        },
        error: function(xhr, errmsg, err) {
            console.log(xhr.status + ": " + xhr.responseText);
        }
    });
}

var form = document.getElementById("imgForm");
form.addEventListener("submit", ocr, true);
</script>

This code will first do preprocessing via javascript and then send it to views.py via AJAX with required parameters "txt_voc_en" and "txt_voc_de".

Vishwas Patel
  • 331
  • 4
  • 9
  • Thank you! The only problem is that it runs the Tesseract part after the ajax call. So the value of "txt_voc_en" and "txt_voc_de" is still empty. Is there a way to put the Tesseract part in the beforeSend function? – anonimostilton Sep 10 '21 at 09:14
  • 1
    Since, Tesseract.recognize() can't execute instantaneously(It is time taking process), it just returns the promise and let the code next to it to be executed while it completes the process. Even beforesend is not promise aware, so same thing would happen while using beforesend. – Vishwas Patel Sep 10 '21 at 12:45
  • 1
    One possible solution would be wrapping the AJAX call in another function and calling that function at the end of second Tesseract.recognize()'s .then() block(where you have put console.log(text)). Also make 2 separate function for 2 tesseract calls and make call to second tesseract.recognize() from first .then() block. – Vishwas Patel Sep 10 '21 at 12:54
  • Thanks! That works now. But when "txt_voc_en" and "txt_voc_de" get printed in the views.py function it's empty. And I think the reason may be that the values in the html sheet which are "" in the beginning don't get updated fast enough. Do you know how I could pass the text values from the tesseract functions directly to the ajax call, without using the input tag in the html? – anonimostilton Sep 10 '21 at 13:42
  • Although I am not very certain why values are still empty. But if you want to pass these text values to Ajax call, without storing it in input tag, you can do so by passing these values as function parameter. I have updated my answer for the same. – Vishwas Patel Sep 10 '21 at 16:16
  • Thanks a lot! The last and only issue is that the views.py function doesn't return the next html sheet. But I know that it runs the function because the correct values get printed. Any idea why? – anonimostilton Sep 10 '21 at 16:51
  • An AJAX request's response can't redirect you to new html page(It generally takes Json Response), although the HttpResponse will be fetched in json object of success block. – Vishwas Patel Sep 10 '21 at 17:03
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/236991/discussion-between-vishwas-patel-and-anonimostilton). – Vishwas Patel Sep 11 '21 at 00:50
-1

You could send a request to a URL in the JS function and have it be picked up by a view.

This post should help you

jeremy_lord
  • 469
  • 7
  • 23
  • where should I put the ajax request? At the end of the js function? – anonimostilton Sep 05 '21 at 08:45
  • I am not well versed with AJAX, but you would want to wrap your current function in and AJAX method. Obviously, if you want to use the `$.ajax` syntax, you'll have to migrate your current JS code to jQuery. – jeremy_lord Sep 05 '21 at 09:08