In backbone what's the best way to swap out click events for touch events.
I went down the route of using MBP.fastbutton which worked well for iOS however I am trying to move my code over to Android and need to use iScroll which doesn't seem to play nice with MBP.fastbutton.
initialize: function () {
addFastButtons(this);
},
events: {
'fastclick': 'showDetails'
},
showDetails: function (e) {
// Do stuff
}
I have tried swapping out click with touchend i.e.
events: {
'touchend': 'showDetails'
}
But this causes issues when scrolling as the app responds when the user lifts there finger, so they can jump to other pages accidentally
You should checkout the Junior code, they do this for you in their framework but you could steal the snippet to do something similar. https://github.com/justspamjustin/junior/blob/master/src/javascripts/junior.js#L3
Related
I'm trying to run some code to resize a div after my header is done rendering. I have looked at answers here and the Backbone documentation. this is what I wrote:
Backbone.View.extend({
template: header_tpl,
render: function() {
this.$el.html(this.template({});
setTimeout(function() {
$(window).on("resize",function(){
$(".somediv").height($(".someotherdiv").height())
})
.resize()
}, 0);
return this;
},
childViews: {
// Some childViews in here
}
});
This works, but the childViews in this view won't render. I think it has to do with the empty object being passed on the this.template(). The backbone docs say to pass on this.model.attributes, but this view doesn't have a model. Its a simple header with no data being passed on to it.
As pointed out by #CoryDanielson 's comment, Backbone has no default handling of "childViews". If your job is to make a Backbone View render it's child Views, there are lots of reasonably simple ways to do that.
But I think what you are really trying to do is to keep some sort of pre-built render functionality that is built into Backbone.View somewhere else in your codebase. Since the only extension you seem to need is attaching a resize event to window, maybe the best option is to not do this in the render method, then you can continue to use whatever is pre-built elsewhere in your codebase.
Backbone.View.extend({
template: header_tpl,
// no override of render
initialize: function() {
setTimeout(function() {
$(window).on("resize",function(){
$(".somediv").height($(".someotherdiv").height())
})
.resize()
}, 0);
},
childViews: {
// Some childViews in here
}
});
This code should attach the event when the view is instanced, not at each render.
Of course, if your Codebase may also be altering the default initialize method, we really can't know. In that case, there might be some options to override the default methods (initialize, render, ...) just by extending, but still calling the old methods under the hood.
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).
I'm using the angular leaflet directive. Everything is working properly on my laptop. But on iPad, the double click is working but the click event is not working at all. I have one event handler for click but it doesn't get triggered.
$scope.events = {
map: {
enable: ['mousedown', 'dblclick', 'click'],
logic: 'broadcast'
}
};
$scope.$on('leafletDirectiveMap.mousedown', function(event) {
alert('click');
});
$scope.$on('leafletDirectiveMap.click', function(event) {
alert('click');
});
$scope.$on('leafletDirectiveMap.dblclick', function(event) {
alert('dbclick');
});
Double click event gets triggered but the other ones not. Anything I can try to debug this?
checkout this https://github.com/angular/material/issues/1300.
Having this below code fixed that issue for us,
$mdGestureProvider.skipClickHijack();
I am creating a single page app with a lot of tooltips and pop ups on different areas. I am closing those elements by checking where the click is happening. for exmaple something like:
$scope.popup1 = {
open: function(){
$scope.popup1Open = true;
$timeout(function(){
$document.bind('click',function(e){
if(!angular.element('#popup1-container').find(e.target).length) {
// if in directive, ill use: $elem.find(e.target).length
$timeout(function(){
$scope.popup1.close();
$scope.$apply();
});
}
});
});
},
close: function () {
$scope.popup1Open = false;
}
}
Now like I said I have multiple popups happening, which can be opened at different areas of the page. They all have their own ids and some in their own directives. So I'm creating $document.bind('click') each time when a popup opens, and I'm not going to bother unbinding it because it will a) affect the other popups and also the popups are accessed so many times for very key areas.
So my question is, are there any performance issue that might come up with what I'm doing?
I'm working on a component stub where I have a grid of tiles, each that require a click handler, and also a specific "new" tile that has a different click handler. I'm trying to get the click handlers working correctly, but the event never seems to fire.
Any ideas?
var grid = React.createClass({
onCreateNew: function () {
console.log("onCreateNew");
},
render: function () {
var tiles = [];
if (this.props.items) {
tiles = this.props.items.map(function (item, index) {
//create a tile for each item
});
}
//always append "new" tile for the last one
tiles.push(React.DOM.div({
onClick: this.onCreateNew, className: "tile new_tile"
},
React.DOM.div({ className: "plus", onClick: this.onCreateNew }, "+")
));
return React.DOM.div({ id: "flowsheetPane" }, tiles);
}
});
As commenters have mentioned, your code appears to work as expected in isolation.
React delegates to event handlers with a single event listener at the root of the DOM, so events need to propagate all the way to the top in order for React to call your function.
Could you have added some event listeners somewhere in the component hierarchy that are calling event.stopPropagation()? If you did this outside of React (e.g. natively or with jquery), it would cause the events to never reach the top of the DOM, and React would never have a chance to delegate out to your methods.