Custom menu of options for InsertFragmentOperation

Post here questions and problems related to oXygen frameworks/document types.
mboudreau
Posts: 37
Joined: Sat Jan 07, 2017 1:23 am

Custom menu of options for InsertFragmentOperation

Post by mboudreau » Tue Nov 26, 2019 12:28 am

I'm creating a framework author action to add a subject heading to a document when it's missing. E.g.,

/article/front/article-meta/article-categories/subj-group/subject

At the moment, however, my action only adds this fragment with the placeholder "My Heading" as the text content of <subject>.

What I'd like is to present the user with a menu of choices based on the journal being edited.

For example, if /article/front/journal-meta/journal-id = "Journal A", then the possible subject headings would be "Research Article", "Brief Report", or "Letter". But if journal-id = "Journal B", then the possible headings would be "Research Article", "Editorial", and "Book Review".

Is there a way to do this?

And a follow-up: once I have this action configured, I'd like to copy it to a different framework. Is there an easy way to do that?

mboudreau
Posts: 37
Joined: Sat Jan 07, 2017 1:23 am

Re: Custom menu of options for InsertFragmentOperation

Post by mboudreau » Wed Nov 27, 2019 5:57 am

To follow up, I've figured out how to style the inserted element to display a menu of choices:

Code: Select all

article-categories subj-group subject:before {
  content:"Subject: " 
          oxy_combobox(
            edit, '#text',
            values, 'Research Article, Brief Report, Obituary',
            fontInherit, true);
}
article-categories subj-group subject {
    visibility:-oxy-collapse-text;
}
If I could make the list of values conditional on the value of /article/front/journal-meta/journal-id, that would be ideal.

sorin_carbunaru
Site Admin
Posts: 258
Joined: Mon May 09, 2016 9:37 am

Re: Custom menu of options for InsertFragmentOperation

Post by sorin_carbunaru » Wed Nov 27, 2019 11:28 am

Hello,

For computing the values from the "oxy_combobox" you could use "oxy_xpath". The XPath expression should look at the value of "journal-id" and return a corresponding string of values.

