Skip to content
This repository has been archived by the owner on May 5, 2018. It is now read-only.

Implementing "input's type property CAN be changed" #371

Closed
wants to merge 2 commits into from

Conversation

mikoto
Copy link

@mikoto mikoto commented Jan 21, 2013

This directive enables to write an input tag with a variable type property like:

 <input type="{{model}}" ui-input2 />

You can not write the following code without this directive:

<input type="{{model}}" />

because jQuery throws an error: "type property can't be changed" when an type property is dynamically changed.
This is due to an IE problem: http://stackoverflow.com/questions/1544317/jquery-change-type-of-input-field

This directive enables to write an input tag with a variable type property like:

     <input type="{{model}}" ui-input2 />

You can not write the following code without this directive:

    <input type="{{model}}" />

because jQuery throws an error: "type property can't be changed" when an type property is dynamically changed.
This is due to an IE problem: http://stackoverflow.com/questions/1544317/jquery-change-type-of-input-field
@pkozlowski-opensource
Copy link
Member

@mikoto does your version work on IE? AFAIK IE doesn't allow changing of input types...

@mikoto
Copy link
Author

mikoto commented Jan 21, 2013

The answer is Yes.
Because I do NOT CHANGE type property of input tags.
This directive watch a change of iAttrs.type(argument of link function) and clone a input tag which has a constant type(evaluated iAttrs.type).

@mikoto
Copy link
Author

mikoto commented Jan 21, 2013

For testing, I loaded a jQuery on the line 9 in http://plnkr.co/edit/Ddp8prhsKsKRhPL8uYLc.
You get the error "type property can't be changed" from jQuery if this directive change type property.
But there are no errors because this directive clones with constant type, replaces and recompiles a input tag when type property is changed.

@ProLoser
Copy link
Member

I foresee problems when working with other directives.

You should possibly replace the node with a comment placeholder at compile time (not linking time).

Then render out upon linking

@petebacondarwin
Copy link
Member

Dean is right that you have to be careful when replacing elements. If you
replace the node with a comment tag at compile then you need to copy over
all attributes/directives that have not been run already, based on
priority. Also you can't, at the moment, insert a new tag after the
compiled tag in the post-link function as the compiler gets confused about
how many tags there are in the current list of siblings.

On 21 January 2013 18:35, Dean Sofer notifications@github.com wrote:

I foresee problems when working with other directives.

You should possibly replace the node with a comment placeholder at compile
time (not linking time).

Then render out upon linking


Reply to this email directly or view it on GitHubhttps://github.com//pull/371#issuecomment-12511131.

@mikoto
Copy link
Author

mikoto commented Jan 21, 2013

omg! Sorry, I uploaded wrong version of my codes.(It does not work on IE because of using attar() method for type property.)
Now, I upload correct version.

@mikoto
Copy link
Author

mikoto commented Jan 21, 2013

Thanks for your advices. you are correct. I have to be careful with replacing element on/after a link step.

But to solve the problem "type property can't be changed" needs to watch type property changes because we can not change type property of input tag.
And this "watching changes" code must be in link function(at least I do not know how to write watching codes in a compile function).

So, my solution is "recompile" the input tag after replacing by using $compile(http://docs.angularjs.org/api/ng.$compile) function.
And my code is based on the sample in the $compile page.

@mikoto
Copy link
Author

mikoto commented Jan 21, 2013

@petebacondarwin, I want to confirm order of compiles and links step.

All link steps run after all compile steps, right?
If it is correct, iAttrs(link function argument) can access all attributes set up on compile functions. So, we can copy all attributes/directives.

Otherwise, for example, we have directiveA(has compileA and linkA) and directiveB(has compileB and linkB),
if the order can be compileA -> linkA -> compileB -> linkB, my program does not work, maybe. (I do not know any examples it does not work.)

Back to my motivation.
I want to generate input tags from models like "Use Case" in http://embed.plnkr.co/Ddp8prhsKsKRhPL8uYLc/preview.
Are there some good way?

@petebacondarwin
Copy link
Member

@mikoto - I find this example useful : http://plnkr.co/edit/qrDMJBlnwdNlfBqEEXL2?p=preview
All link steps run after all compile steps. Yes.
At the point the "post"-link function runs the AngularJS compiler is completely finished with the element. So anything you do with the element (or its children) will not be seen by the compiler unless you manually run $compile on it.

So you can indeed copy attribute values from the current element to any that you decide to replace it with. But what is a bit more difficult is copying the "behaviour". In other words any bindings that have been set up between the element and its scope and any controllers that have been attached to the element.

In the link function, the following siblings of the element have not yet been linked and if you start adding siblings after then the compiler will get confused and try to link those instead of the elements that it expects to be there. Worse still if you try to add a sibling before this element, the the compiler will get in an infinite loop because it will then try to link this element over and over again!

@mikoto
Copy link
Author

mikoto commented Jan 21, 2013

@petebacondarwin, Thank you so much!
I understand completely and that example is so helpful.

Now, I close this pull request.
But my motivation "generating input tags from models" does not be achieved and it is general purpose.
Please tell me if someone know a good way.

@mikoto mikoto closed this Jan 21, 2013
@ProLoser
Copy link
Member

ProLoser commented Feb 2, 2013

@mikoto I realize this is way overdue but you should pop over to here: #191

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants