General XMetaL Discussion

XMetaL Community Forum General XMetaL Discussion Moving Rows and Columns for CALS Table

  • MrPaul

    Moving Rows and Columns for CALS Table

    Participants 2
    Replies 3
    Last Activity 9 years, 6 months ago

    I 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 right

    Basically, 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.

    Reply

    Derek Read

    Reply to: Moving Rows and Columns for CALS Table

    There 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).

    Reply

    MrPaul

    Reply to: Moving Rows and Columns for CALS Table

    I'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…

    Reply

    Derek Read

    Reply to: Moving Rows and Columns for CALS Table

    The 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.

    Reply

  • You must be logged in to reply to this topic.

Lost Your Password?

Products
Downloads
Support