Skip to main content
1-Visitor
November 20, 2012
Question

Embedded XUI - JavaScript

  • November 20, 2012
  • 7 replies
  • 2431 views

Hello again,


Does anyone have experience with embedding the XUI form? I know little JS however the problem I am having is finding a reference to 'prefixes' (Application.event.target for example), also I am not sure what event's could be used (so for example onClick - does it even exist in XUI?).


One of the examples of what I am trying to do:


I would like to add textbox with a new id when the button with lablel 'Add Company Name' is clicked - I understand the logic, go to box object with id="coname", count textboxes, add new textbox with counter+1, however it is really hard to say what to use, for example 'Application.something' or 'Application.event.target.' or anything else (I am not sure how many 'prefixes' exist). Does anyone have a JS reference that they use while implementing embedded forms? or any examples of embedded forms?


<box id="coname">
<label label="COMPANY-NAME"/">
<textbox id="1">
<value></value>
</textbox>
<textbox id="2">
<value></value>
</textbox>
<button label="Add" company=" name&quot;="></button>
<script type="application/x-javascript" ev:event="domactivate">
//var test = Application.document.getElementbyId('coname');
Application.alert('test');
</script>
</box>


Any help would be really appreciated, as always!


Thanks


Marcin


    7 replies

    18-Opal
    November 20, 2012
    Hi Marcin--



    Where the "prefixes" are used in XUI is primarily to get the document
    that forms the basis of the dialog, so you can modify it in the way you
    describe. You can typically do this by using
    Application.event.target.ownerDocument. From there, you can use
    getElementById() to find the thing you're looking for, and the usual DOM
    methods to modify the tree. For the example you describe, the code would
    look something like this:



    <window>

    <box id="coname">

    <label label="COMPANY-NAME"/">

    <textbox id="t1">

    <value></value>

    </textbox>

    <textbox id="t2">

    <value></value>

    </textbox>

    </box>

    <button label="Add" company=" name&quot;=">

    <script ev:event="domactivate" type="application/x-javascript">

    // get the dialog document object

    var dlgdoc = Application.event.target.ownerDocument;

    // now get the target box

    var box = dlgdoc.getElementById("coname");

    // create a new textbox

    var tb = dlgdoc.createElement("textbox");

    // set the ID attribute

    tb.setAttribute("id", "t" +
    (box.getElementsByTagName("textbox").length + 1))

    // create the child value element and add it

    var val = dlgdoc.createElement("value");

    tb.appendChild(val);

    // finally, add the new textbox to the exiting box

    box.appendChild(tb);

    </script>

    </button>

    </window>



    A couple of things to note:

    1) The <script> element that we want to trigger when the button is
    pressed needs to be inside the <button> element. (There are other ways
    you can tie them together with the event attributes, but this is the
    easiest way to do it.)

    2) You probably want the <button> element to be outside the box, so
    you can freely add new fields to the box without worrying about where
    the button is.

    3) The allowed events are described in the help center, under the
    title "Event Types". For most things where you want to react to a click,
    DOMActivate is the event you'll want to listen for. The mouse events
    tend to be limited to the edit window, they are not very useful for XUI
    dialogs.



    Hope that helps. Happy XUI development!



    --Clay





    Clay Helberg

    Senior Consultant

    TerraXML


    1-Visitor
    November 20, 2012
    I should also point out that in addition to the samples provided by the
    Arbortext install, there's quite a bit of sample code up on
    1-Visitor
    November 20, 2012

    Hi Clay


    Great reply, thanks for the information, very helpful!


    Is there a reference where I can find information about the 'prefixes'?


    Thanks


    Marcin


    In Reply to Clay Helberg:


    Hi Marcin--



    Where the "prefixes" are used in XUI is primarily to get the document
    that forms the basis of the dialog, so you can modify it in the way you
    describe. You can typically do this by using
    Application.event.target.ownerDocument. From there, you can use
    getElementById() to find the thing you're looking for, and the usual DOM
    methods to modify the tree. For the example you describe, the code would
    look something like this:



    <window>

    <box id="coname">

    <label label="COMPANY-NAME"/">

    <textbox id="t1">

    <value></value>

    </textbox>

    <textbox id="t2">

    <value></value>

    </textbox>

    </box>

    <button label="Add" company=" name&quot;=">

    <script ev:event="domactivate" type="application/x-javascript">

    // get the dialog document object

    var dlgdoc = Application.event.target.ownerDocument;

    // now get the target box

    var box = dlgdoc.getElementById("coname");

    // create a new textbox

    var tb = dlgdoc.createElement("textbox");

    // set the ID attribute

    tb.setAttribute("id", "t" +
    (box.getElementsByTagName("textbox").length + 1))

    // create the child value element and add it

    var val = dlgdoc.createElement("value");

    tb.appendChild(val);

    // finally, add the new textbox to the exiting box

    box.appendChild(tb);

    </script>

    </button>

    </window>



    A couple of things to note:

    1) The <script> element that we want to trigger when the button is
    pressed needs to be inside the <button> element. (There are other ways
    you can tie them together with the event attributes, but this is the
    easiest way to do it.)

    2) You probably want the <button> element to be outside the box, so
    you can freely add new fields to the box without worrying about where
    the button is.

    3) The allowed events are described in the help center, under the
    title "Event Types". For most things where you want to react to a click,
    DOMActivate is the event you'll want to listen for. The mouse events
    tend to be limited to the edit window, they are not very useful for XUI
    dialogs.



    Hope that helps. Happy XUI development!



    --Clay





    Clay Helberg

    Senior Consultant

    TerraXML


    18-Opal
    November 20, 2012
    I'm not 100% sure what you mean by "prefixes", but there is fairly
    complete documentation on the Arbortext Object Model (AOM) interfaces
    and methods in the Help Center. The information is primarily in the
    Programmer's Reference, which is in the Help Center as both HTML topics
    and as one large PDF.



    The sort of thing I think you might mean by "prefixes", such as
    Application.event.target, is really just a composite object reference.
    It means, "get the Application object, and get the event object from it,
    and then get the target object from that". It's equivalent to something
    like this:



    var app = Application;

    var ev = app.event;

    var tgt = ev.target;



    but it avoids having to save the intermediate objects as variable
    values, when all you really care about is the thing at the end. Each of
    the objects is described in the API documentation (the "Interfaces"
    section of the Programmer's Reference). For example, the Application
    object is described, and its properties (including the "event" property)
    and methods are listed.



    Does that help clarify?



    --Clay





    Clay Helberg

    Senior Consultant

    TerraXML


    1-Visitor
    November 22, 2012

    Hi Clay/All


    Thanks a lot for the previous answers, really useful stuff.


    I am stuck at a weird 'bug' - any clue what could be wrong? Code below.


    Also, is there a way to find out what exception is JS throwing when it fails?


    Thanks


    Marcin


    //this script is for the <window> element and the action is on WindowLoad


    <script type="application/x-javascript" ev:event="WindowLoad">
    var actdoc = Application.activeDocument;
    //var xuidoc = Application.event.target.ownerDocument;
    var myWindow = Application.event.target;
    var xuidoc = myWindow.dialogView.document;


    var parentElement = actdoc.getElementsByTagName('sample:parent').item(0);


    var childrenElements = coreEnrichment.getElementsByTagName('sample:child');
    //var childrenElementsLength = coreCompany.length;
    //var childrenElementsLengthInt = parseInt(coreCompanyLength);
    Application.alert(childrenElements.length); // THIS RETURNS 4



    for (var i=0;i<childrenelements.length;i++)< p=">

    //when I substitute 'childrenElements.length' with number 4 it does not break


    //however if i use childrenElements.length which returns 4 in the alert box it just breaks the script
    {

    some code in here

    }


    </script>

    16-Pearl
    November 22, 2012
    You could wrap in a try { .. } catch (e) { Application.alert(e) } ?
    18-Opal
    November 26, 2012
    Hi Marcin--



    Gareth's idea is good general advice. Also, if you are using Rhino
    javascript, it will often write error messages to the Java console. If
    you show the Java console (Tools->Administrative Tools->Java Console)
    and then run your code, you might see error messages indicating the
    problem.



    In this case, I think your problem may depend on the contents of your
    loop (where you wrote "some code in here"). Specifically, if you are
    modifying the structure of the coreEnrichment, such that the list of
    childrenElements changes (for example, by deleting a child elment or
    inserting a new one), that might explain why childrenElements.length
    starts to throw errors in the loop.



    You might be able to work around this by storing the value, basically
    what you did with the test you described in the comments, except using a
    variable instead of hard-coding "4", something like this:



    var nchildren = childrenElements.length;

    for (var i=0; i < nchildren; i++)

    ...



    However, if you are modifying the elements that belong to the
    childrenElements nodelist, you may still run into problems here, where
    childrenElements becomes invalid. In that case, you may be better off
    with a while() test that checks for descendants of the type you want to
    operate on, rather than trying to iterate over a nodelist that is
    changing on each iteration. For example, this often comes up when trying
    to remove child nodes from a parent node. Code like this won't work:



    for (var i=0; i = parent.childNodes.length; i++) {

    parent.removeChild(parent.childNodes.item(i);

    }



    because you keep changing the childNodes nodelist. The way to do this is
    with a while loop:



    while (parent.hasChildNodes()) {

    parent.removeChild(parent.firstChild);

    }



    --Clay



    Clay Helberg

    Senior Consultant

    TerraXML