Why can't I disable this XUL menuitem? - xul

I'm at my wits end, and it's probably something really simple. Basically I've have got this code:
var menuitem = document.getElementById('mymenuitem');
alert(menuitem);
alert(varImChecking == null);
menuitem.setAttribute('disabled', (varImChecking == null) ? 'true' : 'false');
It should be disabling the 'mymenuitem' menu item, but has no effect. When run, the alerts say '[Object XulElement]' followed by 'true'. I know the getElementById is selecting the correct menuitem element because onclick bindings to the menuitem variable work.
Some alternatives I've tried:
menuitem.setAttribute('disabled', (varImChecking == null));
menuitem.disabled = (varImChecking == null);
So why isn't the setAttribute having any effect? It doesn't even gray out the menu item. Is there another way I'm supposed to do this?
Edit: Forgot to mention, no warnings or errors show up in the console.

Regarding the disabling issue:
If a menuitem contains a command, the menuitem can only be disabled by setting the "disabled" attribute of that command.
If the menuitem contains an oncommand, disabling should work on the menuitem itself.

I believe that setAttribute will be looking for a string "true"/"false", as you originally had.
Although I don't see a bug immediately in why you can't disable. For a test, have you tried simply
menuitem.setAttribute('disabled', 'true');
?
If that doesn't work - perhaps nothing will. It seems odd to disable a menuitem - are you sure you're not wanting to disable the menulist?
I do see a problem with your enabling code. I can't find great documentation for it, but I did deal with this previously. One example you can find in bugzilla is the fact that setting disabled=false actually disables items on Linux. The recommended way from Mozilla is to remove the attribute when you want it enabled.
So although your solution is more concise, you should probably look at something more like this:
var menuitem = document.getElementById('mymenuitem');
alert(menuitem);
alert(varImChecking == null);
if(null==varImChecking){
menuitem.setAttribute('disabled', 'true');
}else{
menuitem.removeAttribute('disabled');
}

I think I finally figured this out. The problem is that I had the menuitem I was trying to edit was hardcoded inside a .xul file. For whatever reason, this made it impossible to change the disabled or hidden attributes.
So I removed the menuitem from the .xul file and dynamically created it in the javascript instead. Now it works exactly as expected:
var menuitem = document.getElementById('mypopupitem').appendChild(document.createElement('menuitem'));
menuitem.setAttribute('disabled', 'true'); // Works.
menuitem.removeAttribute('disabled'); // Also works.
Does anyone know, is this a feature/quirk of XUL, or am I just doing it wrong?
UPDATE: As many comments have pointed out, the above is not correct. You absolutely can change the disabled attribute on an item hard coded in a XUL file.
After much more debugging, paring the problem down to its core elements, pulling hair, etc, it turned out to be.... a typo. Grrr.. Sorry.
It turns out my document.getElementById('menuitem') was grabbing the XUL element, not the element. The fact that the onclick method seemed to be firing correctly seems to have been thanks to event bubbling (I guess?). I still have no idea why setAttribute('label', 'changed') worked when I tried that, but unfortunately, in the frenzy of debugging, I don't have that version to check again.
Anyway, it's working now, without having to dynamically create the menuitem. Thanks for all the help!

I had the very same problem. I've used iconic menu items together with commands. The clue was to set the disabled attribute of the menuitem AND the command to true or false. I also had to set the disabled Attribute after the parent menupopup was opened,e.i. onpopupshown . Now i can update my menuitems dynamically.
I've spend more than an hour to solve this problem xD I hope this will help people to minimize their time expenses.
BTW:
my xul is inside an firebug extension

may be this will work:
var menuitem = document.getElementById('mymenuitem');
alert(menuitem);
alert(varImChecking == null);
menuitem.setAttribute('disabled', (varImChecking == null) ? true : false);
I used true and false rather than 'true' and 'false'

