I am building my first report in BIRT.
Very quickly I ran into a problem in which I wanted to display some text or data based on an expression that included data from two different tables (not tables that can/should be joined - (hypothetically example- take a student's ACT score from his record in the student table and compare it against the statistics table's entry for ACT statistics). I soon realized that a data element has to be bound to a dataset (only one of them.)
I found a similar question in the BIRT mailing list which helped me get to a solution - I can bind an individual data element to a different dataset, but it can still access the elements of its container. I can send a parameters to the dataset that the element is bound to (e.g. "ACT" in the example I mentioned above).
Eventually however, I came to a place where I needed to use data from three different tables. I am stuck here, and I'm assuming that there is a way to do this through the scripting abilities, but I have yet to see in the documentation a way to extract data from a data set - everything I have dealt with so far is associated with binding a report element to a dataset.
To be clear, I have seen that I can add JavaScript functions to the initialize section of the top level report (and call them from an expression in a data element) but I don't see how in a script I can query any of my datasets -- as opposed to only interacting with the dataset bound to my data element).
How can I access an arbitrary (though already defined) data set from JavaScript in BIRT? (Or how can I access more than two datasets from an element - one that it is bound to, and one that its container is bound to?)
I have not tried to do this for a while. The immediate answer that pops to mind is that you need to put the third data set into a table (can have visibility set to false) and you would need to populate the table values to a GlobalValue. Then you could get at the GlobalValues from the data control through script.
I know that it is not pretty. I will have a look over the weekend and see if 2.3 has added any functionality that makes this easier.
Use the this.getValue() which will return the current column's binding value instead of dataSetRow["RUN"]
Related
I've started a new project to sharpen my Javascript skills.
The project (demo here) and (source code here) involves decision making and uses key skills taught in therapy for breaking down future actions, decisions, goals etc, assessing pros and cons and consequences (positive or otherwise). My idea was to see whether I could create an app ready-to-go to meet such needs/demands so that I can help people out there who want to take a moment to think about their next steps and whether it will benefit them, as well as myself.
As you can see from the app, you've got three steps to go through; subject, consequences, comments (on said consequences) and the final forth step is reflection. What I'm having difficulty with is getting all this together. I want to put the data into an array and then render (as well as save to localstorage) to the div container representing the reflection stage. Because the form is not straightforward in the sense that it's not simply getting values of input elements but instead 'linking' the option element value from the parent select element, I'm having difficulty getting all the data together.
How can I do this?
An example of what I'm trying to do:
let array = []
// Logic here
// User defines a subject to 'discuss' and then proceeds to select the consequences and then expands on these consequences. Finally, user goes to save this 'session'. It is rendered to the 'Reflection' container. Source code is available
array = [
subject: "A new job" // all examples here
options: {
advantages: "more pay", "people", "future",
questionable: "apocalypse?",
disadvantages: "traveling to work", "long hours"
}
]
I want the array to be updated dynamically. So, say for example the user adds another 'Advantage' along with some text, I want the advantages property to reflect the new changes without removing existing items. I don't want a new array being added. I only want one array because the intention is for this app to be a single session, not addressing multiple subjects to deliberate on. I have previously opted to disable the subject input element so it cannot be edited and 'sent' again to solve this but have settled at the minute with a basic conditional statement checking if the subject title exists in the array and if it does, attempting to work with the existing array. I've also tried doing a 'modular' approach by processing the form data one step at a time, much like a multi-step form while all on one page and without the dynamic content changes. The aim with this was to break down the collecting and manipulating of data. I hoped all this would make data manipulation easier but I'm still stuck at being able to create an array which can be used to render all the data.
I have come close to figuring this out as I've managed to create an array which resembles the data collected from the form but it isn't dynamic. The options property as mentioned above does not 'join/link/integrate' the data from the inputs for analysis (consequences). The options property remains the same in the array regardless of whether the 'consequence' is an advantage or disadvantage.
Have tried Object.assign, array.push, array.concat, new Object, for loops with conditional statements/switch statements etc.
I have an example working here - http://jsfiddle.net/BM3kX/5
It has a piece of JSON consumed by a YUI DataTable. I have a few queries regarding the same.
The JSON has a 'imageURI' attribute from which I need to render an image [16x16] along with the 'showName' attribute in the same cell. Also, the table can have multiple rows so as the images that should be rendered on each row efficiently.
When I click on a row, the table should alert me of the selected record. But there is a twist here - I need the data exactly as the JSON which is used to render it. (I should get even the 'type' attribute even if I'm not using it anywhere in my table.)
How can I meet the above requirements? Any solutions or possibilities?
1) There is not much you can do there. I assume the images are different for each of the records so there is not a lot to optimize except sending the images in the proper size instead of having the client resize them. If the images were some sort of icons representing status, I would recommend you sent the status coded somehow and let the browser decide on how to represent it, but if they are pictures of the people, you'll just have to let the browser deal with them the best it can.
2) It is easy to reconstitute the original data out of the model for the clicked row. You don't need to keep a copy of the JSON for that row, you can turn it into JSON whenever you want (after all, model has a toJSON method to make that easy). The model for each record in a table can hold more information than that shown in the table. The column property tells the datatable what to show, the datasource what it stores. Use getRecord to reach the underlying model and JSON-encode that. If the type was there originally, it will still be there even if you don't show it.
I am porting quite a huge piece of software to an ExtJS Grid. Lots of data (and I mean lots of data) is loaded on-demand into spans that are placed inside grid's cells.
Imagine grid cells having <span id="foo_bar'></span> as content, and special ajax handlers are polling the backend for updated information and once available the spans are filled with it.
Now, in case I collapse some part of the grid and then re-exand them again I loose all automatically filled cell content, and am left with empty spans (which I started from in the first place).
I know the correct way is to setup a store and push all data into the store. But as I've mentioned above: I am porting quite a huge piece of legacy software to ExtJS, and I do not really have much choice here.
Is there a way to automagically push grid cell values to the store?
Update:
A grid is loaded with, suppose, 2000 cells (this can vary tremendously). Every cell contains various grades of HTML, mostly this is , but this can be pretty much anything (including several spans or divs in one cell). In the background there is a comet process pushing new data to the HTML page almost in real time. This data is populated to the corresponding SPANS and DIVs either based on their IDs or class or both.
What I want to achieve is that either:
a) the model for the grid is atomagically updated with the new html content of the cells (how can I achieve this)?
b) when collapsing/expanding tree's nodes the model data is NOT reloaded afresh.
Is either a or b possible? if so — how?
Just update your store when the 'special ajax handlers' successfully return values. In staid of manually messing with the dom.
so in the success callback do something like -> loadData()
Edit:
Seems like you are working with very bad legacy code :) If adding a simple line of code to the ajax handler is a tremendous effort.. You can however attach dom listeners, but it's very bad practice. Here are some events to listen to
Edit:
Here is an example of the use of how you could listen to dom events, it's rather a pure js solution but, meh.. it works..
I use the same data to create few different parts of my visualization. I want to create a mouseover event on one node of a selection that modifies the corresponding node in another selection. What is the idiomatic d3 way to do that?
(I know I can use the id, or nest the selections, or store info in a map within scope of both selections...but these all seem messy strategies to me)
As a side note, if there is a good "d3 idioms" reference that could be very helpful when doing common tasks.
Selections are generally transient; you don't need to keep them around if you can just as easily reselect them from the document. So, selecting by id is a reasonable option.
If you don't want to give your elements unique ids (which is sometimes a pain when creating visualizations generically), then another option is to store a reference to the associated elements via the bound data. For example:
selection.each(function(d) { d.element = this; })
Now, assuming that the same data d is bound to another element, you can d3.select(d.element) to select the original element. You might choose a more specific name than "element" to make it clear which of the two (original, and decorative) elements you are referring to.
On the other hand, if you have different data on different elements, then you'll need a different way to link them together. If you don't want to use an id or another suitable selector, then a map of references is reasonable too.
I need some conceptual help:
I am trying to display a page that contains a single table with a lot of data (moderately big number of rows, very big number of columns), and I want that page to be as fast and smooth as possible from the user's point of view. What I am doing is the following:
Retrieve a list containing the database primary keys of the elements to be displayed in the table.
Iterate through the list, asynchronously request each element given its primary key, and, every time element is retrieved, add it to the table.
Each of these retrieval operations is implemented as a Web service call.
Now my questions are the following:
How can I reorder the elements if they arrive in a different order than they were requested? (It is absolutely essential for me that these elements be inserted in the table in the same positions as their respective primary keys were in the original list.)
Can this strategy be made compatible with any of the main JavaScript grid controls available out there? (Without me having to modify or understand how these controls internally work, of course.)
I think you can look into the jQuery DataTables plugin. It is quite a powerful tool to display data in a tabular format.