Call an angular function inside html - javascript

I was trying to see if there is a way to call a function I designed inside the scope:
<ul class="ui-listview ui-radiobutton" ng-repeat="meter in meters">
<li class = "ui-divider">
{{meter.DESCRIPTION}}
{{htmlgeneration}}
</li>
</ul>
$scope.htmlgeneration = function()
{
...
}
The function is called htmlgeneration. Essentially, what I want to do is dynamically append HTML inside the li element while using AngularJS.

Yep, just add parenthesis (calling the function). Make sure the function is in scope and actually returns something.
<ul class="ui-listview ui-radiobutton" ng-repeat="meter in meters">
<li class = "ui-divider">
{{ meter.DESCRIPTION }}
{{ htmlgeneration() }}
</li>
</ul>

I guess my problem was related to conflicts with Django tags. This post was helpful.
What worked for me was a simple solution involving using ng-bind and changing the code to something like this:
<ul class="ui-listview ui-radiobutton" ng-repeat="meter in meters">
<li class="ui-divider" ng-bind="htmlgeneration(meter.DESCRIPTION)">
</li>
</ul>

Related

how to add ng-dbclick if condition is verified angularjs?

I want to inject ng-dbclick if just a condition is true :
<li ng-if="condition ? ng-dblclick='event()':nothing">
Thanks.
You can simply do this :
<li ng-dblclick="condition && event()">...</li>
You'll need to create two li's
<li ng-if="condition" ng-dblclick="event()">
<your-component />
</li>
<li ng-if="!condition">
<your-component />
</li>
Otherwise you'll need to compile the template and do it on the javascript and not on the template.
You can take a look at the following:
Dynamically Import Component From Variable (AngularJS)

Unable to access user input in a function called from ng-repeat

I am new to Angular and may be missing something obvious. I did read the ng-model scope documentation. And followed the recommendation to use an object instead of primitives.
I also tried the $parent suggested by a few others here. That didn't help either.
I have read many Q&As here involving ng-repeat. But they are talking about an input inside an ng-repeat. In my case there is only one text box. I am trying to search inside a tree using ng-repeat.
<script type="text/ng-template" id="tree_item_renderer.html">
{{data.name}}
<ul>
<li ng-repeat="data in data.nodes" ng-include="'tree_item_renderer.html'" ng-show="visible(data)"></li>
</ul>
</script>
This is the function being called:
$scope.visible = function(item) {
console.log("SearchText inside visible: " + $scope.input.searchText);
return !($scope.input.searchText && $scope.input.searchText.length > 0
&& item.title.indexOf($scope.input.searchText) == -1);
};
Take a look at my jsFiddle
I saw your code on the jsFiddle. There is an issue that you called ng-controller="TreeController" twice and initialized ng-app = Application. I have commented out these two lines of code, and you can see the change on the console.
The reason why you are getting this problem is you make Angular to re-initialize TreeController which it clears the value of input.searchText.
Check out the working jsFiddle !
<div ng-app="myApp">
<div ng-controller="TreeController">
Search UIC:
<input type="text" ng-change="search()" ng-model="input.searchText"
placeholder="Enter your search terms" />
<!-- <ul ng-app="Application" ng-controller="TreeController"> -->
<ul>
<li ng-repeat="data in tree" ng-include="'tree_item_renderer.html'" ng-show="visible(data)">
</li>
</ul>
</div>
</div>

Trigger function on a certain element - ngrepeat - angularjs

