Can anyone think of a (preferably quick) way to move the data() attached to a DOM element to a new instance of itself?
The lightbox plugin I'm using deletes and re-appends and element to the page in order to display it in the lightbox (to aviod the multiple-ids issue that ASP.net has), and obviously the .data() that is attached to the element is lost when this happens.
There's a relatively new overload for .clone() you can use to do this.
.clone(true) will copy the element with events and data intact.
Alternatively, change your plugin to use .detach() rather than .remove() which keeps data intact. From the docs:
The .detach() method is the same as .remove(), except that .detach() keeps all jQuery data associated with the removed elements. This method is useful when removed elements are to be reinserted into the DOM at a later time.
Related
How can You refresh a grid, when some new row was added to its datasoruce container or one of its rows has been edited?
I have tried the hacks written about here (http://www.helpsforcoder.com/code/31861375-vaadin-refresh-grid-after-row-modification.html ) and here (deleted link to malicious advertisement) but with no positive result. I add / edit the row in a separate subwindow that 'pop-ups' over the view, where the grid, that should update its contents, is placed.
grid.getDataProvider().refreshAll();
Grid listens to changed property values. So if you are working on the property level of vaadin everything should be fine.
If you extract your bean out of the BeanItemContainer you directly manipulate the values of the bean. That way the property container can not recognize your manipluating action.
So you have to send your grid implementation a message, the properties have changed manually.
When your BeanItemContainer still has the hard reference to the changed object, grid.markAsDirty() should work.
I need to completely initialize a custom component in my Flex app (i.e. I should be able to access it from action script and get its properties and its children etc), But I do not want to add it to the display or make it visible.
I have tried to add it to my visible component, but keep it visible, but often many of its properties are set only when it is drawn, so i don't get what i need.
Is there a way to add a custom component to some sort of 'Virtual' display, that is not visible to the user?
You could add the component to an invisible Sprite - that way the component itself could both be on the stage and have its own visible property set to true.
Did you try using initialize()? After a view is added to the display list, the initialization stage begins. Calling initialize() before addChild() should let you initialize the view without needing to first add it to the stage.
For more info visit:
http://flexscript.wordpress.com/2008/10/24/flex-component-lifecycle-and-flex-component-framework/
http://blog.deadinkvinyl.com/2008/10/05/flex-3-addchild-and-initialize/
Not sure if possible without adding it to the display list, although I'd wish it were to some extent.
I once had to make custom drag proxy, which didn't work with the real component, because of some weird skinning issues. So instead I had PopupMananger add a box as a popup, added my component to the box, called validateNow on the component, drew it in a bitmap data, removed the popup, and used the bitmap data as the proxy.
So what you were trying was missing a call to validateNow most likely.
I have a List component using multiple item renderers determined by the itemRendererFunction. When I set the data the first time, it works as expected. Then, when I set the data a second time with new data, it doesn't call the itemRendererFunction and tries to reuse the current renderers even though they don't match the data. Once I scroll, the function is called and the correct renderers are used. I tried calling invalidateDisplayList and such prior to setting the data, but that didn't fix the problem. Any ideas?
It turns out this is a Flex SDK bug. Peter DeHaan provided me with a workaround (re-setting the itemRendererFunction property after the dataProvider is set) and is filing it for a future release of the SDK.
Here's just some ideas:
Try invalidateProperties? Looking at the source I have a hunch it could be that, otherwise, perhaps just start calling every invalidate method you can find till you get the right one.
Another sorta hacky solution might be to take not of current scrolling position (via the scroller on the List) pass in a new array as dataprovider (which will definitely recreate the item renderers) then set the scroll position to the same as it was before the refresh.
Or you could abstract out the selection of the different item renderer into the item renderer itself. :/
FWIW: Here's the link to the Flex bug:
https://bugs.adobe.com/jira/browse/SDK-32018
What is the best way to render to a UIComponent which hasn't been added to the stage? (I'm using UIComponents as renderers for objects, and want to render new copies for image export, filtering, etc.)
Two strategies I've seen/used so far include realizing the component to ensure it calls all the lifecycle methods:
Add the component to Application.application, render with BitmapData.draw(), remove component. This is similar to what I've seen done for printing unrealized components as well.
Add the component to a pop up window, render with BitmapData.draw(), dismiss popup after rendering complete.
I believe both of these just rely on the UI not refreshing while the current thread/event is executing, though (1) could also rely on the component being realized out of view.
Is there a better way?
What I've used in the past with much success is the following:
Create a new instance of your component
Add an event listener for FlexEvent.CREATION_COMPLETE
Set visible=false on the component
Add the component as a child of the main Application
When the component is created, the event listener function will be invoked. The rest of the logic should be put in / invoked from your event listener function
Remove the event listener you added in step #2.
Use ImageSnapshot.captureImage() or captureBitmapData() to capture the visual representation of the component.
Remove the component from the main Application
Process the image data as you need to.
I've used this to snapshot various Flex charting components for use in PDF's generated on the server side. After getting the BitmapData I use the PNGEncoder or JPEGEncoder classes to compress the data, then encode it in Base64 before uploading to the server.
I'm pretty sure you can use the draw() method in BitmapData without having your component on the DisplayList.
For example is use it when I need to modify images I load with the Loader Class. In the init handler I create a BitmapData instance and draw the Bitmap from the loadInfo.content property, then copyPixels() or whatever I need to modify the loaded image
So much of a UIComponent's layout can be tied to it's context. This is especially true for a lot of its derivatives (e.g. HBox) since the fluidity of the layout is tied to it's parent's size and the number of siblings sharing its parents space.
Additionally Flex can be a real pain to get to visually update. Often critical render functions aren't done synchronously ... there are callLater, callLater2 and other hacky approaches that make dealing with the auto-magical layout properties of UIComponents a major headache. Not even calling validateNow or updateDisplayList can guarantee that the layout will be correct on the current frame (instead of a few frames in the future).
I suggest the best thing you can do is not use a UIComponent and try and use a Sprite or other.
Your approach to attach it but make it invisible (alpha = 0, mouseEnabled = false, mouseChildren = false) is decent. You should listen for the FlexEvent.CREATION_COMPLETE callback before you are certain it is properly laid out. Then you can bitmapData.draw it and then remove it from the stage. If you must use UIComponents then I know of no better way.
You can call the lifecycle function manually before using the BitmapData.draw(). Do the following.
createChildren().
commitProperties().
updateDisplayList().
bmd.draw().
The first 2 steps are not 100% necessary, you can put all codes into updateDisplayList(). Because you invoke the function manually, you don't have to worry this is invoked by Flex framework many times.
An MXML component can be quite complex, containing many nested controls, including asynchronously loaded content such as Image/SWFLoader.
Is there one event I can watch for on my component that will only be raised when every control and sub-component has loaded, including SWFs and Images?
CreationComplete will NOT do the trick if you are talking about loading swf content or anything really external like that. CreationComplete gets fired when the MXML components have been laid out as defined in MXML (IE nested components, buttons, boxes, canvasses, etc.), so content that needs to get loaded externally (an image, a swf) does not count.
What you need to do is keep track of everything that you're waiting for and fire off a custom event once all of those elements have loaded.
One possible hackish way to do it would be to listen for whatever load complete event is relevant for each element, then have them call back to the same function that increments a value equal to the number of components you're waiting for. This means you have to pay more attention if you're modifying it, but it also means you don't have to check a boolean for every element that needs to load (IE "if (image1Loaded && image2Loaded && swfLoaded)" etc.)
The onApplicationComplete event?
The creationComplete event should do the trick - creationComplete is called on the parent component after it is called on the children.
You can get some more info on the component lifecycle in the Adobe docs.
In some complex cases, like when your component is considered "finished" only when some data has been retrieved via HTTP or something like that, custom event is your best bet.