Angular Wrap Broken Between Versions? - javascript

Take a look at this Fiddle that's running Angular 1.0.
Hover over the image, and it works fine (you'll see an overlay over the image.)
What I'm doing is wrapping the element with a container div using .wrap(..) function, and later binding the mouseover event to the container div. It works fine.
However, in Angular 1.3 like in this Fiddle with exactly the same code, the container div doesn't recognize my element as its child, which affects the mouseover event from being triggered.
Am I doing something wrong or is it broken in 1.3 ?

The jump from Angular 1.2.x to 1.3.0 involved a few changes to jqLite. One of which was commit #77d3e75 - fix(jqLite): clone wrapNode in jqlite/wrap.
If you run each, the commit before that works, says 1 child exists. That commit says 0. This is intentional, though. This was to prevent unintended side-effects, and to better match JQuery's implementation.
In fact, a test assertion for your exact usage was added in that commit:
expect(root.children().length).toBe(0);
A solution to this particular case might be to change the code slightly, from:
el = angular.element('<div class="overlay-container"></div>');
iElement.wrap(el);
To:
iElement.wrap('<div class="overlay-container"></div>');
el = iElement.parent();
That said, I'm not sure why this behaviour was changed. Given that a angular.element was already created, it doesn't make much sense to me that another is being created.

Angular.js doesn't use semver. It means that your code can be broken by any update of angular. (I don't see the reason why angular team creates that dependency hell)
For each update of angular version you should check changelog and update your code for each breaking change.
You can't even rely on minor version number. There are breaking changes for patch updates in changelog.
If you update your application from 1.0 to 1.3 I advise you to start from changelog, as there can be bugs that isn't visible at first. Because there is huge number of breakings (159 for me using find in browser) and most of them was between v1.0 to v1.4.

Related

MDL on dynamic websites downgrading

