I am using ReportViewer 11 to display a report inside an iframe (aspx page is loaded into iframe). It displays first page properly. But when I click on next page, it loads the first page again. Even if I type in page number manually into the textbox, it loads first page only. It seems like, it doesn't fire the pagenavigation event in the server side. If I set the currentpage property to 2 in code behind, then also it loads page 1 only no matter what settings I provide.
Searched for this for days. Got no solution.
Any help will be appreciated.
Thanks
Apply this logic
Store the records in container1
Pass the records to container2
print 5 records(or may be more) from container2
when "next" button is pressed print next 5 from container2
and so on.
I dont know whether this will help you, but records from database can be paginated in this way.
I have tried this logic too. But the main problem is that ReportViewer.CurrentPage is 0 always (in my case) even when the "next" button is pressed. So it will again show the container1 records. This is my code:
public void SetReportData(ref ReportViewer objRptVwr, ReportParameter[] rptParam, string moduleName, string reportName, string dsName, System.Data.DataTable dtFinal){
objRptVwr.Reset();
objRptVwr.ProcessingMode = ProcessingMode.Local;
objRptVwr.LocalReport.ReportPath = HttpContext.Current.Server.MapPath("~/ReportViewer/" + moduleName + "/" + reportName + ".rdlc");
if (rptParam != null)
objRptVwr.LocalReport.SetParameters(rptParam);
objRptVwr.ShowPrintButton = true;
objRptVwr.ShowParameterPrompts = true;
objRptVwr.AsyncRendering = false;
objRptVwr.InteractivityPostBackMode = InteractivityPostBackMode.AlwaysSynchronous;
objRptVwr.ShowBackButton = true;
objRptVwr.SizeToReportContent = false;
objRptVwr.PageCountMode = PageCountMode.Actual;
objRptVwr.ShowExportControls = true;
objRptVwr.ShowPageNavigationControls = true;
objRptVwr.ShowToolBar = true;
objRptVwr.ShowWaitControlCancelLink = false;
objRptVwr.ShowZoomControl = true;
objRptVwr.LocalReport.EnableExternalImages = true;
objRptVwr.ExportContentDisposition = ContentDisposition.AlwaysInline;
ReportDataSource reportDataSource = new ReportDataSource(dsName, (System.Data.DataTable)dtFinal);
objRptVwr.LocalReport.DataSources.Clear();
objRptVwr.LocalReport.DataSources.Add(reportDataSource);
objRptVwr.LocalReport.Refresh();
}
What I did that the generated buttons will be according to the list size.
Each buttons(may be li tag) will have a textfield containing value like 0,5,10 and so on dynamically(In case of 5 elements per page).
A button is clicked, the value of that textfield(e.g index) I got and shifted the resulset position to index and print the records upto 5 elements.
Related
I want to save just one page of a document but when i try to save it doesn't give me any option and it saves all 15 pages in just one document. Is there any way to do select only one page?
I have a similar code. Maybe this will help you.
Procedure SaveDocument(ObjectDocument) Export
// Printing the first page
SpreadsheetDocument = New SpreadsheetDocument;
SpreadsheetDocument.FitToPage = ObjectDocument.FitToPage;
SpreadsheetDocument.PageOrientation = ObjectDocument.PageOrientation;
SpreadsheetDocument.PrintScale = ObjectDocument.PrintScale;
SpreadsheetDocument.PageSize = ObjectDocument.PageSize;
For counter = 1 To ObjectDocument.TableHeight Do
SpreadsheetDocument.Clear();
SpreadsheetDocument.Put(ObjectDocument.GetArea(1,1,counter,ObjectDocument.TableWidth));
If SpreadsheetDocument.PageCount() > 1 Then
EndOfFirstPage = counter - 1;
Break;
EndIf;
EndDo;
Output(ObjectDocument.GetArea(1,1, EndOfFirstPage, ObjectDocument.TableWidth))
EndProcedure
I have a problem getting the tabPage->Name value, because it will generate when user click the button, first block of my code will create new tabsheet inside PageControl3 and then I use the static int tabNumber; by if condition to generate the tabPage->Caption and then I use the caption for tabPage->Name dynamically.
I need the name of that tabsheet to pass it on the Error line.
static int tabNumber;
if (tabNumber >= 1) ++tabNumber;
else tabNumber = 1;
PageControl3->Visible = true;
TTabSheet *tabPage = new TTabSheet(PageControl3);
tabPage->PageControl = PageControl3;
tabPage->Caption = UnicodeString("Untitled") + IntToStr(tabNumber);
tabPage->Name = UnicodeString("ts") + tabPage->Caption;
The second part of my code should create new TPanel inside current tabpage->Name that was created in the above part of my code, BUT it wont work.
TPanel *panelPage = new TPanel(tabPage->Name); // Error Line
panelPage->Align = alClient;
panelPage->Name = UnicodeString("panel") + tabPage->Caption;
Error massage:
[bcc32 Error] mainUnit.cpp(50): E2285 Could not find a match for 'TPanel::TPanel(const UnicodeString)'
So I not know how to access the tabPage->Name value, because that was create dynamically?
DB Baxter The constructor requires a component variable/object and not a string with the text of the name. Such as TPanel *panelPage = new TPanel(tabPage); Will that work for you? Do you need to make the panel's parent tabPage?
By helping DB Baxter, I think the correct and complete answer for create dynamic TPanel inside the dynamic TTabSheet will requires a component variable/object and then for displaying the TPanel we should use the whatever->show(); command, the full code can bee like this:
static int tabNumber = 0;
if (tabNumber >= 1) {
++tabNumber;
} else {
tabNumber = 1;
PageControl3->Visible = true;
}
// create new tab sheet inside PageControl3
TTabSheet *tabSheet = new TTabSheet(PageControl3);
tabSheet->PageControl = PageControl3;
tabSheet->Caption = UnicodeString("Untitled") + IntToStr(tabNumber);
tabSheet->Name = UnicodeString("ts") + tabSheet->Caption;
// create new panel inside the current tab sheet
TPanel *panelBox = new TPanel(tabSheet);
panelBox->Parent = tabSheet;
panelBox->Align = alClient;
panelBox->Name = UnicodeString("panelPage") + IntToStr(tabNumber);
panelBox->BevelOuter = bvNone;
panelBox->ShowCaption = true;
panelBox->Caption = UnicodeString("panel") + tabSheet->Caption;
panelBox->Show();
I hope this code can help anyone to generate the dynamic tab sheet with panel, by the way if you want add some frame to it the following code should use:
// adding the registration frame to the panel
TregFrame *newRegistration = new TregFrame(panelBox);
newRegistration->Parent = panelBox;
newRegistration->Align = alClient;
Note: don't forget to include your frame in your working file, for example #include "registrationFrame.h".
In the following code I create 3 boxes with the text 1 to 3, in a fourth box I'd like to show the text of the box my mouse is hovering over. So i set an onMouseEnter FProperty for each of the boxes where I change the string of the fourth box and tell it to redraw.
bool redraw = false;
str s = "0";
Figure getTextbox() {
return computeFigure(bool() {bool temp = redraw; redraw = false; return temp; },
Figure() {
return text(str() {return s; });
});
}
list[Figure] boxes = [];
for (i <- [1..4]) {
boxes += box(text(toString(i)), onMouseEnter(void () {s = toString(i); redraw = true; }));
}
Figure changer = box(getTextbox());
render(vcat(boxes + changer));
However, for some odd reason all three boxes will tell the onMouseEnter method to change the text of the fourth box into "3" (the value of the last box) instead of their individual value.
Any clue why? Thanks!
Ah yes, this is the variable capturing closure problem with for loops, also known from other languages which have this particular feature like Javascript. This is the code with the issue:
for (i <- [1..4]) {
boxes += box(text(toString(i)), onMouseEnter(void () {s = toString(i); redraw = true; }));
}
The variable i is bound by the void closure and not its value. So every time the function which is created and passed to onMouseEnter it will read the latest value of the i variable. Since the callback is called after the loop terminates, all calls to the mouse enter function will have the value 3.
To fix this and "do what you want", the following code would work I believe:
for (i <- [1..4]) {
newS = toString(i);
boxes += box(text(toString(i)), onMouseEnter(void () {s = newS; redraw = true; }));
}
This works because for every pass of the for loop a new environment is created which binds the newS variable. So you'll get a fresh newS for every loop instead of the reused i.
I have a Ruby on Rails project where I use a DHTMLX Grid.
Is there a way of showing, using the event handler "onFullSync" provided by the grid API, to show updated data?
Let me explain a little better... I know I can do something like:
dp.attachEvent("onFullSync", function(){
alert("update complete");
})
But what I want is something more complex. I want to, after each completed update, alter a div adding the information like this:
Field 2 was updated to XYZ and field 3 was updated to XER on line X
Field 1 was updated to 123 and field 3 was updated to XSD on line Y
Is this possible?
Thanks
There is a onAfterUpdate event that can be used similar to onFullSync
http://docs.dhtmlx.com/api__dataprocessor_onafterupdate_event.html
It will fire after each data saving operation ( if you are saving 5 rows - it will fire 5 times )
Still, info about updated columns will not be available here.
Also, you can try onEditCell event of grid. It fires after changing data in db, but before real saving in database. Here you can get all necessary info - row, column, old value and new value.
http://docs.dhtmlx.com/api__link__dhtmlxtreegrid_oneditcell_event.html
So, what I end up doing was:
After creating the grid I created an array:
var samples = [];
Then, as per #Aquatic suggestion, I added to "onEditCell" event the following line:
samples[samples.length] = grid.cells(rId, 5).getValue();
This allowed me to add to the array the value present on column 5 of the row changed. Then, on "onFullSync" event I hide or show the div created on the view with the messages (I distinguish if it's on row or more changed on the grid).
//Deals with messages after update
dp.attachEvent("onFullSync", function(){
unique_samples = uniq_fast(samples.sort());
if (unique_samples.length == 1){
$('#updated-samples').text("");
$(".messages").show();
$('#updated-samples').text("A seguinte amostra foi actualizada: " + unique_samples[0]);
//to clear the array
samples = [];
} else if (unique_samples.length > 1){
$('#updated-samples').text("");
$(".messages").show();
$('#updated-samples').text("As seguintes amostras foram actualizadas: " + unique_samples.sort().join(", "));
//to clear the array
samples = [];
} else {
$('#updated-samples').text("");
$(".messages").hide();
//to clear the array
samples = [];
}
})
The problem with using "onEditCell" is that everytime a field is changed on that row I get a repeated value on my "samples" array, I I had to remove duplicate from that array. For that I used one of the suggestions at this answer
// remove duplicates in array
function uniq_fast(a) {
var seen = {};
var out = [];
var len = a.length;
var j = 0;
for(var i = 0; i < len; i++) {
var item = a[i];
if(seen[item] !== 1) {
seen[item] = 1;
out[j++] = item;
}
}
return out;
}
Then I have on the beginning of the view, to show the messages:
<div class="alert alert-success messages" id="updated-samples">
And that's it. I could be not the most efficient way but it works for what I wanted. I will leave the question open a few more days to see if any other option appears.
I would like to disregard the first n items in a pager list of items. I.e. they are being used elsewhere in the design.
So my pager list needs to be as such:
Page 1: Items 8 - 17
Page 2: Items 18 - 27
Page 3: Items 28 - 37
...
However, setting an offset or limit in the criteria object does nothing. I presume they are used by the pager itself.
Is it possible to add a offset to the pager class in some other way?
Ok, I have got around the problem by modifying sfPropelPager.class.php and putting it into a new class file which I have named atPropelPagerOffset.class.php
It works in exactly the same way apart from it takes an extra parameter, $offset
So the top of the file looks like:
protected
$criteria = null,
$peer_method_name = 'doSelect',
$peer_count_method_name = 'doCount',
$offset = 0;
public function __construct($class, $maxPerPage = 10, $offset = 0)
{
parent::__construct($class, $maxPerPage);
$this->setCriteria(new Criteria());
$this->tableName = constant($class.'Peer::TABLE_NAME');
$this->offset = $offset;
}
Then I have made this tiny change around line 50
$c->setOffset($offset+$this->offset);
Works a treat!
Simpler solution would be a custom select method:
$pager->setPeerMethod('doSelectCustom');
and then put your logic in the model Peer Class:
public static function doSelectCustom($c)
{
$c2 = clone $c;
$offset = $c2->getOffset();
$limit = $c2->getLimit();
$someCustomVar = someClass::someMethod();
if ($offset == 0) // we are in the first page
{
$c2->setLimit($limit - $someCustomVar);
$c2->add(self::SOMECOLUMN, false);
} else $c2->setOffset($offset - $someCustomVar);
return self::doSelectRS($c2); // or doSelect if you wanna retrieve objects
}