Image Storage Service

Developer Information

This section contains guidelines on integrating the image cropper into Bizcloud forms and utilities.

Background

Bizcloud forms and utilities are built using AngularJs.

The Image Cropper is  built using the cropperjs image cropper library, written in  plain javascript. A project from https://github.com/InCoderWeb/Image-Editor-InCoderWeb was modified for this application.

The relevant application locations are:

  1. Cropper utility location: [bizversehost url]/a/upload/image
  2. POST upload request service handler:  [bizversehost url]/a/upload

Setting up the Image Editor Parent Window

The to-be-embedded Image Cropper/Editor already contains code for handling the communication with the parent window and the cropper utility.

The cropper utility requires information from the parent window to function correctly. It cannot send information to the image store as the location of the image store, related to the workspace, is unknown.

Communication between the parent window and the image cropper utility which is contained in an iframe, is possible because they are on a common domain. Communication is achieved by the parent window:

  1. Setting a variable ‘parentData’ in the image cropper utility window. The variable is an object used to pass parameters needed by the Utility. See below.

  1. Setting a callback function ‘replaceImage’ in the image cropper utility window. This function has a single parameter and is used to pass the image url back to the parent window for insertion into the model.

It will be necessary to expose in an iframe the cropper utility using the above mentioned utility location. In addition, the display to the image, the iframe content, should also be managed. Below is an AngularJS html template example:

<script type="text/ng-template" id="bv-ctrl-image.html">

   <div class="attr-image-container" ng-controller="imageController" ng-mouseover="showImagePanel()" ng-mouseleave="hideImagePanel()">

       <input

       ng-disabled="isDisabled(formAttr)"

       type="text"

       ng-model="form.data.values[formAttr[0].id]"

       ng-blur="setValue(formAttr)">

       <div class="image-panel" ng-show="showPanel">

           <span ng-hide="cropper" class="material-symbols-outlined" ng-click="toggleCropMode($event)">

               add_photo_alternate

           </span>

           <span ng-show="cropper" class="material-symbols-outlined" ng-click="toggleCropMode($event)">

               close

           </span>

           <img ng-hide="cropper" src="{{form.data.values[formAttr[0].id]}}">

           <iframe ng-show="cropper" class="cropper" src="/a/upload/image"></iframe>

       </div>

   </div>

</script>

The user’s identity is conveyed using the ‘parentData’ object. The following is an example in an AngularJS application, which will differ from case to case:

.controller('imageController',

           ['$scope', '$http', 'userProp',

   function( scope,     http,   userProp  )

   {

       scope.win = null;

       // manage the display of the iframe and image

       scope.toggleCropMode = (e)=>{          

           if (scope.cropper) scope.cropper = false;

           else

           {

               // here we get the iframe contentWindow, to which the parameters and

               // callback function are passed

               let $elm = angular.element(e.target.parentElement),

               iframe = $elm.find('iframe')[0];

               scope.cropper = iframe.contentWindow;

               setInfo();

           }

       }

       scope.showImagePanel = function()

       {

           scope.showPanel = true;

       }

       scope.hideImagePanel = function()

       {

           if (!scope.cropper) scope.showPanel = false;

       }

       // The callback function that updates the model with the image url

       function updateValue(imageUrl)

       {

           scope.form.data.values[scope.formAttr[0].id] = imageUrl;

           scope.setValue(scope.formAttr)

       }

       // The function that sets the parameters and callback function in the utility window

       async function setInfo()

       {

           const uid = scope.perscode.split('@')[0];

           scope.cropper.parentData = {

               gid:uid,

               workspace:scope.ws,

               type:'personnel',

               attribute: scope.formAttr[0].id,

               id: scope.form.id

           };

           scope.cropper.replaceImage = updateValue;

       }

   }

The parentData object used for passing parameters, requires the following:

type

The login method used. String with value ‘personnel’ or ‘googleUser’

gid or userId

The identity of the user. Integer. This depends on the login method. Use ‘gid’ for ‘personnel’ and ‘userId’ for ‘googleUser’

workspace

The workspace ID. An integer.

attribute

The name of the attribute that is to be set with the image url. This is used to record the image storage event.

id

The workspace object instance ID which contains the image url attribute. This is used to record the image storage event.