Dojo grid goes hidden when grid is refreshed - grid

I am refreshing dojox.grid.EnhancedGrid using dojo.data.ItemFileWriteStore per second. I have a dijit.layout.TabContainer where EnhancedGrid is present in one of the tab. When I switched the tab and come back to grid tab, the whole grid disappears.
What can be the solution?
var store = new dojo.data.ItemFileWriteStore({
url: '',
data: result,
urlPreventCache: false
});
grid.setStore(store);

I'm not sure about using EnhancedGrid but I had the same error when I used DataGrid to create a dynamic and changing matrix and this is how I was able to fix it.
Your problem arises because:
Your old structure property in the grid doesn't support the new store (different fieldnames etc.). If you don't get the structure right, Dojo complains and you don't see a grid.
I'm pretty sure it's this one. grid.setStore(newStore) doesn't work the second time probably because grid adapts itself to the first declaration of the store. I had tried the grid.setStore() and grid.setStructure() methods and it didn't show up after the first "refresh".
My solution:
Empty your container with dojo.empty() and create a new grid in that container every time you refresh with your new store

Related

Adobe Scene7 BasicZoomViewer: How to reset zoom

Question
I'm working with Adobe Scene7 BasicZoomViewer and I'm looking for a way to tell the ZoomViewer to reset the zoom so that the user is no longer zoomed in on an image but instead will show the default "zoom" level.
What I've found
The closest thing I found to what I need is this reset property ZoomView.reset which "Resets the viewport when the frame (image) changes. If set to 0 it preserves the current viewport with the best possible fit while preserving the aspect ratio of the newly set image".
This looks close to something I need but it states that it will reset or preserve the aspect ratio when a new image has been inserted but I am not inserting new images.
Demo from Adobe
There is a button on the image that the API inserts into the page that resets the zoom level. Adobe provides a demo page that shows what I'm working with. If you look at the bottom left, the right-most button is the reset button. When clicked, it has to make some kind of API call and I need to figure out which one it is.
Edit
I've been able to find a minified version of the BasicZoomViewer and I am currently attempting to make sense of the code.
There is an event listener placed on the "Zoom Reset Button" that just simply calls a reset() method on line 274 in the uglified version of the file. Currently, I am trying to make sense of the file and figure out how to access this method.
c.zoomResetButton.addEventListener("click", function () {
c.zoomView.zoomReset()
});
I will be answering my own question. If someone finds a better way please feel free to answer as well.
tldr;
Create a variable to hold the instance of your s7viewers.BasicZoomViewer() and inside of that you can access the event handlers and much more.
Example of calling the reset zoom handler
// instantiate the s7viewers class and save it in a variable
var s7BasicZoomViewer = new s7viewers.BasicZoomViewer({
containerId: 's7viewer',
params: {
asset: assetUrl,
serverurl: serverUrl
})
// example of how to call the "zoomReset()" method
s7BasicZoomViewer.zoomResetButton.component.events.click[0].handler()
Explanation
After digging through the minified code that was uglified I found an event listener on the s7zoomresetbutton DOM class name, or perhaps it's watching for the ID of that DOM element which is the same ID as the container div for your S7 BasicZoom Viewer plus some added text to make this ID unique. For example, if the container div is s7viewer then the reset zoom button will have an ID of s7viewer_zoomresetbutton.
Now, going through the code I found this event listener which let me know there must be some way to call the zoomReset() method.
c.zoomResetButton.addEventListener("click", function () {
c.zoomView.zoomReset()
});
In the code above, the value of c is this or in other words it's the instance of your S7 BasicViewerZoom and in my case I have multiple depending on how many images I need to zoom on.
When instantiating the s7viewers class you can then reference that instance later and access the event handlers on each button and other properties and methods.
From there it was just looking through the object returned from the instance and calling the handler for the reset button.

Google Appmaker: Update form based on selected dropdown option

I have an AppMaker app that has a from based off of one address table/datasource. I can get a form with next/prev buttons, but replaced the key field (name) with a dropdown list of all names (a user can start typing names to jump there, with the dropdown showing).
My hope is that when a user selects from the dropdown, the entire form updates and the next/prev buttons work properly as well (there too many records to page thru with next/prev only). I don't have to have next/prev functionality if it complicates things too much.
Currently the dropdown is working, but I cannot get the index for the next/prev buttons set or the rest of the form to reflect the selected dropdown record.
I've tried to set the "onValueEdit" event to something like this...
var selected = widget.value;
var idx = widget.options.indexOf(selected);
console.log("Selected: "+selected+", index = "+idx+"\n");
if(idx < 0) { //...this error is never hit
console.log("Index error - setting to zero!\n");
idx = 0;
}
widget.datasource.loadPage(idx); //...update form?
Two observations via console logging:
The "idx" var is never set to the selected dropdown index reliably, and is
often "0" (tho no error msg ever shows), so the "indexOf()" function
isn't working as expected.
The "selected" var (name) is always correct.
If I call widget.datasource.loadPage(...) with a fixed value (say 5) it has no effect on what is shows in the form either (previous loaded data remains) - obviously not the way to do it :v/
Can you steer a noob in the right direction?
If you are using default App Maker form, then you can see that so-called pager, doesn't actually paginate. It triggers prevItem/nextItem datasource methods, in other words it navigates through datasource items, not pages. Here is a quote from App Maker docs:
nextItem: Selects the next item. For Query Datasources, if the current item is the last item on the page, then this loads the next page and selects the first item on the newly loaded page.
So, if you already have all your items loaded(you set query page size for your datasource to 0), then you need just to change selected item within datasource:
// onValueEdit dropdown event
// assuming, that form and dropdown share same datasource
widget.datasource.selectKey(newValue._key);
If you really have lots of items and it is not feasible to load all of them in one call... then it will be all another story...
UPDATE:
It's important that Options and Value are set as shown in the image below!
However, I had trouble setting them that way (read: wasted hours!) until I wiped them both completely using More options in the binding picklist, and tried again (I had even tried on a brand new app!). I was being forced to choose ..projections.. and then a final field before the OK button would be available.
Not sure if AppMaker is buggy here or there is something simple I'm not understanding!
None of the coding in my original question is required.
Once set this way, binding just works as you would expect it!!
All other fields are set as #datasource.item. and are bound to whatever item is chosen. No Events settings are necessary for the dropdown either, as I thought they might be.
I deleted this page and started again, and replaced the default business name data field with a drop down, I set the dropdown as:
Options: #datasources.Addresses.items
Value: #datasources.Addresses.item
It works fine?! Not sure what happend in my original page!
UPDATE:
So it seems you need to delete both the Value and Options and then re-enter these. The OK will light up when you do.
Also, my original take on App Maker was to build the UI and attach data. That was my first mistake. You build the data then have App Maker build edit/add pages for you.

When modifying a Session used in subscription, template is fully recomputed instead of just add new datas

In my project i have a route that display a list of content.
Content is retreived by a subription and depends on 3 Session var.
At the begining i get 12 items in content. I have a pager that allow to get more data by modifying one of the Session dependency.
But when i do it, the list of content if completly removed and then fully re-rendered.
I tried to have a look inside the app with debugger. It seems that it is in Tracker.flush() method (from Tracker.js meteor file) that it happens.
while (pendingComputations.length) {
var comp = pendingComputations.shift();
comp._recompute(); // HERE IT WILL REMOVE ALL ITEMS AND THEN ADD ALL FROM THE SUBSCRIPTION
}
In fact it should just add new items to the template, and not remove them all and then adding them all again with new ones.
I use Iron Router, my app is on 0.9.3.1 (upgrade from 0.8.x).
[edit] precision about what i mean by "re-render" :
the list of items is completely removed from the template
and then the list appear again with old items and new items
because i do step-by-step debugging i cn say that when list template is cleared, in console i still have access to items collection, and the count on that collection returns me a number greater than 0
[edit] about a reproduction project
I'm working on, and i hope i'll be able to understand the problem to explain it. It's available here http://displaybugreproductionwithironrouterprogess.meteor.com
And source code is here https://github.com/Rebolon/meteor-ironrouterprogress-bug
If you just do a
meteor remove mrt:iron-router-progress
then the app runs correctly and the template is not fully re-rendered (so there is no clipping at the screen).

Devexpress Xtrareports databound generates (unwanted) pagebreak after each record

Using devexpress xtrareports version 11.2 I have setup a databound report using a temporary table. I bind the content to a single xrrichttext on the report.
Each record is generated and each next record starts on a new page. Now I want to lose the automatic pagebreak and implement my own logic for breaking.
But I have not yet been able to drop the auto-break. I went through all the pagebreak properties in design mode but everything is already set to none.
Besides the xrrichtext there is also a xrpanel which contains a xrlabel, all are set to a low height as default with cangrow/canshrink to true.
Is there something specific I can set for this or am I still missing something?
edit:
I am using the detailband, I had given the xrrichtext a minimal height after realizing this might be the problem, but this didnot seem to help. But after I restarted this did however fix the problem.
But now my own pagebreaks are not working as expected, not sure if I should start another question for this.
In the detailband I have added a xrpagebreak.
In the detail_beforeprint I check if the current records needs a pagebreak
If GetCurrentColumnValue("break") = True Then
xrPageBreak1.Visible = True
Else
xrPageBreak1.Visible = False
End If
Only now I am getting a pagebreak for every record, doesnot seem to react on the value for field 'break'?
which reportband are you using?
some report bands only appear once on every page, usually data is added to the detail band, this is displayed until the page is full. or until you break the page yourself

Performance issue with ASP.NET page with many (hundreds of) CollapsiblePanelExtenders

I'm maintaining an ASP.NET site where users can log on to register some set of data (for statistical purposes). One user registers data for a set of units, and for each of these units a set of forms are to be filled out (with a handful of fields in each form, but that doesn't matter here). One scenario is that a user has 12 units, and in each of these units there is 25 forms to be filled, meaning a total of 300 forms.
The ASP.NET page for registering these data is made the following way: each form is in a panel that can be collapsed using an AjaxControlToolkit CollapsiblePanelExtender, and all forms in a unit is inside another panel that also can be collapsed. The result is that you have a tree view-like structure with the units on the top, and under each unit you can expand a set of forms, and further each form can be expanded to fill data (the page is loaded with all panels collapsed by default).
The page is generated completely dynamically (as forms can be added in a database), and for generating the CollapsiblePanelExtenders I have the following code:
private CollapsiblePanelExtender GenerateCollapsiblePanelExtender(string id, Panel headerPanel, Panel contentPanel)
{
CollapsiblePanelExtender collapsiblePanel = new CollapsiblePanelExtender();
collapsiblePanel.ID = id + ID_COLLAPSIBLE_PANEL_POSTFIX;
collapsiblePanel.TargetControlID = contentPanel.ID;
collapsiblePanel.CollapseControlID = headerPanel.ID;
collapsiblePanel.ExpandControlID = headerPanel.ID;
collapsiblePanel.Collapsed = true;
collapsiblePanel.BehaviorID = collapsiblePanel.ID + ID_BEHAVIOUR_POSTFIX;
return collapsiblePanel;
}
With one user having 12 units each with 25 forms, this means a total of 312 CollapsiblePanelExtenders. As I said, they are all set to be collapsed by default, but here's the problem:
When the page loads, they all appear to be expanded, and then the browser "starts collapsing them". This however takes a very long time (in Firefox I even get a warning about an unresponsive script, IE and Chrome only takes forever but without the warning). When all the "collapsing" is complete it works smooth to open and close single panels, but users have complained about the extremely slow initial loading.
So my question is simple: is there a way to optimize this so that the loading goes smoother? Is it for instance possible to only load the header panels in each CollapsiblePanelExtender initially, and then load the content panel asynchronously in some way?
One final clarification:
I know I could simply change the design of the page to only include one unit and thus reducing size of the contents drastically, but I hope to avoid this (users prefer the way with everything in one page). It would also mean a rather large change to the logic of the page (yes, I know - it's a poor code base at that point)
After asking some more around other places, I finally managed to solve this issue. The solution was to skip the CollapsiblePanelExtenders altogether, and instead use jQuery to handle the collapsing/extending.
In my structure, all header panels use the css class HeaderPanel, and all content panels use the css class ContentPanel (all of these are hidden by default). I can then use the following script to handle all the collapse/expand logic:
<script language="javascript">
$(document).ready(function() {
$("div.HeaderPanel").toggle(
function() {
$(this).next("div.ContentPanel").show("slow");
},
function() {
$(this).next("div.ContentPanel").hide("slow");
});
});
</script>
The solution was really quite simple, and it works like a charm! The collapsing/extending is soo much smoother and nicer than what it looked like when I used the CollapsiblePanelExtenders, and the page loads really fast as well :)

Resources