Okay,
I'm using a small programming test to play around with Angular and Sinatra, and I'm done logic wise, but I wanted to add a small progress bar under the play field to show the moves made.
my haml template looks like this:
.progress.progress-striped.active
.progress-bar{role: "progressbar", :"aria-valuenow" => "{{moves}}", :"aria-valuemin" => 0, :"aria-valuemax" => 9}
%span.sr-only
{{moves}} moves out of 9
I've added the Bootstrap CSS from the CDN to my project, but the bar is not working as I want to.
I only see part of it:
Tried to play around with the classes, but it's not making any difference. I've checked whether I am using the correct classes, and this is also the case. I can also the see the aria- values being properly updated on every click, so the binding works as well.
source code: https://github.com/NekoNova/tictactoe
Can someone give me a pointer as to what I am missing?
Just an alternative usage if you want to use angular-ui bootstrap you can use this library for smooth and easy usage:
%script{ type: "text/javascript", src: "//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.12.1.min.js" }
Add the module "ui.bootstrap" to your application:
var TicTacToeApp = angular.module('TicTacToeApp', ['ui.bootstrap']);
Here is the haml expression:
%progressbar{ :max => "max", value: "dynamic"}
%span{ style: "color: white;white-space: nowrap;"}
{{dynamic}} / {{max}}
And for some demostration here is the variables which need to put in your controller:
$scope.max = 100;
$scope.dynamic = 70;
Related
I've been trying to use the ng-grid 3.0 (ui-grid). I have managed to populate my grid and it's been very responsive and it's features are really amazing. But I'm trying to customize my column headers, as I need more info there.
I can create a custom header cell template, as indicated in the docs, but I don't seem able to use a Bootstrap Dropdown there, it gets cropped and I can't use it at all. Some googling got me thinking it is probably some issue with the overflow attributes, but still I can't solve it. My grid options is as follows:
$scope.columnDefs = [
{ name:'name', displayName: 'Vdd', headerCellTemplate: 'headerTemplate.html' },
{ name:'gender', headerCellTemplate: 'headerTemplate.html' },
{ name:'company' }
]
$scope.gridOptions = {
columnDefs: $scope.columnDefs,
rowTemplate: 'rowTemplate.html',
data: 'data'
};
I have forked an example in plunkr and managed to reproduce my issue:
http://plnkr.co/edit/qdrFiifiz18fxB8w6Aja?p=preview
I want to replace the built-in dropdown menu (since it doesn't seem to allow nesting and sub-menus) and add another one (so in the end, I'd have two dropdown menus in each header cell)
Any help is appreciated =)
I am proud to say I think I've figured it out. I've been digging through ui-grid's source code and narrowed it down to this block (lines: 2847 - 2852).
function syncHorizontalHeader(scrollEvent){
var newScrollLeft = scrollEvent.getNewScrollLeft(colContainer, containerCtrl.viewport);
if (containerCtrl.headerViewport) {
containerCtrl.headerViewport.scrollLeft = gridUtil.denormalizeScrollLeft(containerCtrl.viewport,newScrollLeft, grid);
}
}
I noticed that containerCtrl.headerViewport.scrollLeft was never getting set to newScrollLeft. A quick google search led me to this StackOverflow thread which says that you can't set the scrollLeft property of an element if it's overflow is set to visible.
My solution was to replace containerCtrl.headerViewport.scrollLeft = gridUtil.denormalizeScrollLeft(containerCtrl.viewport,newScrollLeft, grid); with containerCtrl.headerViewport.style.marginLeft = -gridUtil.denormalizeScrollLeft(containerCtrl.viewport,newScrollLeft, grid) + 'px'; which just sets a negative margin on the header. Then add an overflow:hidden; style to .ui-grid-render-container-body to hide headers that extend beyond the main grid viewport.
Doing this messed up the placement of column menus, but there is an easy fix. On line 514 replace var containerScrollLeft = renderContainerElm.querySelectorAll('.ui-grid-viewport')[0].scrollLeft; with var containerScrollLeft = renderContainerElm.querySelectorAll('.ui-grid-viewport')[0].style.marginLeft; to use the margin instead of the scroll value in the menu placement calculation.
I'm using angular-translation and angular-foundation modules with AngularJS and have defined Foundation top-bar like this:
<top-bar custom-back-text="true" back-text="My back text">
[...]
</top-bar>
I need to apply translate filter to My back text. Already tried these two solutions but with no success:
example 1 - CODE
<top-bar custom-back-text="true" back-text="'BACK.KEY' | translate">
example 1 - TEXT IN MENU
BACK.KEY
example 2 - CODE
<top-bar custom-back-text="true" back-text="{{ 'BACK.KEY' | translate }}">
example 2 - TEXT IN MENU
'BACK.KEY' | translate
Do I something wrong or is there no possibility to achieve this with these two modules?
Used versions
angular-translate: 2.4.2
angular-foundation: 0.5.1
If you check the js source code of foundation you will find this piece of code that handles back button
if (settings.custom_back_text == true) {
$('h5>a', $titleLi).html(settings.back_text);
} else {
$('h5>a', $titleLi).html('« ' + $link.html());
}
$dropdown.prepend($titleLi);
So it creates new element and adds to dropdown, result of which is that it copies the value you specified in the back_text. By that time "translate" is not resolved so it copies whatever you put there.
A quick hack to do to solve it you could listen for language change by doing
$rootScope.$on("$translateChangeSuccess", function...
As you can see in the piece of code from foundation.js it creates "a" element inside "h5", so you can do something like this
$rootScope.$on("$translateChangeSuccess", function(){
angular.element(".dropdown h5>a").html($filter('translate')('BACK'))
})
where "BACK" is the key used for translation.
But keep in mind that it's not a good practice to manipulate DOM inside controller, so you may create directive for that.
Though there may be better way to achieve it, this could be just quick hack to do the thing.
I have a responsive site that uses the google translate widget. The weird thing is that for some time the widget now appears twice, and this seem to be related to the responsive design because if I place the same widget code on a simple html page it only appears once. I have no idea on how to solve this. Has anyone come across this?
Update.
I have discovered that this is caused by jquery.themepunch.showbizpro.min.js, if I remove that one the widget only appears once. I have not found a way to fix this yet but there might be a way. I found this piece of code.
<script>
function googleTranslateElementInit() {
new google.translate.TranslateElement(
{ pageLanguage: 'sv' },
'google_translate_element'
);
/*
To remove the "powered by google",
uncomment one of the following code blocks.
NB: This breaks Google's Attribution Requirements:
https://developers.google.com/translate/v2/attribution#attribution-and-logos
*/
// Native (but only works in browsers that support query selector)
if(typeof(document.querySelector) == 'function') {
document.querySelector('.goog-logo-link').setAttribute('style', 'display: none');
document.querySelector('.goog-te-gadget').setAttribute('style', 'font-size: 0');
}
//If you have jQuery - works cross-browser - uncomment this
jQuery('.goog-logo-link').css('display', 'none');
jQuery('.goog-te-gadget').css('font-size', '0');
}
</script>
This code remove the logo, so I'm thinking that if I use javascript I could check and remove duplicate occurrences of <select class="goog-te-combo"> then I would only have one left, is that possible?
This happened to me using Bootstrap. I had two instances of the Google Translate code - one instance for larger screen sizes and another that was only visible for smaller screens. Both showed up regardless of screen size. Bootstrap classes like visible-xs and hidden-xs do not seem to affect the display of the Google Translate button.
You can set a global counter and make sure it's only called once.
<div id="google_translate_element"></div>
<script type="text/javascript">
var duplicate_google_translate_counter = 0;//this stops google adding button multiple times
function googleTranslateElementInit() {
if (duplicate_google_translate_counter == 0) {
new google.translate.TranslateElement({pageLanguage: 'en'}, 'google_translate_element');
}
duplicate_google_translate_counter++;
}
</script>
<script type="text/javascript" src="https://translate.google.com/translate_a/element.js?cb=googleTranslateElementInit"></script>
Had the same problem on RoR. Problem caused by cashing pages with turbolinks. I solved it with deprecating cashing all links in (when script loading it adds attr "data-turbolinks="false" to the body-tag)
Hello to all! I had the same issue and I KNOW is not the best practice but I fixed it with CSS just adding overflow: hidden and a right border on it.
It visually fix the problem until we get a solution and really saved time diving into JS files. Hope it works for you too. Cheers!
The following shows the tooltip text in the right place:
%a{:href => "http://google.com/"}
%span{:tooltip => "TEST"}
= "test"
The following shows the tooltip half a screen below (increasing distance for each element)
%div{:"ng-repeat" => "point in points"}
%a{:href => "http://google.com/"}
%span{:tooltip => "TEST"}
= "test"
It's written in HAML, so in plain HTML the last two lines look like this: <span tooltip="TEST">test</span>.
The points are fetched using Rails $Resource, but I get the same problem when I use the regular $resource.
I'm using the tooltip directive from Angular UI Bootstrap. The application is built in Ruby on Rails 4.0 and uses the angularjs-rails gem (unstable).
My best guess is that the CSS on my site is somehow too complex and that I need to find a way to reprocesses these tooltips after loading.
I needed to add this below my app = angular.module(...) line:
app.config( function ( $tooltipProvider ) {
$tooltipProvider.options({appendToBody: true});
});
I'm not sure what's going on here, but it has something to do with https://github.com/angular-ui/bootstrap/pull/254 and perhaps also https://github.com/angular-ui/bootstrap/issues/139.
I am trying to use a video player (the jwplayer) inside my AngularJS project. This post consists with 2 parts: part 1 for background, part 2 is my question. Thanks.
PART 1: Solving the "Error loading player: No playable sources found" problem.
At first the video is not showed, just a black rectangle on the page ui, and a quite misleading console message saying "No suitable players found and fallback enabled".
Hours later I happened to change the jwplayer size configuration from "height:450, width:800" to "height:'100%', width:'100%'". This time jwplayer shows a message on the page ui: "Error loading player: No playable sources found".
That gives me direction. My jwplayer usage looks like this:
<!-- this is my index.html -->
<div id="jw_container">Loading the player ...</div>
<script>
var player = jwplayer("jw_container").setup({
file:"{{model.my_video.video_url}}",
......
Change that file line to a hardcoded absolute video url will work, indicating that is the real problem. So eventually I got:
file: angular.element(document.getElementById('ng-wrapper')).scope().model.my_video.video_url,
and then problem solved, for now. (But still ugly, not intuitive, in my opinion.)
================================ SEPARATOR ===================
PART 2: My real question
Coming from the world of traditional template engines, one might tend to use {{...}} wherever he wants. But in AngularJS, situation is different.
Besides the above example, this is another example bit me before:
<img title="{{my_title}}" src='logo.png'> <!-- This works -->
<img src="{{my_image}}"> <!-- This doesn't. Use ng-src instead. -->
So in general, when and when not to use {{...}} inside the AngularJS view file?
Only for Part 1: If you're working with jwplayer and Angular then I highly recommend calling jwplayer from Angular as opposed to the other way round (what you're doing).
e.g.
myModule.controller('MyController', function ($scope, stuffINeed) {
jwplayer.key = "myKey";
jwplayer("myElement").setup({
file: "MyFileName"
});
As long as jwplayer.js has been loaded (link in index.html or use something like require.js) you're good to go!
Wrap the Jw Player as a Directive. You can use something like this: https://github.com/ds62987/angular-jwplayer
Trying to give my own thoughts on this topic.
Rule #1: Never write {{...}} inside AngularJS's <script>...</script> tag. Simply because AngularJS's template system doesn't work in thay way. Instead, use this:
//This is the usage in the view
angular.element(document.getElementById('the_id')).scope().foo
Alternatively, you can define an extra helper in view file:
//This is another usage in the view
function bar(foo) {
//do something with foo
}
and then use your model in a "usual" way via controller file:
//This is inside controller file
function YourCtrl($scope) {
bar($scope.foo);
}
That is it.
Yet I am still not sure when and when not to use {{...}} inside the html part of view. Leave this part to be answered by someone else. (I am now just a new AngularJS learner in week 2.)
Edit : I added test plunker : http://plnkr.co/edit/BMGN4A
Can you provide a full example? Because I write as below but get message Cannot read property 'videoUrl' of undefined although I have $scope.videodata.videoUrl = "bla bla"; in my controller.
<script type="text/javascript">
jwplayer("myElement").setup({
file: angular.element(document.getElementById('myElement')).scope().videodata.videoUrl,
image : "http://i3.ytimg.com/vi/2hLo6umnjcQ/mqdefault.jpg",
autostart : "false",
id : 'playerID',
width: '700px',
height: '400px',
primary : "flash",
stretching : "uniform",
modes : [{
type : 'html5'
}, {
type : 'download'
}, {
type : 'flash',
src : 'player.swf'
}]
});
</script>