I have a .php file with some javascript that calls a canvas draw, upon submitting the form will upload the canvas draw image and it will submit SQL data to a database. 100% of the time the SQL data will be uploaded. My problem is the javascript will not always upload. My browser is mobile safari on an iPad. Any assistance would be greatly appreciated. Below is the file that captures the image. It then uploads it to upload_data.php. I am using the codeigniter framework.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Trailer Draw</title>
<script src="http://code.createjs.com/easeljs-0.5.0.min.js"></script>
<script src="http://code.jquery.com/jquery-1.8.2.js"></script>
<script type="text/javascript">
$(document).ready(function () {
initialize();
});
// works out the X, Y position of the click inside the canvas from the X, Y position on the page
function getPosition(mouseEvent, sigCanvas) {
var x, y;
if (mouseEvent.pageX != undefined && mouseEvent.pageY != undefined) {
x = mouseEvent.pageX;
y = mouseEvent.pageY;
} else {
x = mouseEvent.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
y = mouseEvent.clientY + document.body.scrollTop + document.documentElement.scrollTop;
}
return { X: x - sigCanvas.offsetLeft, Y: y - sigCanvas.offsetTop };
}
function initialize(canvas, context, onload) {
// get references to the canvas element as well as the 2D drawing context
var sigCanvas = document.getElementById("canvasSignature");
var context = sigCanvas.getContext("2d");
context.strokeStyle = 'red';
make_base();
function make_base(){
base_image = new Image();
base_image.src = '/inc/img/inspection/trailer.png';
base_image.onload = function(){
context.drawImage(base_image, 2, 100);
}
}
// This will be defined for the iPad
var is_touch_device = 'ontouchstart' in document.documentElement;
if (is_touch_device) {
// create a drawer which tracks touch movements
var drawer = {
isDrawing: false,
touchstart: function (coors) {
context.beginPath();
context.moveTo(coors.x, coors.y);
this.isDrawing = true;
},
touchmove: function (coors) {
if (this.isDrawing) {
context.lineTo(coors.x, coors.y);
context.stroke();
}
},
touchend: function (coors) {
if (this.isDrawing) {
this.touchmove(coors);
this.isDrawing = false;
}
}
};
// create a function to pass touch events and coordinates to drawer
function draw(event) {
// get the touch coordinates. Using the first touch in case of multi-touch
var coors = {
x: event.targetTouches[0].pageX,
y: event.targetTouches[0].pageY
};
// Now we need to get the offset of the canvas location
var obj = sigCanvas;
if (obj.offsetParent) {
// Every time we find a new object, we add its offsetLeft and offsetTop to curleft and curtop.
do {
coors.x -= obj.offsetLeft;
coors.y -= obj.offsetTop;
}
// The while loop can be "while (obj = obj.offsetParent)" only, which does return null
// when null is passed back, but that creates a warning in some editors (i.e. VS2010).
while ((obj = obj.offsetParent) != null);
}
// pass the coordinates to the appropriate handler
drawer[event.type](coors);
}
// attach the touchstart, touchmove, touchend event listeners.
sigCanvas.addEventListener('touchstart', draw, false);
sigCanvas.addEventListener('touchmove', draw, false);
sigCanvas.addEventListener('touchend', draw, false);
// prevent elastic scrolling
sigCanvas.addEventListener('touchmove', function (event) {
event.preventDefault();
}, false);
}
else {
// start drawing when the mousedown event fires, and attach handlers to
// draw a line to wherever the mouse moves to
$("#canvasSignature").mousedown(function (mouseEvent) {
var position = getPosition(mouseEvent, sigCanvas);
context.moveTo(position.X, position.Y);
context.beginPath();
// attach event handlers
$(this).mousemove(function (mouseEvent) {
drawLine(mouseEvent, sigCanvas, context);
}).mouseup(function (mouseEvent) {
finishDrawing(mouseEvent, sigCanvas, context);
}).mouseout(function (mouseEvent) {
finishDrawing(mouseEvent, sigCanvas, context);
});
});
}
}
// draws a line to the x and y coordinates of the mouse event inside
// the specified element using the specified context
function drawLine(mouseEvent, sigCanvas, context) {
var position = getPosition(mouseEvent, sigCanvas);
context.lineTo(position.X, position.Y);
context.stroke();
}
// draws a line from the last coordiantes in the path to the finishing
// coordinates and unbind any event handlers which need to be preceded
// by the mouse down event
function finishDrawing(mouseEvent, sigCanvas, context) {
// draw the line to the finishing coordinates
drawLine(mouseEvent, sigCanvas, context);
context.closePath();
// unbind any events which could draw
$(sigCanvas).unbind("mousemove")
.unbind("mouseup")
.unbind("mouseout");
}
</script>
<div>
</div>
<script>
function uploadEx() {
var canvas = document.getElementById("canvasSignature");
var dataURL = canvas.toDataURL("image/png");
document.getElementById('hidden_data').value = dataURL;
var fd = new FormData(document.forms["form"]);
var xhr = new XMLHttpRequest();
xhr.open('POST', '/inc/img/inspection/upload_data.php', true);
xhr.upload.onprogress = function(e) {
if (e.lengthComputable) {
var percentComplete = (e.loaded / e.total) * 100;
console.log(percentComplete + '% uploaded');
//alert('Succesfully uploaded');
}
};
xhr.onload = function() {
};
xhr.send(fd);
return false;
};
</script>
</head>
<style>
input {
margin-left: 200cm;
}
</style>
<body>
<h1>Trailer Inspection</h1>
<div id="canvasDiv" align="center">
<!-- It's bad practice (to me) to put your CSS here. I'd recommend the use of a CSS file! -->
<canvas id="canvasSignature" width="955px" height="465px" style="border:2px solid #000000;"></canvas>
</div>
<p><h2></h2></p>
<p><h4></h4></p>
<?php if( !empty($table)): ?>
<p><h3></h3></p>
<?php if(is_array($table)): ?>
<?php foreach($table as $h1 => $t1): ?>
<?php if( !is_int($h1)): ?>
<p><h3><?php echo $h1; ?></h3></p>
<?php else: ?>
<br />
<?php endif; ?>
<?php if(is_array($t1)): ?>
<?php foreach($t1 as $h2 => $t2): ?>
<?php if( !is_int($h2)): ?>
<p><h4><?php echo $h2; ?></h4></p>
<?php else: ?>
<br />
<?php endif; ?>
<?php echo $t2; ?>
<?php endforeach; ?>
<?php else: ?>
<?php echo $t1; ?>
<?php endif; ?>
<?php endforeach; ?>
<?php else: ?>
<?php echo $table;?>
<?php endif; ?>
<?php else: ?>
<?php endif; ?>
<br />
<?php if( !function_exists('form_open')): ?>
<?php $this->load->helper('form'); ?>
<?php endif;?>
<form onsubmit="uploadEx();" name="form" id="form" accept-charset="utf-8" method="post">
<input name="hidden_data" id="hidden_data" type="hidden" />
<?php $this->load->helper('string');?>
<?php $number = random_string('unique');?>
<input name="sub_id" id="sub_id" type="hidden" value="<?php echo $number; ?>"/>
<div>
<?php if( !empty($options1) AND !empty($label_display1) AND !empty($field_name1)): ?>
<?php echo form_label($label_display1.":",$field_name1); ?>
<?php echo form_dropdown($field_name1,$options1)?>
<?php endif; ?>
<?php echo form_label('Carrier Code','car_code'); ?>
<?php echo form_input(array('name'=>'car_code','type'=>'text')); ?>
<?php echo form_label('Trailer Number','trlr_num'); ?>
<?php echo form_input(array('name'=>'trlr_num','type'=>'text')); ?>
<?php echo form_label('Truck Number','truck_num'); ?>
<?php echo form_input(array('name'=>'truck_num','type'=>'text')); ?>
<?php echo form_label('Temp','temp'); ?>
<?php echo form_input(array('name'=>'temp','type'=>'text')); ?>
<?php if( !empty($options) AND !empty($label_display) AND !empty($field_name)): ?>
<?php echo form_label($label_display.":",$field_name); ?>
<?php echo form_dropdown($field_name,$options)?>
<?php endif; ?>
<?php echo form_label('License Plate','lic_plate'); ?>
<?php echo form_input(array('name'=>'lic_plate','type'=>'text')); ?>
<?php echo form_label('Seal','seal'); ?>
<?php echo form_input(array('name'=>'seal','type'=>'text')); ?>
<?php echo form_label('STN/Delivery Note','del_note'); ?>
<?php echo form_input(array('name'=>'del_note','type'=>'text')); ?>
<?php echo form_label('Ship Number','ship_num'); ?>
<?php echo form_input(array('name'=>'ship_num','type'=>'text')); ?>
<input type="hidden" name="draw_num" id="draw_num" value="<?php echo $number; ?>" />
<?php echo form_label('Driver Name','driver_name'); ?>
<?php echo form_input(array('name'=>'driver_name','type'=>'text')); ?>
<?php echo form_label('Check if Live','live_drop'); ?>
<?php echo form_checkbox(array('name'=>'live_drop','type'=>'checkbox','value'=>'1')); ?>
<?php echo form_label('Check if Damaged','damaged'); ?>
<?php echo form_checkbox(array('name'=>'damaged','type'=>'checkbox','value'=>'1')); ?>
<?php echo form_label('Comment','comment'); ?>
<textarea class="txtarea" style="height:100px; width:350px;" rows="3" name="comment" Id="comment" value=""> </textarea>
<?php echo form_fieldset_close(); ?>
</div>
</br>
</br>
<input align="center" type ="submit" name="submit" onclick="uploadEx();"> </input>
</br>
</br>
</form>
</body>
</html>
Below is my upload_data.php
<?php
$upload_dir = "upload/";
$img = $_POST['hidden_data'];
$img = str_replace('data:image/png;base64,', '', $img);
$img = str_replace(' ', '+', $img);
$data = base64_decode($img);
$id = $_POST['sub_id'];
$file = $upload_dir . $id . ".png";
$success = file_put_contents($file, $data);
print $success ? $file : 'Unable to save the file.';
?>
Once that has a onsubmit event in the form, you didn't need to make a second calling in the submit button. In this situation, the onclick event in the submit button can be fired before the onsubmit event causing a fault.
Furthermore, you can try make the XMLHttpRequest as synchronous in order to avoid disordered execution of your script sequence by changing the following parameter:
Instead:
xhr.open('POST', '/inc/img/inspection/upload_data.php', true);
Change to:
xhr.open('POST', '/inc/img/inspection/upload_data.php', false);
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments