New style for a new GWT component - gwt

I am using SmartGWT 2.4, and I have two types of TabSet(s), each one has a different look and feel, and I am facing a problem implementing that.
The new TabSet has been implemented as the following :
public class MainTabSet extends TabSet{
public MainTabSet(){
super.setStylePrimaryName("MainTabSet");
build();
}
private void build(){
setMargin(6);
setWidth100();
setHeight100();
setStyleName("nt-main-tabset");
Tab inboxTab = new Tab("Inbox");
inboxTab.setPane(new InboxPane().get());
}
}
based on the last paragraph (Multiple looks for the same component type) here :
I've defined a new class that holds the same primary name I used above :
isc.defineClass("MainTabSet", "TabSet");
and then I've added some properties to it :
isc.MainTabSet.addProperties({
tabBarThickness:100,
scrollerButtonSize:100,
pickerButtonSize:100,
symmetricScroller:false,
symmetricPickerButton:false,
scrollerSrc:"nothing",
pickerButtonSrc:"nothingg",
closeTabIconSize:100
})
The code above has been written at the top of section 6 (TabSet) in load_skin.js file.
Now, I am still getting the same old TabSet look and feel in MainTabSet.
my Questions now are :
did I follow the right steps to achieve my goal ?
how could I consider new classes to some sub elements of TabSet -like TabBar- but only for the new component (MainTabSet)?
Thank you guys.

According to last paragraph of the article that you have mentioned, you were suppose to call setScClassName("MainTabSet") to apply smartClient's js class to your java class. I think that should be something like this:
public class MainTabSet extends TabSet{
public MainTabSet(){
setScClassName("MainTabSet");
build();
}
private void build(){
setMargin(6);
setWidth100();
setHeight100();
setStyleName("nt-main-tabset");
Tab inboxTab = new Tab("Inbox");
inboxTab.setPane(new InboxPane().get());
}
}

Related

Best practices in protractor for big pageObject files

In my previous protractor JS project (This new one I will do it with TS) I created one class for all my elements and another one for my functions, something like this:
specs
|_reportPage
|_lib
|_pageElements.js
|_pageFunctions.js
Then I was importing the files as necessary, in this way was easy to find the info since the element list was long.
So far all examples online for protractor TS projects are short pageObject files with a couple of elements and methods, but I would like to know how to correctly proceed when the page requires a lot of elements and functions/methods.
For example, lets say we have 5 specs under the same folder that test the same page and this page is full of fields and tables.
What would be the best practice here? create 1 pageobject for each spec, create one long class with all the elements and functions...?
Thanks for your time!
To Extend my answer you can add additional layer as a service which can execute several actions from the flow in different pages.
Code example:
export class E2EService {
mainPage: MainPage = new MainPage();
innerPage: InnerPage = new InnerPage();
doSomethingE2E() {
this.mainPage.headerPage.weDoSomething();
this.mainPage.contentPage.weDoSomething()
this.innerPage.somethingComplicated();
}
}
export class MainPage {
public readonly headerPage: HeaderPage;
public readonly contentPage: ContentPage;
}
export class InnerPage {
headerPage: InnerHeaderPage;
contentPage: InnerContentPage;
public somethingComplicated() {
this.headerPage.weDoSomething();
this.contentPage.weDoSomething();
}
}
export class ContentPage {
private readonly elements = {
// elements
};
public weDoSomething() {
// code
}
public getElements() {
return this.elements;
}
}
export class HeaderPage {
private readonly elements = {
btn1: element(by.id('')),
div: element(by.id('')),
h2: element(by.id(''))
};
public weDoSomething() {
// code
}
public getElements() {
return this.elements;
}
}
Based on Infern0's answer, I did dependency injection to the classes:
class HeaderElements {
foo = element(by.id("foo"));
//List goes on...
}
class HomePageElements {
foo = element(by.id("foo"));
//List goes on...
}
export class MainCommonElementsPage {
headerElements: HeaderElements;
homePageElements: HomePageElements;
constructor() {
this.headerElements = new HeaderElements();
this.homePageElements = new HomePageElements();
}
}
Best practices, even for large Page Objects is this:
Each page should only have 1 page object class. All of the tools needed to access that page should be located here. Think of your page object as an API.
Don't break the PO into different parts, especially for large pages. You'll eventually need to modify the PO to adjust for content changes. Would you rather change 1 file or 12? This also ensures that each of your e2e tests will remain functional after you update the PO.
I have one PO that handles a page with a lengthy form. The form has 12 controls and three buttons (cancel, reset, and submit). I have about 30 functions that deal with the form. I don't like having more than 1-2 methods in my test, so if it gets more complicated, I add to the PO.

PostSharp C# - How to Implement All Fields Required

PostSharp contracts make it easy to label individual fields as Required. But I want a class attribute that makes all of the class fields required. I'm guessing I would have to implement a custom aspect to support this.
It seems like it would be a common need for anyone passing around data containers. Can anyone direct me to some code that implements a custom "AllFieldsRequired" aspect in PostSharp?
You can implement PostSharp.Aspects.IAspectProvider:
public class AllFieldsRequiredAttribute : TypeLevelAspect, IAspectProvider
{
IEnumerable<AspectInstance> IAspectProvider.ProvideAspects(object targetElement)
{
Type type = (Type)targetElement;
return type.GetFields().Select(
m => new AspectInstance(m, new ObjectConstruction(typeof(RequiredAttribute))));
}
}
[AllFieldsRequired]
public class Foo
{
public string Bar;
public object Baz;
}

Finding a View with IViewFor<InterfaceClass> from a class VM that implements InterfaceClass?

