Incorporate fields from MegaProtoUser into a wizard screen - scala

I'm just starting out with scala and lift and am a bit stuck regarding incorporating form fields from MegaProtoUser into a wizard screen.
I have the following MegaProtoUser code:
object User extends User
with MongoMetaRecord[User]
with MetaMegaProtoUser[User] {
override def skipEmailValidation = true
}
class User private () extends MongoRecord[User]
with MegaProtoUser[User] {
def meta = User
//protected methods ...
}
And my wizard setup looks like the following:
object SignupWizard extends Wizard {
object completeInfo extends WizardVar(false)
val person = new Screen {
//Incoroporate MegaProtoUser fields here ...
override def nextScreen = {
business
}
}
val business = new Screen {
val business = field("Business name","")
}
def finish() {
S.notice("Thank you for registering!")
completeInfo.set(true)
}
}
I want to incorporate some selected (not all) fields from my MegaProtoUser class into the person screen but do not now how to do this with the methods available to both. Any help is much appreciated.

AbstractScreen's addFields method can add individual fields, as well as adding all the fields from a Record object. This works on both LiftScreen and Wizard's Screen.
// assuming you just want to create a new user
object user extends WizardVar(User.createRecord)
val person = new Screen {
// addFields(() => user.is) would add all fields
addFields(() => user.is.email)
addFields(() => user.is.password)
addFields(() => user.is.timezone)
override def nextScreen = {
business
}
}

Related

NatTable - how to implement custom CopyDataToClipboardSerializer

in CopyDataToClipboardSerializer I need to override copiedCells variable.
I do use NatTableFactory.class where I create table, register new CopyDataCommandHandler, override table style and so on. But I do not know how to override CopyDataToClipboardSerializer. Or should I register new one and create own class?
I don't know your NatTableFactory class. So I am not sure what you are doing inside that class.
If you need a custom serializer to for example replace line breaks in a text to a space to avoid breaking the table structure, you need to create a custom implementation and use that.
class MyCopyDataCommandHandler extends CopyDataCommandHandler {
public MyCopyDataCommandHandler(SelectionLayer selectionLayer, ILayer columnHeaderLayer, ILayer rowHeaderLayer) {
super(selectionLayer, columnHeaderLayer, rowHeaderLayer);
}
#Override
protected void internalDoCommand(CopyDataToClipboardCommand command, ILayerCell[][] assembledCopiedDataStructure) {
ISerializer serializer = new MyCopyDataToClipboardSerializer(assembledCopiedDataStructure, command);
serializer.serialize();
}
}
class MyCopyDataToClipboardSerializer extends CopyDataToClipboardSerializer {
public MyCopyDataToClipboardSerializer(ILayerCell[][] copiedCells, CopyDataToClipboardCommand command) {
super(copiedCells, command);
}
#Override
protected String getTextForCell(ILayerCell cell) {
return super.getTextForCell(cell).replace('\n', ' ');
}
}
Then register the custom MyCopyDataCommandHandler like this if the headers should be exported too:
CopyDataCommandHandler copyHandler =
new MyCopyDataCommandHandler(
selectionLayer,
columnHeaderDataLayer,
rowHeaderDataLayer);
gridLayer.registerCommandHandler(copyHandler);

How to pass variable from VaadinServlet to UI?

I'm new to Vaadin. I want to use it to build admin backend. As I am familiar DI (Guice), I would like to inject dependencies into servlet. However, I don't know how to pass from servlet to UI layer. Below is my sample codes:
#Singleton
#VaadinServletConfiguration(productionMode = false, ui = classOf[LoginUI])
class TestServlet #Inject()(userDAO: UserDAO) extends VaadinServlet with LazyLogging {
//How to userDAO to LoginUI?
override def servletInitialized(): Unit = {
}
}
#Theme("valo")
class LoginUI extends UI with LazyLogging {
override def init(request: VaadinRequest) = {
logger.debug("Init Login UI")
val content: VerticalLayout = new VerticalLayout
setContent(content)
val label: Label = new Label("Hello, world!")
content addComponent label
content addComponent new Button("Click Me!",
new ClickListener {
override def buttonClick(event: ClickEvent) =
Notification.show("The time is ")
})
}
}
I see that although it is UI, it acts like controller layer, so I think it does not anti-pattern when doing that. I find it even more difficult to inject things into UI. However, if I can inject directly into UI, it would be better.

Print data received by REST call when using #Resource in Grails

