Vaadin 7 - Set and get attributes into VaadinSession - authentication

I'm currently using Vaadin 7 for creating a RIA and I'm designing the Login functionality.
The application design is simple:
A UI class performs navigation beetwen different View classes. In particular, the first displayed View is a LoginView class and after a user has been authenticated the UI class redirects the user towards a MainView.
After authentication I'd like to set User data (eg name and surname) into the session and display it always (no matter what specific view) on the top right corner of the Web Application.
As a begginner I read the Vaadin Book and I firstly used the scheme illustrated in chapter 11th https://vaadin.com/book/-/page/advanced.global.html, but it doesn't seem to work as expected, probably because I'm using View navigation scheme.
So I use the following approach:
Once authentication is correctly completed LoginView tries to store user data as a VaadinSession attribute with the following code:
VaadinSession.getCurrent().setAttribute("name", name);
then UI navigates to MainView and tries to get the name of the user with:
VaadinSession.getCurrent().getAttribute("name");
but it gets a null value.
Does anyone know why? I appreciate any help.
Thank you.

I would suggest storing the values on the HTTP session instead.
VaadinServletService.getCurrentServletRequest().getSession().setAttribute("name", name);
and
VaadinServletService.getCurrentServletRequest().getSession().getAttribute("name");

Use the #PreserveOnRefresh annotation on main class which is extends the UI.
Then you can store variables data in the main class.
You can give it from anywhere (in any View) with ((MyUIClass)UI.getCurrent()).getSomeVariable method expression.

I have a guess as to why you get your null value. In most tutorials of modern Vaadin, the navigation pages are created first-thing in the UI as objects. If one of these views instantiated in this process is the MainView. If the label displaying the name sets the String in the constructor of the class, the line:
label.setValue(VaadinSession.getCurrent().setAttribute("name", name)); will be null is the attribute has not been set by the login function yet.
You need to either update the label showing the user string in the #override enter() function, or handle it otherwise.

Related

Sitefinity Feather custom action form

I've got the following problem: in Sitefinity (9.1, Feather) I need a form, which can call 3rd party API (Mandrill) once submitted.
As far as I understand, I need some kind of custom widget or something.
Any help would be very appreciated.
Thanks
I would start here. You don't necessarily have to create a separate class library for creating the custom Feather widget (you can just put it in the SitefinityWebApp web project), but you can if you like. With Feather/MVC widgets you basically get a Controller and View, with an optional Model class to play with too.
In your scenario, you'd probably have a Controller with two actions: Display the form, and handling the form submission. In your form submit action you'd then call Mandrill to submit the data (or do whatever it is you need to do). In your Controller you're in C# purely, so you can do whatever you like there.

Accessing Placeholder From Widget MVC Controller Code

I'm using Sitefinity 8.1 in MVC mode. I have an MVC page template with an assortment of placeholders.
I've created an MVC widget designed to be used multiple times on a page. From within the controller code I would like to be able to find out the name of the placeholder the widget is sitting in so that I may make adjustments to the widget on-the-fly.
Is this possible?
Thank you.
Instead of relying on the name of a placeholder, which I think is prone to errors, why not just introduce a public property in the controller?
e.g.
public string Message {get; set;}
Then when you drop the widget in placeholder1 you can edit its properties and put whatever you want in the Message property.
Similarly, when you drop the widget in placeholder2 - you edit its properties and set something else in the Message property.
The controller will do different things depending on the value of the property - this way it is much cleaner than relying on placeholder name.
Do the adjustments need to be server side? If not just make changes based on CSS selectors. If server side I'll have to get back to you.

selenium Page factory handle different elements for same page for different users

