Simply put, I'm using AngularJS trying to do something like this:
<ul>
<li ng-repeat="thing in things">
<a id="mybutton" href="link{{thing.Id}}">Click</a>
<script type="text/javascript">
$("#mybutton").click(function()
{
alert("Id: " + {{thing.Id}});
});
</script>
</li>
</ul>
Both that, and alert("Id: " + thing.Id); yield errors (unespected token '{' and 'thing' is not defined, respectively). Is there a way that I can access thing.Id from a block of javascript within the repeater's scope?
To add a practical reason, I'd like to build and redirect to a URL using that value and a few other things in javascript (where I have access to jquery).
Mike, using angular expressions ({{thing.id}}) in the tag won't work since angular.js is not a text-based template system but rather uses DOM as its templates. Here is more on this topic: http://docs.angularjs.org/guide/compiler
Now, coming back to your question: what you are trying to do can be done very easily in angular.js without using jQuery, here is a working jsFiddle: http://jsfiddle.net/pkozlowski_opensource/n6UfC/
The trick is to use a ng-click on your href:
<a ng-click="click(thing.id)">Click</a>
and then a click-handler function in your controller:
$scope.click = function(thingId) {
alert("Id: " + thingId);
//$location.path('/some/path/'+thingId);
}
In the controller's function you can use jQuery instructions but you would be better off using angular's $location service: http://docs.angularjs.org/api/ng.$location
I would store it to the element like "data-id={{thing.id}}"
Then from javascript read the ID back using the data attribute.
Related
i have an ng-repeat but i need to use Angular expression inside javascript of my html page(of course app and controller are declared, but have not been posted here):
<div ng-repeat="eleRubrique in scopeComplet">
<script type="text/javascript">
alert('index ' + {{$index}});
</script>
</div>
That does not work. what would be a workaround ?
Thank you for an answer.
I think this would work for you
<div ng-repeat="eleRubrique in scopeComplet" ng-init="alert('index ' + $index)"></div>
And if you would need a more complex script I would recommend to write a function for that and call the function from ng-init
You should not use double curly braces {{}} in JavaScript. They are meant for HTML only in Angular.
Since the JavaScript code in your HTML has nothing to do with the view, can you not achieve the same goal in the controller?
I would like to know how I can pass JSF managed bean properties to a JavaScript function.
Something like this:
<script>
function actualizaMenu(key){
#{linkedMenu.setKey(key)}
}
</script>
<ul>
<ui:repeat value="#{moduleList.modulos}" var="entity">
<li>
<a onclick="actualizaMenu(#{entity.key})">#{entity.nombre}</a>
</li>
</ui:repeat>
</ul>
This is not exactly "passing" of JSF variables. This is just printing JSF variables as if they are JavaScript variables/values. You know, JSF and JS do not run in sync at all. JSF runs in webserver and produces HTML/CSS/JS code which in turn runs in webbrowser once arrived over there.
Your concrete problem is most likely caused because you wrote JSF code in such way that it generates invalid JS syntax. An easy way to verify that is by just checking the JSF-generated HTML output which you can find by rightclick, View Source in browser, and by checking if you don't see any syntax error reports in the JS console in browser which you can find by pressing F12 in Chrome/IE9+/Firefox23+.
Imagine that #{entity.key} here
<a onclick="actualizaMenu(#{entity.key})">#{entity.nombre}</a>
prints a Java string variable like "foo", then the generated HTML would look like
<a onclick="actualizaMenu(foo)">some name</a>
But hey, look, that represents a JavaScript variable named foo, not a JS string value! So if you actually want to ultimately end up as
<a onclick="actualizaMenu('foo')">some name</a>
then you should instruct JSF to generate exactly that HTML:
<a onclick="actualizaMenu('#{entity.key}')">#{entity.nombre}</a>
Beware of special characters in the JSF variable though. You can use OmniFaces of:escapeJS() function for that.
Unrelated to the concrete problem, the concrete implementation of actualizaMenu() makes no sense. You seem to be attempting to set a bean property. You should not use JS for that, but a <h:commandLink> instead.
<h:commandLink value="#{entity.nombre}" action="#{linkedMenu.setKey(entity.key)}" />
Nest if necessary a <f:ajax> to make it asynchronous.
I would recommend using event binding with jQuery and the data attribute on elements to get the same result (assuming you use jQuery):
<script>
function actualizaMenu(key){
/* Logic here ... */
}
$(document).ready(function(){
$('.menuItem').click(function(){
var key = $(this).data('key');
actualizaMenu(key);
);
});
</script>
...
<ul>
<ui:repeat value="#{moduleList.modulos}" var="entity">
<li>
<a data-key="#{entity.key}" class="menuItem">#{entity.nombre}</a>
</li>
</ui:repeat>
</ul>
And, as pointed out elsewhere, unless #{linkedMenu.setKey(key)} actually returns a piece of javascript (which seams unlikely and would probably be really bad even if it did) you need to fix the function as well.
I know this question is old, but to those who are still looking there's an alternative.
If you are using primefaces just try this out.
Request Context
I've got this element:
<span id="tag_span"> {{ selectedSection }} </span>
And I want to get its content from controller, which is {{ selectedSection }}. I can get the element like this:
angular.element('#tag_span');
but don't know how to get what inside of it. Any ideas?
P.S. document.getElementById won't work in the case so there's no need to suggest it.
EDIT: No jQuery allowed.
You get the value by $scope.selectedSection from your controller.
If you need the get html inside the span element use
angular.element($('#tag_span')).html();
You need to reference the jquery before angular js like below.
<script type="text/javascript" src="../../Scripts/jquery-2.1.0.min.js"></script>
<script type="text/javascript" src="../../Scripts/angular/angular.js"></script>
Your all html elements are properties of $scope, so you could easily access the content via $scope.selectedSection . Your controller function definition must have a scope injection like function controller($scope), that is all.
I have html template like this:
$scope.template = '<span class="pointer"><i class="icon-refresh pointer" ng-click="refresh()"></i></span>';
I want to bind this template using ng-bind-html, I tried to use it and also I used ng-bind-html-unsafe, but unfortunately It bind the html string as it is with no click action.
<span ng-bind-html="template"></span>
<span ng-bind-html-unsafe="template"></span>
I read about similar problem and it said that ng-click is loaded after ng-bind, so can anybody introduce to me how to solve this problem?
Perhaps you need to compile the template inside the controller?
angular.controller('ABCDCtrl', function($scope, $compile){
var templateHTML = '<span class="pointer"><i class="icon-refresh pointer" ng-click="refresh()"></i></span>';
$scope.template = $compile(templateHTML)($scope);
});
You could try ng-include and put your template in to a static file instead.
Putting HTML content in scope variables kind of goes against some angular philosophy guidelines, I believe.
If you were to later change the template, would you want it to rebind itself and be processed again?
I would like to know how I can pass JSF managed bean properties to a JavaScript function.
Something like this:
<script>
function actualizaMenu(key){
#{linkedMenu.setKey(key)}
}
</script>
<ul>
<ui:repeat value="#{moduleList.modulos}" var="entity">
<li>
<a onclick="actualizaMenu(#{entity.key})">#{entity.nombre}</a>
</li>
</ui:repeat>
</ul>
This is not exactly "passing" of JSF variables. This is just printing JSF variables as if they are JavaScript variables/values. You know, JSF and JS do not run in sync at all. JSF runs in webserver and produces HTML/CSS/JS code which in turn runs in webbrowser once arrived over there.
Your concrete problem is most likely caused because you wrote JSF code in such way that it generates invalid JS syntax. An easy way to verify that is by just checking the JSF-generated HTML output which you can find by rightclick, View Source in browser, and by checking if you don't see any syntax error reports in the JS console in browser which you can find by pressing F12 in Chrome/IE9+/Firefox23+.
Imagine that #{entity.key} here
<a onclick="actualizaMenu(#{entity.key})">#{entity.nombre}</a>
prints a Java string variable like "foo", then the generated HTML would look like
<a onclick="actualizaMenu(foo)">some name</a>
But hey, look, that represents a JavaScript variable named foo, not a JS string value! So if you actually want to ultimately end up as
<a onclick="actualizaMenu('foo')">some name</a>
then you should instruct JSF to generate exactly that HTML:
<a onclick="actualizaMenu('#{entity.key}')">#{entity.nombre}</a>
Beware of special characters in the JSF variable though. You can use OmniFaces of:escapeJS() function for that.
Unrelated to the concrete problem, the concrete implementation of actualizaMenu() makes no sense. You seem to be attempting to set a bean property. You should not use JS for that, but a <h:commandLink> instead.
<h:commandLink value="#{entity.nombre}" action="#{linkedMenu.setKey(entity.key)}" />
Nest if necessary a <f:ajax> to make it asynchronous.
I would recommend using event binding with jQuery and the data attribute on elements to get the same result (assuming you use jQuery):
<script>
function actualizaMenu(key){
/* Logic here ... */
}
$(document).ready(function(){
$('.menuItem').click(function(){
var key = $(this).data('key');
actualizaMenu(key);
);
});
</script>
...
<ul>
<ui:repeat value="#{moduleList.modulos}" var="entity">
<li>
<a data-key="#{entity.key}" class="menuItem">#{entity.nombre}</a>
</li>
</ui:repeat>
</ul>
And, as pointed out elsewhere, unless #{linkedMenu.setKey(key)} actually returns a piece of javascript (which seams unlikely and would probably be really bad even if it did) you need to fix the function as well.
I know this question is old, but to those who are still looking there's an alternative.
If you are using primefaces just try this out.
Request Context