I have a PrimeFaces inputSwitch:
<p:inputSwitch id="snoozeSwitch" value="#{dashBController.snooze}" valueChangeListener="#{dashBController.updateSnoozeStatus}">
<p:ajax listener="#{dashBController.updateSnoozeStatus}" update="msgSnooze" />
</p:inputSwitch>
Now I want to give this switch an initial value from my DB. I get the value with:
#PostConstruct
public void init() {
if (!FacesContext.getCurrentInstance().isPostback()) {
snooze = getSnoozeStatus();
}
}
But I have trouble to update the old value with the new one.
public void updateSnoozeStatus() {
if(snooze == true) {
DBconnector.updateSnooze("true");
} else {
DBconnector.updateSnooze("false");
}
}
The problem: My app always uses the inital value and so the switch is stucking on the state it has originally. Maybe #BalusC knows the answer :)
Unless I am missing something your solution seems complex for something very simple. Why don't you just use a getter and a setter?
The getter should load the value from the database and the setter should save it. I couldn't test the code below because I don't have PF 5.0.4 but it should be a good start.
public class DashBController {
private Boolean snooze = null;
public boolean isSnooze() {
if (snooze == null) {
snooze = getSnoozeStatus();
}
return snooze;
}
public void setSnooze(boolean snooze) {
this.snooze = snooze;
DBconnector.updateSnooze(this.snooze.toString());
}
}
and simply :
<p:inputSwitch id="snoozeSwitch" value="#{dashBController.snooze}"/>
Related
How to navigate to the next page based on the return value from the method called inside the action attribute of the command button.
<af:button id="tt_b2"
rendered="#{attrs.nextRendered}"
partialSubmit="true"
action="#{attrs.backingBean.nextAction}"
text="Next"
disabled="#{attrs.nextDisabled}"/>
private static final String NEXT_NAVIGATION_ACTION = "controllerContext.currentViewPort.taskFlowContext.trainModel.getNext";
public String nextAction() {
if (validate()) {
updateModel();
return NEXT_NAVIGATION_ACTION;
}
return null;
}
The use case is done for train model, which is implemented based on this blog : http://javacollectibles.blogspot.co.uk/2014/10/adf-train-template.html
We need to define a generic next action in the template but the action should be called conditionally, based on whether all the validation checks has been passed on not.
Try using ADFUtils.invokeEl
public String nextAction() {
if (validate()) {
updateModel();
return (String)ADFUtils.invokeEL(NEXT_NAVIGATION_ACTION);
}
return null;
}
Its ain't necessary to hardcode any steps, you can query TaskFlowTrainModel
/**
* Navigates to the next stop in a train
* #return outcome string
*/
public String navigateNextStop() {
String nextStopAction = null;
ControllerContext controllerContext = ControllerContext.getInstance();
ViewPortContext currentViewPortCtx = controllerContext.getCurrentViewPort();
TaskFlowContext taskFlowCtx = currentViewPortCtx.getTaskFlowContext();
TaskFlowTrainModel taskFlowTrainModel = taskFlowCtx.getTaskFlowTrainModel();
TaskFlowTrainStopModel currentStop = taskFlowTrainModel.getCurrentStop();
TaskFlowTrainStopModel nextStop = taskFlowTrainModel.getNextStop(currentStop);
//is either null or has the value of outcome
return nextStopAction;
}
Full code of the sample can be found on the ADF Code Corner.
To navigate by taskflow outcomes you just need to provide exact outcome String as return of your method:
private static final String NEXT_NAVIGATION_ACTION = "next";
public String nextAction() {
if (validate()) {
updateModel();
return NEXT_NAVIGATION_ACTION;
}
return null;
}
Can you verify, you can do it in through phase listener.
Verify you condition in the phase listener and allow it to move ahead if it validates else stop the thread execution.
Below is the sample phase listener code.
public class MyPhaseListener implements PagePhaseListener{
public MyPhaseListener() {
super();
}
#Override
public void afterPhase(PagePhaseEvent pagePhaseEvent) {
if (pagePhaseEvent.getPhaseId() == Lifecycle.PREPARE_RENDER_ID ) {
// DO your logic here
}
}
#Override
public void beforePhase(PagePhaseEvent pagePhaseEvent) {
}
}
I have a function that I derclare beans in my manager and I want to return the value in inputText but when I put the name of my function in the value attribute of inputText tag like this:
<p: inputText value = "#{ticketBean.getLastIndexTache} "/>
this error appear:
Etat HTTP 500 - /pages/test.xhtml #13,106 value="#{ticketBean.getLastIndexTache}": Property 'getLastIndexTache' not found on type com.bean.TicketBean
here is the java code
#ManagedBean(name="ticketBean")
public class TicketBean {
public int getLastIndexTache() {
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
int index = 0;
try {
session.beginTransaction();
String sql = "select MAX(t.IDTICKET) from ticket t ";
Query query = session.createSQLQuery(sql);
if( query.uniqueResult()==null){
index=0;
}else{
index=(int) query.uniqueResult();
index=index+1;
}
} catch (HibernateException e) {
// TODO: handle exception
session.getTransaction().rollback();
e.printStackTrace();
}
return index;
}
}
You should use the bean property in value like
<p:inputText value="#{ticketBean.lastIndexTache}"/>
as JSF by itself adds "get" to the property name. Currently it will look for the method getGetLastIndexTache().
Besides its very bad practice to have logic in any getter as they are called multiple times by JSF. Instead you should make an property like
private Integer lastIndexTache; // +getter/setter
and set the value in a #PostConstruct method:
#PostConstruct
public void init() {
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
// etc....
lastIndexTache = index;
}
The getter would then simply be
public Integer getLastIndexTache() {
return lastIndexTache;
}
and don't forget a setter:
public void setLastIndexTache(Integer newValue) {
lastIndexTache = newValue;
}
Also you should probably put a scope on the bean (for example #ViewScoped).
I have defined a CheckBoc TableColumn as
#FXML private TableColumn<Batch, Boolean> sltd;
And have defined the CellValueFactory & CellFactory
sltd.setCellValueFactory(new PropertyValueFactory<Batch, Boolean>("pr"));
sltd.setCellFactory(CheckBoxTableCell.forTableColumn(sltd));
My problem is i am not able to capture the edit column event for the checkbox. I use the following code:
sltd.setOnEditStart(new EventHandler<TableColumn.CellEditEvent<Batch, Boolean>>() {
#Override
public void handle(TableColumn.CellEditEvent<Batch, Boolean> t) {
//System.out.println("CheckBox clicked.");
}
});
I don't think the check boxes in the CheckBoxTableCell invoke the startEdit(...) method on the table.
The only thing that can happen in an edit is that the boolean property of one of the items in the table changes from true to false, or vice versa. So you can check for this just by listening directly to those boolean properties.
If you want a single listener that will catch changes to any of the properties, you can create an observableList with an "extractor" and register a list change listener with the list. This looks like:
ObservableList<Batch> items = FXCollections.observableArrayList(new Callback<Batch, Observable[]>() {
#Override
public Observable[] call(Batch batch) {
return new Observable[] { batch.prProperty() } ;
}
}
// populate items
table.setItems(items);
items.addListener(new ListChangeListener<Batch>() {
#Override
public void onChanged(Change<? extends Batch> change) {
while (change.hasNext()) {
if (change.wasUpdated()) {
System.out.println("Item at "+change.getFrom()+" changed value");
}
}
}
});
I am trying to do per-keystroke validation in a JavaFX TextFieldTableCell but I do not know how to capture the text-changed events from the embedded TextField control.
If the object in question were simply a TextField, then textField.textProperty().addListener(myChangeListener) would do the trick. TextFieldTableCell also exposes textProperty(), but this property behaves quite differently on TextFieldTableCell. It does not generate change events on a per-keystroke basis. Rather, I see lots of events when the TableView is first displayed, and I see one event each time I begin editing in a cell.
First of all, about textProperty().
Look here to see :
http://docs.oracle.com/javafx/2/api/index.html
TextProperty() is a property of labeled parent class, you will learn nothing from it, because it is not used. It is tricky thing : cell - inheritant of labeled control. TextField, which you see, when start editing, it is a graphic node of cell (graphicProperty()) (as far as I remember documentation).
And, this graphic node is assigned by a text field, only when editing starts.
AFAIK, there is no direct access to editable node.
The way to solve the issue - implement editable cell by your self.
Let me talk to developer, to learn more...
Supposing, you have DataItem class, which contains String, and supposing that TableView has encapsulated data type DataItem, and the only column has the same encapsulated data type, you may use this implementation as basis :
public class TextFieldTableCell extends TableCell<DataItem, DataItem> {
private TextField textField;
public TextFieldTableCell() {
}
#Override
public void startEdit() {
super.startEdit();
if (isEmpty()) {
return;
}
if (textField == null) {
createTextBox();
} else {
textField.setText(new CellCustomStringConverter().toString(getItem()));
}
setGraphic(textField);
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
textField.requestFocus();
textField.selectAll();
}
#Override
public void cancelEdit() {
super.cancelEdit();
setContentDisplay(ContentDisplay.TEXT_ONLY);
}
#Override
public void updateItem(DataItem item, boolean empty) {
super.updateItem(item, empty);
if (!isEmpty()) {
if (textField != null) {
textField.setText(new CellCustomStringConverter().toString(item));
}
setText(item.toString());
}
}
private void createTextBox() {
textField = new TextField(new CellCustomStringConverter().toString(getItem()));
textField.setId(TABLE_EDIT_ID);
textField.setOnKeyReleased(new EventHandler<KeyEvent>() {
#Override
public void handle(KeyEvent t) {
if (t.getCode() == KeyCode.ENTER) {
commitEdit(new DataItem(textField.getText()));
} else if (t.getCode() == KeyCode.ESCAPE) {
cancelEdit();
}
}
});
}
}
I have 3 test web applications, using the same model and controllers, the difference is in JSF session managed beans.
The applications A and C use JSF DataModel to retrieve items :
A JPA Query result set returns a java LIST which is then wrapped in a ListDataModel. The value of this latter is being the items displayed by PrimeFaces dataTable.
The application B uses Java LIST to retrieve items:
A JPA Query result set returns a java List which is being the value of items displayed by PrimeFaces 2.2.1 dataTable.
Sorting and filtering in application B are fully functional and fast, while in application A and C, they are deadly not.
I just want to mention that Filtering in Sorting of other Libraries like Richfaces, OpenFaces, works out of the box using this same code.
The problem also remains in PrimeFaces 3.0.0. Is this a bug?
In App B :
Code:
private List<Customer> items = null;
// remainder of code here
public List<Customer> getCustomerItems() {
if (customerItems == null) {
getPagingInfo();
customerItems = jpaController.findCustomerEntities(pagingInfo.getBatchSize(), pagingInfo.getFirstItem());
}
return customerItems;
}
In App A:
Code:
private DataModel items = null;
public PaginationHelper getPagination() {
if (pagination == null) {
pagination = new PaginationHelper(999999) {
#Override
public int getItemsCount() {
return getJpaController().getChimioCount();
}
#Override // The list of Customers is wrapped in a JSF ListDataModel
public DataModel createPageDataModel() {
return new ListDataModel(getJpaController().findCustomerEntities(getPageSize(), getPageFirstItem()));
}
};
}
return pagination;
}
/**
* this goes for the value attribute in a datatable to list all the Customer items
*/
public DataModel getItems() {
if (items == null) {
items = getPagination().createPageDataModel();
}
return items;
}
In App C:
Code:
private DataModel<Project> items;
// remainder of code here
/**
*The ListDataModel is initialized here
*/
public void init() {
try {
setProjectList(doInTransaction(new PersistenceAction<List<Project>>() {
public List<Project> execute(EntityManager em) {
Query query = em.createNamedQuery("project.getAll");
return (List<Project>) query.getResultList();
}
}));
} catch (ManagerException ex) {
Logger.getLogger(ProjectManager.class.getName()).log(Level.SEVERE, null, ex);
}
projectItems = new LinkedList<SelectItem>();
projectItems.add(new SelectItem(new Project(), "-- Select one project --"));
if (getProjectList() != null) {
projects = new ListDataModel<Project>(getProjectList());
for (Project p : getProjectList()) {
projectItems.add(new SelectItem(p, p.getName()));
}
}
}
Thank you in advance for your help.
This might be a PrimeFaces bug. I have seen some discussion about issues with DataTable sorting when a data model is used. Here is a link to one of the PrimeFaces defects in their tracker.