Good morning,
I'm trying to change the limitTo filter on a certain list, my issue is:
when I click to the trigger who change the filter limit the filter changes on all ng-repeated categories.
my function inside the main controller
$scope.showMore = function(limit) {
if($scope.limitItems === $scope.itemsPerList) {
$scope.limitItems = limit;
$scope.switchFilterText = 'less';
} else {
$scope.switchFilterText = 'more';
$scope.limitItems = $scope.itemsPerList;
}
}
my scenario (I rewrote it in a simplified version)
<li ng-repeat="item in category.items | limitTo: limitItems ">
{{item.title}}
</li>
<li ng-if="limitItems < (category.items.length)">
<a ng-click="showMore(category.items.length)" >Show {{ switchFilterText }}</a>
</li>
Could you explain me what's wrong with me?
I searched how to select a single element to apply the function but I didn't find anything useful
Update:
I found the way to solve my issue in this way:
No functions inside the controller are involved to make this functionality works properly:
<li ng-repeat="category in maincategories" ng-init="limitItems = maxItemsPerList">
{{category.title}}
<ul>
<li ng-repeat="item in category.items | limitTo: limitItems "> {{item.title}}
</li>
</ul>
<a ng-click="limitItems = category.items.length" href>
<b ng-if="category.items.length > maxItemsPerList && limitItems != category.items.length "> Show more </b>
</a>
I'm not really convinced about Angular (I used it in my past and I was impressed by the performance but now I can see logics senseless):
What I learned:
ng-if and ng-click cannot be used in the same content because ng-if creates new scopes so if you put ng-if on top of the "show more" link it will break the code
ng-init cannot be used in the same element of the ng-repeat otherwise the var initialised will not be available inside the ng-repeat block
I think there is another way to do that, maybe more clean but in this specific case I can't do a lot.
ng-if and ng-click cannot be used in the same content because ng-if
creates new scopes so if you put ng-if on top of the "show more" link
it will break the code
Yes, ng-if creates a new scope, but it is possible to mix ng-if and ng-click (and most other directives). To do that, you'll be safer if you always write to atributes of another object instead of a simple variable. It is plain JavaScript prototypal inheritance in play.
<li ... ng-init="category.limitItems = maxItemsPerList">
ng-init cannot be used in the same element of the ng-repeat otherwise
the var initialised will not be available inside the ng-repeat block
True, in the sense that variables are created in the local scope. But again, refer to an object.
I think there is another way to do that, maybe more clean but in this
specific case I can't do a lot.
You don't need to do a lot, it is quite simple to do it right actually.
Some advices:
Use ng-init with care. I know it will tempt us but always try to put logic inside controllers and services;
Avoid assignments inside templates;
Learn how to use controllerAs syntax. It gives you an object to write your models to (the controller), so solves most problems related to scope inheritance;
Do not inject $scope, put your view models inside controllers.
Full code goes like this:
<li ng-repeat="category in maincategories" ng-init="category.limitItems = maxItemsPerList">
{{category.title}}
<ul>
<li ng-repeat="item in category.items | limitTo: category.limitItems "> {{item.title}}
</li>
</ul>
<a ng-if="category.items.length > maxItemsPerList && category.limitItems != category.items.length" ng-click="category.limitItems = category.items.length" href>
<b> Show more </b>
</a>

append data from handlebars value

i'm using emberjs with handlebars and i have an issue.
The idea is append a value into the element, the result will show something like that:
<li data-obj="CASH_IN_BANK">CASH_IN_BANK</li>
i'm trying that:
<li data-obj="{{row.value}}">{{row.value}}</li>
but is not working the result out the taks is fine but the data-obj shows the handlebar script tags
<li data-obj="<script id='metamorph-9-start' type='text/x-placeholder'></script>TAG_CASH_IN_BANK<script id='metamorph-9-end' type='text/x-placeholder'></script>" >
Any Suggestions?
You need to use `{{bind-attr attribute=value}}. See: http://emberjs.com/guides/templates/binding-element-attributes/
in your case it would be...
<li {{bind-attr data-obj=row.value}}">{{row.value}}</li>

Apply Knockout.js model to several elements

Is there a way to apply a single view model to several elements?
Basically I have a section of html that the view model (VM1) should be bound to, and I have another view model (VM2) that needs to be bound to a subsection of this. KO doesn't seem to like this though (I even tried using ko.cleanNode(element) on the subsection). So what I'm trying to do is be more specific in my binding by applying it to each piece that needs it. This is hard to explain without code, so here we go:
<section>
<ul>
<li id="one">...</li>
<li id="two">...</li>
<li id="three">...</li>
<li id="diffmodel">...</li>
</ul>
</section>
What I currently have is VM1 being bound to <section>, and VM2 being bound to #diffmodel, but KO doesn't seem to like this.
My current objective (and the question proposed) is to apply VM1 to #one, #two, and #three, and VM2 to #diffmodel, but that doesn't seem to work either (VM1 isn't being bound at all).
Is there a nice solution to this type of situation?
A pretty easy solution is to use a custom binding to prevent the children of an element from being bound.
It would be something like:
ko.bindingHandlers.ignoreBindings = {
init: function() {
return { controlsDescendantBindings: true };
}
};
var VM1 = {
valueOne: ko.observable("one"),
valueTwo: ko.observable("two"),
valueThree: ko.observable("three")
};
var VM2 = {
different: ko.observable("different")
};
ko.applyBindings(VM1);
ko.applyBindings(VM2, document.getElementById("diffmodel"));
HTML:
<section>
<ul>
<li id="one" data-bind="text: valueOne"></li>
<li id="two" data-bind="text: valueTwo"></li>
<li id="three" data-bind="text: valueThree"></li>
<li data-bind="ignoreBindings: true">
<div id="diffmodel" data-bind="text: different"></div>
</li>
</ul>
</section>​​
Sample here: http://jsfiddle.net/rniemeyer/FesgK/
In KO 2.1 (in RC at the moment), the ignoreBindings custom binding could even be used as a containerless binding like: http://jsfiddle.net/rniemeyer/FesgK/1/

Categories

Resources