How to toggle between responsive and non-responsive design - responsive-design

Ok, so with the help of a couple sites, I was able to put this code together to inactivate the responsive coding for a website and activate the non-responsive coding. However, when the link is clicked again, it doesn't perform this function in reverse.
I tried using ".toggle", but that doesn't work. Which event should I be using to get this effect? Any help would be great!
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script>
$(document).ready(function () {
$("#togglerwd").click(function() {
$('meta[name="viewport"]').prop('content', 'width=1440');
});
});
</script>
Toggle Responsive Layout

Isn't there an event that will allow the code to be active and inactive when the hyperlink is clicked?
The click itself is the event that is happening – but that event does not know anything about what “state” your page is currently in.
A “flag” is a common programming basic, and not specific to jQuery or JavaScript. Basically it is just a variable with a value that alternates between true and false, and based on which you decide what to do.
It would look something like this:
$(document).ready(function (e) {
// set the initial flag value, we assume your page “starts” in responsive mode
var isResponsive = true;
$("#togglerwd").click(function() {
// check flag, to see what state the page is in
if(isResponsive) {
// set viewport meta to “non-responsive”
$('meta[name="viewport"]').prop('content', 'width=1440');
// remember current state in flag for check on next click
isResponsive = false;
}
else {
// set viewport meta to “responsive”
$('meta[name="viewport"]').prop('content', 'width=device-width');
// remember current state in flag for check on next click
isResponsive = true;
}
});
});

Thank you so much for your help CBroe, but I ended up creating the exact solution I wanted. Here is the code:
<script>
$(document).ready(function () {
$("#togglerwd").click(function() {
$('meta[name="viewport"]').prop('content', 'width=1440');
});
$("#togglerrl").click(function() {
$('meta[name="viewport"]').prop('content', 'width=device-width');
});
});
</script>
Full Site |
Responsive Layout

Related

How to change title using ng-idle title directive

I'm trying to change the page title using ng-idle:
My title:
<title>MySite Local</title>
The code that doesn't seem to be working:
app.run(function (Title) {
Title.idleMessage('You are idle');
});
Taken from https://github.com/HackedByChinese/ng-idle/issues/128
Am I missing anything here? The title doesn't change without the above code either.
I've also got TitleProvider.enabled(true); just in case.
I'm not familiar with that directive, but if all you're trying to do is set the title, a plain old controller will work.
titleController.js
(() => {
"use strict"
angular.module('myApp').controller('titleController', titleController)
function titleController($scope) {
$scope.appTitle = "Hi Dad, I'm in jail!"
}
})()
index.html
{{appTitle}}
Of course, you'd have to add your own logic to detect an idle user.

How to add a custom error page in Cordova InAppBrowser or hide the error url?