Following along with groovies docs on REST, i've setup a model like so:
import grails.rest.*
#Resource(uri='/books')
class Book {
String title
static constraints = {
title blank:false
}
}
I'd print out the parameters I receive when creating and saving. Is there away to override these methods created by the #Resource(uri='/books') annotation? Or handle the annotation a closure or something to do this?
I think you may have 2 choices if you wish to have a default RESTful interface and modify it somewhat for your needs.
Use the $ grails generate-controller [Domain Class Name] command that will generate the appropriate controller and change the generated file as needed.
Create a Book controller and extend the RestfulController; then override the default methods with the #Override annotation, print/log the params, and then call the matching super method.
import grails.rest.RestfulController
class BookController extends RestfulController {
static responseFormats = ['json', 'xml']
BookController() {
super(Book)
}
#Override
def save() {
println params
super.save params
}
#Override
def update() {
println params
super.update params
}
}

How to signal/notify super-controller of change in sub-controller?

In JavaFX, how do you model the following:
I show a List of Customers in a Scene. On the left side there is a table on the right side (contentPane) the currently select customer's details are shown.
(Relevant part of) Main-Controller:
#jfxf.FXML
protected def newButtonPressed(): Unit =
{
contentPane.getChildren.clear
contentPane.getChildren.add(FXMLLoader.load(GUILoader.load("customers/form.fxml")))
}
There is a Button to add a new Customer. Upon clicking this button instead of opening a Popup, I replace the "details"-part of the scene and add a form there.
Now for this form (designed - like the rest of the GUI - in the SceneBuilder and saved as .fxml) I use another controller.
class Form extends Main with jfxf.Initializable
{
#jfxf.FXML
private var foreNameTextField: jfxsc.TextField = _
#jfxf.FXML
private var lastNameTextField: jfxsc.TextField = _
#jfxf.FXML
private var ageTextField: jfxsc.TextField = _
override def initialize(url: URL, resourceBundle: ResourceBundle): Unit =
{
}
#jfxf.FXML
protected def ok(): Unit =
{
// TODO validation
val newPerson = new Person(-1, foreNameTextField.getText, lastNameTextField.getText, ageTextField.getText.toInt)
// Save to DB
// Close whole form
}
}
When I'm done with filling in a new customer's detail I click on another button (that calls ok()) and save it to a database.
What I want to do now is close the form and replace it with the detail-form.
Something like calling a protected method in the main-controller like:
protected def clearDetails(): Unit =
{
contentPane.getChildren.clear
contentPane.getChildren.add(savedOldDetails)
}
won't work of course. (Will throw a runtime-exception because there is no contentpane in the sub/form-controller (even if I make it protected)
In Qt (C++) I'd use signals/slots and connect them accordingly.
Seems like in JavaFX there is nothing the like. How am I supposed to share such information?
Do I need to create a "super-controller" for the contentPane?
(I don't know Scala, so I'll write this in Java, hope that is ok).
You can define an observable property in the Form controller, and observe it when you load the form from the main controller:
public class Form implements Initializable {
private final ObjectProperty<Person> person = new SimpleObjectProperty<>(null);
public ObjectProperty<Person> personProperty() {
return person ;
}
public final Person getPerson() {
return personProperty().get();
}
public final void setPerson(Person person) {
personProperty().set(person);
}
// ... code you had before...
#FXML
protected void ok() {
Person person = new Person(-1, foreNameTextField.getText(), lastNameTextField.getText(), ageTextField.getText());
// save to DB...
personProperty().set(person);
}
}
Now in your main controller, load the form as follows:
#FXML
protected void newButtonPressed() {
contentPane.getChildren().clear();
FXMLLoader loader = new FXMLLoader(getClass().getResource("customers/form.fxml"));
Parent form = loader.load();
Form formController = loader.getController();
formController.personProperty().addListener((obs, oldPerson, newPerson) {
if (newPerson != null) {
// clear form, etc, e.g.
clearDetails();
}
});
contentPane.getChildren().add(form);
}

Eclipse refactor overridden method into final and abstract parts

I have a method which i'd like to refactor
Basically i want to split the top level method in a abstract and a final part.
The method in question is overridden in quite a few places where additional functionality is added, but eventualy the super call is always made.
The code now basically look like:
(not all Extending classes override but those that do, do it this way)
class Base {
public Object getStuff(String key) {
out = //code to get data from the Database.
return out
}
class Extended1 extends Base {
public Object getStuff(String key) {
if("some_non_db_value".equals(key)) {
return "some custom stuff";
}
return super.getStuff(key);
}
}
What i'd like as a result would be something like:
class Base {
public final Object getStuff(String key) {
out = getCustom(key);
if(out != null) {
return custom;
}
out = //code to get data from the Database.
return out
}
public abstract Object getCustom(String key);
}
class Extended1 extends Base {
public Object getCustom(String key) {
if("some_non_db_value".equals(key)) {
return "some custom stuff";
}
return null;
}
}
I was hoping there would be a refactor action (or partial refactor) to get to (or closer to) this point.
I would first rename getStuff() to getCustom() which would take care of all the extended classes. Then changing the Base class should be relatively easy.