Dynamic link labelling for Custom Unit

29 Jun '13, 03:26 AM
64,015 Views
Forum Forum Starter - Level 2

Hi, Is it possible to have the Style Unit for a custom class change the label for a link from the custom class.

I have the Style Unit for the custom unit query a database to retrieve the text, but is it possible to set the link text to the specific text?

Something like :


[wr:Link class="link" name=varLinkName/]  (*NOTE : Obviously angle brackets instead of square)

or

${[wr:Link/].name} = ${varLinkName}

Any help greatly appreciated!

 
x 0
Follow
Answer Answer at this question and get points!
No Forum Badges

Hi,

in your case you can try this solution:

1) Create a "Form Based" Content Unit that shows the dropdown menu. The Html code of the dropdown is defined the Unit Layout template. For example:

<select name="option" id="option">
    <c:forEach var="option" items="${<wr:UnitId/>.optionLabels}" varStatus="status">
        <option value="${option.key}" <c:if test="${status.count eq 1}"> selected 
        </c:if> >${option.value}</option>
    </c:forEach>
</select>

In this example, I added the "varStatus" parameter and the condition on the "status.count" value in order to set a default selected value for the dropdown.

The Layout template has to be applied to the Custom Unit.

2) To discover the option chosen by the user you can analyze the Http request and its parameters. In the Java service class of your custom Operation Unit, you can retrieve the "option" request parameter that is passed when the user performs the request (e.g. when a submit link is clicked). For example:

HttpServletRequest request = (HttpServletRequest)operationContext.get(RTXConstants.HTTP_SERVLET_REQUEST_KEY);
String chosenOption = request.getParameter("option"); // "option" is the "name" attribute 
                                                     // of the "select" Html element
System.out.println("selected option " + chosenOption); // instruction for testing

In this example, "chosenOption" contains the value selected by the user from the dropdown. You can perform some computations (if needed) and then you can assign the final value to the output parameter. For example:

bean.put("testOutput", chosenOption); // output

where "testOutput" is the name of the output parameter of the custom Operation Unit. In this way, the output parameter of the unit is valorized with the option chosen by the user from the dropdown.

Example:

alt text

"MyContentUnit" shows the dropdown in the page, while "MyOperationUnit" retrieves the chosen value and set its output parameter. This parameter that can be used for the coupling.

alt text

   
x 0
No Forum Badges

Hi,

could you better explain you current situation and the result you wish to obtain ? Can you make an example ?

 
x 0
Forum Starter - Level 2

Hi Laura ... thanks for the continuing help you are giving!! :) Here is an exhaustive explanation of my situation (both reason and design) ... apologies if it's too verbose but it's meant to illustrate how I have 2 separate Custom Units, and that each of them will be instantiated to take one of two different variations at run-time.

The Reason:

