how to add id in mentio textarea div dynamically - angularjs

i want to use ment-io in my project from http://jeff-collins.github.io/ment.io/#/examples.i had implement this about 100% .but that cannot be applicable in that. how to add id in mentio textarea div dynamically
my code :
<div contenteditable mentio
mentio-typed-term="typedTerm"
mentio-macros="macros"
mentio-require-leading-space="true"
class="editor form-control"
id="htmlContent{{index}}"
ng-model="htmlContent">
</div>
<mentio-menu
mentio-for="'htmlContent'"
mentio-trigger-char="'#'"
mentio-items="people"
mentio-search="searchPeople(term)"
mentio-select="getPeopleText(item)"
></mentio-menu>

The issue is that when using an id that has an expression in it, it will not have resolved by the time the menito-menu directive tries to locate the element. One way to work around this is to use a ng-if on mentio-menu that waits for the expression to have resolved.
http://plnkr.co/edit/BUjixoaGZ8f54ZTv84bh?p=preview
<body ng-app="app" ng-controller="testCtrl">
<div contenteditable
mentio
mentio-typed-term="typedTerm"
mentio-require-leading-space="true"
class="editor form-control"
id="{{'htmlContent' + index}}"
ng-model="htmlContent">
</div>
<mentio-menu ng-if="index"
mentio-for="'htmlContent' + index"
mentio-trigger-char="'#'"
mentio-items="people"
mentio-search="searchPeople(term)"
mentio-select="getPeopleText(item)">
</mentio-menu>
</body>
Or if you want to do it in an ng-repeat you could do something like this:
http://plnkr.co/edit/JslXZ4ETZa3qFZyPMbAK?p=preview
<div ng-repeat="item in items">
<div contenteditable
mentio
mentio-typed-term="typedTerm"
mentio-require-leading-space="true"
class="editor form-control"
id="{{'htmlContent' + $index}}"
ng-model="htmlContent">
</div>
<mentio-menu ng-if="item"
mentio-for="'htmlContent' + $index"
mentio-trigger-char="'#'"
mentio-items="people"
mentio-search="searchPeople(term)"
mentio-select="getPeopleText(item)"
></mentio-menu>
</div>

The ID of the element is the way to connect the mentio directive to its menu when it's specified externally. If you only have one trigger char, one way you can work around this is just to move mentio-items, mentio-search and mentio-select on to the div. If you have more than one trigger character, then you need the separate specification.

FYI - A new version of ment-io was published: 0.9.12 that allows you to specify the ID of the mentio with the mentio-id field. This attribute can contain {{'htmlContent' + index}} and will evaluate appropriately without the need for an ng-if. See the ment.io project for details in the documentation.
http://jeff-collins.github.io/ment.io/#/documentation

You can directly edit the ID of the element via a directive on which you just add the id on the "elem" received as parameter (link stage).
Make sure mentio-menu triggers its init after your directive compilation (directive priority: ...).

Related

Evaluating an expression which contains an expression

