How to access element and elementId from within didInsertElement - coffeescript

Using Ember.CollectionView I want to access and manipulate the DOM element which is being inserted by each child view. The issue I have is that I don’t know how to get a reference to the element from within didInsertElement. Here is the jsFiddle -- the summery of coffeescript is below:
window.App = Ember.Application.create()
window.App.initialize()
App.Item = Em.View.extend
didInsertElement: () ->
console.log ">>> element is: ", this.element
App.items = Em.ArrayController.create()
App.items.set('content',[
Em.Object.create({title:"AN", id:"item-one"}),
Em.Object.create({title:"Epic", id:"item-two"}),
Em.Object.create({title:"View", id:"item-three"})
])
App.EpicView = Ember.CollectionView.extend
classNames: ['epic-view']
contentBinding: 'App.items'
itemViewClass: 'App.Item'
this.element is undefined. I have also tried calling element and that is undefined as well. According to the docs, there is an element property available inside the view, but I don’t know how to access it, and I am not sure if it is available from within didInsertElement or not.
How can I get the id of the DOM element that was just inserted into the view? Ideally, I would like not having to search for it in the DOM since the view should already be aware of what it is inserting into the DOM.
ps: I am using Ember 1.0pre

Use get('element') or get('elementId') to access properties in Ember

Related

How can customData can be binded with JavaScript

In the affected application is a responsive table whose ColumnListItems are added via JavaScript code. Now the lines should be highlighted by the highlighting mechanism depending on their state. The first idea was to control the whole thing via a normal controller function. I quickly discarded the idea, since the formatter is intended for such cases. So I created the appropriate Formatter function and referenced it in the JavaScript code. The call seems to work without errors, because the "console.log" is triggered in each case. Also the transfer of fixed values is possible without problems. However, the values I would have to transfer are located within customData of each line...
No matter how I try to form the path I get an "undefined" or "null" output.
I have already tried the following paths:
"/edited"
"/customData/edited"
"mAggregations/customData/0/mProperties/value"
"/mAggregations/items/0/mAggregations/customData/0/mProperties/value"
The code from Controller.js (with consciously differently indicated paths):
var colListItem = new sap.m.ColumnListItem({
highlight: {
parts: [{
path: "/mAggregations/items/0/mAggregations/customData/0/mProperties/value"
}, {
path: "/edited"
}],
formatter: Formatter.setIndication
},
cells: [oItems]
});
// first parameter to pass while runtime to the formatter
colListItem.data("editable", false);
// second paramter for the formatter function
colListItem.data("edited", false);
oTable.addItem(colListItem);
The code from Formatter.js:
setIndication: function (bEditable, bEdited) {
var sReturn;
if (bEditable && bEdited) {
// list item is in edit mode and edited
sReturn = "Error";
} else if (bEditable || bEdited) {
// list item is in edit mode or edited
sReturn = "Success";
} else {
sReturn = "None";
}
return sReturn;
}
The goal would also be for the formatter to automatically use the value of the model in order to avoid its own implementation of a listener, etc.
I hope one of you has a good/new idea that might bring me a solution :)
Many thanks in advance!
You cannot bind against the customData. Because the customData is located in the element, it is like a property.
Thats why you defined it here on colListItem: colListItem.data("key", value)
You only can bind against a model.
So I see three solutions
Store the information in a separate local JSON model whereof you can speficy your binding path to supply the values to your formatter
Do not supply the information via a binding path to the formatter, but read a model/object/array from a global variable in the controller holding the information via this (=controller) in formatter function
Store the information in the customData of each element and access the element reference in the formatter function via this(=ColumnListItem).data().
Passing the context to the formatter similar to this formatter: [Formatter.setIndication, colListItem]
Cons of 1. and 2: you need a key for a respective lookup in the other model or object.
From what I understand I would solve it with solution 3.

Can choices in a list be changed after it has been been rendered?