pleas check this attached image I'm building an Ionic Android app with the InAppBrowser plugin. When the internet connection is not available, the plugin shows web page not available and requesting url.
Please help me customise the InAppBrowser error page (404 page). Or help me hide the requesting url.
Thank you.
I think I misunderstood your problem, first time, sorry about that. I'm reading again your problem and I'm figuring out what's happening. You need to add a custom configuration at config.xml to redirect to an error page when Cordova detect it. I hope this solve your problem.
<preference name="ErrorUrl" value="myErrorPage.html"/>
The original response works when you want to open a link through Cordova inAppBrowser plugin. If this doesn't sort out your problem, please reformulate your question.
Original response
You could be listening inAppBrowser events to figure what's happening.
Here, you can see how listen browser events, such as loaderror and manage the 404 error as you want. You must save a reference to inAppBrowser when open method is called, and then you could listen for error event.
function loadErrorCallBack(params) {
// Do stuff
}
inAppBrowserRef = cordova.InAppBrowser.open(url, target, options);
inAppBrowserRef.addEventListener('loaderror', loadErrorCallBack);
I am using Ionic 4 and I couldn’t manage to make the solution based on config.xml editing to work :
preference name="ErrorUrl" value="myErrorPage.html"/
Placing an addEventListener on loaderror didn’t work neither. It looks like it is not triggered by http errors and the plugin need a fix.
But we found a hack that is much simpler.
On loadstop we wait 500 milliseconds and then we get the loaded url by triggering executeScript with and window.location.href
If the loaded url is of the custom error page, in Cordova (not in IAB) we display a custom message with a back button.
It's a hack but that cover the requirement for now
I just came across the same problem and here's what I did. The code is for Android and works on IOS as well. But you would want to remove navigator.app.exitApp(); for IOS as Apple does not allow apps to take exit without pressing the home button.
Let me know if this works for you. It will hide default error page and open your custom error page. Write your own error code in myerrorpage.html
document.getElementById("openBrowser").addEventListener("click", openBrowser);
document.addEventListener("offline", onOffline, false);
function onOffline(e) {
e.preventDefault();
var src = 'myErrorPage.html';
var target = '_blank';
var option = "loaction=no, toolbar=no, zoom=no, hidden=yes, hardwareback=no";
var ref = cordova.InAppBrowser.open(src, target, option);
alert('Your device is Offline. Please check your connection and try again.');
navigator.app.exitApp();
}
function openBrowser() {
var url = 'https://www.yourlink.com';
var target = '_self';
var options = "location=no,toolbar=no,zoom=no, hardwareback=no, hidden=yes" ;
var ref = cordova.InAppBrowser.open(url, target, options);
}
When the components do not work, I perform the following procedure
ionic state reset
ionic platform remove android
ionic platform remove ios
ionic platform add android
ionic platform add ios
and try with ionicPlatform ready
<button class="button button-balanced" ng-click="OpenBrowser()">Test</button>
In controller
$scope.OpenBrowser = undefined;
$ionicPlatform.ready(function () {
$scope.OpenBrowser = function () {
$cordovaInAppBrowser.open('http://ngcordova.com', '_blank', options)
.then(function (event) {
})
.catch(function (event) {
$scope.Error = event;
});
};
});
I couldn't manage solution with setting ErrorUrl in Ionic 4 on Android to work.
Finally I came up with another solution - hide default error page and redirect user to any page (I use last page from event.url).
constructor(private iab: InAppBrowser) {
}
private openUrl(url: string)
{
this.platform.ready().then(() => {
if (this.platform.is('cordova')) {
this.openBrowser(url);
}
});
}
private openBrowser(url: string): InAppBrowserObject
{
const options: InAppBrowserOptions = {
location: 'no',
zoom: 'no',
hidden: 'no'
};
const browser = this.iab.create(url, '_blank', options);
browser.on('loaderror').subscribe(
event => this.onLoadError(event, browser)
);
return browser;
}
private onLoadError(event: InAppBrowserEvent, browser: InAppBrowserObject): void
{
browser.executeScript({
code: `
window.addEventListener('DOMContentLoaded', function () {
document.querySelector('body').style.background = 'black';
document.querySelector('body').innerHTML = '';
}, true);
window.addEventListener('load', function () {
window.location.replace('${event.url}');
}, true);
`,
}
).then();
}
Changing background and redirecting is tricky - from my experiments using injectCss won't work, because body is generated in the meantime. Using DOMContentLoader makes it black and clears text on screen.
But redirecting won't work in DOMContentLoader (don't ask me why), so you need to use load event.
It works great when user is using hardware back and returns to POST request - this way he will be redirected to GET of the same url (but you can use any url you want).

View changing on fullcalendar doesn't work

I'm facing this nightmare since many days and I still cannot figure what I'm missing to make the changeView event work.
What am I doing? I'm programmatically trying to make the calendar's view changed. How? Searching for fullcalendar by his id within the controller and setting the new view.
Lots of guides/threads tell many ways but the more comprehensible I got was the following:
That's my HTML code (it's the whole HTML page):
<div class="container">
<div id="eventsCalendar" ui-calendar="main.uiConfig.calendar" class="span8 calendar" ng-model="main.eventSources">
</div>
</div>
This's how to get the calendar, setting the new view within the controller:
angular.element('#eventsCalendar').fullCalendar('changeView', 'agendaView');
It looks fine, no errors and angular got the calendar (yay!!!). Amazing! No "calendar-related-dependencies" injected, a very simple and short way... That's awesome! Set a function with that line of code but nothing happened and the calendar still be in the month view (holy damn... back to the drawing board...)
Some threads for the ui-calendar (maybe something similar to fullcalendar?) tells to inject uiCalendarConfig as controller's dependency, declaring the calendar="myCalendar" attribute in HTML declaration and calling uiCalendarConfig.calendars.myCalendar... the result was: uiCalendarConfig is empty... I'm confused.
Does anyone ever get the changeView work properly? How could I do that? I'm sure I'm missing something stupid... I can feel it!
Any help will be appreciated.
<div calendar="eventsCalendar" ui-calendar="main.uiConfig.calendar" class="span8 calendar" ng-model="main.eventSources">
To change the calendar view, use this function
$scope.changeView = function(view) {
uiCalendarConfig.calendars["eventsCalendar"].fullCalendar('changeView',view);
};
call the function as below
$scope.changeView('month'); //or
$scope.changeView('agendaDay'); //or
$scope.changeView('agendaWeek'); //or
Unfortunately, there does not seem to be an onload callback. However, this is what I came up with for my app
// watcher for on load
var calendarOnLoad = null;
var calendarOnLoadCallbacks = [];
$scope.changeView = function(view) {
if(uiCalendarConfig.calendars.eventsCalendar) {
// already initiated or beat the race condition, great!
uiCalendarConfig.calendars.eventsCalendar.fullCalendar('changeView',view);
}
else {
// calendar is undefined. watch for onload
if(!calendarOnLoad) {
calendarOnLoad = $scope.$watch(function () {
// prevent type error which breaks the app
try {
return uiCalendarConfig.calendars.eventsCalendar;
} catch (err) {
return null;
}
}, function (calendar) {
// uiCalendarConfig.calendars.eventsCalendar is now initiated
if(calendar) {
calendarOnLoad(); // clear watcher since calendar exists
// call all the callbacks queued
calendarOnLoadCallbacks.forEach(function (fn) {
fn(calendar);
});
}
});
}
// run this calendarOnLoadCallbacks queue once calendar is initiated
calendarOnLoadCallbacks.push(function(calendar) {
calendar.fullCalendar('changeView',view);
});
}
}
$scope.changeView('agendaWeek');
$scope.changeView('month');
$scope.changeView('agendaDay');
I hope this helps.