I have the following class which is my view model (this is very simple right now, but it will contain a chunk more logic eventually):
public class IndicoTalk : ITalk
{
private Talk _talk;
public IndicoTalk(Talk t)
{
this._talk = t;
}
public string Title
{
get { return _talk.Title; }
}
}
Now, I have a reactive ui view for this guy:
public sealed partial class TalkView : UserControl, IViewFor<ITalk>
{
public TalkView()
{
this.InitializeComponent();
this.Bind(ViewModel, x => x.Title, y => y.TalkTitle.Text);
}
Note that the IViewFor is for ITalk, not IndicoTalk. This is because I can have other types of talk, and they will all fit into the same view.
And I register this ViewModel in my App start up:
Locator.CurrentMutable.Register(() => new TalkView(),
typeof(IViewFor<IWalker.DataModel.Inidco.IndicoMeetingRef.IndicoTalk>));
Finally, in another viewmodel I have a ReactiveList which contains a bunch of these IndicoTalks's. Of course, when I bind this to a ListBox, ReactiveUI fails to find the view. If I switch to IViewFor then everything works just fine.
What is the proper way to gently redirect the view resolution in this case?
A half-way solution: leave all code above the same, but put in the IViewFor ITalk instead of IndicoTalk. This works, but means I will have to register with Splat (the CurrentMutable call above) every ViewModel that inherrits from ITalk. I'd love to avoid that if possible!
Many thanks!
So, why not just do:
Locator.CurrentMutable.Register(() => new TalkView(), typeof(IViewFor<ITalk>));

Usage of JsniBundle: calling methods on initialized js library

When I initialize d3.js and dc.js using JsniBundle there is no global variable "dc" or "d3" that is created. But I initialze crossfilter in the same way and there is window.crossfilter present.
My question is: what is the best way to call methods from the dc library using JsniBundle? Is using JsUtils.prop(window, "dc") the correct way to get a reference to the library object?
In the method drawBarChartWidget() below, the variable "dc" is null.
public interface D3Bundle extends JsniBundle {
#LibrarySource("d3.js")
public void initD3();
}
public interface CrossfilterBundle extends JsniBundle {
#LibrarySource("crossfilter.js")
public abstract void initCrossfilter();
}
public abstract static class DCBundle implements JsniBundle {
#LibrarySource("dc.js")
public abstract void initDC();
public void drawBarChart(Widget container, JSONValue data, Properties chartConfig) {
JavaScriptObject dc = JsUtils.prop(window, "dc");
}
}
LayoutPanel layoutPanel = new LayoutPanel();
SimplePanel chartPanel = new SimplePanel();
public ChartDemo() {
D3Bundle d3 = GWT.create(D3Bundle.class);
CrossfilterBundle crossfilter = GWT.create(CrossfilterBundle.class);
final DCBundle dc = GWT.create(DCBundle.class);
d3.initD3();
crossfilter.initCrossfilter();
dc.initDC();
Maybe not a direct answer to your question, but if you want to use d3.js with GWT, there is a wrapper that cover most of the main APIs from d3.js :
https://github.com/gwtd3/gwt-d3
Here's what made it work:
change final assignment statement in d3.js library from
this.d3 = d3;
to
window.d3 = d3;
and change final assignment statement in dc.js library from
this.dc = _dc(d3);
to
window.dc = _dc(window.d3);
I assume this is because of some weirdness around the iframe context that GWT code is executed in, but I'm not totally clear on why it works. I haven't done it yet but I believe that instead of editing the original library you can use the "replace" attribute of the LibrarySource annotation to automate that substitution.

use GwtCreateResource to provide text programatically

I would like my uiBinder to use a ClientBundle which will provide some runtime customized labels. Kind of a TextResource but not from a text file !
I tried with GwtCreateResource but from the DevGuide it seems like it's not possible. Am I right ? (create() and name() are the only methods available)
What I would like to achieve is something like this:
client bundle:
public interface MyWidgetResources extends ClientBundle {
GwtCreateResource<WidgetLabels> labels();
#Source("lol.css")
CssResource style();
}
labels class:
public final class MyWidgetLabels {
public String title() {
return load("mywidget-title");
}
public String banner() {
return load("mywidget-banner");
}
private String load(String key) {
// load from external..
}
}
uiBinder:
<ui:with type="com.package.MyWidgetResources" field="res"/>
<gwt:SimplePanel>
<gwt:Label text="{res.labels.title}"></gwt:Label>
<gwt:Label text="{res.labels.banner}"></gwt:Label>
</gwt:SimplePanel>
My code looks like this already but res.label.title does not work because GwtCreateResource can only serve as class instantiator (res.labels.create().title()).
Is there a solution for me ? Maybe with a custom ResourceGenerator ?
As long as MyWidgetLabels can be created by GWT.create, you can put anything you want into that type, and you can make it behave however you'd like. You will need the create reference in your uibinder as you suggested at the end of the post to actually build the object, so your lines will look about like this:
<gwt:Label text="{res.labels.create.title}"></gwt:Label>
Each . separated piece (except the first, which is a ui:field/#UiField) is a no-arg method to be called - you declared labels() in MyWidgetResources, create() already existed in GwtCreateResource, and you created title() in your own MyWidgetLabels type.
Since that first piece is a ui:field/#UiField, you could have another that references res.labels.create as something like labels so that later you could instead say:
<gwt:Label text="{labels.title}"></gwt:Label>
Finally, yes, you could build your own ResourceGenerator which would enable you to do whatever you wanted to emit the type in question, as long as you extended the ResourcePrototype type and had a getName() method.