Image Component Customization - Image Size Restriction - Drag/Drop - Touch UI


Customization of Image component or file upload resource type drag and drop from content/asset finder and restrict it to 1 MB or to any size.

Step 1: Create a AEM Image Component or use file upload resource type to drag and drop images in Touch UI dialog.

Step 2: Create Client library in your project application structure or inside component. Use categories as cq.authoring.dialog or add extra clientlibs as needed.

Step 3: Create a js file and add below piece of code which talks about file upload functions and accommodate for drag and drop behavior for coral classes from Content/Asset finder.

As the page div for drag and drop creates on run time and becomes messy to retrieve the image size, hence a ajax call is used to get the image size post adapting resource to Asset.

(function($, $document, ns) {
    var FILE_UPLOAD_SELECTOR = ".cq-dialog .cq-FileUpload";

function imageSizeValidation(widget, elementName, imageSize, operation) {
        if (widget && elementName) {
            var inputElement = $('input[name="' + elementName + '"]');
if (operation === 'imageUpload') {
if (inputElement && imageSize > 1) {
ns.ui.helpers.prompt({
title: Granite.I18n.get("Invalid Input"),
message: "Image size should be less than or equal to 1 MB",
actions: [{
id: "CANCEL",
text: "OK",
className: "coral-Button"
}],
callback: function (actionId) {
if (actionId === "CANCEL") {
}
}
});
$('.cq-FileUpload-thumbnail-img img:last-child').remove();
$('.cq-FileUpload-edit, .cq-FileUpload-clear').css('display', 'none');
$('.cq-FileUpload.is-filled .cq-FileUpload-icon').css('display', 'block');
$("input[name='./fileOReference']").val('');
$("input[name='./fileOReference']").attr('disabled', 'disabled');
$("input[name='./file@Delete']").val('true');
$("input[name='./fileOReference']").attr('disabled', false);
$("input[name='./imageMap@Delete']").val('true');
$("input[name='./imageMap@Delete']").attr('disabled', false);
$("input[name='./imageCrop@Delete']").val('true');
$("input[name='./imageCrop@Delete']").attr('disabled', false);
$("input[name='./imageRotate@Delete']").val('true');
$("input[name='./imageRotate@Delete']").attr('disabled', false);
} else {
$('.cq-FileUpload-clear .coral-Button, .coral-Button--quiet').css('display', 'block');
$('.cq-FileUpload.is-filled .cq-FileUpload-icon').css('display', 'none');
}
} else if (operation === 'imageClear') {
$('.cq-FileUpload-edit, .cq-FileUpload-clear').css('display', 'none');
$('.coral-Icon, .coral-Icon--image, .cq-FileUpload-icon').css('display', 'block');
}
        }
    }

function registerImageDrop(widget){
        //when the image is drag n dropped from asset finder
        widget.$element.on("assetselected", handleImageDrop);

        function handleImageDrop(event){
            var assetPath = event.path;
  $.ajax({
                type: 'GET',
                url: '/apps/imagesizecheck/imagesizen' + '?assetPath=' + assetPath,
                success: function(data, status) {
                if (data.imageSize && data.imageSize) {
imageSizeValidation(widget, './file', data.imageSize, 'imageUpload');
            }
                },
                error: function() {
                    console.error("Image Size Servlet Failed");
                }
            });
            if(_.isEmpty(assetPath)){
                return;
            }
        }
    }

    $document.on("dialog-ready", function() {
        var $element = $document.find(FILE_UPLOAD_SELECTOR),
            widget = $element ? $element.data("fileUpload") : undefined;

        if (_.isEmpty(widget)) {
            return;
        }
        registerImageDrop(widget);
    });

    $(document).on("click", ".cq-FileUpload-clear", function() {
var $element = $document.find(FILE_UPLOAD_SELECTOR),
            widget = $element ? $element.data("fileUpload") : undefined;

        if (_.isEmpty(widget)) {
            return;
        }
imageSizeValidation(widget, './file', undefined, 'imageClear');
    });

})(jQuery, jQuery(document), Granite.author);

Step 4: Add a Sling Servlet in your project structure. Below is the code.

import java.io.IOException;

import javax.servlet.Servlet;
import javax.servlet.ServletException;

import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.servlets.SlingSafeMethodsServlet;
import org.osgi.service.component.annotations.Component;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.day.cq.dam.api.Asset;
import com.day.cq.dam.api.Rendition;

/**
 * Servlet that returns the image size which is present in DAM.
 */
@Component(immediate = true, service = Servlet.class, property = { "sling.servlet.paths=/apps/imagesizecheck/imagesizen",
"sling.servlet.methods=get" })

public class ImageSizeServlet extends SlingSafeMethodsServlet {

private static final long serialVersionUID = 7482871355549531696L;
private static final Logger LOGGER = LoggerFactory.getLogger(ImageSizeServlet.class);

@Override
protected void doGet(final SlingHttpServletRequest request, final SlingHttpServletResponse response)
throws ServletException, IOException {
LOGGER.debug("Enter Do Get method");
String assetPath = (String) request.getParameter("assetPath");
ResourceResolver resourceResolver = request.getResourceResolver();
Resource resource = resourceResolver.getResource(assetPath);
Asset asset = resource.adaptTo(Asset.class);
long imageSizeInBytes = rendition.getSize();
float imageSizeInKB = imageSizeInBytes / 1024;
float imageSizeInMB = imageSizeInKB / 1024;
response.setContentType("application/json");
response.getWriter().write("{\"imageSize\":" + "\"" + imageSizeInMB + "\"}");
LOGGER.debug("Exit Do Get method");
}
}

Step 5: Below is the test result for higher size images.



Comments

  1. It would be really great if you make a git repository and commit files there.

    ReplyDelete
  2. Nice customization.

    I was wondering how to know there are events like "assetselected"?
    How can I find more events of other granite ui?

    Thanks.

    ReplyDelete

Post a Comment

Popular posts from this blog

AEM 6.3 | Apache Sling Content Disposition Filter | Hosting Static HTML in JCR

Access OSGI ser­vice from Sightly WCMUsePojo | AEM 6.3