We have a old large ajax based GUI adapted to MDL.
The whole page content is build dynamically (from xml description).
componentHandler.downgradeElements( /all old notes/ ;
remove all old notes form DOM
add new page content to DOM
componentHandler.upgradeAllRegistered();
This works fine, but it leaks memory if the component MaterialLayout is alos created dynamically .
With the "downgrading fix (#2009" the internal references are removed.
The reason for the memory leak is that the component MaterialLayout adds a listener to the MediaQueryList (MDL 1.1).
this.screenSizeMediaQuery_.addListener(this.screenSizeHandler_.bind(this));
In MDL 1.1.2 there are two windows event handler added which lead to the same problem.
window.addEventListener('pageshow', function (e) { ... } );
...
window.addEventListener('resize', windowResizeHandler);
This listeners are not removed by downgradeElements. And therefore the DOM elements are not GC.
Questions:
Is it not indented to delete the element with MaterialLayout?
Is it completely wrong what I doing here?
Is this an MDL issue?
Is there a workaround without changing MDL code?
There was a issue report for MDL Layout downgrade #1340
The final conclusion was:
MDL is geared towards stateless sites with 1.x. Destroying the entire layout is not something that was thought about during the initial build of the layout component.
So right answer is:
It is not indented to delete the element with MaterialLayout for MDL 1.x.
Additional information:
For a hack work around (for testing) I removed adding the MediaQueryList listener from material.js (still 1.0.4 with deconstructComponentInternal form 1.1.2). This seems to work for our solution. I did not found any drawbacks (again in our solution) up to now.

listen to z-index change in Javascript? [duplicate]

I need an efficient mechanism for detecting changes to the DOM. Preferably cross-browser, but if there's any efficient means which are not cross browser, I can implement these with a fail-safe cross browser method.
In particular, I need to detect changes that would affect the text on a page, so any new, removed or modified elements, or changes to inner text (innerHTML) would be required.
I don't have control over the changes being made (they could be due to 3rd party javascript includes, etc), so it can't be approached from this angle - I need to "monitor" for changes somehow.
Currently I've implemented a "quick'n'dirty" method which checks body.innerHTML.length at intervals. This won't of course detect changes which result in the same length being returned, but in this case is "good enough" - the chances of this happening are extremely slim, and in this project, failing to detect a change won't result in lost data.
The problem with body.innerHTML.length is that it's expensive. It can take between 1 and 5 milliseconds on a fast browser, and this can bog things down a lot - I'm also dealing with a large-ish number of iframes and it all adds up. I'm pretty sure the expensiveness of doing this is because the innerHTML text is not stored statically by browsers, and needs to be calculated from the DOM every time it is read.
The types of answers I am looking for are anything from the "precise" (for example event) to the "good enough" - perhaps something as "quick'n'dirty" as the innerHTML.length method, but that executes faster.
EDIT:
I should also point out that whilst it would be "nice" to detect the precise element that has been modified, it is not an absolute necessity - just the fact that there has been any change would be good enough. Hopefully this broadens people's responses. I'm going to investigate Mutation Events, but I still need a fallback for IE support, so any whacky, creative, outside-of-the-square ideas would be very welcome.
To bring this up to date, the DOM4 standard does away with Mutation Events and replaces them with Mutation Observers: https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver
http://www.quirksmode.org/js/events/DOMtree.html
jQuery now supports a way to attach events to existing and future elements corresponding to a selector: http://docs.jquery.com/Events/live#typefn
Another interesting find - http://james.padolsey.com/javascript/monitoring-dom-properties/
Mutation events are the W3 recommendation of what you are looking for..
Not sure if they are supported all around.. (IE will most likely not support them..)
You could try using the DOMNodeInserted and DOMNodeRemoved events. Acording to Quirksmode, they kind of work in most browsers, with the notable exception of IE...
http://www.quirksmode.org/dom/events/index.html
I have recently written a plugin that does exactly that - jquery.initialize
You use it the same way as .each function
$(".some-element").initialize( function(){
$(this).css("color", "blue");
});
The difference from .each is - it takes your selector, in this case .some-element and wait for new elements with this selector in the future, if such element will be added, it will be initialized too.
In our case initialize function just change element color to blue. So if we'll add new element (no matter if with ajax or even F12 inspector or anything) like:
$("<div/>").addClass('some-element').appendTo("body"); //new element will have blue color!
Plugin will init it instantly. Also plugin makes sure one element is initialized only once. So if you add element, then .deatch() it from body and then add it again, it will not be initialized again.
$("<div/>").addClass('some-element').appendTo("body").detach()
.appendTo(".some-container");
//initialized only once
Plugin is based on MutationObserver - it will work on IE9 and 10 with dependencies as detailed on the readme page.
jQuery Mutate does this too, by default it supports like height, width, scrollHeight etc... but it also can be extended with a little bit of extra code to add new events like see if text has changed etc...
http://www.jqui.net/jquery-projects/jquery-mutate-official/
Hope it helps

JqueryMobile issue when working with Knockoutjs

I found jquery mobile is not rendering correctly when the element is generated by knockoutjs (or probably not rendering correctly when element is generated dynamically). See the demo at http://jsfiddle.net/wRRZk/1/
updates:
One solution is to load jquery-mobile js file after KO binding finished as shown in http://jsfiddle.net/wRRZk/3/, however this doesn't solve the problem that jquerymobile render fail when changing KO model dynamically, as shown in http://jsfiddle.net/wRRZk/4/
I think you'll need to tell jQueryMobile to create those elements into the jQM enhanced version using the API. Check here :: http://jquerymobile.com/demos/1.1.1/docs/pages/page-scripting.html and look halfway down for "Enhancing new markup" and the section just below.
As for the create/refresh ... might need to be somewhat judicious in know when and where you're adding new stuff, and whether a create or refresh is needed.
I've done a new version of the jsFiddle here :: http://jsfiddle.net/wRRZk/5/.
I'm also removing from the model afterwards, which does seem to remove the links too, BUT, I think that may also be because the jQM enhancement is keeping the same anchor, thus the reference knockout as is still valid.
Not too sure how well that will work for the other enhancements done by jQM.

Dojo 1.6 dialog widget losing content attachpoints

We've recently upgraded a project from Dojo 1.5 to 1.6 [for the basic IE9 support] and its broken one of our widgets. We have a dialog widget [dijit.Dialog] with another widget within it [any widget here will produce the same behavior], the expected behavior is for the inner widget to be placed within the dialog widget's contentNode, and each of their attachpoints to be available through the main widget.
This isn't happening, instead we only find the dialog's attachpoint. More details below:
We're doing something like this in our main widget's template:
<div dojoType="dijit.Dialog" dojoAttachPoint="dia_widget"
autofocus="true" draggable="false" open="false" preventCache="true">
<div dojoType="dijit.form.ValidationTextBox" doLayout="false" dojoAttachPoint="val_widget">
</div>
</div>
This provides us a parent widget [main_widget] with two attach points: dia_widget and val_widget, which could be accessed within the main widget [after the buildRendering() function] by calling this.dia_widget and this.val_widget respectively.
After upgrading to 1.6.0 things go awry.
My guess is that when a dialog widget gets parsed it removes the domNode of its content into its new containerNode. When the rootnode is having attachpoints assigned, since the domNode is no longer available, it wont get added.
I've been debugging and from what I can see buildRendering() calls _attachTemplateNodes() in dijit/_Templated.js. This loops over the nodes in the widget, looking for their dojoattachpoint attribute and pushing them in the widget's _attachpoints attribute.
The first loop has two nodes [our dia_widget and val_widget] nodes. At this point it then begins parsing each node individually, beginning by calling buildRendering() on dia_widget and finding the attachpoints of all its children.
At some point here the main_widget's dom is modified to include the parsed/rendered dia_widget. The loop then returns to the main node _attachTemplateNodes() call, where it only sees dia_widget as a child node, having lost the val_widget entry. Since the node isn't found, it never gets added as an attachpoint in main_widget, and we can't access it down the line.
I hope this isn't too convoluted to follow, I'm new to Dojo and chasing through the code in firebug wasn't the most fun experience in the world, so I've written things up as they make sense to me.
I'm left wondering why the behavior varies from 1.5 to 1.6, is this simply a feature/parameter I should be passing to the dialog to behave as it did before? Is this a bug in the way I'm creating the nested widget? Is this a [known?] bug in dojo itself?
Thanks,
vic
There are some changes in 1.6.0 that potentially adds a "lang" attribute to dynamically-loaded content. Sometimes this "lang" attribute value is undefined and causes problems.
See if you are having problems with a "lang" attribute -- if so, this is likely to go away with 1.6.1.

jQuery Mobile - Dynamically creating form elements

I'm creating a web-database driven offline web-app targeted at iOS devices. I'm trying to use jQuery Mobile, but I have a problem in creating the various forms.
The form options are taken from a database query, so they are inserted into the page after it has loaded, so the "jQuery-Mobilification" doesn't happen. Taking a quick look through the source, there doesn't seem to be any obvious way to call into this at this stage (of course it's an alpha release, and I think this would be a reasonably common request, so I'm hopeful it will come). Is there some kind of workaround I can put in to do this? I'm particularly interested in radio buttons, check boxes and select lists.
UPDATE
Beta2 has a create event. I will update my faq when the beta2 gets released. See http://jquerymobile.com/blog/2011/07/22/jquery-mobile-team-update-week-of-july-18th/
Updated faq: http://jquerymobiledictionary.pl/faq.html
As CaffeineFueled proposed - .page() is the way to make JQM work with any part of HTML
.page() can be called only once for an element. Call it on a wrapping element you add to the page. It should handle everything.
The current selected answer is slightly out of date. Use 'refresh', not 'page', for styling dynamically added content (lists or forms).
If you add items to a listview, you'll
need to call the refresh() method on
it to update the styles and create any
nested lists that are added. For
example, $('ul').listview('refresh');
via the jQuery Mobile docs, 1.0.4a
This is messing around in undocumented internals, but the following is working for me:
$("#some-div").load("/html/fragment/",
function() {
$(this).find("input").customTextInput();
});
There are equivalent methods for buttons, checkboxes etc.
Have a look at the _enchanceControls [sic] method in http://code.jquery.com/mobile/1.0a1/jquery.mobile-1.0a1.js.
Update for 1.0Alpha2: As can be expected when playing around with the internals of a library, this no longer works in the latest version. Changing customTextInput() to textinput() fixes it a bit, but the theme isn't fully applied for some reason. We were warned...
After your AJAX call finishes and you insert the form elements try calling:
$("#the-page-id").page();
I believe the jquery-mobile team will be adding a .refresh() method on the various UI elements to solve this issue in the future.
Yeah the issue is as you described. The 'mobilization' is fired when the document is ready. But since your offline DB queries are asynchronous it ends after the document.ready is fired. So the DOM is updated later in the process and doesn't have the extra CSS added to all the divs and list items.
I think you would have to change the source of the mobile js to not run on document ready but run when you tell it to run. Then you would have to call that function in your database callback.
Looks like that is the only option at the moment.
Traditionally I used jqtouch and now sencha. I haven't played much with jQuery mobile.
ALTERNATIVELY - you could write out your HTML after querying it out of the database with the necessary CSS styles on it. If you use Firebug plugin for Firefox you can see what styles / classes are getting applied when the mobilization runs. You could just write out your HTML using those conventions. Not ideal, but would work.
naugtur is right, you have to call .page() on any element that you add to the dom, then it works out nicely:
var el = $('<input type="text"/>')
el.page();
$('#something').append(el);
This worked for me (jquerymobile1.7.0):
$('#formular').append('<div data-role="fieldcontain" class="ui-hide-label">' +
'<label for="name" class="ui-hidden-accessible">Name:</label>' +
'<input type="text" name="name" size="25" id="name" placeholder="Name"/>' +
'</div>');
$('#name').textinput();
There are currently so called plugin functions for all kind of form elements (e.g. slider, textinput etc.) to create them.
Here's a link to the docs for this feature that Tom talked about. Not sure exactly when they were added, but I'm using it and it works for me!
http://jquerymobile.com/test/docs/forms/plugin-eventsmethods.html

Categories