Ok, so I'm doing a PhD on Stigmergy (think ants leaving pheromone trails when finding food) in Web 2.0. It's about users leaving trails in Web sites both intentionally (Marker Based) and unintentionally (Sematectonic). Perfect examples of this are seen in Facebook with "Like" being intentional and "Seen By" being unintentional (viz: doesn't require the user to do anything explicitly). My research project is to create a generic design pattern to easily define and include these into web pages.

Alt text

Hopefully this gives some insight into the design, but I need to get 2 things working before I can start experiments and data collection.

My preferred solution:

Now I can build all of this using standard IFML and Data Units and Links, but ideally the implementation will be completely encapsulated in Custom Units. There is no variation in deployment, so I want the whole Custom Unit(s) to be black box. Just drop them on the page you want them, and specify the Sign Oid as the input parameter that the Unit builds itself (just add link to the current Selector (or Index) for run-time context). You can see this in the image attached where:

- Actuator Custom Unit (instantiates as Marker Based or Sematectonic) creates the "trail" and
- Sensor Custom Unit (instantiates as Quantitative or Qualitative) displays the trail.

NOTE : The Sensor can provide Quantitative output (number of "Likes" or "Seen By" or Qualitative output (similar to Facebook "Share" where it displays some linked content ... or Amazon "People who bought this also bought ...". Getting the Qualitative output is the second of the two things I need to get working and I will add detail to your response in this thread regarding the Sensor Unit.

Ok, so this question is only about the Actuator Custom Unit. It's a standard design Custom Unit with a service java class and a bean java class. It creates a record in the Contribution database table is two ways; one for Marker Based, one for Sematectonic.

The Sematectonic instantiation works because the unit calls the service bean upon page arrival, and fires of an INSERT method (viz: unintentional trail). No user interface is displayed, the bean returns this fact (via a boolean property) and the style unit has code to only create the interface if it's Marker Based. E.g.:

<c:if test="${<wr:UnitId/>.isMarkerBased}"> // build drop list (if needed) and button ..... </c:if>

If the instantiation is Marker Based, then the style unit builds a User Interface. It can be either a single choice such as "Like" where only a single button is added to the style unit output. It can also offer a selection of options such as with eBay's "Rate It" feedback (viz: Satisfaction rating from 1 to 5), where the bean returns a map with an Oid/Description Map. As you can see on the image, the drop list is populated with the map contents (for the "Rate It" example) and a save button, or just a single button (for the "Like" example).

The Problem:

The button needs to respond to a user clicking it, and fire off an INSERT (somehow ... anyway at all) to store the intentional Contribution. The INSERT will need to include the value from the drop list that has been selected.

My best attempt was to create a button in the style sheet using:

<input title="<c:out value="${<wr:UnitId/>.signInputLabel}"/>" onclick="saveContribution(); return false;" class=" button" value="<c:out value="${<wr:UnitId/>.signName}"/>">

It is intended to fire some javascript (see saveContribution()) but I haven't been able to get it working. But you can see that the names of the buttons are dynamically created as per the description stored in the Sign database table.

I really would like to get this working, but can't find an example of how the button would be able to:

- fire off an INSERT into the Contrituion table
- link back to the page so that the Sensor Unit shows updated result for the new contribution.

I did ask a question here as to how to do this but alas no responses

I also hoped maybe the style unit could make a subsequent call back to the service class to notify that a link should be triggered programatically. Again, no response :(

Please note, ideally the button will fire code in the Custom Unit, or a Web Service! But this question I ask in this thread is my next attempt at a work around ... Getting either working will be excellent!

This Attempt:

My first attempt used a link to generate a button using default IFML. It creates the button, and can provide the code automatically to first the INSERT via a Create Data Unit, and solve the problem of re-entering the page to update the Sensor Unit display using an "OK Link". This is less than ideal because the code and INSERT never changes, and loses the black box simplicity if it could all be handled within the Custom Unit. However if the fact is it can't be done my preferred way, then adding Links is probably my only option but I need the link to be labelled as per the Sign data at runtime.

Reclarifying this question:

An IFML Link from the Actuator Custom Unit would auto-generate the button used to save users' intentional Contribution. But depending on what Sign Oid is passed in to the Custom Unit (to instantiate itself as), and what the "Input Label" description is for that sign's database record, how can I make the style unit re-label the Link Button to use the description from the custom unit bean ${<wr:UnitId/>.signInputLabel} at run-time?

Any help greatly appreciated ... in fact if you even can make sense of the above and read this far then more Thank You! ;p

 
x 0
No Forum Badges

Hi,

if you want that the button is able to fire off an insert into a table and then link back to the page, you could try this solution:

1) Model a Link outgoing from your unit and pointing to the operation chain that creates the record in the database and returns to the page (with an OK Link). This link should not be visible in the page. You can hide it by applying a Link visible condition.

2) Follow the modeled Link on the click on the button. In this way, when the user clicks the button, the operation chain will be executed. This is a sample code:

In the unit template, with this code you select the modeled Link outgoing from the unit (e.g. the link with name "Link10"):
[%
  def link = unit.selectSingleNode("layout:Link[@name='Link10']");
%]

With this code (similar to the one you wrote) you create the button. When you click it, the Link (e.g. Link10) will be followed:
<input title="<c:out value="${<wr:UnitId/>.signInputLabel}"/>" onclick="<wr:AjaxURL context="link" type="button"/>" type="submit" id="button:<wr:Id context="link"/>" name="button:<wr:Id context="link"/>" value="<c:out value="${<wr:UnitId/>.signName}"/>""/>

 
x 0
Forum Starter - Level 2

Hi Laura, As usual ... thanks for the ongoing support and help! I'm not sure if you help with putting together the online WebRatio help but (if those that do are reading) could I suggest the Custom Unit example be enhanced to describe not just WHAT facets are available and WHERE they are located, but WHY they are there, and HOW they interrelate? My further questions below probably illustrate this ...

So I have tried your option as suggested, however to retain the encapsulation I am working towards, I have created a new Custom Unit to perform the saving after the button link has been selected. The final problem I am facing is HOW to write the selected value of the drop list (or that associated with the button) into the output.template descriptor so that it can be picked up by the new Custom Unit which performs the save.

Firstly,

to retain encapsulation (ie. inside the Style template I don't want people to have to keep updating the link number inside the Custom Unit style code):

[% def link = unit.selectSingleNode("layout:Link[@name='Link10']"); %]

is changed to :

[% def unitLink = unit.selectSingleNode("layout:Link") // the first link of the unit def link = unitLink?.valueOf("@link") %]

If I understand this correctly, this will get the first link (irrespective of name), and set the link variable that you describe. My design would be that you can only ever define one link leaving the Actuator Custom Unit ... This is fine.

Secondly,

I'm trying 2 versions, one that calls a javascript method that calls a WebService, the other firing the link as you suggest:

Version 1: The ajaxSave() Javascript fires, and I can get the drop list selected index value. I guess there's no way to set the java bean associated with the service to that value?! <input title="<c:out value="${<wr:UnitId/>.signInputLabel}"/>" onclick="ajaxSave(option.options.selectedIndex);" type="submit" value="<c:out value="${<wr:UnitId/>.signName}"/>""/>

Version 2: This is exactly as you suggest, but I get the following compile error tagged against the onclick assignment. "No signature of method:java.lang.String.selectSingleNode() is applicable for argument types (java.lang.String) values: {"."}" <input title="<c:out value="${<wr:UnitId/>.signInputLabel}"/>" onclick="<wr:AjaxURL context="link" type="button"/>" type="submit" id="button:<wr:Id context="link"/>" name="button:<wr:Id context="link"/>" value="<c:out value="${<wr:UnitId/>.signName}"/>""/>

Version 2 is conceptually the same as you suggest, but there is a bit more complex processing than just the database insert ... but it looks like this when modelled. Is this how you imagine it?

Alt text

Thirdly,

If I can get your suggestion working (fire the Link button, have it link to my new "MarkerResponse" Custom Unit then I need to couple the output parameters from the Actuator Unit to the input parameters. I'm not sure how to do this:

The output.template for the Actuator Custom Unit is:

#?delimiters <%,%>,<%=,%> <% setXMLOutput() def unitId = unit.valueOf("@id") %>`

<OutputParameters> <OutputParameter name="positionIndex" type="" label="Content Primary Key (as Integer)"/> <OutputParameter name="optionOid" type="" label="Selected Contribution Option"/> <OutputParameter name="isRevoking" type="" label="Whether user selection means revoking previous contribution"/> </OutputParameters>

Questions ...

How do I populate these output parameters for the Actuator Custom Unit? They are populated as described below:
- positionIndex : Set to the same value as passed in by the Input.template for the unit
- optionOid: Set to the value of the style unit drop list as selected value by the user after Link button is selected
- isRevoking: Set at runtime by the Service. Note: this is already set within the associated Bean for the Actuator Custom Unit.

 
x 0
No Forum Badges

Hi,

the generation error refers the <wr:AjaxURL> tag, whose "context" attribute should be the variable used to locate the <layout:Link> node. In your code, the "link" variable is not the Link node, but it is the value of an attribute (@link). If your wish to retrieve the first link (the one with the smallest id), irrespective of name, you can try this code:

def link = unit.selectSingleNode("layout:Link");

Regarding the model, my idea is to model a Normal Link outgoing from your unit and pointing to the operation chain that executes the operations. This normal link will be automatically followed on the click on the created button.

 
x 0
No Forum Badges

Hi,

the error "Undefined Link Context: Unable to find the link in the specified context [context = link/.]" means the link hasn't been found. I obtained this error in case the link does not exist or the xpath expression does not retrieve the modeled link.

You should select your unit in the model -> Properties Panel (XML tab) -> Show XML button -> the xml structure of the unit is shown, with the outgoing links. The @name in the xpath expression (e.g. ...layout:Link[@name='Link52']) refers the "name" attribute value of the <Link> xml node. For example:

<NoOpContentUnit id="gctu1" .....>
   <Link id="ln52" name="Link52" to="opu1" automaticCoupling="true" type="normal" ..... />
</NoOpContentUnit>

 
x 0
No Forum Badges

Hi,

the "Output.template" specifies the output parameters of the unit. These parameters can be set within the associated bean related to the unit. In your case, to set the output depending on the value selected from the dropdown list you can for example:

1) Add an output parameter in the Output.template of your Custom Unit. E.g:

....
<OutputParameter name="testOutput" type="" label="testOutput" />
....

2) Add an input parameter in the Input.template of your Custom Unit. It represents the value selected from the dropdown list. E.g.:

....
<InputParameter name="<%=unitId%>.dropdown" type="" label="dropdown" />
....

3) In the Java class related to the unit you can read the value selected by the user from the dropdown, perform some computations (if needed) and then assign the final value to the output parameter. E.g.

String inputValue = BeanHelper.asString(operationContext.get(getId() + ".dropdown"));   // input
....
....
bean.put("testOutput", inputValue); // output

4) In the model, you have to couple the input parameter of the custom unit (in the example "dropdown") with the value selected by the user from the dropdown (e.g. the Selection Field of an Entry Unit). The custom unit exposes the defined output parameter (in the example "testOutput"). For example:

alt text

Parameters coupling dialog of the link incoming to My Unit: alt text

Parameters coupling dialog of the link outgoing from My Unit: alt text

 
x 0
Forum Starter - Level 2

Hi,

As mentioned I am defining the drop-list in the Custom Unit Style.unit.template file. So the drop -list is not available while in design mode, hence can't be coupled, and doesn't exist until client side instantiation. E.g.:

<td valign="middle" nowrap="nowrap" class=" value">
    <select name="option" id="option">
        <c:forEach var="option" items="${<wr:UnitId/>.optionLabels}">
            <option value="${option.key}">${option.value}</option>
        </c:forEach>
    </select>
</td>

Any idea on how to have the javascript to populate the output.template where the drop-list is part of the custom unit but populated as above? Thank you.

 
x 0
Forum Starter - Level 2

This is soooo close!

I see Tomcat output the system.out with the passed in variable (as per your HttpServletRequest solution)... functionally my whole project is now working except for one thing:

Without the wr:AjaxURL link (excluded because it doesn't compile) obviously following the link doesn't return back to the original page context. However it is following the operation chain and firing the execute() method on the Save Custom Unit.

So reiterating, if I have the following code in the link:

 onclick="<wr:AjaxURL context="link" type="button"/>"

I get this compilation error:

com.webratio.commons.transform.EvaluateException: Undefined Link Context: Unable to find the link in the specified context [context = link/.].
[occurred at line 11 in AjaxURL.template]

using the link defined as you suggest

                <input title="<c:out value="${<wr:UnitId/>.signInputLabel}"/>" onclick="<wr:AjaxURL context="link" type="button"/>" type="submit" id="button:<wr:Id context="link"/>" name="button:<wr:Id context="link"/>" value="<c:out value="${<wr:UnitId/>.signName}"/>"/>

I checked the xml as you suggest and it looks the same as yours, see below:

 <ActuatorUnit id="sau6" name="Actuator Rate It" customDescriptor="false" xmlns:gr="http://www.webratio.com/2006/WebML/Graph" gr:x="0" gr:y="0" SignId="2" StigmergyType="0" OptionCardinality="2" linkOrder="ln54">
      <Link id="ln54" name="Link54" to="unit3" automaticCoupling="true" type="normal" validate="true" ajaxEnabled="true"/>
 </ActuatorUnit>

I checked whether the link variable is finding the Link54

 <%
 def link = unit.selectSingleNode("layout:Link");
 %>

I also do a toString() on the link variable at runtime (again .. without the wr:AjaxURL tag) it certainly seems to have extracted the correct node. It outputs to the page the following string (but I don't see any localhost URL):

 com.webratio.generator.expand.ExpandedElement@79dde928 [Element: <layout:Link uri: http://www.webratio.com/2006/WebML/Layout attributes: [org.dom4j.tree.DefaultAttribute@2845b3ca [Attribute: name link value "ln54"], org.dom4j.tree.DefaultAttribute@781ea76d [Attribute: name _sel value "t"], org.dom4j.tree.DefaultAttribute@248222b7 [Attribute: name id value "ln54"], org.dom4j.tree.DefaultAttribute@5bb52f1a [Attribute: name name value "Link54"], org.dom4j.tree.DefaultAttribute@542782ff [Attribute: name to value "unit3"], org.dom4j.tree.DefaultAttribute@6e095e82 [Attribute: name automaticCoupling value "true"], org.dom4j.tree.DefaultAttribute@291be13e [Attribute: name type value "normal"], org.dom4j.tree.DefaultAttribute@6560c287 [Attribute: name validate value "true"], org.dom4j.tree.DefaultAttribute@33836110 [Attribute: name ajaxEnabled value "true"]]/>]

So to me it looks like the link variable is populated and finding the appropriate link. But it mustn't be a correct link to generate the error?! Or am I still misunderstanding something? Thanks again!

 
x 0
No Forum Badges

Hi,

the "link" variable seems to correctly refer the link outgoing from your unit. The compilation error is about the <wr:AjaxURL> tag, where the "context" attribute is the variable used to locate the link. To better understand the problem:

  • Can you paste the complete code parts of the custom template related to the error ?
  • Can you describe (e.g. with a screenshot ) the updated model ?
  • Is the code of the link inserted only in the custom template, or are there other custom templates related to the unit and containing that code ?
  • What is the obtained behavior without the <wr:AjaxURL> tag ? For example, the operation chain is fully executed but the computation stops at the Save Custom Unit and doesn't return back the initial page. In this case, does the operation chain end with an OK / KO Link pointing to the initial page ? Is the OK / KO Link followed ?

 
x 0
No Forum Badges

The above information you have shared really so helpful for me. Thanks a lot.

 
x 0
Answer at this question and get points!

Related questions

2 grids inside one/same cell result in non-selectable 2nd grid Access page variable in a page template add html Ajax is not working in own style project Ajax web app with javascript history object using the WebRatio Alimentar graficas con base de datos Alternate way to get current User Oid in layout template groovy script? Any way to localize the Tab Grid Template (Webratio Store)? Applicare un template ad un Web Project Ayuda Simple List Component Layout personalizado Bootstrap Style Button to go on another page Cambiare dimensioni bottoni - Change button size Can I inject html into custom unit template?! Change color template bootstrap style Change Style Changing the login page does not work ckeditor - change directory for the browser Colore Attributi index unit Dinamico - Index unit dynamic attribute color Como abrir una ventana en ajax desde una master page Como embeber un video subido desde archivo ? Como mostrar una imagen de portada arriba del menu? Como mostrar una imagen en una lista o en la componente detalles? Confirm Dialog Criptare dati sensibili nel database CSV Component with utf8 encoding Custom components Custom descriptors Customize layout mobile platform Custom Plug-in Custom Time Unit Custom Tooltip Position Custom Unit and AJAX / SOAP Custom Unit: Difficult example in Guide ... any suggestions? Data flow from a page which is not visible anymore Default error pages default login page Display contents of a URL Encoding Confirm Dialog Error in Excel Unit - Font size Export to a HTML/CSS/JS project Field as link soruce file analysis then update MySQL database File CSS non considerato in generazione Form element Form template Get date pattern Get home page from template Google map is not shown properly in the tab grid Google Map Unit Guardar Saltos de LINEA HelloWorld Unit sample code Hiding landmarks (or flows) when the user is logged in How can I add a credit card payment gateway or integrate paypal in my web app logic? How can i create pagemenu or landmarkmenu with multiple levels. How can I modified the htmls files to perform my style how can i open a pdf file using download dialog How complex can Custom Unit output be? How to add an image in a modal/pop-up window? How to include a template into other template? How to localize AJAX waiting dialog? How to localize the multi message unit in the notification layout How to modify template? How to modify the FertileEnviroment Default page How to remove default Linked Resources? How to run the example from Custom Unit Guide? How to use LandmarkMenu as AJAX navigation how to use the landmark menu as AJAX navigation integrate framework to webratio mobile Integrazione javascript Is there any custom unit store or repository? Do you create/sell custom units? java.lang.NullPointerException Javascript and html javascript history object Localize "Welcome..." and "Process details" logo webratio meaning of each tag in the XML code (Show XML/Show Layout XML) modify field html Modify html generated by wr:NavigationBar More Custom Unit questions: example of Content and Operation Unit? Need help with Landmark Overlays for Google Map Unit. Pages Problem After Project Generation pass template variable Personalizzazione del login component Problema Invocation Unit Problem Login Form only if user not logged Problem print Problems with Custom components: Can't get values from output parameters on ok flow. Problems with the page refresh (Tab Grid) Problem with adding templates query unit who to hide fields that are used in a link Recursive Hierarchical Index Unit Style Tree Redirect to the default module Remove default BPM css import for all templates Responsive Bootstrap Grid Responsive Layout Manager "Run Now" on a job scheduled to run later Selezione sul giorno "Events Planning" Set context parameter Simple Static Page Standard confirm dialog replacement Status ProcessInstance and activityInstance in spanish Stored procedure component Style hierarchical unit help!! Supoort for Mobile and Desktop display Target tabs in Tab Grid Control Tooltip on a field Too much layout parameters = no scroll in parameters config window Twitter Unit - Get Geo location of twitt Uppercase Usage of the Gantt Unit Use image as interaction flow ¿Visor de imágenes y reproductor de video para la versión 7.2? Image viewer and video player for version 7.2? Vista de diferentes Site Views Web project without initial login form - how to create custom logins? Webratio Add-ons no permite login Webratio don't recognize JSON library WebRatio Platform 7.2 Community Cloud Edition wr-ajaxDivs break layout on ajax pages.