4

I am trying to perform a cross domain ajax request from a phonegap app and its not working. I am trying to submit form data to a database. I have uploaded it to a test domain i am using on a server and It works perfectly even on my mobile browser however not when i package it with phonegap. I have looked on stackoverflow and can't find a solution. thanks for help.

HTML:

<form id="uploadimage" method="post" action="" enctype="multipart/form-data" >
    <label>name</label>
    <input type="text" name="product_name" id="product_name" size="50"/>                            
    <label>Image</label>
    <input type="file" id="image_file" name="image_file"/>
    <input type="submit" class="button_style" value="Add this item">
</form>

JQuery:

$(document).ready(function() {
    //detect the deviceready event and call onDeviceReady function
        document.addEventListener("deviceready", onDeviceReady, false);
    onDeviceReady();
});

function onDeviceReady(){
    $("#uploadimage").submit(function(e) {
        var file_data = $('#image_file').prop('files')[0]; 
        var form = $('form')[0];  
            var form_data = new FormData(form);                  
            form_data.append('file', file_data);
        //alert(form_data);                             
            $.ajax({
                    url: 'http://www.testdomain.com/iwp/form_app1/form_process.php', // point to server-side PHP script 
                    dataType: 'text',  // what to expect back from the PHP script, if anything
                    cache: false,
                    contentType: false,
                    processData: false,
                    data: form_data,                         
                    type: 'post',
                    success: function(php_script_response){
                            //alert(php_script_response); // display response from the PHP script, if any
                    },
                error: function(xhr, status, error) {
                alert("sarah" + xhr.responseText);
            }

            });
    });
}

form_process.php

<?php
header("Access-Control-Allow-Origin: *");

require("include/db_connect.php");
    if(isset($_POST["product_name"])){
        //insert new item into database after submitting add new item form

        $product_name = $_POST['product_name'];

        $stmt_insert_item = $pdoConnection->prepare("INSERT INTO test (testName) VALUES (:testName)");
        $stmt_insert_item->bindValue(':testName', $product_name, PDO::PARAM_STR); 

        $stmt_insert_item->execute();

        $pid = $pdoConnection->lastInsertId();
        $pid_image = "id-" . $pid . ".jpg";
        $image_directory = "images/" . $pid_image;

        $stmt_update_item = $pdoConnection->prepare("UPDATE test SET testImage=:testImage WHERE testID=:pid");
        $stmt_update_item->bindValue(':testImage', $image_directory, PDO::PARAM_STR);
        $stmt_update_item->bindValue(':pid', $pid, PDO::PARAM_INT);
        $stmt_update_item->execute();

        move_uploaded_file($_FILES['file']['tmp_name'], "" . $image_directory);

    }
?>

I have included the following which i thought were necessary for cross domain requests in my config.xml (for phonegap):

<feature name="http://api.phonegap.com/1.0/network"/>

