One of the interesting features in Cordova's Camera API is something called popoverOptions. While the docs do explain what this feature does, it may not be entirely clear how it works so I whipped up a quick example, with screen shots, to demonstrate what it does.

First off - this feature is only for iOS (and the iPad at that) and only for existing pictures, it is not something you can use when having the user take new pictures. So right away you can see this is something that will have limited usage. But what exactly does it do? The docs say:

iOS-only parameters that specify the anchor element location and arrow direction of the popover when selecting images from an iPad's library or album.

The options include:

  • X and Y values to anchor the popover. This makes sense.
  • Width and height for the anchor. This didn't quite make sense. My take is - if you are binding the popover to a UI item, then you specify this so iOS knows how big the anchor is, and combined with x and y, it gives it enough data to know how to position it.
  • An arrowDir property that specifies what direction the popover will be from the anchor. So if you specify a right arrow, the popover will be on the left. Most likely you will use the "any" option to let iOS figure it out.

Let's look at a simple example. I built a very simple HTML page that includes a button for prompting the user to select an image as well a blank image (styled red) that will serve as my anchor. Here is the HTML.

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
		<title></title>
		<meta name="description" content="">
		<meta name="viewport" content="width=device-width">
        <link rel="stylesheet" type="text/css" href="css/app.css" />
	</head>
	<body>

	<img id="canvas" />
	<button id="startCamera">Start Camera Test</button>

	<script src="cordova.js"></script>	
	<script src="js/app.js"></script>
	</body>
</html>

I used a bit of CSS to specify the position and size of the image:


body {
	margin-top: 20px;
}

#canvas {
	position: absolute;
	left: 300px;
	top: 300px;
	background-color: red;
	width: 200px;
	height: 200px;
}

Now let's look at the JavaScript code.

document.addEventListener("deviceready", init, false);
function init() {
	document.querySelector("#startCamera").addEventListener("touchend", startCamera, false);
}

var cameraPopoverHandle;

function startCamera() {

	cameraPopoverHandle = navigator.camera.getPicture(onSuccess, onFail,
     { destinationType: Camera.DestinationType.FILE_URI,
       sourceType: Camera.PictureSourceType.PHOTOLIBRARY,
       popoverOptions: new CameraPopoverOptions(300, 300, 200, 200, Camera.PopoverArrowDirection.ARROW_ANY)
     });

}

function onSuccess(u) {
	console.log('onSuccess');
	document.querySelector("#canvas").src = u;
}

function onFail(e) {
	console.log('onFail');
	console.dir(e);
}

 // Reposition the popover if the orientation changes.
 window.onorientationchange = function() {
 	console.log('running onorientationchange');
	var cameraPopoverOptions = new CameraPopoverOptions(0, 0, 100, 100, Camera.PopoverArrowDirection.ARROW_ANY);
    cameraPopoverHandle.setPosition(cameraPopoverOptions);
 }

Basically, all we have here is a touch handler for the button that fires off a call to the Camera API. Notice we passed in popover options. The X, Y, Width, and Height attributes are based on the CSS I used for the image. Finally, there is a bit of code to handle orientation changes that I took right from the docs. More on that in a minute. So let's look at this in action.

Note how the popover is anchored to my image DOM element. Note too how it is positioned automatically. Once an image is selected, the popover automatically goes away and the rest of my code is fired.

That's mostly it. It's a simple change and it does work better for tablets. You would need to add a bit of logic to see if this is an iPad. Remember that the Device API makes this trivial. Although in my testing it didn't really matter. I switched to the iPhone and the popover options were simply ignored.

Now let's talk about the orientation change. I got this right from the docs and it certainly makes sense, but oddly, it seems as if the X,Y values are ignored. Based on the code from the docs, it seems like it should reposition to 0,0 and assume an anchor size of 100,100. I should have used better values for that, but I wanted to test it as is at first. In my testing, these values seemed to have no impact. In fact, if I remove the code completely, iOS still handles the orientation change ok. If I get some clarification on why this is I'll update the code accordingly.

As before, I've put this up on GitHub in case you want to quickly test: https://github.com/cfjedimaster/Cordova-Examples/tree/master/popovertest