I use Tapestry 4.1.1 and i need to change the order in wich some components are rendered in a tapestry application page.
I have the following in HTML:
-start of page
-component1 (a map showing a location)
-component2 (a resulttable contrib:table)
-end of page
the resulttable gets 90 objects to show. It is paged. 10 objects per page. 9 pages.
Becouse tapestry handles the sorting order of the objects i don't know wich objects will be displayed. I think i need to wait for it to render to know exactly what is being shown to the user?
component1 shows a location on the map. It needs an identifier from one of the objects displayed in the resulttable. Not any identifier. one of the 10 being displayed out of all 90.
I use the 'row' binding setRow(Object 0) to know wich objects are displayed. The method gets called 10 times. This is perfect.
I then need to pass the identifier to component1. Becouse in the HTML component1 comes before component2 it will be rendered before rendering the resulttable.
I tried placing component2 before component1 in the .page specification but that makes no difference. Only by putting component2 before component1 in the HTML did the trick.
i really hope someone can help me out here becouse i have been stuck for a while now and i really need to get this to work.
Thanks in advance for any help!!
Could this be done using JavaScript on the client side? What you want to do is much easier in Tapestry 5. In Tapestry 4 you can do some wierd tricks, like rendering the table first, capturing its output HTML, than inserting it later on the page.
Alternately, you could provide the correct model objects to the contrib:Table (rather than let it handle all the pagination work) and that way you'll know, before it renders, exactly what it will be rendering.
Related
In my app there's a page where I am showing several snackbars depending on results from server.
There can be several triggered by the server's result. They are also triggered from different components, so I don't have a single controller that could render them where I want.
So, they all display at once and overlap each other. I linked the official Vuetify docs page because the problem is clearly visible there. Just click on two of the buttons in short enough succession.
Is there any way I could render them such that they would stack one above the other instead of all bottom-centering over each other?
I was thinking I'd need a way to tell them the component that would be their rendering parent. But I can't seem to find a way to do this. Slots don't seem to be much help with this either since I can't declare global ones.
Is there any way I can do this?
I am trying to use one of the Material Design Lite templates inside my Vue.js application.
What happens is, when I am routed(using this.$router.push('/templateX') to the next page, the component is not fully rendered(I can see only the header).
What is really interesting, when I take a look at the source section inside the browser console, I can see that the template is loaded but not fully rendered.
Once I reload the page, then the whole template is rendered and everything is shown as expected.
I think the problem is in the component life cycle but I am not sure what shall I do exactly. Any thoughts?
I am currently developing a web application that is used to display elements for events on a map provided by HERE Maps. I am using Vue.
I have some components, but the relevant component is the component HereMaps.vue which initializes the map using the HERE Maps Api.
The HERE Maps Api provides the possibility to place so called InfoBubbles on the map showing additional information. These InfoBubbles can be provided some HTML-code in order to customize their appearance.
Please refer to the documentation for additional information
Following the documentation the code looks something like this:
let bubble = new H.ui.InfoBubble(marker.getPosition(), {
content: "<div class='someClass'>Some Content</div>"
});
this.ui.addBubble(bubble)
This is happening after mount in the "mounted" method from Vue in the "HereMaps" component.
The Bubbles are added in a "closed" (hidden) form and dynamically "opened" to reveal their content when the corresponding marker icon on the map is clicked. Therefore the HTML-code is present on the DOM after the component is mounted and is not removed at a later stage.
Now instead of supplying custom code within each bubble added to the UI i want to just add a component like this:
let bubble = new H.ui.InfoBubble(marker.getPosition(), {
content: "<myDynamicComponent></myDynamicComponent>"
});
this.ui.addBubble(bubble)
It does not matter to me wether the component is initialized using props or if it is conditionally rendered depending on the state of a global variable. I just want to be able to use the "myDynamicComponent" in order to customize the appearance in a different file. Otherwise the design process gets very messy.
As far as i know this is not possible or at least i was not able to get it work. This is probably due to the fact that the "myDynamicComponent" is not used within the "template" of the "HereMaps" component und thus Vue does not know that it needs to render something here after the directive is added to the DOM in the "mounted" method.
This is what the InfoBubble looks using normal HTML as an argument:
This is what the InfoBubble looks using the component as an argument:
It appears to just be empty. No content of the "myDynamicComponent" is shown.
Does anyone have any idea how i could solve this problem.
Thank You.
Answer is a bit complicated and I bet you wouldn't like it:)
content param can accept String or Node value. So you can make new Vue with rendered your component and pass root element as content param.
BTW, Vue does not work as you think, <myDynamicComponent></myDynamicComponent> bindings, etc exists in HTML only in compile time. After that all custom elements(components) are compiled to render functions. So you can't use your components in that way.
Give us fiddle with your problem, so we can provide working example:)
I am using the vue-masonry plugin which let me create a masonry grid easily.
I created a system of infinite loading where you scroll to the bottom of the page and it append new pictures to an array binded with the vue-masonry plugin.
The problem happen when I created a system of polling for the new pictures that were upoaded by other users. Those new pictures need to be at the top of the masonry grid.
The plugin use two Vue Directive masonry (parent) and masonryTile (element). masonryTile has a v-for which loop through the array binded with my Vue instance (which does all the heavy lifting, preloading, sanityzing, etc...).
Is there a way in the directives to know the differences between something being appended or prepended? And try to react differently (I know masonry has some append/prepend method) but in here and with this plugin, the items where already added (at the beginning so the prepend works with Vue) but there's no masonry interaction nor redraw (I tried to use the prototype to trigger the redraw this.$redrawVueMasonry();).
So I don't know what's next to do. Continue finding a way to differentiate a prepend from a append and trying to bind it to the respective masonry's methods ? Or another method that I didn't think of...
Thanks in advance for you help
Ps : I don't think my code is really relevant since It's more a way to optimize the plugin. If you want some specific part of my code anymay, tell me in the comment !
This probably comes a bit too late, this being a 10 month old question.
However vue-masonry is able to handle situations where items are spliced anywhere in the array. But to properly update the grid this.$redrawVueMasonry() should be called inside this.$nextTick() like this:
this.$nextTick(() => this.$redrawVueMasonry());
Hope this helps, if not the original poster, someone else.
I have two scenarios I need help with, and I thought posting them together would prove more
valuable for myself, and other viewers.
Setup:
Worklight 6.1
dojo 1.9
Application:
MainView.html (Contains Body, and a transition Div, and NorthSouthView.js script reference)
View1.html (Contains a single Div that displays and unordered list
View2.html (Contains a single Div that Displays <p> data, and also plays audio)
View3.html (Contains a single Div that Displays instructional information)
application-descriptor <mainFile> MainView.html </mainFile>
All of the views are stored together in the application. There are no external http queries made by the application. All view transitions are local to the application.
Scenario #1:
At application start the MainView.html is invoked by worklight. Anticipated format::
<body>
<div>
<h1 id="SSheader" data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top"'>Loan Snapshot</h1>
</div>
<div id="TransitionViewDiv">
/* Would like to load content of View1.html, View2.html, or View3.html here */
</div>
<script>SetView.js</script>
</body>
Description + Questions:
When the application starts, SetView.js will be loaded, and the purpose of this script is to look at localStorage and determine which view should be displayed. (View1, View2, or View3). The goal is to keep SSheader fixed at the top of the screen at all times. Only TransitionViewDiv would update.
Questions:
1) What coding approach can be used in SetView.js to load one of the 3 possible views into the TransitionViewDiv?. I did findin dojo 1.9 specs an example using dojox/mobile/ViewController but I was not able to get the sample code to work as documented by dojo.
2) Is the approach of having the TransitionViewDiv necessary, or could View1, 2 or 3 be loaded without TransitionViewDiv? Keep in mind that each view View1, 2, and 3 are defined as individual Div's.
Appreciate any advice to accomplish the above approach, or welcome any suggestion on the best practices to accomplish the transition.
Scenario #2:
As a follow-on to the scenario 1 above. Once View1, 2 or 3 is successfully loaded the views will have buttons defined that will want to cause the transition to another one of the remaining views. So, if inside SetView.js the decision is to slide in View2 to be displayed, View2
will have buttons that will want to load for example View3.html.
Description + Questions:
1) Would the best approach to load View3.html from View2.html be to use the moveTo on the button click, or should the button use the callback to invoke javascript to cause the transition similar to what was used to load the initial view?
Appreciate any advice on the best practices to managing multiple view stored in independent files. In the end the application will have upwards of 15+ ViewXX.html files each containing a Div. Based on this, having all of the views in one html file and forcing the hide, and show is not feasible.
Appreciate your time and help
To load an HTML fragment (View1.html, View2.html or View3.html), you can use the dojox/mobile/ContentPane. This widget allows you to provide a href property that can be used to specify the location of the view.
You can also alter it later on by setting the href property again, for example:
registry.byId("myContentPane").set("href", "View2.html");
You should keep the div#TransitionViewDiv and programmatically add the dojox/mobile/ContentPane to it, or use declarative syntax and add the following attributes:
<div id="TransitionViewDiv" data-dojo-type="dojox/mobile/ContentPane" data-dojo-props="href: 'View1.html'"></div>
Your second scenario is differs from the first one. In the first one, you actually have 1 view with many fragments, while in your second scenario you have many views.
If you only have 1 view, you cannot transition to other views (there are none). So if you want to use transitions you cannot use dojox/mobile/ContentPane.
However, if you have seperate views, then that means you need to move the header to each view (since they're part of it). For these, more complex cases I think you should look at the dojox/app module. This covers a lot of the MVC code for you and the only thing you need to do is configure it.
If you're not interested in the dojox/app module, you can try to inherit views. You might want to look at this answer I once provided. In the comment section of that answer you can also find a more detailed JSFiddle. In this example the header is actually inherited. I also wrote a more detailed article to handle this case .