Based on a jsfiddle I made a directive, which shows some information in a Bootstrap Popover, when hovering over a Bootstrap badge or clicking into it. It's working fine, as long it's "standalone"
I made a plunker to demonstrate
(need to add code here)
The button and the first to badges in the wells are doing fine.
The badges with dynamically generated ids in the ng-repeat are not doing anything at all.
With the badges with fixed ids, only the first one works (as this is initialized 2 times), which makes sense.
What I do not understand is, in the console log you can see, all the badges in the ng-repeat are found and set up.
Don't know, where to look anymore. Any ideas?
I would suggest that you try to rely on the angular-ui bootstrap library to accomplish the functionality that you want. But based on your reliance on using the id attribute and your desire to use dynamically generated ids I figured that your problem was in the way that you get the element with the popover attribute. You don't need to do a $("#" + elemId) to get the element for the popover, you already have a reference to the element as one of the parameters in your link function.
Right now you have:
testApp.directive "popoverClickNHover", ->
restrict: "A"
link: (scope, element, attrs) ->
asPopover = undefined
console.log "popoverClickNHover"
asPopover = (elemId) ->
clickToggle = undefined
enterShow = undefined
exitHide = undefined
popoverTriggerElem = undefined
console.log "asPopover: " + elemId
popoverTriggerElem = $("#" + elemId)
console.log popoverTriggerElem
popoverTriggerElem.data "state", "hover"
...
return
asPopover attrs["id"]
But you can just use the element that the link function gives you and it will work:
testApp.directive "popoverClickNHover", ->
restrict: "A"
link: (scope, element, attrs) ->
asPopover = undefined
console.log "popoverClickNHover"
asPopover = () ->
clickToggle = undefined
enterShow = undefined
exitHide = undefined
popoverTriggerElem = element /* just use the element, no need to do $("#"+elemId) */
console.log popoverTriggerElem
popoverTriggerElem.data "state", "hover"
...
return
asPopover
Here's an example using the element from the link function: http://plnkr.co/edit/jA6zc0JQKiQaoQNo7BaH?p=preview
And here's a different example using angular-ui/bootstrap:
http://plnkr.co/edit/jpRh0fJfiFnsOavpW55s?p=preview
Related
I'm brand new to Ember and I'm using Konacha to test my app. I'm having trouble using the data store in my tests. The following code attempts to check if the itemText property of an Item model is equal to the displayed text in the DOM:
it "should display the item text", ->
item = undefined
Ember.run ->
item = store.find('item', 1) # store is defined in the spec helper
content = item.get('itemText')
console.log(item) # Logs the correct item
console.log(content) # Logs undefined
$('.list-item:eq(0)').text().should.equal content # Fails since content is undefined
Clearly, the content = item.get('itemText') is not doing what I'm expecting it to. However, running the same code line by line in the console gives me back the property I want, so I'm not sure where I'm going wrong. I have a feeling I may be testing this in entirely the wrong way, so any feedback is appreciated.
I think your console logs is ran before the the model is fetched. What you need is a promise, have a look.
it "should display the item text", ->
item = undefined
Ember.run ->
item = store.find('item', 1).then (item) ->
content = item.get('itemText')
$('.list-item:eq(0)').text().should.equal content
I have following code.
var list = this.getNavigation();
if (list.itemsCount > 0) {
list.removeAll(true, true);
}
list.setData(filtered);
List = xtype: list.
So idea is next i have menu and some times i need to rebuild it. as you see i am not using store because i need to filter array and set it.
When i call removeAll i got error
Uncaught TypeError: Cannot call method 'getScroller' of undefined
And i cant find method to cleanup it...
I rewrote my menu to use store and instead of setData on list i am setting data on store and it works as expected
Another option would be calling removeAll with destroy set to false like so:
var list = this.getNavigation();
if (list.itemsCount > 0) { list.removeAll(false); }
list.setData(filtered);
The list DOM items get deleted anyways by some sort of auto-cleanup.
I'm creating dijit widget from input:
<input name="serviceName" type="text"/>
input = new ValidationTextBox({required: true}, query('[name=serviceName]')[0])
I have a lot of inputs and I want to batch-process them, giving them to separate function.
The problem is, that I can't find in docs, how to get the input name back from widget (which can be also Select, DateBox etc., neither I can find that property inspecting element in Firebug
function processInput(input) {
var inputName = ???
}
I've tried input.name and input.get('name'), but they are returning undefined.
When instantiating your widget programmatically, properties are usually not copied. It's only when you use declarative markup that these properties are copied. This means that the name property is not copied from your original input node, so it's in fact empty.
When creating your ValidationTextBox, just provide the name property like the example below:
var inputNode = query('[name=serviceName]')[0];
var input = new ValidationTextBox({
required: true,
name: inputNode.name
}, inputNode);
You can then retrieve the name with either input.name or input.get('name').
I also made an example JSFiddle.
I'm building a Google Maps app, and have an image of a compass outside of the map. Each of the compass points is on an image map, and has its own id. I want the 45° orientation to change, depending on the compass point clicked.
Within the google maps initialize function, I have this line:
google.maps.event.addDomListener(document.getElementById('compassSouth'), 'click', map.setHeading(180));
However, that handler is fired on page load, and doesn't respond after that. It's not due to the image map - the same behavior happens if the element is a button.
I have another handler in the same format that responds to a button press, which works fine.
The code is doing exactly what you are telling it to do: It is calling the map.setHeading(180) function immediately when you execute your code.
Let's write it out line by line for clarity:
var element = document.getElementById('compassSouth');
var listener = map.setHeading( 180 );
google.maps.event.addDomListener( element, 'click', listener );
As you can see, this code calls map.setHeading(180) immediately where you write that code, and then it passes the return value from that function (which I'm now calling listener) into addDomListener().
But map.setHeading(180) doesn't return any value at all - or put another way, it returns undefined, so listener is undefined.
addDomListener() sees that undefined value and ignores it: it doesn't set any listener at all!
What you need to do instead is pass a reference to a function into addDomListener(). You could do this easily like this:
function compassClick() {
map.setHeading( 180 );
}
var element = document.getElementById('compassSouth');
google.maps.event.addDomListener( element, 'click', compassClick );
Or as you'll often see, you can make that compassClick function an anonymous function instead (now going back to code more like your original):
google.maps.event.addDomListener(
document.getElementById('compassSouth'), 'click',
function() {
map.setHeading( 180 );
}
);
How can I receive all events attached to an element with dojo?
dojo.query('#mydiv') // which events does #mydiv has?
To get all events on a DOM element:
// Get my div
myDiv = dojo.byId("myDiv");
// Obtain all event-related attributes
var events = dojo.filter(
myDiv.attributes,
function(item) {
return item.name.substr(0, 2) == 'on';
}
);
// Execute first found event, just for fun
eval(events[0].value);
If you get myDiv using dojo.query, remember that dojo.query returns an array, so your element would be in myDiv[0].
This solution does not work with events attached with dojo.connect. There probably is a way to extract this info from Dojo inner workings, but you would have to delve into the source code to understand how.
Another option is that you explicitly manage all dojo.connect events with a global registry. You could use dojox.collections to make this easier. For example, creating a global registry whose keys will be the dom nodes, and values will be the handles returned by dojo.connect (these handles contain the dom node, the type of event and the function to execute):
// On startup
dojo.require(dojox.collections.Dictionary);
eventRegistry = new dojox.collections.Dictionary();
...
// Registering an event for dom node with id=myDiv
var handle1 = dojo.connect(dojo.byId("myDiv"), "onclick", null, "clickHandler");
// Check if event container (e.g. an array) for this dom node is already created
var domNode = handle1[0];
if (!eventRegistry.containsKey(domNode))
eventRegistry.add(domNode, new Array());
eventRegistry.item(domNode).push(handle1);
...
// Add another event later to myDiv, assume container (array) is already created
var handle2 = dojo.connect(dojo.byId("myDiv"), "onmouseover", null, "mouseHandler");
eventRegistry.item(domNode).push(handle2);
...
// Later get all events attached to myDiv, and print event names
allEvents = eventRegistry.item(domNode);
dojo.forEach(
allEvents,
function(item) {
console.log(item[1]);
// Item is the handler returned by dojo.connect, item[1] is the name of the event!
}
);
You can hide the annoying check to see if event container is already created by creating a subclass of dojox.collections.Dictionary with this check already incorporated. Create a js file with this path fakenmc/EventRegistry.js, and put it beside dojo, dojox, etc:
dojo.provide('fakenmc.EventRegistry');
dojo.require('dojox.collections.Dictionary');
dojo.declare('fakenmc.EventRegistry', dojox.collections.Dictionary, {
addEventToNode : function(djConnHandle) {
domNode = djConnHandle[0];
if (!this.containsKey(domNode))
this.add(domNode, new Array());
this.item(domNode).push(djConnHandle);
}
});
Using the above class you would have to dojo.require('fakenmc.EventRegistry') instead of 'dojox.collections.Dictionary', and would simply directly add the dojo connect handle without other checks:
dojo.provide('fakenmc.EventRegistry');
eventRegistry = new fakenmc.EventRegistry();
var handle = dojo.connect(dojo.byId("myDiv"), "onclick", null, "clickHandler");
eventRegistry.addEventToNode(handle);
...
// Get all events attached to node
var allEvents = eventRegistry.item(dojo.byId("myDiv"));
...
This code is not tested, but I think you get the idea.
If its only for debugging purpose. You can try dijit.byId("myId").onClick.toString(); in your firebug console and you can see the entire onclick code this works even if the function is anonymous you can view the content of anonymous content.