Get Value ID from <p:autoComplete>
this is my xhtml
<p:autoComplete
dropdown="true"
value="#{kabupatenBacking.selectedServiceLocation}"
completeMethod="#{kabupatenBacking.autoComplete}"
var="svl"
itemLabel="#{svl.serviceLocationName}"
itemValue="#{svl.serviceLocationID}">
</p:autoComplete>
and this is my bean
private KabupatenEntity selectedServiceLocation;
public List<KabupatenEntity> autoComplete(String query)
{
listServiceLocation = kabupatenRules.getServiceLocationByStatus();
List<KabupatenEntity> queried = new ArrayList<KabupatenEntity>();
String output = query.substring(0,1).toUpperCase() + query.substring(1);
for(KabupatenEntity kabupaten : listServiceLocation)
{
if(kabupaten.getServiceLocationName().contains(output))
{
queried.add(kabupaten);
}
}
return queried;
}
and the problem is when i put component itemValue.autocomplete doesn't work
but when i remove ItemValue from <p:autoComplete> is work
but i need the value,how to i can get the value?
Thank You
I'm trying to make the following work in Tapestry.
I have a Dictionary<String, Dictionary<String, Object>> which contains my data.
I'm trying to accomplish that I have 1 drop-down menu (Select component) which contains the keys from outer Dictionary.
When that selection changes, grid should be updated with the keys and values from the selected sub-dictionary.
For example:
Dictionary<String, Dictionary<String, Object>> dictionaries = new Hashtable<String, Dictionary<String, Object>>();
Dictionary<String, Object> dict1 = new Hashtable<String, Object>();
Dictionary<String, Object> dict2 = new Hashtable<String, Object>();
dict1.put("k1", "d1v1");
dict1.put("k2", "d1v2");
dict2.put("k1", "d2v1");
dict2.put("k2", "d2v2");
dictionaries.put("d1", dict1);
dictionaries.put("d2", dict2);
Would anyone would be so kind to give me an example or push me in the right direction?
EDIT:
I managed to get the first part working, with grid contents changing depending on which keys from outer dictionary are selected.
However, I I'm having problems with updating the grid and saving the changes:
I am using my own GridDataSource:
public class EntityDataSource<T> implements GridDataSource {
private Class<T> persistentClass;
protected List<T> data;
protected int count = -1;
protected int startIndex = 0;
public EntityDataSource(Class<T> persistentClass, List<T> data) {
this.persistentClass = persistentClass;
this.data = data;
}
public static final <T> EntityDataSource<T> create(
Class<T> persistentClass, List<T> data) {
return new EntityDataSource<T>(persistentClass, data);
}
public int getAvailableRows() {
return this.data.size();
}
public void prepare(int startIndex, int endIndex,
List<SortConstraint> sortConstraints) {
this.startIndex = startIndex;
this.data = this.data.subList(startIndex, endIndex + 1);
}
public Object getRowValue(int index) {
return this.data.get(index - this.startIndex);
}
#SuppressWarnings("rawtypes")
public Class getRowType() {
return this.persistentClass;
}
}
My grid looks like this:
<t:form t:id="configSelectForm">
<t:select t:id="storageKeySelecter"
t:model="storageKeyModel"
t:value="storageKey"
zone="configZone" />
</t:form>
<t:zone t:id="configZone" id="configZone">
<t:form t:id="configReviewForm">
<table width="100%">
<t:grid t:source="configurationEntrySource"
t:add="update, delete"
t:row="configurationEntry"
t:mixins="DisableGridSorting"
t:include="configKey, configValue"
t:encoder="configurationEntryEncoder">
<p:configValueCell>
<input t:id="value" t:type="TextField" t:value="configurationEntry.configValue"
t:validate="required" t:context="configurationEntry.configValue" />
</p:configValueCell>
<p:updateCell>
<t:actionlink t:id="update" zone="configZone" context="[configurationEntry.configKey, configurationEntry.configValue]">Update</t:actionlink>
</p:updateCell>
<p:deleteCell>
<t:actionlink t:id="delete" zone="configZone" context="configurationEntry.configKey">Delete</t:actionlink>
</p:deleteCell>
</t:grid>
</table>
<br></br>
<!-- <input type="submit" value="Update" class="button" /> -->
</t:form>
</t:zone>
I have managed to make a delete link work, however, I cannot seem to update the value for the arbitrary key.
When I click the link to update, the value from the text field is not the one that is being passed:
public Object onActionFromUpdate(String configKey, String configValue) {
// my stuff here
return request.isXHR() ? configZone.getBody() : null;
}
The configValue is the value of the entry that currently exist and not the one I'm trying to change it to.
Is there a way to get that value? My grid has an an arbitrary number of rows.
EDIT2: Even more info provided
This is my TML:
<t:form t:id="configSelectForm">
<t:select t:id="storageKeySelecter"
t:model="storageKeyModel"
t:value="storageKey"
zone="configZone" />
</t:form>
<br/>
<t:zone t:id="configZone" id="configZone" elementName="div">
<form t:type="form" t:id="configReviewForm" id="configReviewForm" t:zone="configZone" zone="configZone">
<table width="100%">
<t:grid t:source="configurationEntries"
t:add="update, delete"
t:row="configurationEntry"
t:mixins="DisableGridSorting"
t:include="configKey, configValue"
t:encoder="configurationEntryEncoder" >
<p:configValueCell>
<input t:id="configValueTextField" t:type="TextField" t:value="configurationEntry.configValue"
t:validate="required" />
</p:configValueCell>
<p:updateCell>
<t:actionlink id="update" t:id="update" zone="configZone" t:context="[configurationEntry.configKey, configurationEntry.configValue]">Update</t:actionlink>
</p:updateCell>
<p:deleteCell>
<t:actionlink id="delete" t:id="delete" zone="configZone" t:context="configurationEntry.configKey">Delete</t:actionlink>
</p:deleteCell>
</t:grid>
</table>
<br/>
<input type="submit" value="Update" class="button" zone="configZone"/>
</form>
</t:zone>
<br/>
<br/>
<t:form t:id="addNewEntryForm">
<table width="100%">
<tr>
<td>
<input t:id="newEntryKey" t:type="textfield" t:value="newEntry.configKey"
t:validate="required" t:context="newEntry.configKey" />
</td>
<td>
<input t:id="newEntryValue" t:type="textfield" t:value="newEntry.configValue"
t:validate="required" t:context="newEntry.configValue" />
</td>
<td>
<input type="submit" value="Add New Entry" zone="configZone"/>
</td>
</tr>
</table>
</t:form>
This is my JAVA:
public class PropertyConfiguration {
#Inject
private BeanModelSource beanModelSource;
#Component
private Form configReviewForm;
#Property
private List<ConfigurationEntry> configurationEntries;
private List<ConfigurationEntry> persistentEntries;
#Property
private ConfigurationEntry configurationEntry = new ConfigurationEntry("", "");
#Property
private ConfigurationEntryEncoder configurationEntryEncoder;
#InjectComponent
private Zone configZone;
#InjectComponent
private TextField configValueTextField;
#Inject
private ConfigurationPersitanceDAO dao;
private GridDataSource dataSource;
#Inject
private Messages messages;
#Property
private ConfigurationEntry newEntry;
#Inject
private Request request;
#Property
#Validate("required")
#Persist(PersistenceConstants.SESSION)
private String storageKey;
private StringSelectModel storageKeysSelectModel;
public ValueEncoder<ConfigurationEntry> getConfigurationEntryEncoder() {
initConfigurationEntityEncoder();
return this.configurationEntryEncoder;
}
public BeanModel<ConfigurationEntry> getModel() {
return beanModelSource.createDisplayModel(ConfigurationEntry.class, messages);
}
public SelectModel getStorageKeyModel() {
if (storageKeysSelectModel == null) {
storageKeysSelectModel = new StringSelectModel(this.dao.getStorageKeys());
}
return storageKeysSelectModel;
}
private void initConfigurationEntityEncoder() {
if (this.configurationEntryEncoder == null) {
this.configurationEntryEncoder = new ConfigurationEntryEncoder(dao, storageKey);
}
}
private void initZoneData() {
if (this.storageKey == null) {
this.storageKey = this.dao.getStorageKeys().get(0);
}
initConfigurationEntityEncoder();
}
public Object onActionFromDelete(String configKey) {
System.out.println("Deleting from: " + storageKey + " entry: " + configKey);
this.dao.deleteConfigurationEntry(storageKey, configKey);
return request.isXHR() ? configZone.getBody() : null;
}
public Object onActionFromUpdate(String configKey, String configValue) {
this.dao.updateConfigurationEntry(storageKey, configKey, configValue);
return request.isXHR() ? configZone.getBody() : null;
}
void onActivate(String storageKey) {
initZoneData();
this.newEntry = new ConfigurationEntry("", "");
}
String onPassivate() {
this.newEntry = new ConfigurationEntry("", "");
return this.storageKey;
}
Object onRefresh() {
return request.isXHR() ? configZone.getBody() : null;
}
Object onSuccessFromAddNewEntryForm() {
String configKey = this.newEntry.getConfigKey();
String configValue = this.newEntry.getConfigValue();
this.dao.addConfigurationEntry(storageKey, configKey, configValue);
return request.isXHR() ? configZone.getBody() : null;
}
void onValidateFromAddNewEntryForm() {
return;
}
Object onValueChangedFromStorageKeySelecter(String storageKey) {
this.storageKey = storageKey;
initConfigurationEntityEncoder();
this.configurationEntries = wrap(this.dao.getConfiguration(storageKey));
return configZone.getBody();
}
private void updateChangedConfigurations(List<ConfigurationEntry> changedEntries) {
for (ConfigurationEntry changedEntry : changedEntries) {
String configKey = changedEntry.getConfigKey();
String configValue = changedEntry.getConfigValue();
System.out.println("Updated: [" + storageKey + ":" + configKey + ":" + configValue + "]");
this.dao.updateConfigurationEntry(storageKey, configKey, configValue);
}
}
void onValidateFromConfigReviewForm() {
this.persistentEntries = wrap(this.dao.getConfiguration(storageKey));
List<ConfigurationEntry> tmpList = new ArrayList<ConfigurationEntry>();
for (ConfigurationEntry newEntry : this.configurationEntries) {
for (ConfigurationEntry oldEntry : this.persistentEntries) {
System.out.println("NewEntry: " + newEntry.toString() + " vs. OldEntry: " + oldEntry.toString());
if (oldEntry.getConfigKey().equals(newEntry.getConfigKey())) {
if (!oldEntry.getConfigValue().equals(newEntry.getConfigValue())) {
newEntry.setConfigValue(newEntry.getConfigValue().trim());
tmpList.add(newEntry);
}
}
}
}
this.persistentEntries = tmpList;
}
Object onSuccessFromConfigReviewForm() {
updateChangedConfigurations(this.persistentEntries);
return request.isXHR() ? configZone.getBody() : null;
}
/**
* Wraps dictionary entries in instances of ConfigurationEntry
*/
private List<ConfigurationEntry> wrap(
Dictionary<String, Object> rawConfiguration) {
Set<String> keySet = new TreeSet<String>();
List<ConfigurationEntry> wrappedEntries = new ArrayList<ConfigurationEntry>();
Enumeration<String> keys = rawConfiguration.keys();
while (keys.hasMoreElements()) {
String key = keys.nextElement();
keySet.add(key);
}
for (String key : keySet) {
String value = (String) rawConfiguration.get(key);
ConfigurationEntry entry = new ConfigurationEntry(key, value);
wrappedEntries.add(entry);
}
return wrappedEntries;
}
}
For some reason, when the "Update" action link is clicked the values passed to the public Object onActionFromUpdate(String configKey, String configValue) aren't the ones I just wrote into the designated textfield, but the ones that were fetched from my database when page was rendered.
For example, if I had these pairs initially:
key1 => value1
key2 => value2
key3 => value3
and I wanted to change value for key2 to "newValue2" the parameters passed to the method are "key2" and "value2" instead of "key2" and "newValue2".
The same problem is the reason the mass-update doesn't work. All the values in configurationEntries are shapshot values from the database instead of the values currently written in my grid.
So, my question would be how I can update my DB from editable grid using AJAX for my concrete example. I've tried many things suggested on SO and rest of internet, but they don't seem to work and I don't know why.
You need to use the zone parameter.
Take a look at the SelectZoneDemo.tml and SelectZoneDemo.java from the select component's javadoc. It gives an example of updating a zone when a select changes.
For more complex interactions, you might be interested in this
To have actual values from inputs you need to submit form. As you use ActionLink the values from its context are used (this values was saved in context during link rendering and can't be changed on client side without hacking).
To have your example working you can use separate form for each row. You will also need some submit component that can work outside the form:
<t:zone t:id="configZone" id="configZone">
<table width="100%">
<t:grid t:source="configurationEntrySource"
t:add="update, delete"
t:row="configurationEntry"
t:mixins="DisableGridSorting"
t:include="configKey, configValue"
t:encoder="configurationEntryEncoder">
<p:configValueCell>
<t:form t:id="configReviewForm" zone="configZone">
<input t:id="value" t:type="TextField" t:value="configurationEntry.configValue"
t:validate="required" t:context="configurationEntry.configValue" />
</t:form>
</p:configValueCell>
<p:updateCell>
<t:customlinksubmit form="configReviewForm">Update</t:customlinksubmit>
</p:updateCell>
<p:deleteCell>
<t:actionlink t:id="delete" zone="configZone" context="configurationEntry.configKey">Delete</t:actionlink>
</p:deleteCell>
</t:grid>
</table>
<br/>
</t:zone>
CustomLinkSubmit:
#SupportsInformalParameters
public class CustomLinkSubmit implements ClientElement {
#Parameter(required = true, allowNull = false, defaultPrefix = BindingConstants.COMPONENT)
private Form form;
#Parameter(allowNull = false, defaultPrefix = BindingConstants.LITERAL)
private SubmitMode mode = SubmitMode.NORMAL;
#Inject
private ComponentResources resources;
#Inject
private JavaScriptSupport javascriptSupport;
private String clientId;
#BeginRender
void beginRender(MarkupWriter writer) {
clientId = javascriptSupport.allocateClientId(resources);
writer.element("span", "id", clientId);
resources.renderInformalParameters(writer);
}
#AfterRender
void afterRender(MarkupWriter writer) {
writer.end();
JSONObject spec = new JSONObject()
.put("form", form.getClientId())
.put("clientId", clientId)
.put("validate", mode == SubmitMode.NORMAL);
javascriptSupport.addInitializerCall(InitializationPriority.EARLY, "linkSubmit", spec);
}
public String getClientId() {
return clientId;
}
}
I have been working on a Spring project that makes use of the Spring form taglib (http://www.springframework.org/tags/form).
I am using some multiple select boxes to indicate some options (Country, factory,...)When I pass an entire list to the select - all is well: the first option of the select list is selected by default. However, when a user is from a specific country, the list is filtered and only his country is shown. In this case the first element is not selected by default.
JSP page:
<%# taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<form:select path="countryValues" multiple="true" size="9" style="width:192px;" cssErrorClass="field-error">
<form:options items="${command.countries}" itemValue="countryCode" itemLabel="correctDisplayString"/>
</form:select>
Command.java
public List<CountryMaster> getCountries() {
return countries;
}
public void setCountries(List<CountryMaster> countries) {
this.countries = countries;
}
Controller.java
#RequestMapping(value = "/overview", method = RequestMethod.GET)
public String overview(HttpServletRequest request, Model model) {
Attrs attrs = getAttrs(request);
UserLocale.initUser(getUser(request));
User user = UserLocale.getUser();
List<FactoryMaster> factoryList = getFactoryList(attrs);
List<CountryMaster> countryList = getCountryList(attrs);
Command command = initCommand(attrs);
model.addAttribute(command);
if(user.hasRole(User.NORMAL)&& user.getCountryCode() != null){
if(countries == null){
countries= getDaoBuilder().getDaoCountry().countryMap();
}
String isoCode = countries.get(user
.getCountryCode());
List<CountryMaster> buffer = new ArrayList<CountryMaster>();
for(CountryMaster i : countryList){
if(isoCode.equalsIgnoreCase(i.getIsoCode())){
buffer.add(i);
}
}
System.out.println("List size: "+buffer.size());
command.setCountries(buffer);
}
else{
command.getCountries().addAll(getCountryList(attrs));
}
command.getModels().addAll(getModelList(attrs));
command.setBrands(getBrandList(attrs));
return "/reporting/overview";
}
private List<CountryMaster> getCountryList(Attrs attrs) {
List<CountryMaster> result = new ArrayList<CountryMaster>();
CountryMaster ct = new CountryMaster(CountryMaster.ISO_COUNTRY_JOKER, 00);
ct.setDescription("ALL");
result.add(ct);
result.addAll(attrs.countryList);
return result;
}
On the HTML page, I can see in other lists that the first element has the attribute selected="selected". Anybody have any idea why this is not the case when I manipulate my list? Or does anyone know what is resposible for this selected attribute allocation? (Is this javascript, java attribute,...?)
Thanks in advance!
Turns out the value of the listbox can be set: this piece of code made it quite an easy fix:
public String overview(HttpServletRequest request, Model model) {
Attrs attrs = getAttrs(request);
UserLocale.initUser(getUser(request));
User user = UserLocale.getUser();
List<FactoryMaster> factoryList = getFactoryList(attrs);
List<CountryMaster> countryList = getCountryList(attrs);
Command command = initCommand(attrs);
model.addAttribute(command);
if(user.hasRole(User.NORMAL)&& user.getCountryCode() != null){
if(countries == null){
countries= getDaoBuilder().getDaoCountry().countryMap();
}
String isoCode = countries.get(user
.getCountryCode());
List<CountryMaster> buffer = new ArrayList<CountryMaster>();
for(CountryMaster i : countryList){
if(isoCode.equalsIgnoreCase(i.getIsoCode())){
buffer.add(i);
}
}
System.out.println("List size: "+buffer.size());
command.setCountries(buffer);
// FIXED SELECTION OF ELEMENT
command.setFactoryValues(new String[]{isoCode});
// FIXED SELECTION OF ELEMENT
}
else{
command.getCountries().addAll(getCountryList(attrs));
}
command.getModels().addAll(getModelList(attrs));
command.setBrands(getBrandList(attrs));
return "/reporting/overview";
}
This way, you set the value of the listbox using code, and when the page is opened - the value is already there, making it selected by default.
I'm using primefaces 3.0.M2 with backing bean to add files arranged in folders (modules) and subfolders(assignments). I have managed to do that successfully, but I can't have control over the file to make it downloadable. I want to make the file as a button to download that specific file instead of just being a normal text. Please check the jsf code below:
<p:tree id="tree" value="#{files.root}" var="doc" selectionMode="single"
selection="#{files.selectedTreeNode}">
<p:treeNode>
<h:outputText value="#{doc}"/>
</p:treeNode>
</p:tree>
Here is my backing bean class:
public class FilesBean implements Serializable {
private TreeNode root;
public TreeNode getRoot() {
root = new DefaultTreeNode("root", null);
TreeNode general = new DefaultTreeNode("General", root);
TreeNode module = null;
TreeNode assignment = null;
TreeNode fileNode = null;
if(getMoudles()!=null)
{
for(String s : getMoudles())
{
module = new DefaultTreeNode(s, root);
if(getAssignments()!=null)
{
for (Assignments as : getAssignments())
{
if(as.getMoudleid().equals(s))
assignment = new DefaultTreeNode(as.getAssignmentsPK().getAssignmentid(), module);
for(Files file : getFiles())
{
if (file.getFilesPK().getAssignmentid().equals(as.getAssignmentsPK().getAssignmentid()) && file.getThemodule().equals(s))
{fileNode = new DefaultTreeNode(file,assignment);}
}
}
}
}
}
return root;
}
PS: PrimeFaces 3.0.M2, JSF 2.0, J2EE 6 Web, Servlet 3.0, Glassfish 3.0, EJB 3.0, browser: IE8 also tried on FireFox 3.6.12
Have you tried using a <p:commandButton> with <p:fileDownload>?
<p:commandButton
value="Download"
title="Download"
image="ui-icon-arrowthick-1-s"
ajax="false">
<p:fileDownload value="#{myBean.fileStreamedContent}" />
</p:commandButton>
In your backing bean (for example purposes, assuming your files are JPEGs):
public StreamedContent getFileStreamedContent() {
try {
InputStream is = new BufferedInputStream(
new FileInputStream("/your/file/path/fileXYZ.jpg"));
return new DefaultStreamedContent(is, "image/jpeg", "fileXYZ.jpg");
} catch (FileNotFoundException e) {
}
}
The last part is associating a particular file with a particular tree node. You can use the <p:tree> attributes selectionMode="single" and selection="#{myBean.selectedTreeNode}". The user selects a tree node and this will cause the selectedTreeNode to be set (via a setter method) on your bean.
private TreeNode selectedTreeNode;
public void setSelectedTreeNode(TreeNode selectedTreeNode) {
this.selectedTreeNode = selectedTreeNode;
if (this.selectedTreeNode != null) {
Object yourTreeNodeData = this.selectedTreeNode.getData();
// do whatever you need to do with the data object...
}
}
In the getFileStreamedContent() method, just use the filename stored in your tree node object as the parameter to the FileInputStream() constructor.
EDIT
Rather than try to embed command buttons in the tree, provide one command button somewhere on the page. When a tree node is selected it can set the associated file (to be downloaded) as a property on your bean. Make your tree look like this:
<p:tree
value="#{myBean.rootTreeNode}"
var="node"
selectionMode="single"
selection="#{myBean.selectedTreeNode}">
<p:ajax event="select" listener="#{myBean.onNodeSelect}" />
<p:ajax event="unselect" listener="#{myBean.onNodeUnselect}" />
</p:tree>
public void onNodeSelect(NodeSelectEvent event) {
// put some logging here...
}
public void onNodeUnselect(NodeUnselectEvent event) {
// put some logging here...
}
Put a println or logging statement in your setSelectedTreeNode method to make sure the setter is being invoked when you click the tree node. Use the getData() method on the TreeNode to get back the data value that you originally put in it when you created the tree. The getFileStreamedContent() method will use that value to deliver the correct file that the user selected by clicking on a tree node.
Bound values are not getting updated from editable data table without setting ID in JDK 1.5. But the same does work without setting ID in JDK 1.6.
Does anyone know why? Thanks
Code, Bean part
public void setDataTable(HtmlDataTable dataTable) {
this.dataTable = dataTable;
}
public HtmlDataTable getDataTable() {
if (dataTable == null)
setEditableDataTable();
return dataTable;
}
private void setEditableDataTable() {
dataTable = new HtmlDataTable();
dataTable.setValueBinding("value",
createValuebinding("#{testBean.stringList}"));
dataTable.setVar("items");
for (int i = 0; i < getDatastable().get(i).size(); i++) {
UIColumn column = new UIColumn();
dataTable.getChildren().add(column);
HtmlOutputText header = new HtmlOutputText();
header.setValue("Header "+i);
column.setHeader(header);
HtmlInputText input = new HtmlInputText();
input.setValueBinding("value", createValuebinding("#{items[" + i
+ "]}"));
column.getChildren().add(input);
}
}
private ValueBinding createValuebinding(String valueExpression) {
return FacesContext.getCurrentInstance().getApplication()
.createValueBinding(valueExpression);
}
JSP part
<h:dataTable binding="#{testBean.dataTable}" >
</h:dataTable>
Solution
Give id for the datatable