I am a newbie to Angular js and I just started doing a project in Angular JS.
Let me give you a brief idea about my application. I have a json data which contains data of some nodes, which form a hierarchy. I am using to display this data. So It will take one node at a time and display based on the data in it. I need to display a select field based on the data.
Everything worked fine until I need to display error messages, if the user doesn't select a value in the field. It should be displayed on that particular node. For this I should identify each node( as this is a template). I mapped the id in the data as the name of the select tag, made the tag as required and written a span which displays an error message.
This span will be displayed based on the condition
$error.required
.
The code snippet is as follows.
<form class='css-form form-search' name="myForm" novalidate>
......
<script type="text/ng-template" id="mynodetemplate">
........
<select name="{{node.id}}" ng-model="node.attributeId" ng-options="attribute.id as attribute.name for attribute in attributes" ng-show ="node.showData" required>
<option value="">Select an Attribute</option>
</select>
<span ng-show=”myForm.node.id.$error.required" style="text-align:center; color:red">Please select</span>
'''''''
</script>
..........
<div ui-tree id="tree-root">
<ol ui-tree-nodes ng-model="nodes">
<li ng-repeat="node in nodes” ui-tree-node ng-include="mynodetemplate”></li>
</ol>
</div>
..........
But I am not able to give the correct expression here-
ng-show=”myForm.node.id.$error.required"
I have tried so many ways to evaluate the correct expression, but its not working.
Any help appreciated.
Thanks in advance.
Just as in JavaScript, if you want the name of an object attribute to be node.id, you can't just write
object.node.id
because that references the attribute id of the attribute nodeof the object. So you're forced to use
object['node.id']
So your expression should be
ng-show="myForm['node.id'].$error.required"
But I agree with charlieftl in the comments. You're making your own life difficult by choosing a name containing a dot. Just rename it nodeId, and you can use
ng-show="myForm.nodeId.$error.required"
EDIT:
The name is now in fact a dynamic name. So, in JavaScript you would use
object[node.id]
In the expression, since the scope is implicit, you would use
ng-show="myForm[node.id].$error.required"
I have used the solution posted here
What I have done is that , I will just check whether value exists in the modal or not, or its length.
A sample snippet from the answer is as follows
<input ng-model="somefield">
<span ng-show="!somefield.length">Please enter something!</span>
<span ng-show="somefield.length">Good boy!</span>
Thanks #Supr for the answer.
I dont know why the form validation is not working though :(

Using expression from ng-repeat inside an ng-include

I may have worded this title incorrectly but I am hoping to still get some help. I am trying to use an expression that I get from an ng-repeat to include an new page using ng-include but it is not rendering. I can write in the page I want, but I want to use the expression to include multiple pages dynamically
<div ng-app="" id="container" ng-controller="pagesController">
<span ng-repeat="x in pages">
{{x.Page | uppercase}}
<b ng-if="!$last" href="#"> - </b>
<div ng-include="'{{x.HTML}}'" name="{{x.Page}}"></div>
</span>
But if I manually enter the pages like so:
<div ng-include="'generic.htm'" name="generic"></div>
It works as expected.
I am getting used to Angular.js obviously and I am not sure if this is possible or if I can do what I want really. Any help would be appreciated.
ng-include is an angular directive, and assuming x.HTML is a string, omit the {{}} and the single quotes:
ng-include="x.HTML"

AngularJs unable to use custom directive inside tr

I've just started looking at AngularJs. I was attempting to use a custom directive inside a tr element. I get the following error regarding the switch directive
Controller 'ngSwitch', required by directive 'ngSwitchWhen', can't be found!
Some sample code is here: http://plnkr.co/edit/YiSFYK5l8mNIlBo6OGFW
Even after I removed the swtich it still doesn't seem to do anything. I changed the repeat direct to be over currentSheetData and removed the swtich entirly but there's no code in the rows.
However in my example I do the same setup inside a div element and it works fine. Would someone explain what I'm doing incorrectly
You need ng-switch directive on the parent node before declaring ng-switch-when on the child node.
Example:
<div class="animate-switch-container"
ng-switch on="selection">
<div class="animate-switch" ng-switch-when="settings">Settings Div</div>
<div class="animate-switch" ng-switch-when="home">Home Span</div>
<div class="animate-switch" ng-switch-default>default</div>
</div>
https://docs.angularjs.org/api/ng/directive/ngSwitch

AngularJS : How to properly transclude child elements in custom directive?

Here's some code : link
I'm trying to create a directive that wraps its children in some boilerplate. But if the children have ng-if controlling their appearance, the "transclusion" doesn't work. Well it sort of does, but as you can see the ng-if logic is not getting passed through correctly.
I'd like to know how to fix it, but also where (if anywhere) this is described in the Angular docs.
The problem is that Angular initially replaces ngIf with a comment that it uses to track where to place the conditional code. It's easiest to see with an example.
Your HTML:
<div control-group>
<label>Test</label>
<input type="text" ng-model="editing.name" />
<span class="text-error" ng-if="editing.name.length != 3"> Name must be 3 characters </span>
</div>
Looks like this inside your transclude function's cloned variable (transclude(function (cloned) {):
<div control-group>
<label>Test</label>
<input type="text" ng-model="editing.name" class="ng-valid ng-dirty">
<!-- ngIf: editing.name.length != 3 -->
</div>
So, the element with class text-error that you're filtering on (below) isn't in cloned. Just the comment is there.
var inputsAndMessages = cloned.filter('input, button, select, .text-error');
Since you're only transcluding elements that match the above filter the ngIf comment is lost.
The solution is to filter for comments as well and add them in your append (so Angular maintains it's reference point to the ngIf). One way to do that is to replace the above with this (using the fact that an html comment is node type 8)
var messages = cloned.filter(function(){ return this.nodeType == 8; }); //comments
var inputs = cloned.filter('input, button, select')
var inputsAndMessages = inputs.add(messages);
Working plunker
You need to tell the directive where to place child elements with the ng-transclude directive: (plnkr)
template: "<div class='control-group' ng-transclude>" +
"<label class='control-label' for=''></label>" +
"<div class='controls'></div>" +
"</div>",
From the docs:
Directive that marks the insertion point for the transcluded DOM of the nearest parent directive that uses transclusion.
Any existing content of the element that this directive is placed on will be removed before the transcluded content is inserted.
I wasn't sure what exactly your intent was since you have the input and label both in the template and as children in the HTML. You might want to place your ng-transclude elsewhere.

Angularjs : dom manipulation replacing and then reattaching to another parent with map

PROBLEM
I have a dom element, which i want to detach it from its parent and append it at some other location in the dom, angularjs way.
i could easily do this in jquery with detach and appendto, but i am unable, to find the same in angularjs way.
var detached = jQuery('.toBeDetached');
jQuery('.itemMaximixed').append(detached);
Note i need to detach since the element contains a map in it.
It may not be applicable in your case, but you can use the transclude facility of an Angular directive to do this.
I don't think attaching and deattaching would work. What I can suggest is destroying the recreating the template under different node.
You can use something like ng-if in Angular 1.1.5 for this. Using multiple ng-if and associated conditions you can bind the same template at multiple location, which ever ng-if returns true that template would get loaded.
The template code can be duplicated or be out inside a ng-template script. Something like this
<div id='parent'>
<div id='child1'>
<div ng-if='condition1'><ng-include src='datatemplate' /></div>
</div>
<div id='child2'>
<div ng-if='condition2'><ng-include src='datatemplate' /></div>
</div>
</div>
<script id='datatemplate' type='text/ng-template'>
<!-- Template HTML -->
</script>

Resources