I am using iscroll4 in my application. I am facing problem with iScroll that made drop down lists(combo box) unusable when used at the same time.
I tried how they mentioned here
( http://groups.google.com/group/iscroll/browse_thread/thread/5b2fbad6aa667907# )
$(document).ready(function() {
var destinations_scroll, accounts_scroll;
function loadingIscroll() {
accounts_scroll = new iScroll('accounts_container');
destinations_scroll = new iScroll('destinations_container', {
checkDOMChanges: true
});
setTimeout(function() {
destinations_scroll.refresh();
}, 0);
}
document.addEventListener('touchmove', function(e) {
if (e.target.tagName != "SELECT") {
e.preventDefault();
e.stopPropagation();
}
}, false);
addEventListener('DOMContentLoaded', loadingIscroll, false);
});
But still select box (combo box/drop down) not working. Any suggestions?
Hi I got an answer from iScroll 4 not working with form <select> element iPhone Safari and Android browser. Thanks to #comonitos. I used his solution.
Related
I am working with standalone (not mobile) and I think it is _getScroll method for reaching it.
how to implement it here qooxdoo selectbox example
I found similar for mobile implementing virtual scrolling list console.log says container._getScroll is not a function.
The idea is to get scrollbar from a widget, the scrollbar you are needed is NativeScrollbar of the widget qx.ui.list.List. Then add event handler for a "scroll" event. In handler u have to compare current position of scroll and maximum.
Try the code below (eg copy and paste into the Qooxdoo playground).
qx.Class.define("SelectBoxWithScrollEndEvent", {
extend: qx.ui.form.SelectBox,
construct: function(){
this.base(arguments);
this.__setupScroll();
},
events: {
"scrollEndHappened": "qx.event.type.Event"
},
members: {
__setupScroll: function(){
const list = this.getChildControl("list");
const scrollbar = list.getChildControl("scrollbar-y");
scrollbar.addListener("scroll", function(e){
if (scrollbar.getMaximum() === scrollbar.getPosition()){
this.fireEvent("scrollEndHappened");
}}, this);
}
}
});
const box = new SelectBoxWithScrollEndEvent();
const data = new qx.data.Array([1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5]);
const controller = new qx.data.controller.List(data, box);
box.addListener("scrollEndHappened", function(){
alert("SCROLL HAPPENED ALERT");
}, this);
this.getRoot().add(box);
I am planning to trigger a click event programatically when user presses a spacebar key. I have been used fireEvent('click') it is working for chrome, but It is not working for IE-11. I also tried, dispatchEvent for IE but it is throwing an error: "element does not support method or property dispatchEvent". Please follow below code.
onCustomRender: function(thisEl, args){
var fetchTrigger = thisEl.getTrigger('fetchID
fetchTrigger.el.on('keydown',function(e,thisEl){
if (e.keyCode === 32) {
//fetchTrigger.el.fireEvent('click'); //this is working in chrome //not working in IE and did not throwing error.
var evObj = document.createEvent('MouseEvents');
evObj.initEvent('click', true, false);
fetchTrigger.el.dispatchEvent(evObj);
}
});
}
Please Help
Thanks in Advance
First of all you have syntax error in the code you provided...
Calling the function directly is easiest (as Evan said) but if you want to keep the logic in the controller you can fire events. Else you need some ugly code to get the controller first, then call the method...
I don't like fireing events and attaching listeners on the 'Ext.dom.Element' if you don't have to. Just use your ext elements..
Here is what I would do:
onCustomRender: function(thisEl, args){
var fetchTrigger = thisEl.getTrigger('fetchID');
fetchTrigger.on('keydown',function(trigger, e){
if (e.keyCode === 32) {
trigger.fireEvent('click', trigger);
}
});
}
Or even better, use the controller:
implement listeners
init: function () {
this.control({
'#fetchID': { //you can optimize the componentQuery
keydown: this.onTriggerKeyDown,
click: this.onTriggerClick
}
});
},
and methods like this:
onTriggerKeyDown: function(trigger, e){
if (e.keyCode === 32) {
this.onTriggerClick(trigger);
}
},
onTriggerClick: function(trigger) {
//do you thing!
}
In my mobile safari project, i need to create a message posting feature. it is requires scrolling inside a textarea when lines of texts exceed the max rows of the text area. i couldn't find 'scrollable' property in Ext.field.textarea, any idea how?
Cheers!
There is a bug in touch 2.0.x such that the framework explicitly prevents the scroll action. Supposedly a fix will be in 2.1, though I didn't see that officially, just from a guy on a forum.
Until then, there is kind of a solution for touch1 here http://www.sencha.com/forum/showthread.php?180207-TextArea-scroll-on-iOS-not-working that you can port to V2. It basically involves adding an eventlistener to the actual textarea field (not the sencha object) and then calling preventdefault if it's a valid scrollevent.
The full code is at that link, but the salient bits are here.
Grab the <textarea> field (not the Sencha Touch object) directly and use addListener to apply
'handleTouch' on touchstart and 'handleMove' on touchmove
handleTouch: function(e) {
this.lastY = e.pageY;
},
handleMove: function(e) {
var textArea = e.target;
var top = textArea.scrollTop <= 0;
var bottom = textArea.scrollTop + textArea.clientHeight >= textArea.scrollHeight;
var up = e.pageY > this.lastY;
var down = e.pageY < this.lastY;
this.lastY = e.pageY;
// default (mobile safari) action when dragging past the top or bottom of a scrollable
// textarea is to scroll the containing div, so prevent that.
if((top && up) || (bottom && down)) {
e.preventDefault();
e.stopPropagation(); // this tops scroll going to parent
}
// Sencha disables textarea scrolling on iOS by default,
// so stop propagating the event to delegate to iOS.
if(!(top && bottom)) {
e.stopPropagation(); // this tops scroll going to parent
}
}
Ext.define('Aspen.util.TextArea', {
override: 'Ext.form.TextArea',
adjustHeight: Ext.Function.createBuffered(function (textarea) {
var textAreaEl = textarea.getComponent().input;
if (textAreaEl) {
textAreaEl.dom.style.height = 'auto';
textAreaEl.dom.style.height = textAreaEl.dom.scrollHeight + "px";
}
}, 200, this),
constructor: function () {
this.callParent(arguments);
this.on({
scope: this,
keyup: function (textarea) {
textarea.adjustHeight(textarea);
},
change: function (textarea, newValue) {
textarea.adjustHeight(textarea);
}
});
}
});
I am working with Twitter Bootstrap and ran into something I could not fix when testing on iPad and iPhone. On mobile (at least those devices) you need to click to engage the tip or popover (as expected). The issue is that you can never close it once you do. I added a listener to close it if you click it again, but I find it hard to believe that the default behavior would not be to click to remove it. Is this a bug in Bootstrap popover and tooltip?? My code is below - it seems to work, but ONLY if you click the same item that created the tip or popover - not anywhere on the page (could not get that to work).
Code to fire:
$(function () {
//Remove the title bar (adjust the template)
$(".Example").popover({
offset: 10,
animate: false,
html: true,
placement: 'top',
template: '<div class="popover"><div class="arrow"></div><div class="popover-inner"><div class="popover-content"><p></p></div></div></div>'
//<h3 class="popover-title"></h3>
//Need to have this click check since the tooltip will not close on mobile
}).click(function(e) {
jQuery(document).one("click", function() {
$('.Example').popover('hide')
});
});
});
HTML:
<a href="javascript:void(0);" class="Example" rel="popover" data-content="This is the Data Content" data-original-title="This is the title (hidden in this example)">
Thanks in advance!
Dennis
I tried dozens of solutions posted to stackoverflow and other various corners of the web, and the following is the only one that worked for me!
Explanation
As noted here, you can a CSS-directive the element in order to make it touch-device-clickable. I can't tell you why that works or what's going on there, but that seems to be the case. So, I want to make the entire document aka body clickable on mobile devices, which will allow me to touch anywhere to dismiss the popover.
Popover JS
$(function () {
$('[data-toggle="popover"]').popover({ trigger: "hover"}})
});
Directions
1. Install Modernizr
I'm using rails, so I used the gem.
gem 'modernizr-rails'
2. Create a touch class with a css-directive
Add the following to your CSS:
.touch {
cursor: pointer
}
3. On touch devices only, add the touch class to the body
If you want other elements to be clickable, instead of the entire body, add the touch class to them.
if (Modernizr.touch) {
$( "body" ).addClass( "touch" );
}
That's it! Now, you can use your popover normally on desktop (even with hover-trigger) and it will be touch-dismissible on mobile.
I had the same problem with my IPad. But in browser it works fine. Solution for me was adding listeners for all possible element that i can hide tooltip:
$('*').bind('touchend', function(e){
if ($(e.target).attr('rel') !== 'tooltip' && ($('div.tooltip.in').length > 0)){
$('[rel=tooltip]').mouseleave();
e.stopPropagation();
} else {
$(e.target).mouseenter();
}
});
Yes, it's small overhead to send event for all tooltips, but you can't define which element tooltip is showing.
Main concept is that make popover manually on mobile device
$(document).ready(function() {
if ('ontouchstart' in window) {
$('[data-toggle="popover"]').popover({
'trigger': 'manual'
});
}
});
Refer following code snippet to get it works:
$('[data-toggle="popover"]').popover();
$('body').on('click', function (e) {
$('[data-toggle="popover"]').each(function () {
//the 'is' for buttons that trigger popups
//the 'has' for icons within a button that triggers a popup
if (!$(this).is(e.target) && $(this).has(e.target).length === 0 && $('.popover').has(e.target).length === 0) {
$(this).popover('hide');
}
});
});
This is the easiest way of detecting clicks on the body and close all the tooltips on the page.
You can check the live example here
Solution on this jsfiddle,
test on iOS (iPad and iPhone), Android and Windows.
$(document).ready(function(){
var toolOptions;
var toolOptions2;
var isOS = /iPad|iPhone|iPod/.test(navigator.platform);
var isAndroid = /(android)/i.test(navigator.userAgent);
///////////////////////////////////////// if OS
if (isOS){
toolOptions = {
animation: false,
placement:"bottom",
container:"body"
};
$('.customtooltip').tooltip(toolOptions);
$('.customtooltip').css( 'cursor', 'pointer' );
$('body').on("touchstart", function(e){
$(".customtooltip").each(function () {
// hide any open tooltips when the anywhere else in the body is clicked
if (!$(this).is(e.target) && $(this).has(e.target).length === 0 && $('.tooltip').has(e.target).length === 0) {
$(this).tooltip('hide');
}////end if
});
});
///////////////////////////////////////// if Android
} else if(isAndroid){
toolOptions = {
animation: false,
placement:"bottom",
container:"body"
};
toolOptions2 = {
animation: false,
placement:"left",
container:"body"
};
$('.c_tool1').tooltip(toolOptions);
$('.c_tool2').tooltip(toolOptions);
$('.c_tool3').tooltip(toolOptions2);
///////////////////////////////////////// if another system
} else {
toolOptions = {
animation: true,
placement:"bottom",
container:"body"
};
$('.customtooltip').tooltip(toolOptions);
}//end if system
document.getElementById("demo").innerHTML = "Sys: "+navigator.platform+" - isOS: "+isOS+" - isAndroid: "+isAndroid;
});
<h6>
first tooltip
Second tooltip
third tooltip
</h6>
<p id="demo"></p>
Bootstap-tooltip v3.3.7
Actual: tooltip on hover doesn't work with touch devices in our project
Solution: Subscribe to tooltip's show event and call mouseenter
$body = $('body');
$body.tooltip({selector: '.js-tooltip'});
// fix for touch device.
if (Modernizr.touch) { // to detect you can use https://modernizr.com
var hideTooltip = function(e) {
tooltipClicked = !!$(e.target).closest('.tooltip').length;
if (tooltipClicked) { return; }
$('.js-tooltip').tooltip('hide');
}
var emulateClickOnTooltip = function(e) {
tooltipsVisible = !!$('.tooltip.in').length;
if (tooltipsVisible) { return; }
$(e.target).mouseenter();
}
var onTooltipShow = function(e) {
tooltipClicked = !!$(e.target).closest('.tooltip').length;
if (tooltipClicked) { return; }
$body.on('touchend', hideTooltip);
}
var onTooltipHide = function() {
$body.off('touchend', hideTooltip);
}
$body
.on('touchend', '.js-tooltip', emulateClickOnTooltip)
.on('show.bs.tooltip', onTooltipShow)
.on('hide.bs.tooltip', onTooltipHide);
}
I am a little desperate here. I have been reading everything I was able to find on Drupal.behaviours but obviously its still not enough. I try running a masonry grid with the infinitescroll plugin to attach the new images to the masonry. This works fine so far. The next thing I wanted to implement to my website is a hover effect (which shows information on the images) and later fancybox to show the images in a huger size.
(function ($) {
Drupal.behaviors.views_fluidgrid = {
attach: function (context) {
$('.views-fluidgrid-wrapper:not(.views-fluidgrid-processed)', context).addClass('views-fluidgrid-processed').each(function () {
// hide items while loading
var $this = $(this).css({opacity: 0}),
id = $(this).attr('id'),
settings = Drupal.settings.viewsFluidGrid[id];
$this.imagesLoaded(function() {
// show items after .imagesLoaded()
$this.animate({opacity: 1});
$this.masonry({
//the masonry settings
});
});
//implement the function of jquery.infinitescroll.min.js
$this.infinitescroll({
//the infinitescroll settings
},
//show new items and attach behaviours in callback
function(newElems) {
var newItems = $(newElems).css({opacity: 0});
$(newItems).imagesLoaded(function() {
$(newItems).animate({opacity: 1});
$this.masonry('appended', newItems);
Drupal.attachBehaviours(newItems);
});
});
});
}
};
})(jQuery);
Now I read that I need to Reattach the Drupal.behaviours if I want the hover event to also take place on the newly added content.
(function ($) {
Drupal.behaviors.imgOverlay = {
attach: function (context) {
var timeout;
$('.img_gallery').hover(function() {
$this = $(this);
timeout = setTimeout(change_opacity, 500);
}, reset_opacity);
function change_opacity() {
//set opacity to show the desired elements
}
function reset_opacity() {
clearTimeout(timeout);
//reset opacity to 0 on desired elements
}
}
};
})(jQuery)
Where do I now write the Drupal.attachBehaviours() to make it work actually? Or is there some other error I just dont see atm? I hope I wrote the question so that its understandable and maybe it also helps somebody else, since I experienced that there is no real "official" running Version of this combination in drupal 7.
Ok, the solution is actually pretty simple. When writing it correctly than it also runs. its of course not Drupal.attachBehaviours() but Drupal.attachBehaviors() . So this combination now works and I am finally relieved :).