I tryed to create a group box with the _createChildControlImpl()-Methode but the layout looks like crap as you can see her http://tinyurl.com/odzgy3v
But when I implement it without _createChildControlImpl() it works fine: http://tinyurl.com/kwzvdm2
Could anybody please tell me what's the reason for this? Thanks in advance!
Have a look at your browser console - there is already a hint.
When you introduce child controls qooxdoo can't reuse the former default appearance of widgets because the appearance id changed (from "groupbox" to "widget/groupBox"). So you have to add your own appearance theme (which can simply forward by using an alias):
qx.Theme.define("test.myAwesomeTheme", {
extend : playground.theme.Appearance,
appearances :
{
"widget/groupBox" : "groupbox",
}
});
qx.theme.manager.Appearance.getInstance().setTheme(test.myAwesomeTheme);
I'm extending playground.theme.Appearance here which extends qx.theme.indigo.Appearance which again extends qx.theme.simple.Appearance. And their you have the groubox definition we are forwarding to.
Here is the complete playground sample.
You are supposed to implement _createChildControl, but not call it directly. Instead call getChildControl in your constructor and let it call _createChildControl, if needed, since it is also caching the result.
GroupBox seems to be a bad fit for what you want - it seems to assume identically sized and shaped elements inside its frame sub-widget, when filled from within the implementation of _createChildControl().
Use another Composite() inside the main container instead, add "Registration" as yet another child control of type label as the first child of the custom widget, and things will look much better (although not identical).
Quick and sloppy proof of concept: http://tinyurl.com/m7ykhta
Related
I have a ItemSelector component inside a Window. I have implemented a search functionality that dynamically finds the matching entry based on user's keyboard input.
Now I just want to highlight/focus such item inside the ItemSelector.
I'm looking for something like:
// when the search returned a result and got the related index in the store
function onSearchPerformed(index) {
var cmp = this;
cmp.itemSelector.setSelected(index); // here I'd be highlighting the entry
}
Example
Imagine a simple ItemSelector like this one taken from the web.
User types 'Delaw' and my search function detects that there is an entry with name Delaware and it's at position 3 in the store.
All I want to do is to programmatically highlight the row/entry 'Delaware' just as if you clicked on it.
This ux component uses a boundList, or better 2 of them.
A from and a toList.
You need to get a reference to the right boundlist.
More on that you will find here: http://docs.sencha.com/extjs/6.0.1/classic/src/ItemSelector.js.html
Basically you can do something like this:
https://fiddle.sencha.com/#view/editor&fiddle/24ec
afterrender: function(cmp){
Ext.defer(function(){
var boundlist = cmp.down('boundlist');
item = boundlist.all.item(1);
boundlist.highlightItem(item);
},300);
}
After you have a ref to the correct boundlist, you can simply highlight the item using:
http://docs.sencha.com/extjs/6.0.1/classic/Ext.view.BoundList.html#method-highlightItem
Take care that you may need to call following function before:
http://docs.sencha.com/extjs/6.0.1/classic/Ext.view.BoundList.html#method-clearHighlight
To find the correct item should't be too hard.
There are two ways to solve the issue
One is by following #devbnz answer, marked as correct. This is preferable, if you just want to graphically highlight the entry without triggering any event.
However, by hovering on other entries, you will lose the highlight on your current entry.
The second one, as suggested by #guilherme-lopes in the comments, may be preferable in cases in which you want the selection to act as if you actually clicked on an entry, which will trigger the selectionchange event and similar...
Depending on the situation, I ended up using either.
UPDATE
I've tried to make a standalone version here: https://codepen.io/neezer/pen/pPRJar
It doesn't work quite like my local copy, but I'm hoping it similar enough that you can see where I'm trying to go.
I'm not getting quite the same behavior as well because I changed the listener target to document, which seemed to help some.
Also, I'm using RxJS v5 and the latest version of React.
Still getting the hang of RxJS...
I have two Observables: one subscribed to mouseover x coordinates on a table to show a resize column, and the other to allow the user to drag on that column.
Roughly speaking, the first one looks like this (all of the below defined in a componentDidUpdate lifecycle method in a React component):
Rx.DOM.mouseover(tableEl)
.map(/* some complicated x coordinate checking */)
.distinctUntilChanged()
.subscribe(/* setState call */)
That works great, and gives me this:
So now I want to provide the actual "drag" behavior, and I tried setting up a new Observable like so
// `resizerEl` is the black element that appears on hover
// from the previous observable; it's just a div that gets
// repositioned and conditionally created
Rx.DOM.mousedown(resizerEl)
.flatMap(md => {
md.preventDefault()
return Rx.DOM.mousemove(tableEl)
.map(mm => mm.x - md.x)
.takeUntil(Rx.DOM.mouseup(document))
})
.subscribe(/* do column resizing stuff */)
There are three problems with that:
Once I've done my first "drag", I can't do any more. My understanding is that takeUntil completes the Observable, and I'm not sure how I can "restart" it.
The mousemove from the first observable is still active while I'm dragging, so my black div will disappear once my x position changes enough to trigger that behavior.
The binding on the second Observable doesn't always seem to trigger (it's unreliable). I think there might be a race condition or something happening here because sometimes I'll refresh the page and I'll get the drag once (from #1), and other times I won't get it at all.
Note at first after a clean refresh I can't drag the handle (#3), then I refresh, and I can't drag the handle past the bounds setup from the first Observable--and the black resizer bar disappears and reappears as my mouse's x coordinate enters and leaves that envelope (#2).
I've been head-banging on this for quite some time now and would really appreciate any insight as to what I'm doing wrong here. In short, I want
the first Observable to "pause" when I'm dragging, then resume when I'm done dragging
the second Observable to not "complete" (or "restart") once a drag is done
the second Observable to reliably work
As I mentioned earlier, I currently have this logic setup in a React component's componentDidUpdate lifecycle method, the shape of which looks roughly like this:
componentWillUpdate() {
// bail if we don't have the ref to our table
if (!tableEl) {
return;
}
// try not to have a new Observable defined on each component update
if (!this.resizerDrag$ && this.resizer) {
this.resizerDrag$ = // second Observable from above
}
// try not to have a new Observable defined on each component update
if (!this.resizerPos$) {
this.resizerPos$ = // first Observable from above
}
}
I've played around with this a bit now, I don't think this answer will be complete, but I'd like to share my insights. Hopefully a more advanced RxJS mind will chime in, and we can all work together to figure it out :).
I recreated a "lite-er" version of this in CodePen, using some light jQuery manipulation as opposed to React. Here's what I have so far:
"the first Observable to "pause" when I'm dragging, then resume when I'm done dragging"
Solving the first point helps with the other two. Based on what I had to do to get my resizerEl, I get the feeling it is rendered in the render method of the component based on something in this.state. If this is true, that means that when the first observable still has the ability to create and destroy resizerEl even while the second observable is listening. This means that resizerEl will no longer be able to generate any events, even though the observable doesn't complete until you've moused up.
In my case, I noticed that if you moved the mouse fast enough to go outside of width of what you were trying to drag, it would eliminate resizerEl, which is of what we want, but not while we're trying to drag something!
My solution: I introduced another variable to the "state" of the "component". This would set to true when we moused down on resizerEl, and then false when we moused up again.
Then we use switchMap.
Rx.DOM.mousemove(tableEl)
.switchMap(function(event) {
return this.state.mouseIsDown ? Rx.Observable.never() : Rx.Observable.of(event);
})
.map(...
There's probably a better way to do it rather than just sticking event back in an Observable, but this was the last part of it I worked on and my brain is kind of fried hehe. The key here is switching to Observable.never while the mouse is down, that way we don't go any further down the operator chain.
Actually, one nice thing is that this may not even need to be put in this.state, since that would cause a re-render. You can probably just use an instance variable, since the variable is only essential to the Observables functionality, and not any rendering. So, using this.mouseIsDown would be just as good.
How do we handle the mouse being down or up?
Part 1:
...
Rx.DOM.mousedown(resizerEl)
.do(() => this.mouseIsDown = true)
Better to abstract this to a function of course, but this is the gist of what it does.
Part 2:
...
return Rx.DOM.mousemove(tableEl)
.map(mm => mm.x - md.x)
.takeUntil(Rx.DOM.mouseup(document))
.doOnCompleted(() => this.mouseIsDown = false)
Here we take advantage of doOnComplete to perform this side-effect once the observable has completed, which in this case, would be on mouseup.
"the second Observable to not "complete" (or "restart") once a drag is done"
Now here's the tricky one, I never ran into this problem. You see, every time Rx.DOM.mousedown(resizerEl) emits an event, inside of flatMap, a new Observable is created each time with return Rx.DOM.mousemove(tableEl).... I used RxJS 4.1 when making this, so it's possible that there could be behavioral differences, but I found that just because the inner observable completed didn't mean the outer one would complete as well.
So what could be happening? Well, I'm thinking that since you're using React, that resizerEl is being created/destroyed respectively when the component is rendering. I haven't seen the rest of your code of course, but please correct me if I'm wrong about this assumption.
This wasn't a problem for me because, for the sake of simplicity, I simply re-used the same element as a dragger, only hiding it when I wasn't hovering over a draggable element.
So the important question is: how is resizerEl being defined and used in your component? I'm assuming the actual reference to it is made using, well, a ref. But if it that DOM element is ever destroyed or recreated, then the Rx.Dom binding needs to be repeated all over again.
I see you're doing this with componentDidUpdate. However, the Rx.Dom.mousedown event may still be bound to an old copy of the ref to resizerEl. Even if the component destroys the resizer in the DOM, and sets the ref (I assume that is this.resizer) to null or undefined, that does not destroy the Observable that is bound to that element. In fact, I don't even think it removes it from memory, even if it's removed from the DOM! That means that this.resizerDrag$ will never evaluate to false/null, and it will still be listening to an element that is no longer in the DOM.
If that is the case, something like this in componentWillUpdate might help:
if (!this.resizerDrag$ && this.resizer) {
this.resizerDrag$ = // second Observable from above
}
else if (!this.resizer && this.resizerDrag$) {
this.resizerDrag$ = null;
}
This will remove the Observable if the resizer object ceases to exist, that way we can properly reinitialise it upon it's return. There's a better to way to do with Subjects, keeping the subscription to one subject and just subscribing the subject to different mousedown streams once they become available, but let's keep this simple :).
This is something where we'd have to see the rest of your code (for this component) tell what's going on, and figure how to address it. But, my hypothesis is that you'd need to intentionally destroy the Observable if this.resizer is ever removed.
the second Observable to reliably work
Pretty sure that once the above two issues work, this one goes away. Nice and easy!
The CodePen
Here is the very naive mockup I made of this problem:
https://codepen.io/anon/pen/KmapYZ
Drag the blue circles back and forth along the X axis. (Has some little problems and bugs unrelated to the scope of this question, so I'm not worried about them.)
I made some slight changes of course just to keep it in-step with the more dumb downed approach I used. But all the concepts are there, as well as most of the code you wrote, modified to match this approach.
As I mentioned before, I didn't encounter the problem of the dragging only working once, so this better demonstrates the solution to pausing the first Observable. I re-use the dragging element, which I assume is why I didn't run into the 'drag-only-once' problem.
I hope that you or anyone else can comment with some improvements to this approach, or just show us a better (potentially more idiomatic) approach.
How do I render the view result that I get by calling "views_get_view_result"
So right now I have:
$variables['result'] = views_get_view_result('name', 'name-block');
And it returns an array of Object, which is what I want. Just can't figure out how to render it. Trying to render $result[0], $result[1] for example.
Thanks,
Tee
For a simple way of doing this, use
print views_embed_view('view_name', 'display_id');
which is a utility function for doing what you want to do. See https://api.drupal.org/api/views/views.module/function/views_embed_view/7
Here is a thread with additional ways of doing this, if you need the extra complexity / depth. https://drupal.org/node/951442
For instance, is it possible to define:
#FindBy(By.id("id1") OR By.id("form1:id1"))
public WebElement button
So that button having either "id1" or "form1:id1" should work fine?
You can use the #FindBys annotation, the syntax is:
#FindBys({#FindBy(id = "foo"),
#FindBy(className = "bar")})
The JavaDoc describes it here:
http://selenium.googlecode.com/git/docs/api/java/org/openqa/selenium/support/FindBys.html
Well,
use whathever you want, as long as it works
Personally I would use #FindBy(By.id("id1")) but it is just point of choice.
Also, there is no value added in referring same element twice with two different methods. It will only cause mess in your code
EDIT
As I understood your comment, there is element on the page which constantly changes its ID. If you need to refer to such elements, try using xPath See for example this xpath tutorial
The idea is that you will point to some place in the DOM rather than to specific ID
Use Xpath or CSS selector to do that. Or Java to store the ID name in String and then you can fill it to your Id.
Can anybody point me in the right direction to how I could use UICollectionViewLayout to create an interface similar to the Pinterest column layout?
I tried searching online, but it looks like there are not many examples out there yet.
The 1000memories "Quilt" view is pinterest-like and open source: http://blog.1000memories.com/168-opensourcing-quilt, and you can dig through that to see how it works.
If you're looking for a more conceptual overview, here's the basic idea of what you're going to want to do. The easiest thing by far, if you just need a Pinterest-style layout, is to subclass UICollectionViewFlowLayout. You get a lot of layout help from this class, and Pinterest style is within its capabilities. You only need to override one method.
Set up a normal UICollectionView using UICollectionViewFlow layout. A quick way to do this is:
Drag a UIViewController onto a storyboard, drop a UICollectionView on that. Set the classes to match your custom classes, etc. You can use a delegate and create a delegate class here but strictly speaking that is not necessary to achieve JUST the Pinterest flow layout (you will almost definitely want to break the selection responsibility stuff into a delegate class in reality though).
Stub out a data source. Implementing the data source protocol for UICollectionView (http://developer.apple.com/library/ios/#documentation/uikit/reference/UICollectionViewDataSource_protocol/Reference/Reference.html) is trivially simple. Make sure you set a reuse identifier on your UICollectionViewCell. You need:
(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
just return 1 for now;
(NSInteteger)collectionView:numberOfItemsInSection:
hardcode a number for now, make it 20.
– (UICollectionViewCell *)collectionView:cellForItemAtIndexPath:
This is one of the places where subclassing the flow layout's gonna do you a favor. All you really need to do here is call dequeueReusableCellWithReuseIdentifier:forIndexPath: with the index path. If you added a UIImageView or some labels to the cell, this would be a great place to actually assign the image, text, etc.
In the viewController's viewDidLoad instantiate a UICollectionViewFlowLayout and set the UICollectionView's datasource to yours and layout to flowlayout. Remember, this class is a subclass of UICollectionViewViewController.
self.collectionView.dataSource = [[YourDataSource alloc] init];
self.collectionView.collectionViewLayout = [[UICollectionViewFlowLayout alloc] init];
Ok. At this point you should be able to run your app and see some stuff on the screen. This is a whirlwind overview. If you need more details about how to set up ViewControllers and so on there's tons of stuff available about that.
Now comes the important part, Pinterest-izing the flow layout.
First, add a new class that is a subclass of UIViewControllerFlowLayout. Change your ViewController's viewDidLoad to instantiate this class and assign as the UICollectionView's collectionViewLayout.
The method you are going to need to implement is - (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect.
Here's the thing: The superclass is going to do almost all the work for you. Your code is going to look something like this:
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
{
NSArray *attributes = [super layoutAttributesForElementsInRect:rect];
[attributes enumerateObjectsUsingBlock:^(id attr, NSUInteger idx, BOOL *stop) {
float newYCoord = [calculationMethodYouHaveToWriteFor:attr.frame];
attr.frame = CGRectMake(attr.frame.origin.x, newYCoord, attr.size.width, attr.size.height];
}];
}
Pinterest uses fixed-width columns, all you need to do in your calculation method is figure out what column you are in (`attr.origin.x / _columnWidth), and look up the total height in that column from the ivar you've been saving it in. Don't forget to add it to the new object's height and save it back for the next pass.
The flow layout superclass handles: making cells, determining which cells are visible, figuring out the contents size, figuring out the arrangement of the rows in the x direction, assigning index paths to cells. Lots of junk. And overriding that one method lets you fiddle with the y-pos to your heart's desire.
Heres two from github
https://github.com/jayslu/JSPintDemo
https://github.com/chiahsien/UICollectionViewWaterfallLayout
I've used a modified version of Waterfall in a project now, and I'm investigating JSPint now.
I have created a custom uicollectionviewlayout which is used in my personal project. Here is the link. Hope it helps.
https://github.com/johnny0614/YJZAlbumCollectionViewLayout
You can get anything you want from here:
https://github.com/ParsifalC/CPCollectionViewKit
For example(Both these two layouts are custom UICollectionViewLayout):