I have a w2ui form that contains a w2ui Drop List of choices. The choices will be different depending on what the user selected to bring up the form. My question is: can the contents of a Drop List be changed after it has been rendered?
With standard HTML controls, I would do something like this:
$("#mySelect option[value='xyz']").remove();
or
$("#mySelect").append('<option value="abc">abc</option>');
Can these kinds of operations be done with a w2ui Drop List? Any example code?
In w2ui 1.5 you can use $jQueryElement.w2field() to access the w2fild object - and then manipulate it.
Example:
var field = $("#my_input").w2field();
field.options.items = ["my", "new", "items"];
// optionally: pre-select first item
field.setIndex(0);
// if you do NOT use "setIndex" you need to call "refresh" yourself!
// field.refresh();
Note: setIndex() internally calls refresh() - so as stated above, you do not need to call refresh yourself in that case.
If you want to completely clear/empty your field, you can call field.reset().
Edit: after clarification that it's about a form field:
// Note: ``this`` refers to the w2form
// ``field[8]`` refers to a field of type "select"
this.fields[8].options.items = ["my", "new", "items"];
this.record = {
field_select: 'new'
};
this.refresh();

D3 invalid character in element

I'm getting a response in JSON format, which contains an _id that is stored as an ObjectID in Mongodb on the server side. However, I change it into a String, and it still won't let me add it. Is it because it has numbers? I need the element to be identifiable by the id, so if I can't append this way, is there any other way I can reference the element by the id?
var group = d3.select("#containerthing");
var id = response._id.toString();
console.log(id);
//5802bc044f6313c1097de4a2
var responseNode = group.append(id).attr("fill","black").attr("x", 15).attr("y", 15).attr("width", 190).attr("height", 90);
//InvalidCharacterError: String contains an invalid character
I believe that I understand your problem.
D3's .append():
If the specified type is a string, appends a new element of this type (tag name) as the last child of each selected element, or the next following sibling in the update selection if this is an enter selection. [...] This function should return an element to be appended. (The function typically creates a new element, but it may instead return an existing element.
Why .append() work fine if you pass 'foo'? Because D3 append a custom tag element. If you see in your console I'am sure that you will see <foo>...</foo>
Why .append() work wrong if you pass '5802bc044f6313c1097de4a2'? A custom tag element can't start with a number. You don't use _id, you should try to find another pattern for identify your element.
I hope that helps
The reason was that you can't start elements with numbers. I had to do:
var responseNode = group.append("n"+id).attr("fill","black").attr("x", 15).attr("y", 15).attr("width", 190).attr("height", 90);
to get it to work.

Get back the webdriver.Locator out of an elementFinder

Given I have the elmFinder variable:
var elmFinder = element(by.css('.thing'));
What if i need to get back the webdriver.Locator, a.k.a locator strategy? i.e.
elmFinder.??? //=> by.css('.thing')
I'm looking after the function ??? if it exists.
UPDATE:
This feature has been merged and we can now do:
elmFinder.locator();
UPDATE:
This feature has been merged and we can now do:
elmFinder.locator();
Old answer:
You cannot. The element finder does not keep a reference to the locator:
https://github.com/angular/protractor/blob/master/lib/protractor.js#L103
What I typically do is store the selector in it's own var, and then place that string into the selector, so I can use both interchangably:
var cssThingSelector = '.thing';
var elem = $(cssThingSelector);
Something like that.
Edit:
I will also add that you can nest findElement calls from selenium webelement objects.
So, if there is another item in the inner html of the .thing web element (say, a span tag), you could just nest another findElement call:
var spanElem = elem.$('span');
You can do this as much as you'd like.

What exactly is DOM Extension / Wrapping?

I have 2 main questions.
Does extending things like Object count?
What is DOM wrapping?
http://perfectionkills.com/whats-wrong-with-extending-the-dom/
After reading that article I couldn't find anything about DOM wrapping, and no specification and what exactly is and isn't DOM extension.
No, Object is specified as part of the Javascript language, while the DOM is an API only relevant in a browser environment and is used to "access and update the content, structure and style of documents" (W3C).
However, one of the reasons provided in that article arguing against the extension of DOM objects still applies to extending native types such as Object - namely the chance of collisions.
Wrapping an object refers to creating a new object that references the original, but providing additional functionality through the new, wrapper object.
For example, rather than extending a DOM Element object with a cross-browser addClass function like this:
var element = document.getElementById('someId');
element.addClass = function (className) {
...
};
You can instead define a wrapper function:
var ElementWrapper = function (element) {
this.element = element;
};
And add the function to its prototype:
ElementWrapper.prototype.addClass = function (className) {
...
};
And "wrap" elements like this:
var element = document.getElementById('someId');
var wrapped = new ElementWrapper(element);
wrapped.addClass('someClass');