If user 'touches' form inputs on profile & forgets to save: show `POP UP` when they click SideMenu icon

I've tried to come up with some sort of "error checker/validation" for my users IF they forget to Save the edits they made on their profiles.
The user enters the Profile.html state. They start to update some of their info (i.e name, phone number, etc.). INSTEAD of pressing the SAVE CHANGES button they navigate away from the Profile state by clicking the SideMenu icon at the top left of their mobile screen.
Since the form is technically now consider to be "$dirty". I've tried to use this angular property at first but I couldn't really get the results I wanted so I tried my luck with $watch..
ProfileController.js
$rootScope.isFormDirty = false;//global variable 'isFormDirty'->inject in controller.js (toggleLeftSideMenu())
$scope.$watch('updateDriverProfileInfo', function(newValue, oldValue) {//new & oldValue = ng-model when form is 1st 'viewed' is dirty
//http://tutorials.jenkov.com/angularjs/watch-digest-apply.html
if (newValue !== oldValue) {
// console.log("updatingg")
$rootScope.isFormDirty = true;
}
}, true);
Angular docs on $watch
Maybe I should of made a factory or Service for this now that I think about it but at the time I used $rootScope so that I can set a global variable isFormDirty on this controller and use it on the General Controller that holds the Side Menu's logic in this Ionic app.
controller.js (this is where the Controller for the SideMenu is)
$scope.sidemenuIsOpen = false;
$scope.toggleLeftSideMenu = function() {//ng-click from menu.html
$scope.sidemenuIsOpen = !$scope.sidemenuIsOpen;
if ($scope.sidemenuIsOpen && $rootScope.isFormDirty) {
var confirmPopup = $ionicPopup.confirm({
title: 'Changes were not saved',
template: 'Do you want to save your changes?',
});
confirmPopup.then(function(res) {
if (res) {
console.log('Run updateDriverProfile()');
} else {
console.log('Allow user to continue w/o changes');
}
});
}
};
That's basically the gist of my code. It actually "works" but I have identified a pattern and this is where I need your assistance to either suggest a whole different method to accomplish this or perhaps some refactoring tips for this current code.
The Pop up does show when the user clicks on the Side Menu button BUT I don't think it really matters if the form is $dirty or not..
The bigger issue is that the Pop up starts showing regardless if you are trying to leave the profile.html view or any other view for that matter.
When I wrote this code I was under the impression that the Pop up and toggleLeftSideMenu functions would ONLY work on the Profile view since I am "watching" the updateDriverProfileInfo object and I also created that global variable to use between the Menu Controller and Profile Controller.
you need to have a good understanding on ionic Lifecycle, try with any of the below events
$scope.$on('$ionicView.leave', function(){
// Anything you can think of
});
$scope.$on('$ionicView.beforeLeave', function(){
// Anything you can think of
});
$scope.$on('$ionicView.unloaded', function(){
// Anything you can think of
});
find more information here http://www.gajotres.net/understanding-ionic-view-lifecycle/

Backbonejs - Back button doesn't work if page transition on same page

