April 7, 2020
Estimated Post Reading Time ~

Form field Validation – Classic UI Dialog

We have already seen how to validate a form field in Touch UI here. Now let us see how to create a validation for a duplicate check which can be used against any property in classic UI using EXTJS. As an example, I would illustrate the same to check the duplicate for ‘Title’ field in the page properties dialog in a ‘Geomextrixx’ site

PageProperties Dialog

Override the ‘Basic’ tab of page properties under your project template.
To do the same copy the ‘tab_basic’ node from /libs/foundation/components/page/tab_basic and paste it under your page component node. Ex: /apps/geometrixx/components/page
Need to add 2 properties for a widget to do a validation
vtype – validation function which needs to be created for a form field validation
vtypeText – custom error message to be displayed

Override BasicTab

Create a validation function

  1. All the OOB validation functions are present /libs/cq/ui/widgets/source
  2. To add our custom functions, create a same folder structure under your apps. Ex: /apps/cq/ui/widgets/source
  3. Add js.txt under /apps/cq/ui/widgets
  4. Create a file called ‘duplicateTitleCheck.js’ under /apps/cq/ui/widgets/source
Override CQUI Widget

CQ.Ext.apply(CQ.Ext.form.VTypes, {

 duplicateTitleCheck: function(v, f) {
  var dialog = f.findParentByType("dialog");
  var dialogPath = dialog.path;
  var cqresponse = CQ.HTTP.get("/services/duplicateCheck?validate=jcr:title&title=" + v + "&pagePath=" + dialogPath);
  var json = eval(cqresponse);
  var duplicateCheckJson = json.responseText;
  var JSONObj = JSON.parse(duplicateCheckJson);
  var jsonDuplicatePath = JSONObj.validateProperties;
  if (jsonDuplicatePath.length == 0) {
   return true;
  } else {
   return false;
  }
 }
});

Create a service which checks for the duplicate for the given 


@SlingServlet(paths = {
 "/services/duplicateCheck"
}, methods = {
 "GET"
})

public class DuplicateValidator extends SlingAllMethodsServlet {
 private static final long serialVersionUID = 1 L;
 private final Logger log = LoggerFactory.getLogger(DuplicateValidator.class);
 String rootPath = "/content/";

 @Override
 public void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException {
  String check = request.getParameter("validate");
  if (check != null) {
   getDuplicatePath(request, response);
  }
 }

 private void getDuplicatePath(SlingHttpServletRequest request, SlingHttpServletResponse response) {
  Session session = request.getResourceResolver().adaptTo(Session.class);
  try {
   log.debug("DuplicateValidator : Session UserId : " + session.getUserID());
   String checkProperty = request.getParameter("validate");
   final String validateProperty = request.getParameter("title");
   final String pagePath = request.getParameter("pagePath");

   try {
    String pageSite = getSite(pagePath);
    NodeIterator nodes = getPaths(session, rootPath + pageSite, validateProperty, checkProperty);
    TidyJSONWriter tidyJSONWriter = new TidyJSONWriter(response.getWriter());

    tidyJSONWriter.object();
    tidyJSONWriter.key("validateProperties").array();
    String nodeSite = null;
    while (nodes.hasNext()) {
     Node node = nodes.nextNode();
     if (node != null && node.getPath().contains("/content"))
     {

      // check whether the path of the page where the validating property is defined matches the dialog's path

      nodeSite = getSite(node.getPath());
      if (node.getPath().equals(pagePath) || !(nodeSite.equals(pageSite)))
      {

       //do not add that to the list
       log.debug("DuplicateValidator : Node path is {}", node.getPath());
       log.debug("DuplicateValidator : Page path is {}", pagePath);
      } else {
       tidyJSONWriter.value(node.getPath());
      }
     }
    }

    tidyJSONWriter.endArray();
    tidyJSONWriter.endObject();
    response.setContentType("application/json");
    response.setCharacterEncoding("UTF-8");
   } catch (RepositoryException re) {
    log.error("DuplicateValidator : Error in doGet", re);
   }
  } catch (JSONException e) {
   log.error("DuplicateValidator : Error in doGet", e);
  } catch (Exception e) {
   log.error(e.getMessage());
  } finally {
   if (session.isLive()) {
    session.logout();
   }
  }
 }

 private String getSite(Page page) {
  String[] sites = page.getPath().split("/");
  String site = sites[2];
  return site;
 }

 private String getSite(String pagePath) {
  String[] sites = pagePath.split("/");
  String site = sites[2];
  return site;
 }

 private NodeIterator getPaths(Session session, String path, String validateProperty, String checkProperty) throws RepositoryException, PathNotFoundException,

  UnsupportedRepositoryOperationException, InvalidQueryException {
   log.debug("####### DuplicateValidator : session ######### : " + session.getUserID());
   Node root = session.getRootNode();
   Node currentNode = root.getNode("content");
   QueryObjectModelFactory qf = currentNode.getSession().getWorkspace().getQueryManager().getQOMFactory();

   Selector selector = qf.selector("nt:base", "s");
   Constraint constriant = qf.descendantNode("s", path);
   constriant = qf.and(constriant, qf.propertyExistence("s", checkProperty));
   if (validateProperty != null) {
    ValueFactory valueFactory = session.getValueFactory();
    String operator = QueryObjectModelConstants.JCR_OPERATOR_EQUAL_TO;
    DynamicOperand dynOperand = qf.propertyValue("s", checkProperty);
    StaticOperand statOperand = qf.literal(valueFactory.createValue(validateProperty));
    constriant = qf.and(constriant, qf.comparison(dynOperand, operator, statOperand));
   }

   QueryObjectModel qm = qf.createQuery(selector, constriant, null, null);
   log.debug("######### DuplicateValidator : Query ######### : " + qm.getStatement());
   NodeIterator nodes = qm.execute().getNodes();
   log.debug("### DuplicateValidator : query result : " + nodes.getSize());
   return nodes;
  }
}

This service will expect 3 parameters
Validate – property for which the duplicate validation needs to be done
Title – a value of the property
pagePath – a path of the page where the value is been given.
getDuplicatePath() is the method which queries the JCR for the given value against the property mentioned and returns the list of nodes available under the given content node

Now, go to the page properties and try entering the ‘Title’ which already exists and see the validation works!

Watch out for an Adobe community article soon where you can know much more in detail and get the complete source code!


By aem4beginner

No comments:

Post a Comment

If you have any doubts or questions, please let us know.