How to use typeahead with custom widgets like NavSearch - gwt-bootstrap

I'm trying to hook up the typeahead widget to the NavSearch. I would like to do:
<b:Typeahead ui:field="typeahead">
<b:NavSearch ui:field="navSearch"></b:NavSearch>
</b:Typeahead>
And then call typeahead.setWidget(navsearch.getTextBox()) but it throws the error "Typeahead should be set to TextBoxBase childs". I understand this is caused at compile time when I call ui_binder.createAndBindUi(this).
I've been able to workaround this by switching the navsearch for a TextBox which I then style appropriately but I was hoping for a more elegant solution.

The setWidget of Typeahead specifically checks for a widget of type TextBoxBase so i guess there is no alternative!! Sad but Reality!
public void setWidget(Widget w) {
if (!(w instanceof TextBoxBase || w instanceof com.google.gwt.user.client.ui.TextBoxBase)) {
throw new IllegalArgumentException("Typeahead should be set TextBoxBase childs");
}
super.setWidget(w);
}

Related

Dynamic type inferring, or custom VariableScope. How is it done correctly?

I have a scripting system where depending on where the script is executed you have access to different variables. I also want to have inferred types for a type of Auto-Completion for the script editor.
But when the types are inferred during the compile phase, I have no way of giving a Binding which explains to the compilation phase what types those dynamic variables have.
I have currently solved this by:
Not compiling the code with either #TypeChecked nor #CompileStatic but later manually running a subclassed StaticCompilationVisitor on the dynamically typed codebase and manually filling in the StaticTypesMarker.INFERRED_TYPE inside visitVariableExpression() for the dynamic variables that I know exists.
However, this seems like the wrong way to go about it, and I would actually like to work with the VariableScope instead. But it seems to be under rough lockdown inside the VariableScopeVisitor, so it's difficult to pop in a CustomVariableScope that dynamically does the lookups. I have managed to do this with reflection, replacing the VariableScopeVisitor inside CompilationUnit and currentScope and such inside VaribleScopeVisitor. It works, but I don't like working against hard-coded private field names.
This might be a long-winded way of asking: Is there an official way of handling a situation of static typing with dynamic variables? I cannot do this by setting scriptBaseClass for reasons too complex to explain here.
If the question is unclear, please tell me and I'll try to edit in better explanations.
The answer was to add a GroovyTypeCheckingExtensionSupport to a StaticTypeCheckingVisitor and then use visitClass on the first ClassNode of the CompilationUnit.
final ClassNode classNode = this.compilationUnit.getFirstClassNode();
final StaticCompilationVisitor visitor = new StaticCompilationVisitor(this.sourceUnit, classNode);
visitor.addTypeCheckingExtension(new MyGroovyTypeCheckingExtensionSupport(visitor, this.compilationUnit));
visitor.visitClass(classNode);
visitor.performSecondPass();
And create something like the class below:
private static class MyGroovyTypeCheckingExtensionSupport extends GroovyTypeCheckingExtensionSupport {
private static final ClassNode CLASSNODE_OBJECT = ClassHelper.make(Object.class);
public MyGroovyTypeCheckingExtensionSupport(StaticTypeCheckingVisitor typeCheckingVisitor, CompilationUnit compilationUnit) {
super(typeCheckingVisitor, "", compilationUnit);
}
#Override
public boolean handleUnresolvedVariableExpression(VariableExpression vexp) {
final ClassNode type = this.getType(vexp);
if (type == null || type.equals(CLASSNODE_OBJECT)) {
if (vextp.getName().equals("something")) {
this.storeType(vexp, ClassHelper.make(SomeClass.class));
return true;
}
}
return false;
}
}

change label value using value stored at session

