cancel
Showing results for 
Search instead for 
Did you mean: 

Prepopulating edit-metadata form fields with data from a web service

tchoupitoulos
Champ in-the-making
Champ in-the-making
I have seen simliar posts to this on the forums, as well as other sources, but all replies have either been mere snippets of code with almost no context or explanation, or links to documentation like the forms developer guide that provide more of a 10,000 foot view of the system as a whole than real examples that would guide me.

I have created a custom content type, an extension of cm:content, called ai:bulletin. It has some new metadata properties associated with it, and I have implemented a share-config-custom.xml configuration file to modify the form to include these items, as per the various Alfresco docs as well as Mr. Potts' "Working With Custom Content Types" publication. This has all been completed relatively painlessly.

What I need is fairly simple. I would like to present an editing form for this content type that includes multiselect boxes that are prepopulated using data retrieved from a web service internal to my organization but external to the alfresco system. I've been through your forms documentation, your forms developer guide, Spring surf docs, Alfresco share and repo docs, Freemarker docs, etc. etc. and what I seem to miss is how are all these things tying together? Should I be implementing my service calls using client side javascript, and can freeMarker even support that? Or do I need to extend backend java classes in order to accomplish this?

I feel like the information to do this exists throughout your documentation, but is so piecemeal and dispersed that I could spend a week trying to locate and pin down everything I need. Can anyone provide a quick but complete synopsis or cookbook recipe of exactly what I need to implement, where, and how within the Alfresco system to accomplish this?
7 REPLIES 7

zladuric
Champ on-the-rise
Champ on-the-rise
If I understand correctly, you want to create multi-select dropdowns for certain properties, and pre-select them based on the property value?
If that is the case, I think you need to add a custom field renderer. In
share-config-custom.xml
you've created a <strong>&lt;form></strong> tag that contains a <strong>&lt;field-visibility></strong> group  with several of
<show id="ai:myProperty"/>
inside, right?
Now add a custom field renderer. Alfresco will take your property, and if it is a d:text, it will, by default, use textfield.ftl renderer. IF it is a d:boolean, it will use a checkbox renderer. IF it is a d:date, it will use a date field renderer (which includes calendar and stuff).
All of them are located in
/share/WEB-INF/classes/alfresco/site-webscripts/org/alfresco/components/form/controls/
, so take a look. They are basically a Freemarker templates included for each property.

So you should create a mycustomfieldrenderer.ftl (I usually place them in the extensions folder). Look at how the, say, textfield.ftl is created, then instead of a regular &lt;input type="text", create a &lt;select> tag in there.
It would be too long to describe it here, so just take a look at one of them there, then come back with questions Smiley Happy

Anyway, when you have it, then tell alfresco share forms to use your custom renderer - add an <strong>&lt;appearance></strong> tag in share-config-custom.xml.

Something like this:


<form id="edit-metadata">
  <field-visibility>
    <show id="cm:name"/>
    <show id="cm:description"/>
    <show id="cm:created"/>
    …
    <show id="ai:myCustomProp" />
  </field-visibility>
  <appearance>
    <!– lets make the description a textarea instead of input –>
    <field id="cm:description>
      <control template="controls/textarea.ftl"/>
    </field>
    <!– now our custom prop with custom renderer –>
    <field id="ai:myCustomProp">
      <control template="controls/my-custom-renderer.ftl"/>
    </field>
  </appearance>
</form>

tchoupitoulos
Champ in-the-making
Champ in-the-making
Not preselect, but prepopulate. For example, some content items will be targeted to a specific account or set of accounts. So I want to make a call to our enrollment REST service, either via an AJAX call in javascript, or in the java backend if necessary, to get a collection of our existing accounts, and then use that data to populate the multiselect box with account names for display and ids for values, so that my content producers can then select the account(s) to target each piece of content to. So what you have given me is good but I already know that piece. Where I'm getting confused is how to integrate the call to the external service with the Freemarker template and the rest of the Share architecture. Does that make more sense?

zladuric
Champ on-the-rise
Champ on-the-rise
Well, I see two ways for this. You have the backend script to list or search all members of this group or that site or all users.

One is a client-side Ajax call, like you said. Add a bit of JS to your frontend JS where you call this script and create the widget(s) you need dynamically.

Now, the other way is very similar to what I've written in the previous post - except that you make a remote call to your, say, user accounts  script, in your controller. Then give the result to freemarker. Finally, freemarker prepopulates the stuff before anything even gets to the client.

Time-To-Glass or whatever it is called is slower, but the user gets a complete page right away.

So, after some talk with some folks on my end, I'm finding that for security reasons I will be unable to implement this via client-side javascript AJAX call. They want the interaction to occur entirely behind our firewall, so it will have to all happen on the server side.

So, now we get to where I have been having the most confusion. When you talk of my controller, what exactly are we talking about? From what I can see, aren't the edit-metadata form .ftls for ALL content types backed by the same java controller, as part of the Share implementation of Surf? Or can the controller be extended and each template configured to use a specific controller somehow? Or can javascript text in the freemarker template make calls to server-side web scripts? Or am I just seriously confused? When you speak of my "user accounts script," in your second example, you are talking about a server-side web script?

I tried searching through your post history, but couldn't find the information you were referring to. Got a link? And thanks for your assistance throughout all this.

tchoupitoulos
Champ in-the-making
Champ in-the-making
Looking further through it, I have some better ideas, was hoping to get your input.

First, it looks like I could create a server-side web script to gather the data from the external account service, and then call that web script from javascript text in the freemarker template for the form or control, or from a javascript lib that I can configure as a dependency for the control maybe. This should work, but seems inefficient, having a template that is assembled via freemarker that's backed by server side javascript or java have to call back to a new script to get my customizations.

The second would be to reconfigure the controller(s) that back the form .ftl, which sounds like what you are saying in your response. This is where I am finding the documentation to be incomplete. The .ftls within Share webapp are already backed by the Forms Engine's controllers, right? Is there any documentation illustrating how to add filters or extend and reconfigure those controllers to retrieve and add my external data to the template model when editing my new content type, while still leveraging the rest of the forms system? Right now it looks like the only way is to dig through the code directly to figure out how it works.

zladuric
Champ on-the-rise
Champ on-the-rise
I was thinking more of this second approach. But like you said, one would have to sift through the code and find the proper way to do it. I must say I'm not that deep into forms engine, the stuff I had to make work was easier and I could do it on the client side.
Maybe somebody more experienced can say what would be better. If I had to do it, I would just extend the controller, but it would not be as efficient, probably. I'd blame the hardware guys when something went wrong Smiley Happy

Alright, thanks. I feel like I at least know where I'm at now a little better, and the next steps to approaching this.
Getting started

Tags


Find what you came for

We want to make your experience in Hyland Connect as valuable as possible, so we put together some helpful links.