I have a simple question. I 'm sure many of us might have got into the same situation. I am using page object pattern. Below are the steps i do along the navigation.
Login to my application as one type of user.
Click some link to go form page.
On form page , fills the fields and submit
Logout
On 3) the form object page shows some different input fields depending on the type of the user, which i need to interact with. So how do i deal it within the same page object. Has anybody got into the same situation and have found some decent way of doing this ?
I know it a simple automation script not a Java project where we should be using all oops concepts but still I would go with the following:
Create a parent page class containing the common WebElements and methods.
Create child classes with elements and methods specific to that customer.
In the test, pass a parameter which specifies the type of customer and call the appropriate child class.
If you don't want any of this inheritance stuff, you can also try the following.
Create a page class with elements for all types of customers.
Create generic methods which can take a parameter customerType and perform operations like if customerType==1 do these operations else do these.
Another solution which popped up in my mind, assuming that all fields for a particular customer are mandatory, is as follows.
Create a common class for all elements.
Create a generic method in the page class which follows the condition, if this element is present then enter value.
If you understand the concept of Page object model then this questions will be more clear to you. Yes, inheritance is a big factor here. I suggest you read through this to see how a real page object model should work. And, solution of #3 question is as simple as UI mapping. Something like
#FindBy(how = How.NAME, using = "q")
private WebElement searchBox;
for each elements or similar implementation.
For a complete page object you should map all the elements not depending on the users. The reason being, every time you call that class it will be instantiated and all the mapped elements as well. There is no need of dynamically load the elements If any elements are not used or hidden on the page those will be available and you will not be using them anyway

DNN get params in view are not available in edit

I am creating a dnn module. The content depends on the param in the url.
I want to be able to edit this content in the 'edit content' mode. However when i go to edit content the param in the url is no longer accessible because it is the parent document. How do i go about passing this value from the view.ascx to the edit.ascx?
Try storing the param in cookies or localstorage. Then you should be able to access it. Of course the user will be able to modify it but you can do a check that the user has not modified it by storing a server side encryption or somthing like that.
A workaround is to have a field where the user enters this parameter. But i know this isn't a very good solution. I am guessing that you will have to override the dotnetnuke core to do this (yes i know it sucks).
I hope I am understanding the question properly.
To pass parameters from your View to Edit controls, you should first make sure they are registered properly in the module definition. You default View should have an empty controlkey and your Edit should be registered with a control key, for example "addedit".
When creating a link between your view control and edit control, use the EditUrl() method of PortalModuleBase. When passing a parameter, for example an id of the item you want to load into your edit control, you can pass them as arguments in the EditUr method.
Example (in my view.ascx.cs):
lnkEdit.NavigateUrl = EditUrl("id", "16", "addedit");
This will assign a module view link to the edit.ascx (assuming the controlkey in the definition is addedit) passing in a url parameter "id" with value 16.
See my DNN Module Views tutorial for a complete lesson on how to do DNN module views and navigation.
http://www.dnnhero.com/Premium/Tutorial/tabid/259/ArticleID/204/Introduction-and-Module-Definition-basics-in-DNN-Part-1-6.aspx

ExtJS 4 MVC multiple instances of views and sub/child controller difficulties

