Prendre une photo

L’icone de l’appareil photo n’apparaît pas à coté du champ de type image

Le bouton “Take a picture” présent sur la photo de l’objet métier utilisateur n’est pas une fonction standard. Elle est ajoutée via un hook client, cf. la ressource SCRIPT de l’objet User

J’ai joins le fichier comme ressource en m’inspirant de l’objet métier utilisateur mais cela ne fonctionne pas.
Je refais la même chose sur mon instance de test et je n’ai toujours pas l’appareil photo qui apparaît.
Vous pourriez me donner un peu plus d’indications?

Merci de copier/coller le contenu de la ressource SCRIPT de votre objet car sans cela il nous est impossible de vous aider.

(function(ui,$) {
	if (!ui) return;
	var app = ui.getAjax(),
		view = ui.view,
		tools = view.tools;

	function takePicture(media,pict) {
		var dlg, div = $('<div/>').css({ "text-align":"center", position:"relative" }),
			vw = 320, vh, // video size
			x, y, m, // crop rect
			w = 128, // image size
			video = $('<video/>')[0],
			rect = $('<div/>').css({ position:"absolute", border:"solid 1px blue" }),
			btn = $('<button class="btn btn-default"/>').append(view.icon("fas/camera")).click(function() {
				var canvas = $('<canvas/>').attr({ width:vw, height:vh })[0],
					context = canvas.getContext('2d'),
					image = new Image();
				context.drawImage(video, 0, 0, vw, vh);
				image.onload = function() {
					// Crop center
					var c = $('<canvas/>').attr({ width:w, height:w })[0],
						ctx = c.getContext('2d');
					ctx.drawImage(image, x, y, m, m, 0, 0, w, w);
					var data = c.toDataURL("image/png"); // data:image/png;base64,...
					pict.ui.val({
						id: "0",
						name: "picture.png",
						mime: "image/png",
						content: data ? data.split(",")[1] : null
					}).change();
					tools.dialogClose(dlg);
				};
				image.src = canvas.toDataURL("image/png");
			});
		dlg = tools.dialog({
			title: pict.label,
			closeable: true,
			width: (vw+40)+"px",
			content: div.append(video).append(rect).append("<br/>").append(btn),
			onload: function() {
				// Start the video
				media.getUserMedia({
					video: { facingMode: 'user' }
				}).then(function(stream) {
					video.srcObject = stream;
					video.onloadedmetadata = function(e) {
						vh = video.videoHeight * vw / video.videoWidth;
						$(video).attr({ width:vw, height:vh });
						x = vw>vh ? (vw-vh)/2 : 0;
						y = vw>vh ? 0 : (vh-vw)/2;
						m = Math.min(vw,vh);
						rect.css({ left:x+"px", top:y+"px", width:m+"px", height:m+"px" });
						video.play();
					};
				}).catch(function(err) {
					console.error(err);
				});
			},
			unload: function() {
				// Stop the video
				var stream = video.srcObject;
				$(stream.getTracks()).each(function() { this.stop && this.stop(); });
				video.srcObject = null;				
			}
		});
	}

	Simplicite.UI.hooks.User = function(o, cbk) {
		try {
			if (o.isMainInstance()) {
				var p = o.locals.ui;
				p.form.onload = function(ctn, obj) {
					// Bind action to take a picture
					var media = navigator.mediaDevices,
						btn = $("button[data-action='UserTakePicture']",ctn).hide(),
						pict = ui.getUIField(ctn, obj, "usr_image_id");
					if (pict && pict.ui && media && media.getUserMedia && !btn.hasClass("disabled")) {
						// Addon camera on Picture field
						var addon = $('<span class="input-group-addon" data-action="UserTakePicture"/>')
							.append(view.icon("fas/camera"));
						$(pict.ui.input).closest(".input-group")
							.append(tools.tooltip(addon, $("span",btn).text()));
						$("[data-action='UserTakePicture']",ctn)
							.click(function() { takePicture(media, pict); });
					}
				};
			}
		}
		catch(e) {
			app.error("Error in Simplicite.UI.hooks.User: "+e.message);
		}
		finally {
			cbk && cbk();
		}
	};
})(window.$ui, jQuery);

On parle bien de la resource SCRIPT d’un de vos objets métier ?

Quel est le nom de cet objet ?

Je pose la question car il ne peut pas s’appeler User or le code que vous avez copié/collé est pour l’objet User (cf. le Simplicite.UI.hooks.User) qui doit donc être transposé pour s’appliquer à votre objet.

Vous devez, bien entendu, aussi transposer l’action UserTakePicture et le nom de l’attribut usr_image_id pour que ça corresponde au paramétrage de votre objet.

Sur le User il y a une Action paramétrée UserTakePicture

  • ce code front le masque cf btn.hide()
  • L’action sert juste pour vérifier que l’utilisateur a les droits via !btn.hasClass("disabled") remonté par les meta-data (en gros on ne peut changer que sa propre photo, pas se faire passer pour un autre)
  • pour alors ajouter un addon au champ input-group

Vous pouvez simplifier sans paramétrer d’action habilitée en back, et directement ajouter un l’addon sur le champ image :

...
Simplicite.UI.hooks.VOTRE_OBJET = function(o, cbk) {
...
p.form.onload = function(ctn, obj) {
	// Bind action to take a picture
	var media = navigator.mediaDevices,
		pict = ui.getUIField(ctn, obj, "VOTRE_CHAMP_IMAGE");
	// le champ existe et la camera accessible ?
	if (pict && pict.ui && media && media.getUserMedia) {
		// Addon camera on Picture field
		var addon = $('<span class="input-group-addon"/>')
			.append(view.icon("fas/camera"));
		$(pict.ui.input).closest(".input-group")
			.append(tools.tooltip(addon, "Prendre une photo"));
		addon.click(function() { takePicture(media, pict); });
	}
};
...

Sinon vous devrez également créer une action back qui implémente la règle de “qui peut se prendre en photo sur ce formulaire en fonction du login” dans le isActionEnable.