How to restrict TAB navigation within the one window widget? - javascript

I have a Webix modal window with a form with several inputs:
var form = {
view:"form",
borderless:true,
elements: [
{ view:"text", label:'Login', name:"login" },
{ view:"text", label:'Email', name:"email" },
{
view:"button", value: "Submit", click:function(){
console.log(this.getParentView().getValues())
}}
]
};
The following sample there's a window that illustrates the current behavior:
http://webix.com/snippet/4bd116bb
If I use TAB navigation, focus goes out the window from the last in-window control. Is there a way to localize TAB navigation within the window once the focus gets in?

Code can catch onFocusChange event and move focus back if target is outsideo of the window.
webix.attachEvent("onFocusChange", function(target){
if (!target || target.getTopParentView() != $$("win"))
webix.delay(function(){
webix.UIManager.setFocus($$("win").getBody().elements.login);
});
});
http://webix.com/snippet/7db250dd

Related

Jquery tab. Check if any of them is open

I have some tabs. All are collapsed by default. If the user click on a button first tab opens. I figured out that part:
jQuery(document).ready(function() {
jQuery('#showFirstTab').on('click', function() {
var tabObj = jQuery('#podcast-tabs li:first a');
tabObj.tab('show');
var programId = tabObj.data('programid');
jQuery('#calendar-' + programId).fullCalendar('render');
});
});
Now I need to check if any tab is open, and click again on the same button, all tabs should collapse. I was thinking in use a variable to save the state, but not sure if library provides already a solution for this.
You can first check if any tab is open, by using the tabsactivate event:
var isActive = false;
$(".podcast-tabs").on("tabsactivate", function( event, ui ) {
isActive = true;
});
Now, inside your click code check for that variable and if true close all tabs using option like:
if (isActive)
$("#podcast-tabs").tabs("option", "active", false);

Close javascript popup by clicking anywhere

I am super novice and need a quick advice. I have installed a javascript based popup plugin on my wordpress site, witch opens automatically when somebody visits the site. To close the popup the user will have to click a cross X in the corner of the popup.
I need to edit the plugin so that the user can click ANYWHERE, and the plugin will close.
Here is the javascript code I found. any tips about this?
function open_lightbox(){
//var closebut = (typeof(ujiPopups) !== 'undefined' && ujiPopups != null && ujiPopups.showclose && ujiPopups.showclose == "true") ? true : false;
jQuery("#popup").modal({
onOpen: function (dialog) {
dialog.overlay.fadeIn('fast');
dialog.data.hide();
dialog.container.show('fast', function () {
dialog.data.fadeIn('slow');
});
},
autoResize: false,
autoPosition: true,
escClose: false,
zIndex: 999999,
overlayClose: false
});
}
function popups_close(){
jQuery.modal.close();
jQuery("#popup").remove();
}
Something like this should do it:
$(document).click(function() {
if($('#popup').is(':visible')) {
popups_close();
}
});
If you wish to keep the modal active on interaction with the popup itself:
$(document).click(function(e) {
if (!$(e.target).is("#popup")) {
if ($('#popup').is(':visible')) {
popups_close();
}
}
});
A simple example here: http://jsfiddle.net/wnT4G/
*Check comments for some elegant revisions by #ComFreek
I use a rather strange method, but it works:
$('.click-btn').click(function(){
$('.modal').show(); //show popup
})
$('body').click(function(){
$('.modal').hide(); //hide modal
})
$('.click-btn, .modal').click(function(e){
e.stopPropagation; // don't close modal by clicking inside modal and by clicking btn
})
user event
function addEvent(action) {
$("body").click(function() { action();});
}
function clearEvent() {
$("body").off('click');
}
You want to do this:
$(document).click(function()
{
popups_close();
})
$('Your selector of the popup').click(function(e)
{
e.stopPropagation();
})
.stopPropagation(); Will actually cancel the .click() function that was triggerd by clicking in the document.
So whenever you click anywere in the document the popup will close, except when clicked on the popup itself.
Hope this helped!
jsFiddle
I think you just want to set overlayClose and possibly escClose to true. Your plugin probably creates an overlay on the page so users can't click anywhere else so I'm guessing overlayClose: true will get the plugin to close the dialog when the overlay is clicked.
escClose: true,
overlayClose: true
I'm not sure what plugin you're using, but this one uses a clickClose property.

two onClick() events happening simultaneously?