I have encountered a problem with the MVC pattern in ExtJS 4. At least, I think I have. Having approached multiple people with this question, and having posted numerous times in the Sencha forums, I am now turning to a broader audience in hopes of getting either a light bulb or a confirmation.
Problem
Your application has the ability to open many different views, some of which themselves are mini-applications. Additionally, a user may wish to have multiple concurrent copies of a view open.
This application is a single-page client-side Javascript application.
The ExtJS 4 MVC model expects you to define all of your controllers in your Application class. These controllers are then initialized when the Application loads. Controllers keep track of views, models and stores.
When you initialize controller A multiple times, say to create more than one copy of a view, you end up with two views that reference the same data stores, and functionally send duplicate events to the Application event bus.
I have refactored my application by adding new prototype methods to Component and Controller to allow for both a) sub controllers (some of my controllers were getting pretty huge) and b) defining stores specifically for the view they work with. The models can still be defined on the controller, just for ease of use by handlers if you need to do something like grab a record from the server.
Question
My understanding of MVC would lead me to believe that models more directly relate to the View than then Controller. I asssssume that ExtJS 4 decides to attach stores (which I think can be seen as wrappers to a more classic model) to Controllers for purposes of encouraging re-use of loaded data, and to optimize away from having many copies of the same class instantiated. It seems to me, however, that one cannot do this if one intends to have many instances of a view available to the user. To my thinking, having many instances is an important option in an OO framework, hence why I have bucked the trend and implemented prototypes on some of the Ext base classes. (Thank you Ext.implement!).
Is there any way to have multiple concurrent instances of a view with different data loaded into them using the out of the box MVC classes and making uses of the provided setters, getters, etc?
I was faced with a similar problem:
Consider a tabpanel for a CRM type application which opens new instances of a view for each client. And say that tab view contains 3 or 4 row-editing gridpanels for interacting with different collections of data relating to that client.
The solution I came up with was based on this from the Sencha forums. In a nut shell, almost all events that are dispatched from a view contain a reference to the view itself. The handlers in my controller's control function all use these to get a reference to the correct view instance.
For dealing with the multiple instances of the same store needed for this, I took this to heart from that post:
For the Store instance on the view or a global one... depends on the
needs. If you are going to use globally then make it global. If you
only are going to need it on the view then put it on the view. MVC is
not a law, you can change it to fit your needs. Technically the
Controller part of MVC is suppose to be the middle man between the
View and Model parts but sometimes that's just not needed. I create
the Store in the view 95% of the time. I'll give you an example...
If you have a Store for products, you probably only need to reference
that Store in your Grid. That usually isn't needed for other parts of
the application. However, if you have a Store to load countries, I
often need it globally so I only have to load it once and can then
set/use that Store in several views.
So I just created the needed store's that relate to a view instance specifically, inside the view's initComponent method. The application did have a few global stores that I created as store classes following the MVC recommendations. It worked out nicely to encapsulate the view instance stores inside the view. Then I only needed one instance of the controller.
To answer your question specifically, currently, there is no ExtJS official recommendation or config for dealing with multiple instances of the same view that use the same store constructor. I have spent some time looking for something like that and the best I have found was this recommendation from one of their forum moderators.
I don't think you ever need more than 1 instance of a controller, regardless of how many views/models you have. See functional example here:
http://whatisextjs.com/extjs-4-extension/fieldset-w-dynamic-controls-7
This can be done, reasonably easily. You need to follow a few rules:
load your controllers at app startup. Don't unload them. Don't worry about the memory or time, it's pretty small even for hundreds of controllers, as long as you minimize and concatenate your js.
Never use the refs or views properties of a controller. You are going to use one instance of a controller, but multiple instances of views, so you never want a reference to a view.
only use event listeners in controllers. You are only going to listen to events on your views. You can always get a (temporary) reference to a view in the event handler via the "cmp" parameter in the handler.
To "launch" a view, create it and add it to another view. To destroy it, destroy it. You don't use a controller to launch a view. You can use the afterrender and beforedestroy events in the controller to add logic.
In ExtJS' MVC the controller is a Singleton for you view. I like how DeftJS thinks about MVC. Each instance of a view has an own instance of a controller. In this way you can put all "controlling rules" in a controller for a particular part of your view, and this will be instantiated only when the view opens.
I did not have any experience how I could use multiple Defts JS apps in the same project.
Of course. What led you to believe otherwise?
Here is an example of creating a custom View which extends from a Window component. You can run this method many times from the same controller and each time you will get a new instance of a View.
"this" refers to a controller that code runs in:
this.getRequestModel().load(requestID,{ //load from server (async)
success: function(record, operation) {
var view = Ext.widget('requestEdit',{
title: 'MyRequest '+requestID
});
var form = view.down('form');
form.loadRecord(record);
}
});
How do you create your views? I see no reason why you cannot pass a different store or config data to every object. Some code samples would help for what exactly you are doing. For example, we have a similar sounding application, and everything is done with extensions. So, if we need a grid, we run
Ext.define('MyApp.grids.something',{
extends:'Ext.grid.panel'
//...
These classes are predefined. Then, when a controller or view is loading this grid, they are using
var grid=Ext.create('MyApp.grids.something',{id:'unique',store:mystore});
As you can see, we can pass in different config options to the same grid each time it is created. We can treat this exactly as you would treat
Ext.create('Ext.grid.Panel');
Except of course that we make some options predefined, and some non-override-able, and so on.
Hope this helped.
Check out this post. The idea there is to take some configuration (like store and itemId) from view config and put it into the viewport config:
// .../app/view/Viewport.js
Ext.define('MyApp.view.Viewport', {
// ...
items: [
// ...
{ xtype: 'testview', store: 'Store1', itemId: 'instance1' },
{ xtype: 'testview', store: 'Store2', itemId: 'instance2' }
]
});
The problem with store will be solved, obviously. Different itemIds will enable you to handle events properly.