I am using tag to add a custom context menu. When I use "onpopupshowing" event to handle the enable/disable of a menu-item, my context menu is getting populated with a lot of menu items which I have not intended to add. Here is the new popup tag that I added in the overlay.xul
<popup onpopupshowing="isAssertTextEnabled(this)" id="contentAreaContextMenu">
<menuitem id="context-recorderpopup" label="Assert text present"
accesskey="T"
insertafter="context-stop"
oncommand="onAssertionMenu(event)"
/>
</popup>
please let me know if I am missing out something
Thanks,
Vinay

Related

DOJO 1.9. FilteringSelect ComboBox scroll to last selected item on show [IE]

How to make dropdown scroll to the last selected option after dropdown is re-opened?
Calling filtering_select_ref.dropdown.set('selected', selected_node_ref) or filtering_select_ref.set('scrollOnFocus', true) did not work for me on IE 11.
If you just need to scroll to the option, you could use win.scrollIntoView(node_ref) from "dojo/window" module as shown in the docs and pass the id or the node reference to the option as an argument.
You may also find these methods interesting to help solve your problem:
filtering_select_ref.openDropDown()
var dropdown = filtering_select_ref.dropdown;
dropdown.selectFirstNode()
dropdown.selectNextNode()
dropdown.selectPreviousNode()
dropdown.selectLastNode()
#Carlos Nantes suggested good options however I was aware of them and my problem with them was that I could not "catch" the moment when dropdown got opened.
I finally found a way to "catch" that moment with filtering_select_ref.watch('_opened', function()...
watch doc can be found here

Force reapply of ItemTemplateSelector in WinRT

I have a GridView as my zoomed out view in a SemanticZoom control. This GridView uses a custom DataTemplateSelector as the ItemTemplateSelector. It shows an item for each content group that my app shows.
The template is different depending on whether the group is empty or not. This works fine on load, but it doesn't update when a group becomes empty or stops being empty.
I've found that the ItemTemplateSelector is only run when the page is first shown. How can I force the DataTemplateSelector get run again.
The WPF questions on this topic all suggest triggers, but these aren't available in WinRT XAML.
I've found an answer to a similar WPF question that answers this in a way that works in WinRT:
https://stackoverflow.com/a/11327087/31569
Basically you set the ItemTemplateSelector to null and then set it again. Like this:
var templateSelector = MyGroupView.ItemTemplateSelector;
MyGroupView.ItemTemplateSelector = null;
MyGroupView.ItemTemplateSelector = templateSelector;
This works, but happy to be told if there is a better way to do this.
I find it easier to just just remove the item in need updating from the collection and adding it back. This forces the GridView or ListView to apply the template. This is easy to do in MVVM world.
var itemToReload; //The object who's template needs updating
var reloadIndex = this.SomeCollection.IndexOf(itemToReload);
this.SomeCollection.Remove(itemToReload);
this.SomeCollection.Insert(reloadIndex, itemToReload);
One thing to note, is that if the item is a "Selected" item, you'll need to reapply that selection.

Checking if an element is really visible to the user

I'd like to check whether the user can see an element in the current web browser view without scrolling.
What I've found can check whether the element is somewhere on the page.
Another hint suggested to check the elements position but then I would need to get the dimensions of the visible window of the browser plus its x/y offset to 0/0.
I would be grateful if someone could point me to a solution that does not need JavaScript code.
How do you define 'visible to the user'? How do you propose to check it?
If it has a height? If it isn't hidden by CSS? What if it's parent element is hidden by CSS?
The most reliable way will be to use Selenium's built in .Displayed property (if you are using C#, Java has something similiar), and combine it with jQuery's 'visible' selector: http://api.jquery.com/visible-selector/. Example below, in C#.
var element = Driver.FindElement(By.Id("test"));
bool isVisible = element.Displayed;
var javascriptCapableDriver = (IJavascriptExecutor)Driver;
bool jQueryBelivesElementIsVisible = javascriptCapableDriver.ExecuteScript("return $('#myElement').is(:visible);");
bool elementIsVisible = isVisible && jQueryBelievesElementIsVisible;
This will get the majority of cases.
It isn't possible without client side code, or in the preparation that someone else finds a way that it can be done in a server side language, I highly doubt it will be pretty, readable or reliable.
jQuery has the offset() method:
http://api.jquery.com/offset/
This, however, won't work when taking into account borders, margins, that kind of stuff.

Dojo 1.4.2 Tree Grid "expando click" event? persist state?

Question:
Given a DOJO TreeGrid, how can I capture the event when a user clicks the expando ("+") button to expand a row, and store the specific row number or associated item's identifier? I'd like to do this for the express purpose of completely deleting the TreeGrid from the DOM, rebuilding it, and restoring it's state once rebuilt (i.e. programmatically expanding the rows that the user has previously expanded).
Background:
So I've got a custom DOJO TreeGrid, hooked up to a custom QueryReadStore, in my app. It was constructed using the following tutorial:
http://www.ibm.com/developerworks/web/library/wa-dojotreegrid/index.html?ca=drs-
Pretty interesting tutorial, but it might be irrelevant to my question because it doesn't really squash any functionality, it only seems to augment it.
Anyway, googling around for a moment, I found a nice function in the DOJO forums that I can use to programmatically expand a row, given the specific row index. Works perfectly.
The problem is that I haven't been able to find a good way to capture the expando click event, and relate it to a specific "parent item row" index in the grid.
Details aside, I'd like to get the row index of every row that the user has expanded, into an array (and delete the index of a row that the user collapses, obviously), so I can destroy this TreeGrid, and faithfully rebuild it, with the user's selections expanded properly.
I'm not really a novice to DOJO, but I'm certainly no expert by any means. I've done a fair bit of googling, and FireBugging, and haven't really been able to find anything that I can use to do this.
Suggestions? Anybody done something similar before? Stupid question with obvious answer that I've missed? I'm totally misguided and am going about it all wrong? Thanks everybody!
Something similar to this would probably work, this is how the dijit.Tree implementation wouldve looked;
var expandedNodes = {}
dijit.tree._onExpandoClick = function (args /* object wrap for args.node */) {
var treeNode = args.node,
path = treeNode.getTreePath(),
id = treeNode.getIdentity();
expandedNodes[id] = path;
}
I am not 100% sure im being strictly correct but for the TreeGrid you will have to look through code of dojox/grid/_TreeView.js (link). The _setOpen would be an entrypoint from which you can 'hook' the onclick action. from there, find the expandoCell.openStates hash, this is a true/false variable set, indexed by itemId. This hash is most likely what you need as your state

Dojo : show() and hide() .... HOW?

I have a container element in which I create on the fly/place() a form, then another one..etc.
My goal is to switch between them i.e. hide all and show only the active form.
It hides alright, but I can't show the active back.
I tried using:
.style.display(none<->block) and visibility(visibility<->hidden)
dojo.style(...)
resize() and startup() after the changes
Several other variants i found on Internet from old dojo's
Nothing works.
/I need it to work with display, so that it does not occupy space./
Can you tell me what is the correct way to show and hide with dojo()
Also looked at this one :
How do I dynamically show and hide an entire TabContainer using DOJO?
Does not work.
The pseudo code I use is something like this :
....
//find or create the FORM element
form = dijit.byId(...);
if(typeof form != 'object') {
form = dojo.create('form', ....);
dojo.place(form,'containerx','last');
}
//hide all
dojo.query('#containerx > *').forEach(function(item){
dojo.style(item, 'visibility','hidden');// and all other variants i mentioned
})
//show only the current form
dojo.style(form, 'visibility','visible');
//if the dojo form obj was already created, then skip it
if (this.form_obj) return;
....build the form and the elements....
this.form_obj.startup()
thanx
I just answered the question in that thread you referenced in your question a few minutes ago. Basically it involved getting jQuery involved. Works great for me. I have all the tabs created statically (as opposed to programatically) and I'm able to manipulate whether they are shown or hidden with the help on jQuery. All the code any everything is in my post here:
How do I dynamically show and hide an entire TabContainer using DOJO?
Sounds like you might be looking for StackContainer functionality.
Just set things up so that the StackContainer has the dijit.form.Forms as children and you can use the selectChild method to choose what form to display.