General XMetaL Discussion
XMetaL Community Forum › General XMetaL Discussion › Moving Rows and Columns for CALS Table
-
MrPaul April 5, 2013 at 9:17 pm
Moving Rows and Columns for CALS Table
April 5, 2013 at 9:17 pmParticipants 2Replies 3Last Activity 9 years, 10 months agoI am implementing the “Move row or column” functionality for a CALS table and am wondering about setting the enable/disable state of the following options in my dialog based on the current selection, before actually calling the internal built in functions.
– Move row up
– Move row down
– Move column left
– Move column rightBasically, if you're anywhere in the first row (or in the thead element if there's one), you shouldn't be able to move the row up so that option should be disabled. If you're in the left most column, you shouldn't be able to select “Move column left”, etc. I want the dialog to display the states the same way that Author does it, but with XMAX v6.
Is there a quick way to achieve this functionality?
Thanks in advance.
Derek Read April 5, 2013 at 10:21 pm
Reply to: Moving Rows and Columns for CALS Table
April 5, 2013 at 10:21 pmThere are no APIs that let you ask “Can the current row be moved up?” (etc…) so I think you will need to implement some logic based on the current user's selection in this case.
This type of logic would probably do it:
1. Create a Range from ActiveDocument.Selection.
2. Check to see if the Range is inside a table using InContextOfType. If it is true then continue, otherwise everything should be disabled (or you should have already checked this before even launching your own dialog)…
3. Move the Range backwards (or into the parent depending on which APIs you prefer) until you get to a row.
4. Check to see if the selection has a previousSibling that is also a row (that's a DOM call so you'd need to also convert the Range to a node to use that, otherwise you could continue moving the Range but I think using previousSibling is probably better).MrPaul April 8, 2013 at 6:35 pm
Reply to: Moving Rows and Columns for CALS Table
April 8, 2013 at 6:35 pmI'm not sure I understand your steps 3 and 4. When you talk about moving the range backwards, do you mean using ActiveDocument.Range.MoveUp()? Do I need to move up more than once to check if it has a row above the current selection or will MoveUp always go to the previous row, even if the selection is in the top most tbody row (row 2a in my example) and the table has a header?
[code]
header 1a
header 1b
header 1c
row 2a
row 2b
row 2c
row 3a
row 3b
row 3c
[/code]
I'm also unsure about what you mean for checking that previousSibling is also a row. Could you provide an example?
I have something like this:
[code]var rng = ActiveDocument.Range;
rng.MoveUp();
if (Selection.IsEqual(rng)) {
// cannot move row up
else {
// can move row up
}[/code]I was hoping that rng.MoveUp() would stay put when the selection is in “header 1a” in my example, but it still seems to change so this code always falls into the else…
Derek Read April 8, 2013 at 8:36 pm
Reply to: Moving Rows and Columns for CALS Table
April 8, 2013 at 8:36 pmThe user's selection is most likely going to be inside an entry or one of its children (if allowed by your DTD — most DTD define paragraph-like and formatting-like elements for use inside entry, such as
, , etc). You need to check if the current row has a row before it. I think something similar to the following may be close to what you are looking for: [code]//XMetaL Script Language JScript:
//Assumptions:
// We are working with CALS tables that use lowercase element names.
// The document is valid.var rng = ActiveDocument.Range;
//Check if we're in a table cell:
if(rng.InContextOfType(“tablecell”)) {
var nd = rng.ContainerNode;
var emergencyBreak = 0;
//If we're not already in a row then move to a parent that is:
while(nd.nodeName != “row”) {
nd = nd.parentNode;
emergencyBreak++;
if(emergencyBreak > 20) {
//Something has probably gone wrong.
//”emergencyBreak” is my way of saying I threw this code together but YOU need to test it.
//Once all potential cases are handled properly this is probably not necessary.
break;
}
}
//Check if the row has a row before it:
var prevSibling = nd.previousSibling;
if(prevSibling) {
//The following check may be redundant:
if (prevSibling.nodeName == “row”) {
//…your code for enabling / disabling stuff goes here…
Application.Alert(“has row before…”);
}
}
//Check if the row has a row before it:
var nextSibling = nd.nextSibling;
if(nextSibling) {
//The following check may be redundant:
if (nextSibling.nodeName == “row”) {
//…your code for enabling / disabling stuff goes here…
Application.Alert(“has row after…”);
}
}
}[/code]You would need to have similar code to check for “columns”. In that case check to see if the current entry has a previousSibling.
-
AuthorPosts
- You must be logged in to reply to this topic.