How to reuse the old views in JSF - jsf

I have concurrent view limit exceeded problem in icefaces. It supports not more than 50 views per one session. In the process of finding issue with the code, I have doubt regarding view reusability.
Consider the below cases.
Case 1:
Returning empty string would recreate a view though the user stays on the current page, as shown below.
public String submit(){
//...
return "";
}
Case 2:
But, below code would reuse the old view.
public String submit(){
//...
return null;
}
Case 3:
I think, below code snippet would also do the same. Correct me here, if I am wrong.
public String submit() {
// ...
return "viewId?faces-redirect=true";
}
What is the difference between case 2 and case 3?
UPDATE:
I have tested an application with JSF 1.2, it allows all the 3 cases, as mentioned above.
In my bean I am using the following code
public String saveData() {
//String returnString = "";//Case 1 : works - user stays on the same page
//String returnString = null;//Case 2: works - user stays on the same page
// Case 3:
String viewId = FacesContext.getCurrentInstance().getViewRoot().getViewId();
System.out.println("view id = "+ viewId);
String returnString = viewId+"?faces-redirect=true";
System.out.println("return string = "+ returnString);
return returnString;
}
I have deployed the above application in jetty.In the above example, every time the method saveData() is called, the user stays on the same page with his filled in data in input fields, I infer from this that, its reusing the old page or view(I am not clear with a view in JSF). This is happening in all the 3 cases, so not sure of the exact difference, How to experience this difference? What is a view from JSF perspective?

Related

Save values between page navigation in Windows Phone

How do I save values between page navigation in windows phone,
suppose I have two text blocks in my one phone application page, and they contains dynamically changing values every time, now suppose my text block have value "abc" and for some reason I go back to previous page, now when I get back on my page, I want that text block having value "abc". How to do it??
There are several methods available
IsolatedStorageSettings
Save
IsolatedStorageSettings settings = IsolatedStorageSettings.ApplicationSettings;
// txtInput is a TextBox defined in XAML.
if (!settings.Contains("userData"))
{
settings.Add("userData", txtInput.Text);
}
else
{
settings["userData"] = txtInput.Text;
}
settings.Save();
Read
if (IsolatedStorageSettings.ApplicationSettings.Contains("userData"))
{
txtDisplay.Text +=
IsolatedStorageSettings.ApplicationSettings["userData"] as string;
}
PhoneApplicationService.Current.State
PhoneApplicationService.Current.State["param"] = param
and on other page we can get it like this.
var k = PhoneApplicationService.Current.State["param"];
Define two static variable in your App.xaml.cs
public static valueOne = string.Empty;
public static valueTwo = string.empty;
//Assign textbox value to variable on page leaving event
protected override void OnNavigatingFrom(System.Windows.Navigation.NavigatingCancelEventArgs e)
{
if(!string.IsNullOrEmpty(txtBoxOne.Text))
App.valueOne = txtBoxOne.Text;
if(!string.IsNullOrEmpty(txtBoxTwo.Text))
App.valueTwo = txtBoxTwo.text;
}
//Get value from page load
protected override void OnNavigatedTo(NavigationEventArgs e)
{
if(!string.IsNullOrEmpty(App.valueOne))
string valueFirst = App.valueOne;
if(!string.IsNullOrEmpty(App.valueTwo ))
string valueTwo = App.valueTwo ;
}
There are various approaches to solve this.
Common thing is using a Static Class, which holds static properties and binding it to your View.

JSF navigating to a different view programatically

My application has a save and retrieve function. I have the save/retrieve working in that the objects are saved to a database and retrieved correctly. However, in my retrieve landing page, depending on the state of the saved application, I either want to validate some details with the user, or silently navigate to the last accessed view. The latter is where I'm having trouble.
We're using spring beans and in my SaveAndRetrieve page bean I have:
#PostConstruct
public void initialise() {
caseNotFound = false;
caseReference = saveAndRetrieveActionHandler.getRequestedCaseReference();
LOGGER.debug("Retrieve initialise. Case ref is {}", caseReference);
if (caseReference != null) {
try {
saveAndRetrieveActionHandler.retrieveApplicationByCaseRef();
LOGGER.debug("Retrieve initialise - case found");
final NavigationOutcome outcome = saveAndRetrieveActionHandler.getLastAccessedView();
if (outcome.getApplicationState() == ApplicationState.QUOTE) {
LOGGER.info("Quote retrieved, navigating to view");
// HERE IS WHERE THE TROUBLE LIES! THIS DOESNT WORK
FacesUtils.setNextViewNavigation(outcome.getViewId());
}
} catch (final FrameworkException fe) {
LOGGER.debug("Exception caught {}", fe);
caseNotFound = true;
}
}
}
outcome is an enumeration containing amongst other things the view I need to navigate to, and the application state (another enumeration). If applicationState is quote, I want to silently navigate. For all other applicationStates I want to challenge the user to verify them.
My facesUtils method is:
public static void setNextViewNavigation(final String p_lastAccessedViewId) {
if (p_lastAccessedViewId != null) {
getCurrentViewRoot().setViewId(p_lastAccessedViewId);
}
}
I've also tried calling this method
public static void navigateToOutcome(final String p_outcome) {
final FacesContext context = getFacesContext();
final NavigationHandler navigationHandler = context.getApplication().getNavigationHandler();
navigationHandler.handleNavigation(context, null, p_outcome);
}
Despite my efforts, I'm seeing the landing page wheras I want to silently navigate to the saved page
Basically I want to abort the current lifecycle and reset the viewroot to the saved view. (note I am not saving the component tree itself, just my business objects)
One more piece of information, this is jsf1.2, but with facelets. I cannot use any jsf2 specific functionality, nor can I use any third party JSF extenstions.
Help please!
We solved this by using a ui:include tag with the src attribute being a jsf method that determines the name of the page to navigate to.

