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!
Related
I have previously created a web app, and now I would like to integrate it with OnsenUI to enable my app to be used on all mobile devices as well as the web.
I am using a splitter in a toolbar which will be the header of all pages, and it will redirect the user to other pages when they click an item in it. Clicking the home item successfully redirects to the home page (index, which is already loaded correctly). However, clicking any of the other items in the splitter redirects me to the requested page, but shows the content of the file in text format instead of actually rendering the page. It looks like the following, except it's all jumbled together with no spaces:
searchForTrainer.jade:
//-ons-template(id='searchForTrainer.jade')
ons-page(ng-controller='SearchController' ng-init='showme = false; getAllTrainers();')
ons-toolbar
.left
ons-toolbar-button(ng-click='mySplitter.left.open()')
ons-icon(icon='md-menu')
.center
| Search Trainer
// ***** I cut off the rest of the file for simplicity
// ***** I should still be able to see the toolbar if the page loads correctly
Here is the content of index.jade:
doctype html
html
head
link(rel='stylesheet' href='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css')
link(rel='stylesheet', href='/stylesheets/style.css')
link(rel='stylesheet' type='text/css' href='/stylesheets/jquery.datetimepicker.css')
link(rel='stylesheet' type='text/css' href='/stylesheets/ratings.css')
link(rel='stylesheet' type='text/css' href='/stylesheets/searchTrainerTab.css')
link(rel='stylesheet' type='text/css' href='/onsenui/css/onsenui.css')
link(rel='stylesheet' type='text/css' href='/onsenui/css/onsen-css-components.css')
block loadfirst
script(src='https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js')
script(src="https://code.jquery.com/jquery-1.12.3.min.js"
integrity="sha256-aaODHAgvwQW1bFOGXMeX+pC4PZIPsvn2h1sArYOhgXQ=" crossorigin="anonymous")
script(src='/onsenui/js/onsenui.js')
script(src='/onsenui/js/angular-onsenui.js')
script(src='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js')
script(src='/angular/fitnessapp.js')
script(data-require='angular-credit-cards#*', data-semver='3.0.1', src='https://rawgit.com/bendrucker/angular-credit-cards/v3.0.1/release/angular-credit-cards.js')
script(async='', defer='', src='https://maps.googleapis.com/maps/api/js?key=AIzaSyDcVf7YAPNwa8gUsMCOZNQZA31s5Ojf2n8&libraries=places')
body
ons-splitter(var='mySplitter', ng-controller='RootController as splitter')
ons-splitter-side(side='left', width='220px', collapse='', swipeable='')
ons-page
ons-list
ons-list-item(ng-click="splitter.load('index.jade')", tappable='')
| Home
ons-list-item(ng-click="splitter.load('searchForTrainer.jade')", tappable='')
| Search Trainer
ons-list-item(ng-click="splitter.load('searchForEvent.jade')", tappable='')
| Search Event
ons-list-item(ng-click="splitter.load('trainerAddEvent.jade')", tappable='')
| Create Event
ons-list-item(ng-click="splitter.load('userProfile.jade')", tappable='')
| Profile
ons-list-item(ng-click="splitter.load('addPayment.jade')", tappable='')
| Payment
ons-list-item(ng-click="splitter.load('userSettings.jade')", tappable='')
| Settings
ons-list-item(ng-click="splitter.load('trainerSignup.jade')", tappable='')
| Trainer Application
ons-list-item(ng-click="href='/logout'", tappable='')
| Logout
ons-splitter-content(page='index.jade')
ons-template(id='index.jade')
ons-page(ng-controller='MapController' ng-init='getEvents()')
ons-toolbar
.left
ons-toolbar-button(ng-click='mySplitter.left.open()')
ons-icon(icon='md-menu')
.center
| Fitness App
//-.right
a(href='https://www.paypal.com/webapps/mpp/paypal-popup', title='How PayPal Works', onclick="javascript:window.open('https://www.paypal.com/webapps/mpp/paypal-popup','WIPaypal','toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=yes, resizable=yes, width=1060, height=700'); return false;")
img(src='https://www.paypalobjects.com/webstatic/mktg/logo/bdg_now_accepting_pp_2line_w.png', border='0', alt='Now Accepting PayPal')
//- google maps stuff
ons-input#pac-input.controls(type='text', placeholder='Search Box')
div#map.col-md-12
ons-bottom-toolbar
.center
| Fitness App
block scripts
script.
// ***** I cut out javascript related to Google Maps for simplicity
here is the splitter load page function I am using in my angular file:
this.load = function(page) { console.log("The page is: " + page);
mySplitter.content.load(page)
.then(function() {
mySplitter.left.close();
});
};
Has anyone successfully built an Onsen app using Jade?
UPDATE
When I leave the code in html instead of jade, everything works correctly. When I convert it back to jade it shows up as text again.
UPDATE 2
Using Solution 1 from the selected answer, I realized and solved my problem with the guidance from the selected answer on my other post:
Answer
By the looks of it you seem to be using Jade on the server side.
To solve the problem I see a couple possible solutions.
Solution 1:
Make sure that whatever Onsen UI is receiving is pure HTML. You're free to use Jade, but as it stands Onsen does not have Jade bundled inside, so there is no way for it to support it out of the box. However as long as Onsen sees only html it should be fine.
The reason why the ons-template(id='index.jade') works initially is actually because when you serve the page you are actually serving actual html, so when onsen starts the contents of that template are actually pure html.
In searchForTrainer.jade it seems that you are giving it raw jade, which it does not know how to handle. You can handle this on the server side, making sure that the request for the searchForTrainer returns html. Returning jade.renderFile('searchForTrainer.jade') from the server instead of the jade file itself should solve the issue.
Solution 2:
As you noticed as long the contents are inside the initial page everything will be fine. So you could just put all your ons-templates inside the initial page.
If you want to retain your current file structure you can just do
include searchForTrainer.jade
while having an ons-template tag in the file itself. That way in the end the result will be a page with the template already converted into html.
Solution 3:
The final option is to give the raw jade files, but help Onsen understand Jade, so that it can use them properly. To do that you need to include jade.js and modify Onsen UI so that it uses it.
However since Onsen does not currently provide an official API for switching template engines whatever hack we use now might break in the future. It's possible that in the near future a feature like that may be implemented, but in order to do it now we need to wrap some of onsen's internal functions.
Here's a simple example to do it.
module.run(function($onsen) {
var old = $onsen.normalizePageHTML;
ons._internal.normalizePageHTML = $onsen.normalizePageHTML = function(html) {
return old(jade.render(html, {}));
};
});
And here's also a working Demo showing this solution in action.
Note: that demo actually checks for a comment // jade at the beginning just to be safe.
Which solution to choose?
Solution 1 - I think this makes most sense as it retains a clear separation of concerns. If you want to change the templating engine it should be handled only in one place. Onsen does not need to know what you're using on the server as long as it gets what it wants.
Solution 2 - Not the best way to solve the problem, but it may be the easiest to use if you just want things to work. One minus is that with it you would load all the templates at the beginning, which may not be very good.
Solution 3 - While this solution can work I would suggest avoiding it as handling jade on the frontend would result in poor performance. It's could be an option if you actually decide not to rely on the server.
I want to show PDFs in my angular application. It should be possible to show multiple pages at once and to search inside the PDF.
I tried angularjs-pdf to do so, but it lacks these features. Is there a angular wrapper for pdf.js that can do this? Or can somebody get me startet on how to implement pdf.js in my angular application without a wrapper?
Assuming this statement:
"I want to show PDFs in my angular application"
Anyone searching for this, could ought to check out ng2-pdf-viewer, for more information on this module, can check this out ng2-pdf-viewer PdfShowcase
Basically, this module could somewhat allow one to display more than one PDF in a single screen.
app.component.ts
// Declare the pdf as an empty array
pdfs = [];
// Assuming requesting PDFs from server through MVC style
getPdfs(){
this.getPdfService.getPdfs().subscribe(response => {
response.body.forEach((value, index) => {
this.pdfs.push({
id: index,
obj: window.URL.createObjectURL(value);
});
});
});
}
app.component.html
<div *ngFor="let pdf of pdfs, index as i;">
<div *ngIf="pdf[i]">
<pdf-viewer
[rotation]="0"
[original-size]="true"
[show-all]="true"
[fit-to-page]="true"
[zoom]="0"
[zoom-scale]="'page-width'"
[stick-to-page]="true"
[render-text]="false"
[external-link-target]="'blank'"
[autoresize]="true"
[show-borders]="true"
[src]="pdf.obj"
(after-load-complete)="onPdfComplete($event)"
(error)="onPdfError($event)"
style="width: 100%; height: 800px;">
</pdf-viewer>
</div>
</div>
If this library is not suitable for your use case, you may try with other libraries which uses iframe or similar strategy. Refer here is a useful source worth checking it out.
I know I'm a little bit late for this post but thought of posting here might help some folks who is looking for the same thing. Hope it helps.
From ng2-pdf viewer page, it recommends your desire "angular wrapper for pdf.js", There are a ton of built in functionality Mozilla's viewer supports; such as print, download, bookmark, fullscreen, open file, zoom, search,......
If you need to display multiple PDF files simultaneously and if you don't mind using iFrames, I recommend ng2-pdfjs-viewer. https://www.npmjs.com/package/ng2-pdfjs-viewer
The page loads without any of the images displaying on IE11 only, but refreshes them accordingly when we resize the browser intermittently (1/3 loads). We cannot replicate this with any of the other browsers. srcset works fine by itself with static content.
Here is a Plunker example of it not working in IE11.
Or quick and easy, the actual img html we're using:
<img data-ng-srcset="{{::image.url}}, {{::image.url2x}}" alt="{{::image.name}}"/>
The images or surrounding divs do not have any transitions, shadows or opacity applied.
The html renders fine with angular passing over and rewriting the srcset attribute correctly. The images just do not appear, only the alt tag. Wondering if this could be a call stack issue due to the intermittence of it, maybe a race condition with Picturefill loading before angular finishes a digest or something.
Cheers in advance!
A work around if you use PictureFill in a loop and in a specific case (not on all images of your application), is calling a function that launch PictureFill directly from HTML, after last item loaded (this is not the best practice but fix the IE11 problem) :
<picture><!-- Your image --></picture>
<span ng-if="$last">
{{ controllerAlias.launchPictureFill() }}
</span>
Came across this as a solution: http://tech.endeepak.com/blog/2014/05/03/waiting-for-angularjs-digest-cycle/
var waitForRenderAndDoSomething = function() {
if($http.pendingRequests.length > 0) {
$timeout(waitForRenderAndDoSomething); // Wait for all templates to be loaded
} else {
$window.picturefill();
}
}
$timeout(waitForRenderAndDoSomething);
The only issue that the blog post describes is here, so if anyone has anything better please let me know:
The $http.pendingRequests supposed to be used for debugging purpose only. If angular team decides to remove this, you can implement the same using http interceptors as suggested in this link.
I have a DNN skin that has some nice containers. I can drop an HTML module onto the page and apply the container to it. I can put a link in the content of the HTML Module, but what I would really like to do is make the whole container/module area a link to another page - in effect as if it were a great big button. How do I do this?
Of course as soon as I posted the question I found a way, but would still be interested to know if this is the "right" way or even a "good" way.
My solution was to take a copy of the container .ascx and add an "onlick" to the outer DIV, which in turn uses JQuery to locate the first tag and to navigate to the href.
<div class="Container-1 Container-1-color1"
onclick="window.location.href = $('a:first',this).attr('href')">
Note: Use window.location.href, not JQuery .click() or .trigger('click') as this creates an infinite loop.
I then added some CSS to show that an action was available when the mouse was over the container:
.Container-1:hover
{
opacity:0.8;
filter:alpha(opacity=80); /* For IE8 and earlier */
border:1px solid gray;
}
I'm developing a website for a business. It's not a web application by any stretch of the imagination but I would like it to look ok on mobile devices rather than simply scale the desktop version. After lots of research into media queries and responsive/adaptive design approaches my requirements are that the mobile layout only kicks in when the user really is on a small screen and not just resizing their desktop window, the solution is simple and can be accomplished with media queries and minimal javascript.
The approach I've come up with is something like this:
<script type="text/javascript">
var isRetina = window.devicePixelRatio > 1 ? true : false;
var isMobile = (screen.width < 768) ? true : false;
if (isMobile && isRetina) {
SHOW MOBILE LAYOUT AND HI-RES IMAGES
} else if (isMobile && !isRetina) {
SHOW MOBILE LAYOUT AND LO-RES IMAGES
} else if (!isMobile && isRetina) {
<<SHOW HI_RES IMAGES>>
} else if (!isMobile && !isRetina) {
SHOW DESKTOP LAYOUT AND LO-RES IMAGES
}
</script>
Before I commit to this approach I figured I'd check in and see if there is a problem or a terrible gotcha awaiting me. Or if there's an even simpler/better way to achieve this goal. I've searched a bunch on SO an haven't seen any mention of using this exact same solution.
The reason javascript is not a preferred method when loading CSS layouts is because javascript is usually the last thing loaded when the browser renders your page. This means that for a flash second you'll see your initial layout on the screen, before it loads the correct CSS. The simplest and most ideal approach is to make use of CSS3 Media Queries (something like this simple tutorial could go a long way: http://webdesignerwall.com/tutorials/responsive-design-in-3-steps).
The other option you have is to use Modernizr to load your stylesheets or other files that you may want to load based on viewport sizes. Look into the Modernizr Doc, you can basically "test" for the functionalities and features on the current browser that's being used to view your webpage - and load files accordingly. As a side note, Modernizr is a JS library so again use with caution when loading CSS files - it's known to load them without the splash screen of your initial layouts but I'd still say the best practices for loading layouts based on media queries is to use the CSS3 media queries themselves.
sorry to post to answer, couldn't add comment.
window.devicePixelRatio on firefox (and i believe Mac) will be bigger than 1 if you zoom in, which could result in a bug
navigator.userAgent.match(/iPhone/i)) || (navigator.userAgent.match(/iPod/i)) || (navigator.userAgent.match(/iPad/i)
this might help