i have two jsf pages (home.jsf and employees.jsf) ,
home page has a button that navigates to employees page,
while navigating i store value in session scope
at (Managed bean)
public void putSessionAL(ActionEvent actionEvent) {
FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("key","value");
}
public String navigate() {
return "employees";
}
i want to change Label at employees viewObject from UIHints tab depending on value stored at session using the following groovy expression
adf.context.sessionScope.key
and changed trustMode to trusted but it fires the following exception
oracle.jbo.script.ExprScriptException: JBO-29114 ADFContext is not setup to process messages for this exception. Use the exception stack trace and error code to investigate the root cause of this exception. Root cause error code is JBO-25188. Error message parameters are {0=Employees.FirstName, 1=, 2=oracle.jbo.script.ExprSecurityException}
at oracle.jbo.script.ExprScriptException.throwException(ExprScriptException.java:316)
at oracle.jbo.script.ExprScriptException.throwExceptionWithExprDef(ExprScriptException.java:387)
at oracle.jbo.ExprEval.processScriptException(ExprEval.java:599)
at oracle.jbo.ExprEval.doEvaluate(ExprEval.java:697)
at oracle.jbo.ExprEval.evaluate(ExprEval.java:508)
at oracle.jbo.ExprEval.evaluate(ExprEval.java:487)
at oracle.jbo.common.NamedObjectImpl.resolvePropertyRaw(NamedObjectImpl.java:680)
at oracle.jbo.server.DefObject.resolvePropertyRaw(DefObject.java:366)
One way to do it at the VO UIHint attribute label level will be programmaticaly by doing as follow :
In your VO go to the java tab and add the RowImpl java class
In the VORowImpl Add the following function
public String getMySessionLabel() {
return (String)FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("key");
}
In the Label add the following EL expression :
adf.object.getMySessionLabel()
This technique allow you more control than pure EL, if you want to do more than getting from session for example. In your case pure EL, as you did, should work as well. (Would need to check what is wrong with yours, maybe just missing the
#{adf.context.sessionScope.key}
If you attempt to get your label from a method in viewRowImpl. So this will be executed at least once for each row. I think this solution isn't fit for your case.
anyway ADF as a framework added strong policy and validations in EL in general and especially in version 12.2.x.
The solution for you case as following:
Create new class in model layer which extends oracle.jbo.script.ExprSecurityPolicy class
Override checkProperty method.
#Override
public boolean checkProperty(Object object, String string, Boolean b) {
if (object.getClass().getName().equals("oracle.adf.share.http.ServletADFContext") && string.equals("sessionScope")) {
return true;
}
return super.checkProperty(object, string, b);
}
Open adf-config.xml source and in startup tag set your class ExprSecurityPolicy property.
like:
<startup ExprSecurityPolicy="model.CustomExprSecurityPolicy">

griffon javafx-groovy and fxml?

I tried the samples given in github griffon-master, also I tried the samples of the guide.
I would like to use javafx and groovy.
I would like to use fxml - thought of a scenario as that: fxml to set the stage, and for changes, use the groovy (set adjustment)
It seems that is not possible. I can use ("make it run"): javafx-java, read an fxml (with loadFromFXML), and the bindings are working. If using javafx-groovy, I can read an fxml, but with the javafx-class Loader (load), and bindings are not working (or it seems so).
Is it not possible at this moment, to use javafx-groovy and read-in fxml (via loadfromfxml)?
Could you post some sample code? Here's one example that makes use of the fxml node form GroovyFX
package org.example
import griffon.core.artifact.GriffonView
import griffon.metadata.ArtifactProviderFor
import javafx.scene.control.Tab
import org.codehaus.griffon.runtime.javafx.artifact.AbstractJavaFXGriffonView
#ArtifactProviderFor(GriffonView)
class Tab4View extends AbstractJavaFXGriffonView {
FactoryBuilderSupport builder
SampleController controller
SampleModel model
private AppView parentView
void initUI() {
builder.with {
content = builder.fxml(resource('/org/example/tab4.fxml')) {
inputLabel.text = application.messageSource.getMessage('name.label')
bean(input, text: bind(model.inputProperty()))
bean(output, text: bind(model.outputProperty()))
}
}
connectActions(builder.content, controller)
Tab tab = new Tab('Hybrid')
tab.content = builder.content
parentView.tabPane.tabs.add(tab)
}
}
This can be done. The trick is to make your Controller actions adhere to a stringent set of rules. The tldr is to make sure they return void.
Good:
def void save() {
Bad:
def save() {
The reason is found in the reflective analysis the Griffon framework uses to create its list of action targets. This list is generated in DefaultGriffonControllerClass.getActionNames(), which requires that:
Actions are subject to the following rules in order to be considered as such:
must have public (Java) or default (Groovy) visibility modifier.
name does not match an event handler, i.e, it does not begin with on.
must pass {code GriffonClassUtils.isPlainMethod()} if it's a method.
must have void as return type if it's a method.
value must be a closure (including curried method pointers) if it's a property.
The criteria defined in GriffonClassUtils.isPlainMethod() are as follows:
isInstanceMethod(method)
! isBasicMethod(method)
! isGroovyInjectedMethod(method)
! isThreadingMethod(method)
! isArtifactMethod(method)
! isMvcMethod(method)
! isServiceMethod(method)
! isEventPublisherMethod(method)
! isObservableMethod(method)
! isResourceHandlerMethod(method)
! isGetterMethod(method)
! isSetterMethod(method)
! isContributionMethod(method)
The list of action target names is subsequently used by AbstractActionManager:
#Nullable
private static Method findActionAsMethod(#Nonnull GriffonController controller, #Nonnull String actionName) {
for (Method method : controller.getClass().getMethods()) {
if (actionName.equals(method.getName()) &&
isPublic(method.getModifiers()) &&
!isStatic(method.getModifiers()) &&
method.getReturnType() == Void.TYPE) {
return method;
}
}
return null;
}

monotouch DialogViewController RefreshRequested "System.ArgumentException: You should set the handler before the controller is shown"

I have some problems with getting the RefreshRequested event to work in one of my ViewControllers that implements the DialogViewController:
public CustomViewController () : base (null, true) {
RefreshRequested += delegate {
...
ReloadComplete ();
};
}
I am calling the CustomViewController from another ViewController like this:
var dvc = new CustomViewController();
this.ActivateController(dvc);
The error message I get is "Toplevel exception: System.ArgumentException: You should set the handler before the controller is shown"
Any pointers of what I am doing from here? Thanks
It looks like you do not have a RootElement specified, i.e. it's set to null by your own constructor, so you get warned that the internal state is not ready to set the event.
You should create an empty RootElement with your constructor and, later, add stuff to it (using the property). That should allow you to set the event in your own constructor. E.g.
public CustomViewController () : base (new RootElement (String.Empty), true)
Any pointers of what I am doing from here?
In doubt you can always see the entire source code MonoTouch.Dialog in it's github repository.
From my testing, the only place that you can set the event handler is in the constructor of the ViewController, as that's the only place where you can rely on the fact that the TableView property is null. I've tried the suggestion above of setting the RootElement in the constructor, but then always seem to have a TableView object before I can set the event handler. The problem with setting the event handler in the constructor though is that I don't have any way of resetting the event handler after cleaning it up.

Grails: How to make everything I create Upper Case?

I am currently using CSS to change everything I write to upperCase when I create an entry, but that is not enough. When I save things, the text shown in the text fields is upper case, but the real value that Grails stores stays in lower case.
I am assuming I'd need to change something in the controller or anything.
Maybe transforming the $fieldValue CSS could work??
Any ideas would help!
Thnks!
You could just write setters for your domain object?
class Domain {
String aField
void setAField( String s ){
aField = s?.toUpperCase()
}
}
I think you are asking how to change values on your domain objects to uppercase. If this is not the case please clarify the question.
You have a bunch of options. I would recommend
1) In a service method, before you save, using String.toUpperCase() to modify the appropriate values on the domain object.
or
2) You can use the underlying Hibernate interceptors by defining a beforeInsert method on your domain object, and doing the toUpperCase there. (see 5.5.1 of the grails documentation)
or
3) You could do this client side. However, if it is a "business requirement" that the values are stored as upper, then I recommend doing the translation server side. It is easier to wrap tests around that code....
Using annotations is cleanest approach
import org.grails.databinding.BindingFormat
class Person {
#BindingFormat('UPPERCASE')
String someUpperCaseString
#BindingFormat('LOWERCASE')
String someLowerCaseString
}
Here is link for it: Grails doc for data binding
You can use Groovy metaprogramming to change the setter for all domain class String-typed properties without actually writing a custom setter for each property.
To do this, add something like the following to the init closure of Bootstrap.groovy
def init = { servletContext ->
for (dc in grailsApplication.domainClasses) {
dc.class.metaClass.setProperty = { String name, value ->
def metaProperty = delegate.class.metaClass.getMetaProperty(name)
if (metaProperty) {
// change the property value to uppercase if it's a String property
if (value && metaProperty.type == String) {
value = value.toUpperCase()
}
metaProperty.setProperty(delegate, value)
} else {
throw new MissingPropertyException(name, delegate.class)
}
}
}
}

Resources