Hi,
I am creating a form to store the data from the client(client want a form to enter the data not in the page and components).and later we need to retrive the data from the repository and diplay dynamically.
How to use form component to store the data in specific node structure which we need.is this possible? or i need to go with the nomal html form and then store the data where i want to store.Please guide me on this.
Thanks,
Ramya
Solved! Go to Solution.
Hi, this is a working example of of my solution here as some kind of guide. With the help of Scott's guide and this Im sure you will be on the right way:
In your JSP (or use the form component) do the equivalent of:
<form id="submitForm" method="post" action="/apps/my/servlets/path/create"> <input type="text" name="name" value="" /> <input type="text" name="email" value="" /> <input type="text" name="title" value="" /> <input type="text" name="phone" value="" /> <input type="submit" value="Submit"/> </form>
Here's just a mock form with some boring values to fill in...
Then in your servlet:
package com.test.servlet; import com.day.cq.commons.jcr.JcrUtil; import org.apache.felix.scr.annotations.Component; import org.apache.felix.scr.annotations.Properties; import org.apache.felix.scr.annotations.Property; import org.apache.felix.scr.annotations.Reference; import org.apache.felix.scr.annotations.sling.SlingServlet; import org.apache.sling.api.SlingHttpServletRequest; import org.apache.sling.api.SlingHttpServletResponse; import org.apache.sling.api.servlets.SlingAllMethodsServlet; import org.apache.sling.jcr.api.SlingRepository; import org.osgi.service.component.ComponentContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.jcr.Node; import javax.jcr.RepositoryException; import javax.jcr.Session; import javax.servlet.ServletException; import java.io.IOException; import java.io.PrintWriter; @Component(immediate = true, metatype = true, name = "com.test.CreateServlet", label = "Create Servlet", description = "Test creation servlet") @SlingServlet(methods = { "POST" }, paths = "/apps/my/servlets/path/create", generateComponent = false) @Properties({ @Property(name = "service.description", value = "CreateServlet"), @Property(name = "service.vendor", value = "My Vendor") }) @SuppressWarnings({ "serial", "unused" }) public class CreateServlet extends SlingAllMethodsServlet{ private static final String CREATE_PATH = "/content"; /// Set the base path here private static final Logger log = LoggerFactory.getLogger(CreateServlet.class); @Reference private SlingRepository repository; @Override protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException { //We are not using this atm.. but you could } @Override protected void doPost(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException { Session session = null; String name = request.getParameter("name"); String email = request.getParameter("email"); String title = request.getParameter("title"); String phone = request.getParameter("phone"); PrintWriter out = response.getWriter(); try { session = repository.loginAdministrative(null); Node firstProduct = JcrUtil.createPath(CREATE_PATH + "/" + name , "cq:Page", session); Node firstSubProduct = JcrUtil.createPath(firstProduct.getPath() + "/subproduct1", "nt:unstructured", session); Node secondSubProduct = JcrUtil.createPath(firstProduct.getPath() + "/subproduct2", "nt:unstructured", session); firstSubProduct.setProperty("email", email); firstSubProduct.setProperty("title", title); secondSubProduct.setProperty("email", email); secondSubProduct.setProperty("title", title); session.save(); out.println("That went well..."); out.flush(); out.close(); } catch (RepositoryException e) { out.println("That went not so well..."); out.flush(); out.close(); e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. } } protected void activate(ComponentContext ctx) { log.trace("Activating my small creation servlet"); } protected void deactivate(ComponentContext ctx) { log.trace("Deactivating my small creation servlet"); } }
Here we just create a node (cq:Page) with the name that you entered in the form. It gets two nodes under neat with set values and then we add properties from the form
to these nodes. You can add more properties/values by only adding more fields and handle them and you can also skip subnodes if you want.
There are also a lot of other nice features in the JCRUtil that could help you.
In our case if we enter name = myName, email= myEmail, title=myTitle and phone = myPhone we will get the following structure
./content/myName (cq:Page)
../subproduct1 (nt:unstructured) -> with properties ( email:myEmail and title=myTitle)
../subproduct2 (nt:unstructured) -> with properties ( email:myEmail and title=myTitle)
Regards
/Johan
Views
Replies
Total Likes
Hi there Ramya.
It it possible to use the form component. If you read up on the documentation here http://dev.day.com/docs/en/cq/current/wcm/default_components/editmode.html#Form%20(component)
you will see that you can make use of the "Element Name" attribute (which will determine the location for that specific value) in the form together with the Store Data/Content Path to determine the location where to store the form data.
As you also pointed out it is possible to create you own post servlet to handle the form submission as well.
Some useful links on that topic:
Hope that will get you going
Regards
/Johan
Hi Johan,
Thanks for the replay.
i have to store the data in different nodes for each time form sumission with different data
Ex: under content/
Product1
subproduct1
subproduct2
subproduct3
Product2
subproduct1(related Product2)
subproduct2(related Product2)
subproduct3(related Product2)
In the link
Thanks,
Ramya
Views
Replies
Total Likes
Views
Replies
Total Likes
Hi, this is a small example of how you could create a simple structure:
Node parentNode = resource.adaptTo(Node.class); Node firstProduct = JcrUtil.createPath(parentNode.getPath() + "/product1", "cq:Page", parentNode.getSession()); Node secondProduct = JcrUtil.createPath(parentNode.getPath() + "/product2", "cq:Page", parentNode.getSession()); Node firstSubProduct = JcrUtil.createPath(firstProduct.getPath() + "/subproduct1", "nt:unstructured", parentNode.getSession()); Node secondSubProduct = JcrUtil.createPath(firstProduct.getPath() + "/subproduct2", "nt:unstructured", parentNode.getSession()); Node thirdSubProduct = JcrUtil.createPath(secondProduct.getPath() + "/subproduct3", "nt:unstructured", parentNode.getSession()); Node fourthSubProduct = JcrUtil.createPath(secondProduct.getPath() + "/subproduct4", "nt:unstructured", parentNode.getSession()); firstSubProduct.setProperty("price", "100K"); secondSubProduct.setProperty("price", "200K"); thirdSubProduct.setProperty("price", "300K"); thirdSubProduct.setProperty("price", "400K"); parentNode.getSession().save();
Here we create 2 nodes (of type cq:Page). Each with 2 sub nodes as the sub products.
In this case there are of type nt:unstructured but you could have what you like there of course :)
Then we set some properties on these fur subproducts and finally we save it.
Hope it helps
/Johan
Hi Johan,
Thanks for help with coding example,
But I am facing a issue with simple form submit.
Below in jsp which has HTML form.
<form action="savenode.jsp" method="post">
<input type="text" name="Product1" >
<input type="text" name="title" size="30">
<div>
<input type="submit" value="Send" onclick>
</div>
</form>
And in savenode.jsp i am trying to create the node with name Product one.
<%@page import="java.util.Properties"%>
<%@include file="/libs/foundation/global.jsp"%>
<%@page import="java.util.Iterator"%>
<%@ page import="org.apache.jackrabbit.commons.JcrUtils"%>
<%@ page import="com.day.cq.commons.jcr.JcrUtil"%>
<%
Node parentNode = resource.adaptTo(Node.class);
Node firstProduct = JcrUtil.createPath(parentNode.getPath() + request.getParameter("Product1"), "nt:unstructured", parentNode.getSession());
firstProduct.setProperty("title", request.getParameter("title"));
parentNode.getSession().save();
%>
But on submit of form I am getting the error as
Status | 500 |
Message | javax.jcr.nodetype.ConstraintViolationException: no matching property definition found for {}Product1 |
Location | /content/optum/savenode.jsp |
Parent Location | /content/optum |
Path | /content/optum/savenode.jsp |
Referer | http://localhost:4502/content/optum/pagehaswblink.html |
ChangeLog | <pre></pre> |
Modified Resource
I am rying to debug but not able to fix the issue,need help
Thanks,
Ramya
Views
Replies
Total Likes
Hi. the code example that i was supplying was thought to be for a servlet/servlet filter that you would create yourself.
What needs to be done in that one is to change what that listen to. Either you can choose between a specific resourceType, a special selector
or even a path. Scott Macdonald has written a small guide of posting data to a search servlet here : http://scottsdigitalcommunity.blogspot.se/2013/06/posting-form-data-to-adobe-cq-using.html and even though that example only shows how to create a search servlet that listens to a specific path I'm quite sure that it will help you. Also this post will shed some more light on the topic https://blogs.adobe.com/aaa/2012/09/cq-tips-and-tricks-1-how-to-define-a-slingservlet-cq5-5-5-6.html
If you don't create your own servlet the thing that will happen is that the predefined POST handler will then intercept your post to "savenode.jsp". It will there try to add the property "Products1" on "savenode.jsp" which it's not allowed to do because of the constraint on property definitions. Once you have created you own servlet that handles a specific post e.g with your own selector or with an override on a specific resourceType you can use the code of your choice in that one and then be able to create your desired structure.
@SlingServlet(paths = "/path/to/resource", methods = "POST") public class MySafeMethodServlet extends SlingSafeMethodsServlet { //.. The logic here } or @SlingServlet(selectors = "MyCreationSelector", methods = "POST") public class MySafeMethodServlet extends SlingSafeMethodsServlet { //.. The logic here }
That will give you an idea to specify that servlet either on a specific path or for all posts that has the MyCreationSelector selector in it (like savenode.MyCreationSelector.jsp)
Good Luck
/Johan
Views
Replies
Total Likes
You can also write an OSGi bundle that stores data submitted from a form to the JCR. See this walk through that teaches you how to do this task: http://scottsdigitalcommunity.blogspot.ca/2013/01/persisting-cq-data-in-java-content.html.
Views
Replies
Total Likes
Hi thank you
I have gone through http://scottsdigitalcommunity.blogspot.ca/2013/01/persisting-cq-data-in-java-content.html. its very good example but i implemented half of the part i am in progress.
But In my case we have many fields need to added like name,Description ,image upload, vedio upload etc.
and we need to pick up the name field from the from and creat a node and add other fields as a propery to that node.
on each time form submit happens i need to create a new node by picking the name field.
If i use cq from it is creating ite one unique ID under that its storing the data.
to customize that what i need to change this is first time i am dealing with CQforms.need help.
Thanks
Ramya
Views
Replies
Total Likes
Hi, this is a working example of of my solution here as some kind of guide. With the help of Scott's guide and this Im sure you will be on the right way:
In your JSP (or use the form component) do the equivalent of:
<form id="submitForm" method="post" action="/apps/my/servlets/path/create"> <input type="text" name="name" value="" /> <input type="text" name="email" value="" /> <input type="text" name="title" value="" /> <input type="text" name="phone" value="" /> <input type="submit" value="Submit"/> </form>
Here's just a mock form with some boring values to fill in...
Then in your servlet:
package com.test.servlet; import com.day.cq.commons.jcr.JcrUtil; import org.apache.felix.scr.annotations.Component; import org.apache.felix.scr.annotations.Properties; import org.apache.felix.scr.annotations.Property; import org.apache.felix.scr.annotations.Reference; import org.apache.felix.scr.annotations.sling.SlingServlet; import org.apache.sling.api.SlingHttpServletRequest; import org.apache.sling.api.SlingHttpServletResponse; import org.apache.sling.api.servlets.SlingAllMethodsServlet; import org.apache.sling.jcr.api.SlingRepository; import org.osgi.service.component.ComponentContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.jcr.Node; import javax.jcr.RepositoryException; import javax.jcr.Session; import javax.servlet.ServletException; import java.io.IOException; import java.io.PrintWriter; @Component(immediate = true, metatype = true, name = "com.test.CreateServlet", label = "Create Servlet", description = "Test creation servlet") @SlingServlet(methods = { "POST" }, paths = "/apps/my/servlets/path/create", generateComponent = false) @Properties({ @Property(name = "service.description", value = "CreateServlet"), @Property(name = "service.vendor", value = "My Vendor") }) @SuppressWarnings({ "serial", "unused" }) public class CreateServlet extends SlingAllMethodsServlet{ private static final String CREATE_PATH = "/content"; /// Set the base path here private static final Logger log = LoggerFactory.getLogger(CreateServlet.class); @Reference private SlingRepository repository; @Override protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException { //We are not using this atm.. but you could } @Override protected void doPost(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException { Session session = null; String name = request.getParameter("name"); String email = request.getParameter("email"); String title = request.getParameter("title"); String phone = request.getParameter("phone"); PrintWriter out = response.getWriter(); try { session = repository.loginAdministrative(null); Node firstProduct = JcrUtil.createPath(CREATE_PATH + "/" + name , "cq:Page", session); Node firstSubProduct = JcrUtil.createPath(firstProduct.getPath() + "/subproduct1", "nt:unstructured", session); Node secondSubProduct = JcrUtil.createPath(firstProduct.getPath() + "/subproduct2", "nt:unstructured", session); firstSubProduct.setProperty("email", email); firstSubProduct.setProperty("title", title); secondSubProduct.setProperty("email", email); secondSubProduct.setProperty("title", title); session.save(); out.println("That went well..."); out.flush(); out.close(); } catch (RepositoryException e) { out.println("That went not so well..."); out.flush(); out.close(); e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. } } protected void activate(ComponentContext ctx) { log.trace("Activating my small creation servlet"); } protected void deactivate(ComponentContext ctx) { log.trace("Deactivating my small creation servlet"); } }
Here we just create a node (cq:Page) with the name that you entered in the form. It gets two nodes under neat with set values and then we add properties from the form
to these nodes. You can add more properties/values by only adding more fields and handle them and you can also skip subnodes if you want.
There are also a lot of other nice features in the JCRUtil that could help you.
In our case if we enter name = myName, email= myEmail, title=myTitle and phone = myPhone we will get the following structure
./content/myName (cq:Page)
../subproduct1 (nt:unstructured) -> with properties ( email:myEmail and title=myTitle)
../subproduct2 (nt:unstructured) -> with properties ( email:myEmail and title=myTitle)
Regards
/Johan
Views
Replies
Total Likes
Hi Johan,
If i use the form component which is available in cq where i will change the action attribute of the form to action="/apps/my/servlets/path/create ? so that onsubmit i can execute my servlet.
Thanks
Ramya
Views
Replies
Total Likes
i have followed your code in that case i am getting some error i tried a lot but couldn't solve this problem if u put some light on my issue i would be greatful thank you in advance i.e com.day.cq.commons.jcr,version=[5.7,6) -- Cannot be resolved
Views
Replies
Total Likes
Views
Likes
Replies
Views
Likes
Replies