• add dynamic values to <select> in Forms.xml

  • We tried to make OpenKM as intuitive as possible, but an advice is always welcome.
We tried to make OpenKM as intuitive as possible, but an advice is always welcome.
Forum rules: Please, before asking something see the documentation wiki or use the search feature of the forum. And remember we don't have a crystal ball or mental readers, so if you post about an issue tell us which OpenKM are you using and also the browser and operating system version. For more info read How to Report Bugs Effectively.
 #28313  by matt81
 
Hi,
I just need to know if it's posible to load dynamic data to <select> in forms.xml.
For example I want to have a drop down where it loads all the users from Openkm in a <select> drop down, by using java code or running an sql statement.
I have read about the metadata definition by using optionsQuery, but that's only for Property groups, so it doesn't suit me.

Is there any way this can be achieved?

Thanks
 #28330  by jllort
 
This is not done but is already studied, is needed:
1- add in select and extra attribute to indicate some Class
2- The clas will implement specific interface ( into you'll do what you want )
3- change the dtd for new atrribute

We've not found time for doint it althougt is interesting. If one of our customer should demanded it sure will be done, but has not been the case and actually we got our roadmap full. You can waiting or do yourself and we'll be pleased trying to orientate you in what parts of the source code need to be changed, extended ( and obviously include in community ).
 #28334  by matt81
 
Thanks for your reply.
I can certainly try and have a go at it and if successful will be more than happy to share.
However I would need a bit of guidance from you.
Can you tell me how that can be achieved.
How can I make the <select> to load values from a class. Can I do something like the below:
<select class="com.openkm.workflow.loadValues" />

And then in the class I can implement the Action handler and return all values to the <select>.
Or is there any other way?

Thanks
 #28343  by jllort
 
- First step is changed dtd to allow new attribute src/main/resource/dtd
- Include var into Select.java
- Second use this property Take a look FormUtils.java -> parseField ( to get class value into select )
.... etc ( better if first concentrate on it ).
 #28376  by matt81
 
Thanks for your reply, but I find it hard to start. I would need more narrow guidence.
1. How do you change dtd. At the moment I have forms.xml. Do I need to create another xml file called called PropertyGroup.xml with the following namespace
<!DOCTYPE property-groups PUBLIC "-//OpenKM//DTD Property Groups 2.1//EN"
"http://www.openkm.com/dtd/property-groups-2.1.dtd">
2. How to include var into Select.java?
3. How to use FormUtils.Java -> parseField ?

It's confusing I would need an example if possible please!

Thank you
 #28401  by jllort
 
- First is change dtd, and store in your file system. Then use as is indicated here http://wiki.openkm.com/index.php/Proper ... definition ( see the third box ). In dtd you must add class attribute
- Modify parseField to consider the new attribute
Code: Select all
else if (fieldComponent.equals("select")) {
					Select select = new Select();
					ArrayList<Option> options = new ArrayList<Option>();
					Node item = nField.getAttributes().getNamedItem("label");
					if (item != null) select.setLabel(item.getNodeValue());
					item = nField.getAttributes().getNamedItem("name");
					if (item != null) select.setName(item.getNodeValue());
					item = nField.getAttributes().getNamedItem("type");
					if (item != null) select.setType(item.getNodeValue());
					item = nField.getAttributes().getNamedItem("data");
					if (item != null) select.setData(item.getNodeValue());
					item = nField.getAttributes().getNamedItem("optionsData");
					if (item != null) select.setOptionsData(item.getNodeValue());
					item = nField.getAttributes().getNamedItem("width");
					if (item != null) select.setWidth(item.getNodeValue());
					item = nField.getAttributes().getNamedItem("height");
					if (item != null) select.setHeight(item.getNodeValue());
					item = nField.getAttributes().getNamedItem("readonly");
					if (item != null) select.setReadonly(Boolean.parseBoolean(item.getNodeValue()));
					item = nField.getAttributes().getNamedItem("table");
					if (item != null) select.setTable(item.getNodeValue());
					item = nField.getAttributes().getNamedItem("optionsQuery");
					if (item != null) select.setOptionsQuery(item.getNodeValue());
					item = nField.getAttributes().getNamedItem("suggestion");
					if (item != null) select.setSuggestion(item.getNodeValue());
					
					NodeList nlOptions = nField.getChildNodes();
					for (int k = 0; k < nlOptions.getLength(); k++) {
						Node nOption = nlOptions.item(k);
						
						if (nOption.getNodeType() == Node.ELEMENT_NODE) {
							if (nOption.getNodeName().equals("option")) {
								Option option = new Option();
								item = nOption.getAttributes().getNamedItem("label");
								if (item != null) option.setLabel(item.getNodeValue());
								item = nOption.getAttributes().getNamedItem("value");
								if (item != null) option.setValue(item.getNodeValue());
								item = nOption.getAttributes().getNamedItem("selected");
								if (item != null) option.setSelected(Boolean.parseBoolean(item.getNodeValue()));
								options.add(option);
							}
						}
					}
					
					select.setOptions(options);
					select.setValidators(parseValidators(nField));
					fe.add(select);
				}
I suggest arrived here debug this part of the code to understand what is doing.
 #28408  by matt81
 
Thanks for your reply.
Ok I know what I have to do, it is a matter of adding a new attribute called class in FormUtils.Java -> parseField.
However in my Jboss Developer studio I have added these classes as a .jar file in my build path. These are compiled classes, I f I understand you correctly I have to modify the following file FormUtils.java by adding that extra attribute and then I have to compile it and geneate a .jar file so i can include it in my build path. I did a checkout of Openkm, so I will go ahead and try it. if in the mean time you guys come up with a full solution please let me know.

Thanks
 #28409  by matt81
 
I did a checkout of openkm, modified the file, and then generated a jar file. However the jar file is not valid, when I place it in the build path it has.java extensions instead of byte code .class, file and it is throwing errors in my project. I used: jar cvf filename.jar com
What is the safest way to create jar files.
 #28419  by jllort
 
No no no.

First you can use eclipse is not necessary use jboss developer studio ( we only suggest it when is necessary do workflows otherside use eclipse ).
You must not create a jar, you must buld the project with changes -> new OpenKM.war with changes. You're compiling entire project not and extension etc... is a change in core.
 #28480  by jllort
 
First should configure development ide as is described here http://wiki.openkm.com/index.php/Developer_Guide to compile open source code. I hope you got it. Then it's so easy, simply in other eclipse project must add the project dependency ( so easy -> select project forder -> right click -> properties -> java build path -> tab projects -> add there ).
 #29068  by matt81
 
OK back to this now. I had some spare time now and have done this, can you please have a look at it and let me know if all good. let me explain what I did.
In FormUtils.java have added a new field under
Code: Select all
} else if (fieldComponent.equals("select")) {

 item = nField.getAttributes().getNamedItem("class");
 if(item != null) select.setClassValue(item.getNodeValue());

And then in Select.java i have added the Getter an Setter:
Code: Select all
public String getClassValue(){
            return classValue;
        }
        
        public void setClassValue(String classes){
            this.classValue = classes;
        }
At the end I have created a new package called "com.openkm.select.values" and have added the attached two java classes. One is an interface. In there I am loading all the users.
Please have alook at it.
For my Forms.xml it will now look as follows:
Code: Select all
?xml version="1.0" encoding="UTF-8"?>
  <!DOCTYPE property-groups PUBLIC "-//OpenKM//DTD Property Groups 2.1//EN"
                                 "http://www.openkm.com/dtd/property-groups-2.1.dtd">
<workflow-forms>
  <workflow-form task="run_config">
     	<select label="Assign user" name="assignee" class="openkm.select.values.ListClass" />
</workflow-form> 
</workflow-forms>
Please have alook at my implementaiotn and let me know if correct or give me suggestions.

Thank you.
Attachments
ListClassValues.png
ListClassValues.png (4.98 KiB) Viewed 6388 times
ListClass.png
ListClass.png (12.54 KiB) Viewed 6388 times
 #29085  by jllort
 
Seems correct, but some minimal suggestions:
- About interface name ( name's always are the most difficult thing :) us we got a lot of problems sometimes and eternal discussions about it ) ListClassValues not indicates really are talking about OptionSelectValues
- Interface method name should be more generic -> getValues(); or getOptions() not listUsers(); Here take in mind what is in the list is not only the value also the label ( Option has value, label )
- about property class I suggest call className as className="openkm.select.values.ListClass", because if on future we want to use some style or similar class should be good idea still get reserved word.
- about new package now I'm not sure where to create it I should take a look in more deep.
- also you've changed the dtd no ?

If you got the patch and is going right we can study to be added in community 6.3 branch
 #29112  by matt81
 
Thanks for your reply and feedback, I am glad I can contribute to OpenKM, it's a great software.
Ok I have amended the following points:
1. I have renamed the Interface and method to:
Code: Select all
public interface OptionSelectValues {
    public String getOptions();
}
2. The classname is the same, I have changed the return type by adding it within <option>, see below:
Code: Select all
public class ListClass implements OptionSelectValues {

    @Override
    public String getOptions() {
       
        String options = null;
        
        try {
       String token = OKMAuth.getInstance().login("okmAdmin", "admin");
       List<String> usersL = OKMAuth.getInstance().getUsers(token); 
        
        String name = null;
        for (Iterator<String> it = usersL.iterator(); it.hasNext();) {
            String usr = it.next();
             name = OKMAuth.getInstance().getName(token, usr.toString());
            
            options += "<option label=\"" + name + "\" value=\"" + usr.toString() + "\"/>";
           
        }
        
        } catch(Exception e){
            System.out.println("Exception occured: " + e.getMessage());
        }
        return options;
    }
}            

3. The getters and setters are now called getClassName() and setClassName().
4. The attribute in forms.xml will now be:
Code: Select all
className="openkm.select.values.ListClass"
5. I am bit confused about my Forms.xml and propertyGroup.xml. Do i need both forms? I currently have the following Forms.xml. Is this enough or do I have to include a PropertyGroup.xml as well.
Code: Select all
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE workflow-forms PUBLIC "-//OpenKM//DTD Workflow Forms 2.4//EN" "http://www.openkm.com/dtd/workflow-forms-2.4.dtd">
<workflow-forms>
  <workflow-form task="run_config">
        <select label="Assign user" name="assignee" className="openkm.select.values.ListClass" />
       <button name="submit" label="Submit" /> 
</workflow-form> 
</workflow-forms>
 #29156  by jllort
 
I suggest do not return String in getOptions, you should return List<Option>

About dtd, there's one for PropertyGroups and other form Workflow forms. In this case I think is good idea change both dtd.

About Us

OpenKM is part of the management software. A management software is a program that facilitates the accomplishment of administrative tasks. OpenKM is a document management system that allows you to manage business content and workflow in a more efficient way. Document managers guarantee data protection by establishing information security for business content.