Disable TableRow based on data

I face a problem with TableView in JavaFX 2.1. I want to disable TableRow based on data.
For eg.:
public class RowData() {
private String name;
private boolean used;
public String getName(){
return this.name;
}
public void setName(String name){
this.name = name;
}
public boolean isUsed(){
return this.used;
}
public void setUsed(boolean used) {
this.used = used;
}
}
In program:
public class ViewController implements Initializable {
#FXML
private TableView<RowData> tableAttribute;
public void initialize(URL location, ResourceBundle resources) {
List<RowData> data = new ArrayList<RowData>();
// datatype col
TableColumn<DataRow, String> attNameCol = new TableColumn<DataRow, DataRow>(
"Name");
attNameCol
.setCellValueFactory(new PropertyValueFactory<DataRow, String>(
"name"));
attNameCol .setMinWidth(110.0);
tableComponent.getColumns().addAll(attNameCol );
loadData(data);
tableAttribute.setItems(FXCollections.observableList(data));
//I want to disable row which used = true, enable otherwise
}
}
How can I do to achieve that?
Example strategies for disabling a row based on the value of a row field:
Use a rowFactory which renders the row content as disabled as needed.
After the table has been shown, lookupAll the TableRows and render them as disabled as appropriate.
I create a sample app which uses the second principle.
The key logic in the sample is the following code executed after the table has been shown on an active stage, which enables and disables rows as needed (as well as applying style classes to each row so that they can be styled separately if required). Note, for this approach, if the rows in the table change or are reordered, then the lookup and enabling/disabling code will have to be re-run over the table after the table has been re-rendered so that the table is correctly styled and has the correct disabled properties for rows.
// highlight the table rows depending upon whether we expect to get paid.
int i = 0;
for (Node n: table.lookupAll("TableRow")) {
if (n instanceof TableRow) {
TableRow row = (TableRow) n;
if (table.getItems().get(i).getWillPay()) {
row.getStyleClass().add("willPayRow");
row.setDisable(false);
} else {
row.getStyleClass().add("wontPayRow");
row.setDisable(true);
}
i++;
if (i == table.getItems().size())
break;
}
}
When using a fxml controller the lookupAll return 0 "TableRow" nodes. It seems that after table.setItems(data) when doing lookup rows are populated why ?
Before answering this, I will note that using a rowFactory is really the preferred solution to this question, rather than using a lookup. Some of the reasons why will become apparent in the rest of this answer. For a sample of a rowFactory approach, please refer to this linked sample code by james-d.
A lookup is a CSS operation and it requires that css has been applied to the nodes being looked up. To explicitly apply css, call applyCss after the node has been placed in a scene.
A difficulty with a controller is that, in the initialize call, the node might not yet be in a scene. To work around that issue you can apply the following pattern:
Pane parent = (Pane) table.getParent();
parent.getChildren().remove(table);
Scene applyCssScene = new Scene(table);
table.applyCss();
table.layout();
applyCssScene.setRoot(null);
if (parent != null) {
// Assumes that the original order in the parent does not matter.
// If it did, you would also need to keep track of the child list position.
parent.getChildren().add(table);
}
. . .
// perform css based lookup operation on the table.
This creates a dummy holder scene with the table in it, applies CSS (after which CSS based lookup operations will work) and then removes the table from the scene so that you can add it to the real scene at a later time and afterwards places the table back in it's original parent. As you may have noted this is a bit confusing. Note that I didn't try to actually execute the CSS application process outlined above in an example application with an FXML controller, however I believe it will work.
In the sample app I linked which uses lookups, the above complexity is not needed because the lookup is made after the stage containing the table has been initially shown. The stage.show() call implicitly runs layout and css application passes on the scene to be shown (it needs to do this to determine the initial size of the stage based upon the calculated size of the initial scene and perhaps for other reasons).