<gap:plugin name="org.apache.cordova.device" />
<gap:plugin name="org.apache.cordova.network-information" />
<access origin="*" />
<plugin name="cordova-plugin-whitelist" version="1" />
<allow-intent href="http://*/*" />
<allow-intent href="https://*/*" />
Sarah
  • 1,943
  • 2
  • 24
  • 39
  • 3
    Your submit event isn't being cancelled, so the page is submitted, and the DOM unloaded before the AJAX call has finished – Elias Van Ootegem Jul 04 '16 at 13:16
  • To add to the above, put `e.preventDefault()` within your `submit()` handler function – Rory McCrossan Jul 04 '16 at 13:29
  • 1
    You've added the file twice to the form data object, first with the constructor then with append. – Musa Jul 04 '16 at 13:34
  • @RoryMcCrossan thanks. i tried that but it didn't submit at all then... so ive changed my button to have an id and ive used an onclick instead of submit. ...$("#upload_button").on('click', function() {.......... }); i dont think it solved the problem though. i will get back to you thanks – Sarah Jul 04 '16 at 13:40
  • @RoryMcCrossan: `e.preventDefault()` + `e.stopPropagation()` would IMO be better here, since OP is using jQ; `return false;` does that – Elias Van Ootegem Jul 04 '16 at 13:49
  • @Sarah: I don't see the point in using jQ document ready callback, to call `document.addEventListener`, passing, as a callback function, a function that attaches an event handler, _and ***then*** calling that callback function again_. Why not simply move the body of your `onDeviceReady` function to the document ready callback to begin with? If not, you might end up binding the submit handler multiple times – Elias Van Ootegem Jul 04 '16 at 13:51
  • @EliasVanOotegem because its for phonegap.. I got that solution from stackoverflow. – Sarah Jul 04 '16 at 13:53
  • @Musa thanks. i've removed this line: form_data.append('file', file_data); – Sarah Jul 04 '16 at 13:54
  • @sarah can you provide me with a link, because TBH, that shouldn't make much difference: phonegap merely uses the fact that an app can be anything inside a browser window. If it supports JS and jQ, then you can write proper JS – Elias Van Ootegem Jul 04 '16 at 13:55
  • @EliasVanOotegem sure.. this isn't the exact solution i used but i just found this one now. its along the same lines. if i find the exact one i used i will show you... http://stackoverflow.com/questions/10893322/phonegap-ondeviceready-method-not-getting-called – Sarah Jul 04 '16 at 14:00
  • @Sarah: The `onDeviceReady` function in the thread you linked to is the _actual_ handler of the event. There's no jQ involved. You're using that function as if it were an event handler, but what it's actually doing is bind an event handler. Move the body of `onDeviceReady` you have to the document ready function body, and get rid of the `addEventHandler` call you have now. Have the submit callback return false, and see how much closer that gets you – Elias Van Ootegem Jul 04 '16 at 14:10
  • @EliasVanOotegem thats what i would have done previously without phonegap and just JQuery but deviceready is important for phonegap applications.. I will add that my code above is working on my website but just not when i zip it up with phonegap. https://cordova.apache.org/docs/en/latest/cordova/events/events.html – Sarah Jul 04 '16 at 14:22
  • 1
    You're missing my point: you're only binding the deviceready listener once the document ready callback is invoked, prior to that, your listener doesn't exist. You all phonegap-specific event bindings should be completely separate from the jQ ones. The submit event handler should be bound by jQ. If you _need_ to tie the two together, use `addEventListener` to listen for the deviceready event, and use the handler to bind the jQ document ready callback. You're doing it the other way around, which doesn't look right – Elias Van Ootegem Jul 04 '16 at 14:26
  • @EliasVanOotegem thanks for explaining. I see your point. how i understand it is deviceready will always fire after document ready so i thought that made sense. actually i have found the solution i am using. it has 76 upvotes on this page. let me know what you think after reading this?as i know you have a good point however i was just going by this: http://stackoverflow.com/questions/12576062/jquery-document-ready-vs-phonegap-deviceready – Sarah Jul 04 '16 at 14:37
  • @EliasVanOotegem actually i guess i dont need this line onDeviceReady(); in the document.ready function... however it didnt work without that before which must have meant deviceReady didnt fire at all on phonegap. – Sarah Jul 04 '16 at 14:39
  • @Sarah: The answer with 76 up-votes quotes the docs saying that, unlike other events in the standard JS event cycle, the deviceready event takes precedence. You're binding it during the document ready event, which is part of the standard event cycle. The problem here is that you're using jQ, which relies on the JS event loop, but the actual _handlers_ reside in JS, it's the jQ handlers that use your code as callbacks. If I were you, I'd use the phonegap events when I can, and move the binding outside of the jQ/standard JS event cycle – Elias Van Ootegem Jul 04 '16 at 14:49
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/116385/discussion-between-sarah-and-elias-van-ootegem). – Sarah Jul 04 '16 at 15:02
  • @EliasVanOotegem thanks for your advice. im going to read up on what you're saying and get back to you. :) – Sarah Jul 04 '16 at 15:06
  • @EliasVanOotegem hi. so like you said I have taken out device ready and put my submit function inside document.ready with return false. this works nicely and it is returning success all the time on my desktop however I wrapped the project up and tested it as a phonegap app on my android and it is not working consistently. two scenarios: 1. returns success and the image uploads successfully to my web server. 2. the error function gets called, but the image does upload correctly to my web server.do you have any advice on how i can get info on the error as xhr.responseText doesnt output anything – Sarah Jul 07 '16 at 16:05

0 Answers0