Short description of my program and finally the problem:
I have got two pages. The first page list products in rows with a short description. If you click on one you will land on a detail page.
The detail page lists the product details and underneath a couple of related products. If you click on one of the releated products the same page is rendered again with the new information fetched from a REST interface.
If I want to use the browser-back-button or the own back-button to get to the previous product-detail-page a blank page appears. This only happens on my iPad. Using Chrome on a desktop browser works fine. I debugged the application and I figured out, that the backbonejs route is never called. I have no idea why.
Here is my code of the details page:
define([
"jquery",
"lib/backbone",
"lib/text!/de/productDetails.html"
],
function(
$,
Backbone,
ContentTemplate
){
var PageView = Backbone.View.extend({
// product details template
template: _.template(ContentTemplate),
// back-button clicked
events:{
'click a#ac-back-button':'backInHistory',
},
// init
initialize: function(options){
this.options=options;
// bind functions
_.bindAll(this,
'render',
'renderRelatedSeriePlainproduct',
'backInHistory'
);
// listen for collection
this.listenTo(this.options.relatedCollectionPlainproduct, 'reset',this.renderRelatedSeriePlainproduct);
},
// back button
backInHistory: function(e){
e.preventDefault();
window.history.back();
},
// render template
render: function(){
// render template
this.$el.html(this.template(this.model.models[0].attributes));
return this;
},
// render related products
renderRelatedSeriePlainproduct: function (){
var models = this.options.relatedCollectionPlainproduct.models;
if(models.length==0){
$('.ac-plainproduct').hide();
} else{
var elem = $('#ac-related-listing-plainproduct');
var ct="";
ct+='<ul id="ac-list-related-plainproduct">';
$.each(models, function(key, value){
ct+='<li>';
ct+='<a href="index.html?article_id='+value.get('article_id')+'&type='+value.get('type')+'&serie='+value.get('series')+'#product-detail">Link';
ct+='</a>';
ct+='</li>';
});
ct+='</ul>';
elem.append(ct);
}
}
});
// Returns the View class
return PageView;
});
I follow one of the links from renderRelatedSeriePlainproduct.If I click on the back button on the new page the backInHistory function is called, but the window.history.back(); does not call the backbone router.
Maybe the problem is the #hash in the URL, that is not changed during page transition. But this would not explain, why it works perfectly with my Chrome on my desktop machine. For me it seemed to be a problem of asynchronous calls but even there I could not find a problem.
Maybe it helps to list my router code as well. First of all I was thinking it is an zombie issue in backbone, but I remove all events and views while making the transition.
// function called by the route
// details page
productdetail: function() {
$.mobile.loading("show");
_self = this;
// lazy loading
require([
'collection/ProductDetailCollection',
'collection/RelatedCollection',
'view/ProductDetailView'
],
function(ProductDetailCollection, RelatedCollection, ProductDetailView){
// get URL parameters
var articleID = _self.URLParameter('article_id');
var type = _self.URLParameter('type');
var serie = _self.URLParameter('serie');
// product - details
var productDetail = new ProductDetailCollection.ProductDetail({id: articleID});
// related products
_self.relatedCollectionPlainproduct = new RelatedCollection({serie:serie, type:"Electronics", article_id:articleID});
// assign binded context
productDetail.fetch({
// data fetched
success: function (data) {
// page transition
_self.changePage(new ProductDetailView({
model:data,
relatedCollectionPlainproduct:_self.relatedCollectionPlainproduct
}));
// fetch data
_self.relatedCollectionPlainproduct.fetch({reset:true});
}
});
});
},
// page transition
changePage:function (page) {
// remove previous page from DOM
this.page && this.page.remove() && this.page.unbind();
// assign
this.page = page;
// assign page tag to DOM
$(page.el).attr('data-role', 'page');
// render template
page.render();
// append template to dom
$('body').append($(page.el));
// set transition
var transition = "fade";
// we want to slide the first page different
if (this.firstPage) {
transition = "fade";
this.firstPage = false;
}
// make transition by jquery mobile
$.mobile.changePage($(page.el), {changeHash:true, transition: transition});
// page was rendered - trigger event
page.trigger('render');
$.mobile.loading("hide");
},
I tried to use allowSamePageTransition but with no success. Maybe someone could give me a hint. Thanks!
Looks like jQuery Mobile and Backbone's routers are conflicting. Take a look here:
http://coenraets.org/blog/2012/03/using-backbone-js-with-jquery-mobile/
Thats not the reason. I disabled the routing of jquery mobile.
// Prevents all anchor click handling
$.mobile.linkBindingEnabled = false;
// Disabling this will prevent jQuery Mobile from handling hash changes
$.mobile.hashListeningEnabled = false;

Resources