OfficeJS Read text from Drop-down List Content Control - listbox

This is part of my Word Template automation that we use internally. I have one drop-down list content control (seen under Developer Tag) which is pre-populated with 5 items. This drop down list is placed along with other Rich Text content control in a document.
I'm able to read the values from rich text content controls without any issue, using this in Script Lab:
async function modifyGetAllControls() {
await Word.run(async (context) => {
let getAllContentControls = context.document.contentControls.getByTitle("richTextBox");
getAllContentControls.load("tag, text, length");
await context.sync();
for (let i = 0; i < getAllContentControls.items.length; i++) {
console.log(getAllContentControls.items[i].text);
} }); }
I get the value printed in Console.log. Everyones happy.
Now I try the same code for my dropdown list content control with title "dropDownContent"
I get length as "0" for getAllContentControls.items.length so it never goes inside that for loop.
Is there anyway to read the text from drop down list box please(which will be selected by the end user)? I've tried loading "lists" as well along with "tag, text, length", but no success.
Many thanks

"Currently, only rich text content controls are supported." from Word.ContentControl. So there is no way to read from a drop down control.

Related

Testing-library unable to find rc-menu

I'm trying to implement integration tests on our React frontend which uses Ant design. Whenever we create a table, we add an action column in which we have a Menu and Menu Items to perform certain actions.
However, I seem unable to find the correct button in the menu item when using react-testing-library. The menu Ant design uses is rc-menu and I believe it renders outside of the rendered component.
Reading the testing-library documentation, I've tried using baseElement and queryByRole to get the correct DOM element, but it doesn't find anything.
Here's an example of what I'm trying to do. It's all async since the table has to wait on certain data before it gets filled in, just an FYI.
Tried it on codesandbox
const row = await screen.findByRole('row', {
name: /test/i
})
const menu = await within(row).findByRole('menu')
fireEvent.mouseDown(menu)
expect(queryByRole('button', { name: /delete/i })).toBeDisabled()
the menu being opened with the delete action as menu item
I had a same issue testing antd + rc-menu component. Looks like the issue is related to delayed popup rendering. Here is an example how I solved it:
jest.useFakeTimers();
const { queryByTestId, getByText } = renderMyComponent();
const nav = await waitFor(() => getByText("My Menu item text"));
act(() => {
fireEvent.mouseEnter(nav);
jest.runAllTimers(); // ! <- this was a trick !
});
jest.useRealTimers();
expect(queryByTestId("submenu-item-test-id")).toBeTruthy();

Text URL in AIR iOS app not selectable

I'm using AIR 2.0 (soon will be updating to 3.3 with Flash CS6) to create an iPad app. We have textfields (Classic, dynamic) which sometimes contain one or multiple htmlText links which need to be clickable. In the desktop version of the program, all text is selectable and the links are easily accessed. My problem is that it takes me mashing the link like 20 times on the iPad before it will recognize that there's a link and navigate to it in Safari. The other strange thing is that none of the text appears to be selectable - I can't get the iPad cursor, copy/paste menu, etc. to show up.
I think, from reading other threads, that the hit area for the URL is only the stroke on the text itself... if that's true, what can I do to increase the hit area? Or make text selectable? It was suggested elsewhere to put movieclips behind the URLs but that's not really possible as this is all dynamic text from XML files.
I've read about StageText but I gather this is only used for input fields, which is not the case here.
I'm reasonably advanced in AS3 but I'd prefer an easy solution over re-writing large chunks of code. At the moment the only thing I can think to do is get the URL and make it so that as soon as you touch anywhere on the textfield, it navigates to the link. But this would break down if there were more than 1 URL in a given textfield.
Any ideas?
I had this exact same issue, and it's had me flummoxed for a while.
Here's what I did to get the desired behaviour:
1) Instead of using a listener for TextEvent.LINK, listen for MouseEvent.CLICK (or TouchEvent.TAP) on the TextField.
eg.
var tf:TextField = new TextField();
tf.addEventListener(MouseEvent.CLICK, linkClicked);
2) In the linkClicked() handler, you use getCharIndexAtPoint() to determine the index of the character that was clicked, and then from that determine the URL from the TextFormat of the character. This is adapted from a post by Colin Holgate on the Adobe Forums (http://forums.adobe.com/thread/231754)
public function linkClicked(e:MouseEvent):void {
var idx:int = e.target.getCharIndexAtPoint(e.localX, e.localY);
trace("Tapped:",idx);
var tf:TextFormat = e.target.getTextFormat(idx);
if(tf.url != "" && tf.url != null) {
var linkURL:String = tf.url;
trace(linkURL);
// Hyperlink processing code here
dispatchEvent(new UIEvent(UIEvent.LINK_TAPPED,tf.url));
}
}
3) The last line (dispatchEvent()) is sending a custom event to another function to process the link, but you could easily inline your code here.
I've tested on an iPad 3 running iOS6.1, building with AIR3.5. Links are much more responsive, and I don't find myself mashing the screen trying to hit the stroke of the text!