Another option would be compute the value when the Author action is invoked. Inside the inserted fragment you could use an ${ask()} editor variable (see https://www.oxygenxml.com/doc/versions/ ... ables.html). When invoking the action, the $ask would show a dialog with a combo box or some radio buttons with the allowed values from which the user would choose. Again XPath should be used to compute the list of allowed values (see "${xpath_eval(expression)}" at the link mentioned earlier).

Yet another option would be to create an Author action based on JSOperation, not InsertFragmentOperation (see https://www.oxygenxml.com/InstData/Edit ... ation.html).

Best wishes,
Sorin Carbunaru
oXygen XML

mboudreau
Posts: 37
Joined: Sat Jan 07, 2017 1:23 am

Re: Custom menu of options for InsertFragmentOperation

Post by mboudreau » Wed Dec 04, 2019 12:25 am

I'm trying to implement the middle option, using ${ask()} and ${xpath_eval()}.

I can get this work as the fragment to be inserted:

Code: Select all

<article-categories>
<subj-group>
<subject>${ask('Choose one', 
               combobox,
               ('Article':'Article';
                'Book Review':'Book Review';
                'Editorial':'Editorial'))}</subject>
</subj-group>
</article-categories>
However, going the next step and using a fairly simple "if...then...else" XPath expression is giving me trouble. I have tried this:

Code: Select all

${ask('Choose one', 
      combobox,
      (${xpath_eval(if matches(/article/front/journal-meta/journal-id[@journal-id-type="publisher-id"]/text(), 'Journal A', 'i') 
                   then "'Subject 1':'Subject 1';'Subject 2':'Subject 2';'Subject 3':'Subject 3'" 
                   else "'Subject 4':'Subject 4';'Subject 5':'Subject 5';'Subject 6':'Subject 6'"
      )})
     )
  }
But Oxygen keeps telling me it can't expand the ${ask()} variable, but the rest of the message isn't helpful.

However, even if I figure out the syntax for this, I think my actual use case is too complicated for this technique. I need to accommodate about 40 different journals, each with a list of 3-5 or more unique subject headings, so the XPath expression will become too large and unwieldy.

If there were a way to read an array in an XML configuration file, that would be ideal.

mboudreau
Posts: 37
Joined: Sat Jan 07, 2017 1:23 am

Re: Custom menu of options for InsertFragmentOperation

Post by mboudreau » Wed Dec 04, 2019 8:34 pm

I finally worked out the syntax for the ${ask()} with an embedded ${xpath_eval()}:

Code: Select all

${ask('Choose one', 
combobox,
(${xpath_eval(if (matches(/article/front/journal-meta/journal-id[@journal-id-type="publisher-id"]/text(), 'Journal A', 'i')) then "'A':'A';'B':'B';'C':'C'" else "'D':'D';'E':'E';'F':'F'")})
)}
But this remains too cumbersome if the choice of menu items is more complex than the binary choice offered by "if...then...else". If you're taking new feature suggestions, please consider a way for editor variables like this to collect values from an XML configuration file, similar to the file used by the ${i18n()} function.

In the meantime, I also found that when I click the "Cancel" button in the combobox produced by the ${ask()} variable, Oxygen produces an error message. I used the dialog box to report this.

mboudreau
Posts: 37
Joined: Sat Jan 07, 2017 1:23 am

Re: Custom menu of options for InsertFragmentOperation

Post by mboudreau » Thu Dec 05, 2019 12:14 am

One more follow-up.

As I noted previously, this works:

Code: Select all

${ask('Choose one', 
combobox,
(${xpath_eval(if (matches(/article/front/journal-meta/journal-id[@journal-id-type="publisher-id"]/text(), 'Journal A', 'i')) then "'A':'A';'B':'B';'C':'C'" else "'D':'D';'E':'E';'F':'F'")})
)}
And when I worked previously with a simpler example, an additional ${xpath_eval()} variable in the combobox label worked:

Code: Select all

${ask('Select subject heading for ${xpath_eval(/article/front/journal-meta/journal-id[@journal-id-type="publisher-id"]/text())}', 
combobox,
('Article':'Article';
 'Book Review':'Book Review';
  'Editorial':'Editorial')
)}
However, when I add the longer label to the first example:

Code: Select all

${ask('Select subject heading for ${xpath_eval(/article/front/journal-meta/journal-id[@journal-id-type="publisher-id"]/text())}', 
combobox,
(${xpath_eval(if (matches(/article/front/journal-meta/journal-id[@journal-id-type="publisher-id"]/text(), 'Journal A', 'i')) then "'A':'A';'B':'B';'C':'C'" else "'D':'D';'E':'E';'F':'F'")})
)}
the combobox appears with no label at all.

sorin_carbunaru
Site Admin
Posts: 258
Joined: Mon May 09, 2016 9:37 am

Re: Custom menu of options for InsertFragmentOperation

Post by sorin_carbunaru » Thu Dec 05, 2019 4:24 pm

Hello Michael,

1. For the values you could use the "doc" function in XPath to read the 'value':'label' pairs from a document.

2. A colleague of mine is already investigating the issue regarding the error shown when cancelling the $ask. We will contact you when we release a kit having a fix for that problem. For reference purposes, EXM-44688 is the issue ID.

3. Regarding your last post, it seems there is a problem with creating a "static_text dynamically_computed_text"' message for $ask when also using $xpath_eval for the values. I created another bug for this (EXM-44698). As a workaround, you could build your message using an $xpath_eval which uses the "concat()" function; something like $xpath_eval( concat( 'TEXT', $xpath_eval(...) ) ).

Best wishes,
Sorin Carbunaru
oXygen XML

Post Reply