ContentManager.Create does nothing

I am trying to build a service in Orchard that allows me to create content through a custom form on a page. The service and the content type definitions look fine to me, but somehow, eventhough I don't get any errors or other signs in the Orchard log files, creating new content using the IContentManager does nothing for me.
Parts involved
The controller accepting the form values
[HttpPost]
public ActionResult Create(CreateSopViewModel viewModel)
{
if(!ModelState.IsValid)
{
var shape = _shape.CreateContent();
shape.Header = _shape.Parts_Title(Title: "New item");
// Add the original fields to the shape.
shape.Title = viewModel.Title;
shape.Description = viewModel.Description;
shape.InitialComments = viewModel.InitialComments;
return new ShapeResult(this, shape);
}
// Store the new procedure in the database
_service.CreateContentItem(
viewModel.Title,viewModel.Description,viewModel.InitialComments);
// Redirect the user back to the homepage.
return Redirect("~/");
}
The service that contains the CreateContentItem method:
public void CreateContentItem(string title, string description, string initialComments)
{
// Initialize a new content item based on the SOP type
var customPart = _services.ContentManager.New<MyCustomPart>("CustomContentType");
customPart.Description = description;
customPart.Identifier = BuildIdentifier(title);
customPart.ContentItem.As<TitlePart>().Title = title;
_services.ContentManager.Create(customPart.ContentItem);
}
The content part + record
public class MyCustomPart: ContentPart<MyCustomPartRecord>
{
[Required]
public string Identifier
{
get { return Record.Identifier; }
set { Record.Identifier = value; }
}
[Required]
public string Description
{
get { return Record.Description; }
set { Record.Description = value; }
}
}
public class MyCustomPartRecord: ContentPartRecord
{
public virtual string Identifier { get; set; }
public virtual string Description { get; set; }
}
The migration
SchemaBuilder.CreateTable(typeof(MyCustomPartRecord).Name, table => table
.ContentPartRecord()
.Column<string>("Description")
.Column<string>("Identifier"));
ContentDefinitionManager.AlterPartDefinition("StandardOperationalProcedurePart", builder => builder
.Attachable(true));
ContentDefinitionManager.AlterTypeDefinition("CustomContentType", builder => builder
.DisplayedAs("Custom Content Type")
.WithPart("TitlePart")
.WithPart("MyCustomPart")
.Creatable(true));
Question
Again, I don't get any errors, not in the log and not in Visual Studio. However, my new content item doesn't get created or at least, I can't see it in the admin section of the site under Content.
What is going on and how can I debug this behavior?
I had a similar problem, which was solved when I used the overloaded Create method taking a VersionOptions enum value:
content.Create(customPart.ContentItem, VersionOptions.Published);
This should work even if the content item is not creatable, as mine isn't.
I had a similar issue. In my case the item did appear eventually, but not right away.
The solution for me was to do:
_contentManager.Flush();
I was having this issue, in my case it was that I actually had an error in the database (trying to put 100+ characters into a field that would only hold 100!).
I found the error I was getting (null id in Orchard.Indexing.Models.IndexingTaskRecord entry (don't flush the Session after an exception occurs) ), actually masked the issue. I had to go hunt in the logs to find the real problem.
So anyway, my advice is if you see that contentmanager.create seems to be doing nothing, and any errors don't seem to help, check the logs carefully. They can be found in the logs sub-folder of the appdata folder in the main Orchard.Web project. Because as I've found in the last 48 hours, often the answer is there.

Trying to pass checkbox list enum value to my view

Just trying to do some quick and dirty testing. I am passing fake data through my controller to a view just to see how the UI looks.
In my controller which I set up just to "test" this I have, for example:
MyViewModel = new MyViewModel
{
MyModel= new Models.MyModel
{
FirstName = "Homer", //This works
SomeDecimal = 10000, //This works
SomeRadioButton = Models.MyModel.Enum.Selection, //This works
SomeCheckBox = Models.MyModel.OtherEnum.OtherSelection, //This doesn't
}
}
I am getting the Cannot implicitly convert type ... to 'System.Collections.Generic.List<string>' error.
My radio buttons and check boxes share similar convention for using enums, but the checkbox uses public List<string> SomeCheckBox { get; set; } whereas radio buttons use public Enum? SomeRadioButton { get; set; }
Please note, I am not using a testing framework. I am just trying to figure out quickly how to pass some fake data to see how the UI is shaping up. Can anyone share a sample of how to accomplish what I want (to pass a checkbox value so my UI can show data that would have been selected by a user)?
The other problem I forsee is in passing more than one selection from the checkbox, but once I get the code down I think I should be able to figure that out.
Thanks.
Your error message makes total sense. Try this
var testViewModel = new TestViewModel
{
SomeCheckBox = new List<string> {TestViewModel.RadioButtonValues.Value1.ToString() }
};

Resources