iSeller Commerce
iSeller POS Retail
iSeller POS F&B
iSeller POS Express
Crosslight
WebUI
ClientUI
What's New
Download Trial
Web Solution
Mobile Solution
Enterprise Solution
Custom Development
Blog
Community
Latest Development Blogs
ForumPostTopic
Browse By Tag
Hi! I'm creating a new page with the following details:
When clicking on this special image, the data of all nodes below the selected row-node are being merged and no folders are shown anymore, only the leaf rows (like files) that are below the selected node (anywhere below). Clicking again should undo everything and return to the folder view.
In InitializeSelfReferenceDataSource I am loading the data below the current node and merging the data into the grid by calling dt.Merge (dt is the DataTable from e.DataSource).
My question would be on how to implement this special feature. When the user clicks on the image I think I should just delete all data below the current node from the RootTable of the grid, then get all data below the current node and merge it into the RootTable.
Now my question is how to implement the onclick event on the image. The image is being added simply by in InitializeRow using e.Row.Cells.GetNamedItem and setting cell.Image="plus.gif". But how do I put a onclick handler on that? And what should it do to refresh the data (requires postback to go to the server somehow).
Ok, I can store the merge-status now. The problem was that I tried to store it in the ViewState and during FlyPostBack the ViewState changes will not get saved onto the page.
Fixes to do this:
Now this all works. Remaining problems are:
Most important is now getting the expand/collapse to work (remain as it is when clicking merge/unmerge).
Regards,
Eric
Hi Handy,
Ok, after working on this for weeks now, I found the final solution. Manually caching the expand/collapse status now works.
What I have done:
Hello Eric,
I am not sure why you need to attach onclick event on the image.However, I think if you want to handle something in (+) or (-) images, you can use some available events such as, expand or collapse. It is easier to handle in available events.If you want to delete all data below the current node, I think you need to check if the current row has been expanded or not.To refresh data, you can use WebGrid1.Refresh() >> Clientside approachor WebGrid1.ClientAction.Refresh() >> Serverside approach, but it needs to have some postback action to call this.
Regards,Handy
Sorry if I didn't explain enough. You didn't understand me. We have two (2) such (+)/(-) boxes per row. One is the usual one drawn by WebGrid to expand and collapse the nodes. The second one, in a separate column, is to merge or unmerge all data below that node. These are two independent functions.
To illustrate this further, here an example of a tree view where the node 'Root' is expanded, but not the two nodes below (called "N1 (parent is Root)" and "N2 (parent is Root)"):
(-) Root (+)
(+) N1 (parent is Root)
(+) N2 (parent is Root)
As you can see, the node 'Root' has a second box on its right to merge (not expand) an a separate column.
If we expand the nodes N1 and N2, you would get this view:
(-) N1 (parent is Root)
Leaf1 (parent is N1)
Leaf2 (parent is N1)
(-) N2 (parent is Root)
Leaf3 (parent is N2)
Leaf4 (parent is N2)
This is just the same as before, but expanded. As you can see, the (+) on the root node remains ready to get clicked, although everything is expanded. The nodes N1 and N2 don't have this box, because they don't have nodes below (they only have leaf entries). In a more complex (deeper nested) tree, N1 and N2 would also have this (+) to get them merged.
If we click on the remaining (+), you would get this view:
(-) Root (-)
As you can see, this second (+)/(-) has a totally different functionality. The normal (+)/(-) are for the nodes to expand and collapse, whereas the second is to merge and unmerge the data below it.
I can draw the second column correctly by setting the MergeCol.Image="..." in InitializeRow.
My question was on how I could handle the clicks on this second column's images and force a reload of the data below that node after the click.
I hope this explanation was better.
Hi Eric,
I am sorry but I still could not understand some parts. Would you mind to send a simple runable sample that described this scenario?As far I know, you can attach an event in an object programmatically via javascript.All you need to obtain the element and use Listener.Example,
Listener.Add( el, "onclick", test);
el>> your element of object.test>>the function that you called when the event is fired.
Ok. Forget about all that hierarchical stuff in the first step.
I have a WebGrid. On aspx there is just the root WebGrid tag, an empty RootTable, some LayoutSettings and a tag for FlyPostBackSettings.
In code behind:
In the event grid_InitializeDataSource, I get the data from the DB and assign it to e.DataSource = ds:
Dim ds As DataSet = DBCall... ds.Tables(0).Columns.Add(New System.Data.DataColumn("Merge", Type.GetType("System.Boolean"))) e.DataSource = ds
in grid_Init:
AddGridColumn(...) grid.RootTable.DataKeyField = ".." grid.RootTable.SelfReferencingSettings...
in grid_InitializeSelfReferenceDataSource:
Dim ds as DataSet = DBCall(e.ParentKeyValues("...")) dt.Merge(ds.Tables(0), True, MissingSchemaAction.Error)
in grid_InitializeRow:
Dim Col As WebGridCell = e.Row.Cells.GetNamedItem("...") Col.Image = "merge_plus.gif"
As you can see in the last line mentioned, I add an image to the column. That image appears. I want to change the data of the grid when the user clicks on that image.
You were talking about some Listener object. That looks like a JavaScript object, not .NET. How would I use this Listener object to bind an event to the Col.Image above? In any case I need a postback to get the new data, so preferrably I don't use JavaScript at all.
If you want to add an image handler that way, it would be hard to achieve.It is easier, if you add a WebGridColumn with Button image type. There is already click event hadler from WebGrid.
Ok, I changed the column type from ColumnType.Image to ColumnType.ButtonImage and also the code to set the image in InitializeRow to use col.ButtonImage instead of col.Image.
Now I have a bunch of buttons in that column, but I have more problems than before. But maybe these are easier to solve:
I hope you can help here.
Thanks.
In the meantime I solved the two visual problems (3. and 4.) like this:
.ISButtonStyle { border:none 0 Red; background-color:Transparent; }
The color of the border will be ignored.
But questions 1. and 2. are still open.
Regards
Ok, the problem is now almost solved. I could solve problem (1.), getting the event to the server. I fixed it this way:
In the grid_Init event handler, when I create (add) the columns to the grid, I just have to add WebGridColumn.ButtonAutoPostback = True for the column with ColumnType.ButtonImage.
Then the grid_ButtonClick event handler gets called. I'm working on changing the data in the RootTable there now.
So only question (2.) remains. If I call grid.ClearCachedDataSource(), grid.RebindDataSource() everything goes away. But I need to keep the data in the modified RootTable and just refresh the display somehow after this postback. How should I do this?
Hello,
You could not do that way because you do FullPostBack. When you edit a cell and click the button to postback, WebGrid has not saved the data yet. So, it would revert back into the old data after PostBack.You need to shift+enter before clicking on the button.The possible way is doing this in client side/ javascript.
The grid is read-only. There is no need to save any data from the client-side. Except of the status of the open/closed nodes and that status of the merged/unmerged status of each node. For the latter, this changes the whole dataset, so it must be done on the server side always. And for the open/closed status of the nodes, I'll use the standard JavaScript code where I have examples already.
So I think I can do a full postback without problems. The only disadvantage would be the full page refresh, right? Going this way would mean that I would have to store in the OnClick event the changed merge/unmerge status and in the normal page or grid OnLoad event (actually in the InitializeDataSource) get the full data set in the new way.
Ok, you propose a smarter refresh through JavaScript. How would I attach an event handler to each button? And what should I do there to get the data in the grid updated and the display refreshed?
And another related problem: The Button_Click event comes after the Render event (actually I only tested PreRender). This is a problem, because if I change the ViewState in the Button_Click event handler, then my ViewState changes will not get rendered. What could I do to avoid this? I want to save the merge/unmerge-status of the clicked row somewhere. I don't think it I should use the database for this temporary data.
In Client side approach, there is also available WebGrid button click client side event.However, if you are not handling save in database and changes. everytime you refresh or RebindDataSource, it would revert back into the old or first data.
Ok, I found out how to get the client side events of the button clicks.
In case anybody else needs this, add to <LayoutSettings><ClientSideEvents> a tag OnButtonClick="xxx", where xxx is the name of your JavaScript function. In that JavaScript function I can do a postback or so:
function xxx(gridId,tblName,colName,cellValue){ var webGrid=wgGetGridById(gridId); if(webGrid.GetSelectedObject()==null) return; var row=webGrid.GetSelectedObject().GetRowObject(); var cell=wgGetCellByName(row.GetElement(),'ColName'); webGrid.AddInput('BlockId',cell.MyCustomAttr); webGrid.SendCustomRequest(); return true;}
The MyCustomAttr is being fetched from the CustomAttributes of another column. We have to do this, because the data needed is in a hidden column and JavaScript has no access to hidden columns, because they are not rendered. To assign the CustomAttributes I used the InitializeRow event and there I set col.CustomAttributes="MyCustomAttr=""" & value & """"
Now my questions:
Why should I need to store anything in a database? This is just temporary. I'd like to store this merge/unmerge flag in the ViewState (or something similar). I just don't get this working. If I set the Autopostback flag to true, like mentioned earlier, I still get a full postback and my ViewState is lost somehow on the postback.
Also, If you use all this client-side stuff like mentioned above, wouldn't it be better to directly use the ButtonClick event? I don't see the need to involve JavaScript at all.
So you know the requirements now. To repeat: I have a read-only hierarchical WebGrid. I need a button per row (is implemented) and I need a binary value per row with the merge/unmerge display status. Clicking on the button should invert this status. This status doesn't need to get stored anywhere, but it must be preserved during postbacks etc. Changing this status per row also changes all shown data in the hierarchical grid below the clicked node, so the data in the grid needs to get refreshed in that case. How would you implement all this?
Any updates?
---
I think it is not possible to do because it is read only. Even though you can SetText, however the value is not changed.That's why you could not obtain the value in viewstate because the value is not changed.Regards,Handy
Hi,
I never set WebGrid to "read-only" or something like that. It's just that I don't change the data in the WebGrid. And I think ViewState (of the page) would be ideally suited to store these values temporarily. Why shouldn't that work? And if not, what should I do? This must be possible somehow - it's trivial from a users perspective.
So you know the requirements now. To repeat: I have a read-only hierarchical WebGrid.
I am sorry but I don't quite understand about your requirement now. I know what you want to achieve but it seems your scenario is too complex. Would you mind to send me a simple sample that replicates the issue that you said in this scenario? It would be more easier if we can meet up the perception.I am sorry if there are any missunderstanding parts.
It took me several days to create this example. I hope it was worth the effort. The problem I had was that WebGrid showed unexpected behaviour when running this form standalone (out of our project). After long investigations I found out that in my sample I didn't use a Session object. Without touching the session, WebGrid doesn't work - probably another bug. You can see that in my sample if you comment out the line Session("abc")="def" in Page_Load. But anyway, now you have a sample.
When you click on one of the "plus" buttons in the merge column, then the grid data below there should get merged. What data is expected you can see from the data generation function.
If you "merge" a node, it actually should show all data rows below it, but not the "folder-type" rows.
So, here's the sample. Copy the ISNET dll's into the bin folder and also:
AjaxControlToolkit.dll, AJAXExtensionsToolbox.dll, System.Web.Extensions.Design.dll, System.Web.Extensions.dll, VwWebSite.Interop.dll
I'm using Framework 3.0.5000.705 and WebGrid 6.0.7200.220. Please use the same version.
Thank you for your sample. I can run it in here. However, when I click on "plus" images to merge the node, what should be happened? I don't see any changes in here.I will investigate the session issue that you mentioned. Btw, since this issue is getting to long, can we scheduler for remote desktop? With this way, I hope that we can find the solution faster.
Yes, nothing happens - that's the missing part I'm asking for.
What should happen: All entries (hierarchically) below the clicked button should be removed from the grid and replaced by what a new call to the DB function returns. This new call to the DB function has to get the input parameter DoMerge=True. Then the button should change to a "minus". When the user clicks on it again, all data below the clicked node should get removed from the WebGrid and replaced back with the data that comes from DB call with DoMerge=False. Then the button should change back to a "plus", like on the beginning.
Remote Desktop? You mean you access my PC? That's not possible here. There are hundrets of company firewalls and proxys and stuff inbetween.
I tried to save the merge-status in the ViewState, but even on normal postbacks (when a node gets expanded) the ViewState is cleared for some reason. I also don't want to save the data in the Session, because users often have several browser windows open. Maybe fix the ViewState problem or save it in a hidden input field or so?
I need a little time to investigate this issue. Actually, I am not directly remote into your environment. We can use tools such as logmein,sharedview or teamviewer. Those tools work as a web confrence that allow user to remote. You can also see what the other user action during the remote.Also, is not possible to save the status with a hidden field?
No chance to install any software. I would upgrade from our IE6 first.
Data storage for the boolean merge value per row is stored now in a hidden field as you can see in the example v2. So that part works now.
Remaining problems are (copied from post above):
Any update?
It seems your scenario could not be done.If you want to only refresh a child after merge ( changes only in a child), then It could not be done.WebGrid could not refresh partially only for a child. It should refresh all.This is a default behaviour. Our WebGrid still hasn't supported refresh only in child level yet.
Ok, no partial refreshes possible.
And what about my remaining questions?
I am not sure why the status in session is not working. I am still investigating this issue. However, if you want only to remember the state of expand/collapse, does this mean that It would remember if the state and persists expand/collapse when refreshed or merged?If yes, why don't you try RestoreExpandChildRows properties? After this properties is set as true, try to expand/collapse a row then refresh WebGrid. You can see that it still persists expand/collapse state.
Thanks for your helpful answer. First I searched for this property, but both Google and your site returned zero results. Then I assumed there was a typo. I also thought that WebGrid 6 doesn't support this feature. But I remember that we upgraded to WebGrid 6 not so long ago, so maybe this was valid only for WebGrid 5. Anyway, I found the property in the meantime. It is called RestoreExpandedChildRows and is located on the LayoutSettings tag.
I have set this to true and removed all other previous code to expand / collaps by JavaScript. Unfortunately it is still not working. Are you sure this should work with WebGrid version 6?
Can you modify my last sample so that it works? With this property or by any other means.
And yes, this is the main problem remaining.
Thanks,
I think the problem is that in FlyPostBack (InitializePostBack event), where I handle the button press, I use grid.ClientAction.Refresh to refresh the grid data after the merge button was pressed.
Because of this data (grid) refresh, the property RestoreExpandedChildRows probably has no effect, because this works only for normal FlyPostBack events like resorting etc.
Can you look at the sample again and tell me what to fix there so that it works? I tried to cache the expanded nodes like it was necessary before the property RestoreExpandedChildRow existed, but it doesn't work.
It would be great if you could fix the demo I created for you.
Ok, but please give me a little time to figure out your sample because your code is too complex.The properties won't work because you were using SelfReference scenario.The properties only works for Hierarchical scenario.
I found that the validation below cause your expand/collapse status issue.
If Not grdResult.IsFlyPostBack AndAlso Session(_SessionState_Expanded_WebGridRows) IsNot Nothing Then
If I only use the condition with below code, your expand/collapse works well.
If Session(_SessionState_Expanded_WebGridRows) IsNot Nothing Then
Back from my vacation, I read your response above. Your above code was about the problem why storing the values in the Session object might have failed. Correct?
Actually I'm not using the Session object anymore. As mentioned, I'm storing the expand/collapse status in a form field on the page. Please also see my attached sample, version 3. This is the final, working solution for me.
The only remaining problem, as mentioned in my last post, is why I have to initialize the Session object (line 20 in Default.aspx.vb). I assume a bug in WebGrid. Can you check that?
This issue is being investigated by our developer teams. I will let you know when I received response from them.
or
Choose this if you're already a member of Intersoft Community Forum. You can link your OpenID account to your existing Intersoft Social ID.
Choose this if you don't have an Intersoft account yet. Your authenticated OpenID will be automatically linked to your new Intersoft account.
Enter your Wordpress Blogname