What I am expecting from my code is this:
When clicking a button, a menu of options appears at the pointer position. Any following click, whether on a menu item or elsewhere in the browser, should close the menu. Clicking on a menu item closes the menu, but not clicking anywhere else. When I uncomment $(document.body).one('click', function() {menu.remove()} the menu never appears in the first place, and I suspect that I somehow have it arranged so that the click to bring up the menu actually closes the menu as well. Here is the code:
render : function() {
this.$el.html(this.template(this.model.toJSON()));
var that = this;
if (this.model.attributes.memberType != 'OWNER') {
this.$('.memberTypeSelector').button({
icons : {
secondary : "ui-icon-triangle-1-s"
}
}).click(function(event) {
that.showPermissions(that.model, event, that);
});
...
},
showPermissions : function(member, event, view) {
var levels = ['ADMIN', 'CONTRIBUTOR', 'VIEWER'];
var menu = $('<ul>');
$.each(levels, function() {
if(member.attributes.memberType !== this) {
var item = $('<li>').appendTo(menu);
$('<a>').attr('href', '#').text(this).appendTo(item).click(function() {
menu.remove();
view.changePermission(member, this.text, view);
});
}
});
menu.menu().css({
position : 'absolute',
left : event.clientX,
top : event.clientY
});
$(document.body).append(menu);
/*$(document.body).one('click', function() {
menu.remove();
});*/
}
Thanks in advance for your help.
If you delay binding to the document by 10ms, that should be enough time for the event to propagate to the body so that it doesn't immediately close the menu, then the next click on the menu will result in the body click handler triggering.
setTimeout(function(){
$(document.body).one('click', function() {menu.remove();});
},10)
you can't use stop propagation or anything similar because that would also stop the 2nd click on the menu.
While delaying the second event binding will probably work 99.999% of the time, I can't help but feel that nagging 'what if' for the one time that something lags and it doesn't work.
This question provides a more satisfactory (at least to me) solution

Extjs panel. Keyboard events

I have a panel which I am rendering using following code.
new Ext.Panel({
id: 'textPanel',
height: 1000,
width: 1200,
renderTo: Ext.getBody(),
html:"An HTML fragment, or a DomHelper specification to use as the layout element content. The HTML content is added after the component is rendered, so the document will not contain this HTML at the time the render event is fired. This content is inserted into the body before any configured contentEl is appended."
});
And then I want to listen to event when an enter key is pressed. So, I am creating a KeyMap as follows...
var map = new Ext.KeyMap(Ext.getCmp('textPanel').body, {
key: Ext.EventObject.ENTER,
fn: onKeyPress,
// handler: onKeyPress,
scope: this
});
But the onKeyPress function is not being called.
I have already tried using
Ext.getCmp('textPanel').body.dom,
Ext.getCmp('textPanel').el.dom,
Ext.getCmp('textPanel').el
instead of
Ext.getCmp('textPanel').body
with no success.
If I use "document" there then the onKeyPress function is called. i.e.
var map = new Ext.KeyMap(document, {
key: Ext.EventObject.ENTER,
fn: onKeyPress,
// handler: onKeyPress,
scope: this
});
This works perfectly but I don't want to listen to whole document.
How can I listen to just the panel?
In extjs 3.4, if you want to use KeyMap then you need to first set focus on the panel element, otherwise key events will always fire at document level hence you will not able to listen for key events on panel (that's why you were able to listen key events on document only)
But in extjs there isn't any way to set focus on panel, so therefore you will need to create a custom panel class which can set focus to itself and listen key events
Ext.namespace('Saket');
Saket.FocusPanel = Ext.extend(Ext.Panel, {
onRender : function()
{
Saket.FocusPanel.superclass.onRender.apply(this, arguments);
// this element allows the Window to be focused for keyboard events
this.focusEl = this.el.createChild({
tag: 'a', href:'#', cls:'x-dlg-focus',
tabIndex:'-1', html: ' '});
this.focusEl.swallowEvent('click', true);
this.getEl().on({
click : this.focus,
scope : this
});
},
focus : function()
{
this.focusEl.focus();
}
});
new Saket.FocusPanel({
id: 'textPanel',
height: 200,
width: 300,
renderTo: Ext.getBody(),
html:"An HTML fragment, or a DomHelper specification to use as the layout element content. The HTML content is added after the component is rendered, so the document will not contain this HTML at the time the render event is fired. This content is inserted into the body before any configured contentEl is appended.",
keys: {
key: Ext.EventObject.ENTER,
fn: function() {alert('bingo');},
scope: this
}
});
Demo: http://jsfiddle.net/silentsakky/PdyqW/3/
Add a listeners for keydown on the panel's element using getEl():
Ext.getCmp('textPanel').getEl().on('keydown', function(f, e) {
if (e.getKey() === Ext.EventObject.ENTER)
{
//do whatever you want here
}
});

Close menu event in jQuery

I have a menu plugin in jQuery.
The menu is closed only when i click the inner circle of it...
www.tranceil.fm -> click the headphones
I want to close the menu by clicking anywhere, not just the inner circle
the header code is this
<script type="text/javascript">
jQuery(document).ready(function(){
var pieMenu = jQuery('#promo').pieMenu({icon : [
{
path : "/wp-content/themes/Tersus/images/piemenu/winamp.png",
alt : "Winamp",
fn : function(){('Click:: Plus');window.location.href = 'http://94.23.250.14:2199/tunein/tranceilfm.pls';return false}
}, {
path : "/wp-content/themes/Tersus/images/piemenu/vlc.png",
alt : "VLC Media Player",
fn : function(){('Click:: Plus');window.location.href = 'http://94.23.250.14:2199/tunein/tranceilfm.pls';return false}
},{
path : "/wp-content/themes/Tersus/images/piemenu/QuickTime.png",
alt : "Quick Time Player",
fn : function(){('Click:: Plus');window.location.href = 'http://94.23.250.14:2199/tunein/tranceilfm.qtl';return false}
},{
path : "/wp-content/themes/Tersus/images/piemenu/WMP.png",
alt : "Windows Media Player",
fn : function(){('Click:: Plus');window.location.href = 'http://94.23.250.14:2199/tunein/tranceilfm.asx';return false}
},{
path : "/wp-content/themes/Tersus/images/piemenu/popup.png",
alt : "נגן Popup",
fn : function(){jQuery("#popupplay").click();return false}
},{
path : "/wp-content/themes/Tersus/images/piemenu/iTunes.png",
alt : "iTunes",
fn : function(){alert('...בקרוב');return false}
}],
beforeMenuOpen: function(){
jQuery('<div id="shadow"></div>').css(
{
'position':'fixed',
'background-color':'#000000',
'opacity': 0.6,
'width':'100%',
'height':'100%',
'z-index' :999,
'top':0,
'left':0
}).appendTo('body');
},
beforeMenuClose: function(){
jQuery('#shadow').remove();
}
});
jQuery('#promo').click(function(){
if(jQuery('#'+pieMenu.id).css('display') != 'block') //if jpie is not visible
pieMenu.initMenu(760,150);
})
});
</script>
The click event in the JS file ->
//click event
jQuery('#'+idCore).live({
click: function() {
if(closable)
removeMenu();
},
contextmenu:function(e){
e.preventDefault();
}
})
Any thoughts?
Looks like you need to remove the pie0 div and the shadow div when the shadow is clicked, because they're being entirely generated/re-generated whenever they are brought on/back to the screen.
So just add this:
$('#shadow').on('click', function(event){
$('#pie0').remove();
$(this).remove();
});
Update: I just realized: because shadow is added dynamically after a user-event, and not present on documentready, you need to define it by attaching it to the body element, and delegating to a click on the shadow element, like this:
$('body').on('click', 'shadow', function(event){
$('#pie0').remove();
$(this).remove();
});
If you want to close it by clicking anywhere:
$(document).live({
....
});
The problem that you will face here is that this click will cause other clicks also to happen. For example, if the user clicks on some link or something, he will be redirected and also the menu will be closed. Moreover, since document is a top level element, events will never propogate FROM it, they will always propogate TO it. Even if such was not the case, live works in a way such that it handles events once they have propagated to the top
What you can do is, set it up in capture mode:
document.addEventListener('click', function(event) {
if(closeable) {
removeMenu();
event.stopPropogation();
}
}, true);
The true parameter at the end sets this event listener in the capturing mode, which will cause it to call the event handler of the highest order ancestor there is, which will be there for document. After calling that event, the event is then bubbled to the target. And within document's event handler, if we consume an event (we shall do it ONLY and ONLY if closeable is set), then we don't propagate it at all.

Categories

Resources