How to delete a jqgrid row without reloading the entire grid?

I have a webpage with multiple jqgrids each with inline editing enabled, "action" column (edit icons) enabled and pager disabled. I need to handle the delete event for each row so that I can process the delete without reloading server-side data. I've looked at the approach mentioned in jqGrid Delete a Row and it's very helpful except I have two questions that are stumping me -
Are there more details around the rp_ge parameter in the delOptions.onClickSubmit event?
My column has the delOptions set as this -
delOptions: {onclickSubmit: function(rp_ge, rowid) {return onRowDelete(rp_ge,rowid);}},processing:true }},
Is there a way to get the grid id from within that event? I'd like to have a generic function that I can use to handle delete events from all the grids on the page. The rp_ge parameter has a gbox which sometimes contains the grid id appended? But I have no idea what it is since i'm not able to figure out when it's populated, when it's not.
function onRowDelete(rp_ge, rowid) {
//hardcoded grid id.. don't like it.
var gridid = '#Grid_X';
//what is this gbox?? can i get grid id predictable from it?
//var gridid = rp_ge.gbox.replace("#gbox_", "");
var grid = $('#Grid_X');
rp_ge.processing = true;
var result = grid.delRowData(rowid);
if (result) {
$("#delmod" + grid[0].id).hide();
}
return true;
}
In the jqGrid Delete a Row approach, the code $("#delmod"+grid[0].id).hide(); is hiding the popup delete confirmation dialog manually. What I noticed is that when the dialog pops-up, jqgrid de-emphasizes the background page (makes it light greyish). But after the popup is manually closed (hidden actually?), the background remains de-emphasized. So it looks like the page doesn't have focus (or even disabled). Any way this can be fixed? This can also be seen on the demo that Oleg wrote.
Any help would be appreciated.
(PS - I would've commented on the same post but I don't have enough points to comment on someone else's answer yet.)
In answer to your second point.
Several examples by Oleg such as this one have the following modification.
$("#delmod" + grid[0].id).hide();
is replaced with
$.jgrid.hideModal(
"#delmod"+grid_id,
{gb:"#gbox_"+grid_id,jqm:rp_ge.jqModal,onClose:rp_ge.onClose}
);
This will return focus after the delete operation.

jQuery UI dialog display inside frame, from bookmarklet?

I'm writing a bookmarklet which needs to work in the context of pages whose design I don't control. Some of the pages I need the bookmarklet to function in use frames (in framesets). Is it possible for a jQuery-UI dialog to work inside a frame?
Currently, when I encounter a page with a frameset, I creating my dialog like this:
var frame = window.frames[0];
var div = $(frame.document.createElement("div"));
div.html("My popup contents");
div.dialog( ... );
The result is that jQuery appends the ui-widget div to the main document, rather than the frame's document. Since the main document is just a frameset, nothing is displayed. I can't find any options in the jquery-ui API to specify which document the widgets should be constructed in. The bookmarklet will necessarily be running (or at least starting) from within the context of the outer document.
I'm aware that it won't be possible to display an overlay over the frames; I'm comfortable with display just in a single frame. Also, some other notable bookmarklets fail to function on pages with framesets, so this may be a common problem.
Suggestions?
Bookmarklets typically don't use jQuery. Most bookmarklets open a window which has jQuery.
Here's what I ended up doing: rather than attempting to display within or over a frame, I just had the bookmarklet rewrite the page to remove the framesets and add my own body and content to the page. This allows the bookmarklet to still introspect the frames and get data that it needs from them to construct the overlay prior to removing the framesets, but allows the overlay to still work.
Something like this:
if (window.frames) {
for (var i = 0; i < window.frames.length; i++) {
// ... grab data from the frame ...
}
}
if ($("frameset")) {
$("html").children("frameset").remove();
document.body = document.createElement("body");
$("html").append(document.body);
// ... add my stuff to body ...
}

Clicking on scrollbar causes unintential firing of event

Morning - I'm having a little problem.
I have an autocomplete extender textbox where a user types in words and suggestions are provide. Should the term be rather generic, a list appears and the user can scroll up or down using the mouse wheel with no problems at all.
However, if the user attempts to click on the scroll bar and scroll through the list, it fires the textchanged event - which I don't want it to do.
This event should only fire once the user has actually selected the appropriate product from the list supplied.
I can set the autopost back of the text file off which has the desired effect but I do require the post back to be performed once the user selects a suggestion.
Does anyone know how I can get around this?
I managed to find a resolution.
Stick this in the page load event:
string contactPostBackFunction = null;
contactPostBackFunction = Page.ClientScript.GetPostBackEventReference(this.tbxProdAC, "", false);
string contactPostBackScript = null;
contactPostBackScript = string.Format("function postBackOnContactSelectedFromDropDown() {0} {1} {2}", "{", contactPostBackFunction, "}");
Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "contactPostBackScript", contactPostBackScript, true);
And have this in your Autocomplete extender properties:
OnClientItemSelected="postBackOnContactSelectedFromDropDown"

Resources