I'm trying to have a button to move a row up or down; all on the client side - I'm finding a lot of column moving tools in the client side doc, but row manipulation seems to be distinctly lacking...
Does anyone have any good pointers on where to find some code to do a client side move of a row up/down?
Thanks
Figured I should include a snippet that I have - Everything works except the repaint.
I break on the lower command (gotta love chrome) and check the grid's datasource and it show my data in the reverse order (good ol' chrome). I'm lost on how to get the grid to visually reflect these changes.
If there is a more better different way to move a row up or down on the client side - I'm all for hearing it.
| var lblID = sender.id.replace("lnkMoveUp", "lblPathFlowID"); |
| var grdId = sender.parentNode.parentNode.parentNode.parentNode.parentNode.id; |
| var grd = $find(grdId); |
| grd.get_masterTableView().set_dataSource(grd.get_masterTableView().get_dataItems().reverse()); |
| grd.get_masterTableView().dataBind(); |
I break on the lower command (gotta love chrome) and check the grid's datasource and it show my data in the reverse order (good ol' chrome). I'm lost on how to get the grid to visually reflect these changes.
If there is a more better different way to move a row up or down on the client side - I'm all for hearing it.
3 Answers, 1 is accepted
0
Hello Baatezu,
Could you please review this online demo which implements row reorder on the client.
For more information about client method rebind() refer to this article.
All the best,
Georgi Krustev
the Telerik team
Instantly find answers to your questions on the new Telerik Support Portal.
Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
Could you please review this online demo which implements row reorder on the client.
For more information about client method rebind() refer to this article.
All the best,
Georgi Krustev
the Telerik team
Instantly find answers to your questions on the new Telerik Support Portal.
Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
0
Baatezu
Top achievements
Rank 2
answered on 27 Aug 2009, 06:58 AM
Thank you for the link - I had looked at that one before, but it wasn't close enough to what I want to do to pull the pieces I needed out of it.
I want to use buttons to move a row up or down a single level, not drag and drop.
What I ended up doing was using jQuery to traverse up the parent() elements to the TR, then go to the next() or prev() and swap the html() of the two rows.
Using some databound attributes I would do a jQuery ajax which updated my database so that serverside and client side remained in tandem.
I think it was my specific desire to not use drag and drop and use buttons that made it difficult to find a corresponding example for the grid to go from.
In case my snippets of code can be useful to anyone else - Here they are
The images to put in a <ItemTemplate> section of a TempateRow in the RadGrid
| <!-- These are the image controls I use as my Up and Down arrows |
| The class is used to make them easier to find with jQuery |
| The onclick is the javascript function used, this will pass the control triggering the event and true is because this is the Up button --> |
| <asp:Image ID="imgMoveUp" class="up" runat="server" onclick="grd_RowMove(this, true);" AlternateText="Move Up" ImageUrl="up.png"></asp:Image> |
| <asp:Image ID="imgMoveDown" class="down" runat="server" onclick="grd_RowMove(this, false);" AlternateText="Move Down" ImageUrl="down.png"></asp:Image> |
Here is my nice long ajax function that does all the work
| grd_RowMove: function(sender, isUp) { |
| //sender.TD.TR.?.MasterTable.Grid |
| var grdId = sender.parentNode.parentNode.parentNode.parentNode.parentNode.id; |
| //Use jQuery to get the control so jQuery is available to use. Such as for .parent() |
| var curRow = $("#" + sender.id).parent().parent(); |
| //jQuery allows an easy grab of the previous element, in this case the previous row |
| var prevRow = curRow.prev(); |
| //and next row |
| var nextRow = curRow.next(); |
| //A check to see if the control is in the top row |
| var isTop = prevRow.html() == null; |
| //Checking if it is in the bottom row |
| var isBottom = nextRow.html() == null; |
| //Checking if it will move to the top row |
| var willBeTop = prevRow.prev().html() == null && isUp; |
| //Checking if it will move to the bottom row |
| var willBeBottom = nextRow.next().html() == null && !isUp && !isBottom; |
| //As can be seen with the asp:Image above, I assign the class 'up' to the up image control |
| var curUp = curRow.find("img.up"); |
| //and a class of 'down' to the down image control |
| var curDown = curRow.find("img.down"); |
| //assigning the up/down class makes it much easier to grab the control using jQuery |
| //A blank var to act as a temp variable for the swap. |
| var curRowHTML = ""; |
| //Getting the ID for the triggering row, swapping the name of the control (imgMoveUp) with the known label control, lblId. |
| //This works because of how the extended names are generated, since they are on the same level, the entire prefix is identical |
| //Won't always be required, depends on the application - I use DotNetNuke, so it's there, and the same for things in the same level |
| var trigId = curUp.attr("id").replace("imgMoveUp", "lblId"); |
| //Variable for the target row - Done the same way as specified above |
| var targId = ""; |
| //If we are moving up and are not the top row. |
| //I had trouble getting jQuery to properly change the onclick value to disable javascript for the top and bottom rows |
| //I had to implement this to prevent the top row from moving up... which made it disappear into... I don't know where |
| if (isUp && !isTop) { |
| //Grab the target row ID, same as mentioned in where it's defined. |
| targId = prevRow.find("img.up").attr("id").replace("imgMoveUp", "lblId"); |
| //If we are moving to the top row |
| if(willBeTop){ |
| //Get the previous rows up image |
| var prevUp = prevRow.find("img.up"); |
| //Change the attributes of the buttons to enable and disable the up image |
| prevUp.attr("src", "../../DesktopModules/SmiBoardingFlowEntry/up.png"); |
| curUp.attr("src", "../../DesktopModules/SmiBoardingFlowEntry/null.png"); |
| } |
| //If we are the bottom button |
| if(isBottom){ |
| //Get the previous rows down image |
| var prevDown = prevRow.find("img.down"); |
| //Change the attributes of the buttons to enable and disable the down image |
| prevDown.attr("src", "../../DesktopModules/SmiBoardingFlowEntry/null.png"); |
| curDown.attr("src", "../../DesktopModules/SmiBoardingFlowEntry/down.png"); |
| } |
| //Do the row swap. |
| //This changes the location of the HTML, so nothing actually changes. |
| //Since it's all done on client side, any postback where the grid will be refreshed |
| //and not rebound will lose the order placement. |
| //In my case - It's just the grid on the page, so any page refresh is caused by the grid, |
| //ensuring a rebind, which pulls the updated data, which matches the client side display |
| curRowHTML = curRow.html(); |
| curRow.html(prevRow.html()); |
| prevRow.html(curRowHTML); |
| } |
| //Using else if, or else the top and bottom row would still execute this javascript |
| //Makes sure we aren't going up, and that we are not at the bottom |
| else if(!isUp && !isBottom){ |
| //Grab the target row ID, same as mentioned in where it's defined. |
| targId = nextRow.find("img.up").attr("id").replace("imgMoveUp", "lblId"); |
| if(willBeBottom) { |
| //Get the previous rows down image |
| var nextDown = nextRow.find("img.down"); |
| //Change the attributes of the buttons to enable and disable the down image |
| nextDown.attr("src", "../../DesktopModules/SmiBoardingFlowEntry/down.png"); |
| curDown.attr("src", "../../DesktopModules/SmiBoardingFlowEntry/null.png"); |
| } |
| if (isTop) { |
| //Get the previous rows up image |
| var nextUp = nextRow.find("img.up"); |
| //Change the attributes of the buttons to enable and disable the up image |
| nextUp.attr("src", "../../DesktopModules/SmiBoardingFlowEntry/null.png"); |
| curUp.attr("src", "../../DesktopModules/SmiBoardingFlowEntry/up.png"); |
| } |
| //Swapping |
| curRowHTML = curRow.html(); |
| curRow.html(nextRow.html()); |
| nextRow.html(curRowHTML); |
| } |
| //Does an ajax update only when a row was swapped. |
| //I could simplify the if - but it is a clear combination of the two if's above |
| //I could also simplify by checking if curRowHTML was "" - If you want it minimal |
| if ((isUp && !isTop) || (!isUp && !isBottom)) |
| { |
| //Get's the target and triggering lblId html. |
| //The lblId is where I store my UID value from the database for that row. |
| var trigHtml = $("#" + trigId).html(); |
| var targHtml = $("#" + targId).html(); |
| //This is the jQuery ajax postback. It is beautiful :) |
| //My first time using it - my requests finish in under 200ms |
| //For general information on it - please see http://docs.jquery.com/Ajax |
| jQuery.ajax({ |
| type: "POST", |
| url: location.href, |
| dataType: "json", |
| //I am passing data with the post request. The above dataType spefifies the data format. |
| //ACTION : Function - In my codebehind I have a few checks to determine what the post back is supposed to do |
| //FUNCTION : 'functionName' - This is the actual function name in my serverside code, I use reflection to call it |
| //param# : 'data' - I use generic parameter names so they can be used generically. |
| data: ({ 'ACTION': 'Function', 'FUNCTION': 'PathGroupDisplayOrderChange', 'param0': trigHtml, 'param1': targHtml, 'param2' : isUp }), |
| success: function(data) {//When things work |
| }, |
| error: function(XMLHttpRequest, textStatus, errorThrown) {//When things fail |
| //Swapping the rows back |
| curRowHTML = curRow.html(); |
| if(isUp && !isTop){ |
| curRow.html(prevRow.html()); |
| prevRow.html(curRowHTML); |
| } |
| else if(!isUp && !isBottom){ |
| curRow.html(nextRow.html()); |
| nextRow.html(curRowHTML); |
| } |
| //Let 'em know it didn't work |
| alert("Row movement failed. Please try again - Or refresh the page"); |
| }, |
| beforeSend: function(xhr) { |
| //This is a simple way for me to identify this as an AJAX request. |
| xhr.setRequestHeader("X-OFFICIAL-REQUEST", "TRUE"); |
| //This is where you can show a loading panel or some other indicator. |
| //$('#ajaxLoadingPanel').show(); |
| }, |
| complete: function(XMLHttpRequest, textStatus) { |
| //Thisis where you would turn off the indicator. - My case is fast, this just flickers |
| //$('#ajaxLoadingPanel').hide();//Can Hide a loading panel |
| } |
| }); |
| } |
| } |
It is much shorter without the commentary - I added that specifically for this post.
On the server side I have
| protected override void OnInit(EventArgs e) |
| { |
| if (Request.Headers["X-OFFICIAL-REQUEST"] == "TRUE") |
| { |
| AjaxWrapper(); |
| } |
| base.OnInit(e); |
| } |
The function I use to update (serverside) my two rows is very small, 4 database hits (1 to pull, 1 to update - Done twice - I use netTiers, I could shrink it but...) and not much else - The entire AJAX request is a miniscule 50ish milliseconds. So I'm not too worried about speeding that up. :) Lowest I had was around 20ms, the highest I managed to get it was 120ms. And that was when I was clicking as fast as I could.
I hope this post and snippets of code prove to be useful to someone for something. :)
0
Hello Baatezu,
Thank you for your cooperation and for the attached code snippets. I have uprated your Telerik points.
Regards,
Georgi Krustev
the Telerik team
Instantly find answers to your questions on the new Telerik Support Portal.
Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
Thank you for your cooperation and for the attached code snippets. I have uprated your Telerik points.
Regards,
Georgi Krustev
the Telerik team
Instantly find answers to your questions on the new Telerik Support Portal.
Watch a video on how to optimize your support resource searches and check out more tips on the blogs.