Hello. I was wondering...
I use reports in simple aspx page, in local processing mode (.RDLC reports).
I want to customize output of report viewer control, so that I can put textboxes into report.
Currently, when you have a table in report bound to some data source,
report table cell is wrapped into some TD and DIV elements, with some class attributes
with cryptic values. For example:
<td class="Aee342afe97834395b087ea29bc3c321326cl" style="height: 6.35mm;">
<div class="Aee342afe97834395b087ea29bc3c321326">SomeData
</div>
</td>
I got an idea, what If I override this somehow, and replace this DIV element with
<INPUT TYPE="textbox" ...>.
I succeded, by overriding Render method of my aspx page.
In Render method, i made regex matching of this div elements on HtmlTextWriter output, something like this:
string pattern = "DIV\\s*class=\"([^\\>]*)\"\\>([^\\<]*)</DIV\\>";
With this I can do some pretty interesting things.
1. My first try was to replace HtmlTextWriter output, so TD and DIV elements from above would look something like this:
<td class="Aee342afe97834395b087ea29bc3c321326cl" style="height: 6.35mm;">
<input type="textbox" class="updatable" tableName="Customers" attibuteName="CustomerName" id="id1234" >SomeData
</div>
</td>
After this, i have a textboxes on the client side, and they have attributes (tableName, attributeName, id) which I
can use to make server calls from javascript and update data in database.
For example, I call some Update.aspx page with params, for example:
Update.aspx?updateFlag=1&tableName=Customers&attributeName=CustomerName&id=1234&value=customer123
With this, I actually succeded to update the database table.
But, problem is with ajax. If I click refresh in report viewer control, it uses some ajax calls and has some dynamic javascript.
This javascript methods expect specific length of http response, but because I changed http response in server-side Render method,
this won't work. Javascript errors are thrown, when ajax response is parsed.
So I decided, I won't change default http response in Render method in this way.
2. My second try was to make changes clientside.
Idea: What if I generate only javascript in render method, write it to response, and made DIVs into <INPUT type=textbox> on the client side?
I rendered following method to the client:
function GetXData() {
this.tableName='Customers';
this.attributeNames=['CustomerId', 'ContactName', 'City', 'Country'];
this.idAttributeName='CustomerId';
this.rowIds=['Aee342afe97834395b087ea29bc3c32139','Aee342afe97834395b087ea29bc3c321326','Aee342afe97834395b087ea29bc3c321326','Aee342afe97834395b087ea29bc3c321326','Aee342afe97834395b087ea29bc3c321326','Aee342afe97834395b087ea29bc3c321326','Aee342afe97834395b087ea29bc3c321326','Aee342afe97834395b087ea29bc3c321326','Aee342afe97834395b087ea29bc3c321326','Aee342afe97834395b087ea29bc3c321326','Aee342afe97834395b087ea29bc3c321326','Aee342afe97834395b087ea29bc3c321326','Aee342afe97834395b087ea29bc3c321326','Aee342afe97834395b087ea29bc3c321326','Aee342afe97834395b087ea29bc3c321326','Aee342afe97834395b087ea29bc3c321326','Aee342afe97834395b087ea29bc3c321326','Aee342afe97834395b087ea29bc3c321326','Aee342afe97834395b087ea29bc3c321326','Aee342afe97834395b087ea29bc3c321326','Aee342afe97834395b087ea29bc3c321326'];
this.colIds=['Aee342afe97834395b087ea29bc3c32139','Aee342afe97834395b087ea29bc3c321313','Aee342afe97834395b087ea29bc3c321317','Aee342afe97834395b087ea29bc3c321321','Aee342afe97834395b087ea29bc3c321326','Aee342afe97834395b087ea29bc3c321330','Aee342afe97834395b087ea29bc3c321334','Aee342afe97834395b087ea29bc3c321338','Aee342afe97834395b087ea29bc3c321326','Aee342afe97834395b087ea29bc3c321330','Aee342afe97834395b087ea29bc3c321334','Aee342afe97834395b087ea29bc3c321338','Aee342afe97834395b087ea29bc3c321326','Aee342afe97834395b087ea29bc3c321330','Aee342afe97834395b087ea29bc3c321334','Aee342afe97834395b087ea29bc3c321338','Aee342afe97834395b087ea29bc3c321326','Aee342afe97834395b087ea29bc3c321330','Aee342afe97834395b087ea29bc3c321334','Aee342afe97834395b087ea29bc3c321338','Aee342afe97834395b087ea29bc3c321326','Aee342afe97834395b087ea29bc3c321330','Aee342afe97834395b087ea29bc3c321334','Aee342afe97834395b087ea29bc3c321338','Aee342afe97834395b087ea29bc3c321326','Aee342afe97834395b087ea29bc3c321330','Aee342afe97834395b087e
a29bc3c321334','Aee342afe97834395b087ea29bc3c321338','Aee342afe97834395b087ea29bc3c321326','Aee342afe97834395b087ea29bc3c321330','Aee342afe97834395b087ea29bc3c321334','Aee342afe97834395b087ea29bc3c321338','Aee342afe97834395b087ea29bc3c321326','Aee342afe97834395b087ea29bc3c321330','Aee342afe97834395b087ea29bc3c321334','Aee342afe97834395b087ea29bc3c321338','Aee342afe97834395b087ea29bc3c321326','Aee342afe97834395b087ea29bc3c321330','Aee342afe97834395b087ea29bc3c321334','Aee342afe97834395b087ea29bc3c321338','Aee342afe97834395b087ea29bc3c321326','Aee342afe97834395b087ea29bc3c321330','Aee342afe97834395b087ea29bc3c321334','Aee342afe97834395b087ea29bc3c321338','Aee342afe97834395b087ea29bc3c321326','Aee342afe97834395b087ea29bc3c321330','Aee342afe97834395b087ea29bc3c321334','Aee342afe97834395b087ea29bc3c321338','Aee342afe97834395b087ea29bc3c321326','Aee342afe97834395b087ea29bc3c321330','Aee342afe97834395b087ea29bc3c321334','Aee342afe97834395b087ea29bc3c321338','Aee342afe97834395b087ea29bc3c321326','Aee342afe97834395b
087ea29bc3c321330','Aee342afe97834395b087ea29bc3c321334','Aee342afe97834395b087ea29bc3c321338','Aee342afe97834395b087ea29bc3c321326','Aee342afe97834395b087ea29bc3c321330','Aee342afe97834395b087ea29bc3c321334','Aee342afe97834395b087ea29bc3c321338','Aee342afe97834395b087ea29bc3c321326','Aee342afe97834395b087ea29bc3c321330','Aee342afe97834395b087ea29bc3c321334','Aee342afe97834395b087ea29bc3c321338','Aee342afe97834395b087ea29bc3c321326','Aee342afe97834395b087ea29bc3c321330','Aee342afe97834395b087ea29bc3c321334','Aee342afe97834395b087ea29bc3c321338','Aee342afe97834395b087ea29bc3c321326','Aee342afe97834395b087ea29bc3c321330','Aee342afe97834395b087ea29bc3c321334','Aee342afe97834395b087ea29bc3c321338','Aee342afe97834395b087ea29bc3c321326','Aee342afe97834395b087ea29bc3c321330','Aee342afe97834395b087ea29bc3c321334','Aee342afe97834395b087ea29bc3c321338','Aee342afe97834395b087ea29bc3c321326','Aee342afe97834395b087ea29bc3c321330','Aee342afe97834395b087ea29bc3c321334','Aee342afe97834395b087ea29bc3c321338','Aee342afe97834
395b087ea29bc3c321326','Aee342afe97834395b087ea29bc3c321330','Aee342afe97834395b087ea29bc3c321334','Aee342afe97834395b087ea29bc3c321338']; return this;
}
This is all information that I need to change my DIVs into INPUT tags.
I have rowIds (so I can update matching rows in database), i have table name, i have
name of column that is primary key, and I have columnIds, which uniquely identifies every cell in report table.
I can also bind some change method for every cell of report table. For example:
var xData = GetXData();
$.each(xData.colIds, function (i, val) {
//gets DIVs inner html
var text = $("." + val)[0].innerHTML;
//replace DIV with INPUT
$("." + val).replaceWith("<input type='textbox' value='"+text+"'/>");
//HERE GOES SOME CODE TO BIND ONCHANGE EVENT TO INPUT TAG, SO I CAN MAKE AJAX CALLS TO UPDATE DATABASE WITH INPUT DATA
});
But, problem is that DIV class attribute values of Report Table repeat. After all, these are class attributes.
Because of this, i cannot use class of DIVs as unique identifier of cells.
I stopped here.
3. Now, what do I do next?
I could rewrite DIV class values in Render method, so they could be unique. I will probably do that.
Then i'll have unique mapping of reports datatable cell with field in database.
But all this chemicals that I do, can they be avoided?
Is there a better way for this.
You're maybe wondering why would I want to do any of this?
If I could make this, I would have fast data entry application.
I could use standard report desiging advantages, and have a fast update of data.
Think about it, report has everything we need - datasources made by select queries (which tells us what to update),
and advanced UI design.
If we can get
<input type='textbox' tableName="xx" attributeName="yy" primaryKeyId="zz">
for every textbox in report (which is currently rendered as DIV),
and some javascript functions that make ajax calls to update data on server/database
we would be very powerful.
Can this be done by Rendering Extensions or something? Has anyone done someting like this? Opensource solution?
(I'm not considering security and other aspects here. Insert and delete of data is also questionable).
Please, feel free to comment.