Prevent Click Event from document Level to child elements - javascript

I am create a hybrid app using Sencha frame work where I have a setting screen, when setting screen is visible in the screen I want to prevent all the touch event from the user to other components except specific views. I saw some of the post saying that event the stopProgation() and preventDefault() will the event further But i am not clear about It.
I tried to add click event to document to release my setting list from the view when user tap on the screen but if the user tap on other component in that screen it will trigger that button action also, how to prevent this.
Also I don't want to prevent the action of touch when user click on setting list or some specific component in my view.
Note: I not able to use jquery in this project because using jquery side by with Sencha may cause performance issue.
Code:
Ext.define('MyApp.view.ControlPanel.ControlPanel', {
extend: 'Ext.Container',
alias: "widget.controlpanel",
requires: [
'Ext.SegmentedButton'
],
config: {
layout: {
pack:'stretch'
},
docked:'bottom'
},
documentClickHandler:function(event){
console.log('Document Clicked');
document.removeEventListener('click', arguments.callee, false);
var settingListContainer = Ext.ComponentQuery.query("#setting-list-container")[0];
if (settingListContainer) {
var controlpanel = settingListContainer.up('controlpanel');
if (controlpanel) {
controlpanel.remove(settingListContainer, true);
var segmentButton = controlpanel.down("#control-segment-button");
if (segmentButton) {
segmentButton.setPressedButtons();
}
}
}
event.preventDefault();
return false;;
},
onSegmentToggled: function (container, button, pressed)
{
console.log("Toggle Event");
var index = container.getItems().indexOf(button);
if (index == 0) {
if (pressed) {
container.setPressedButtons();
var settingListContainer = this.down("#setting-list-container");
if (settingListContainer) {
this.remove(settingListContainer, true);
// close nav by touching the partial off-screen content
}
}
}a
else {
var settingListContainer = this.down("#setting-list-container");
if (!pressed&&settingListContainer) {
this.remove(settingListContainer, true);
}
else if (pressed) {
var existingList = Ext.ComponentQuery.query('settingList')[0];
if (existingList) {
this.add(existingList);
document.addEventListener('click', this.documentClickHandler, false);
}
else {
this.add({ xtype: "settingList", height: '349px', sortHandler: this.config.sortHandler, segmentControl: container });
document.addEventListener('click',this.documentClickHandler, false);
}
}
}
},
listeners: [
{
delegate: "#control-segment-button",
event: 'toggle',
fn: 'onSegmentToggled'
}
],
initialize: function () {
//Ext.require("");
var segmentedButton = Ext.create('Ext.SegmentedButton', {
layout: {
type: 'hbox',
pack: 'center',
align: 'stretchmax'
},
docked: 'bottom',
id:'control-segment-button',
allowMultiple: false,
allowDepress: true,
config: { flex: 1 },
items: [
{
iconCls: 'time',
width: '50%',
cls:'palin-segment',
style:"border-radius:0px"
},
{
iconCls: 'settings',
width: '50%',
cls: 'palin-segment',
style: "border-radius:0px"
}
]
});
this.add(segmentedButton);
}
});

event.preventDefault(); is what keeps the framework or the document from also handling this event.

Related

ExtJS 7.1 Tag field is executing XSS tag

I am having an issue regarding the tagfield component when entering <img src=a onerror=alert('xss!')>. This tag is being executed after entering the whole value. I've tried preventing the tag execution on keyup, keypress, keydown, and beforequery events and it still executing. This block of code prevent the event from executing when it detects an XSS tag.
Ext.application({
name: 'Fiddle',
launch: function () {
var shows = Ext.create('Ext.data.Store', {
fields: ['id', 'show'],
data: []
});
Ext.create('Ext.form.Panel', {
renderTo: Ext.getBody(),
title: 'Sci-Fi Television',
height: 200,
width: 500,
items: [{
xtype: 'tagfield',
itemId: 'tagField',
fieldLabel: 'Select a Show',
store: shows,
displayField: 'show',
valueField: 'id',
queryMode: 'local',
filterPickList: false,
listeners: {
beforequery: function () {
var editor = Ext.ComponentQuery.query('#tagField')[0];
if (editor.inputEl.getValue().search(new RegExp('(<([^>]+)>)')) >= 0) {
editor.inputEl.dom.value = '';
return false;
}
},
keypress: function (textfield, event) {
var editor = Ext.ComponentQuery.query('#tagField')[0];
if (editor.inputEl.getValue().search(new RegExp('(<([^>]+)>)')) >= 0) {
editor.inputEl.dom.value = '';
return false;
}
},
keydown: function (textfield, event) {
var editor = Ext.ComponentQuery.query('#tagField')[0];
if (editor.inputEl.getValue().search(new RegExp('(<([^>]+)>)')) >= 0) {
editor.inputEl.dom.value = '';
return false;
}
},
}
}]
});
}
});
enter image description here
This took a little while to hunt down, but apparently in Ext.form.field.ComboBox, there's an onFieldMutation handler that really is the key to all of this. Take a look at this Fiddle and the code that takes care of handling this... I believe this is what you're looking for:
Ext.define('ComboOverride', {
override: 'Ext.form.field.ComboBox',
onFieldMutation: function (e) {
var inputDom = this.inputEl.dom;
if (Ext.String.hasHtmlCharacters(inputDom.value)) {
inputDom.value = '';
alert('XSS Detected, Removing');
}
return this.callParent(arguments);
}
});

How to slideIn hidden component in ExtJS?

I've got the following situation: some controls that are located next to a button and are slided in and out on button click.
Ext.define ('Site.widget.SomeButton', {
extend: 'Ext.button.Button',
xtype: 'SomeButton',
width: 30,
controlled_inputs: null,
expanded: false,
setControlledCmp: function(controlledInputs) {
var me = this;
me.on('click', function(){
if (me.expanded)
controlledInputs.getEl().slideOut('r', { duration: 250 });
else
controlledInputs.getEl().slideIn('r', { duration: 250 });
me.expanded = !me.expanded;
});
}
});
Ext.define('Site.widget.ComingOut', {
extend: 'Ext.Container',
xtype: 'ComingOut',
layout: 'hbox',
header: false,
referenceHolder: true,
items:[{
xtype: 'SomeItems',
reference: 'SomeItems'
},{
xtype: 'SomeButton',
reference: 'SomeButton'
}],
onBoxReady: function() {
me.lookupReference('SomeButton').setControlledItems(me.lookupReference('SomeItems'));
}
});
The code works fine when the controls are initially shown. The question is: what should I do if I want them to be initially hidden? hidden:false is not the option since when controls are hidden the button moves into the freed position. I suppose I am missing something easy here. Thank you in advance!
PS I've found solution, though it doesn't seem good enough (hides element instead of correctly setting its initial state), so if anyone knows a better one - you are welcome. My solution is the following
setControlledCmp: function(controlled_inputs) {
var me = this;
me.on('click', function( view, eOpts ){
controlled_inputs.setOpacity(1);
if (me.expanded)
controlled_inputs.slideOut('r', { duration: 250 });
else
controlled_inputs.slideIn('r', { duration: 250 });
me.expanded = !me.expanded;
});
}
and
onBoxReady: function() {
var me = this;
var inputs = me.lookupReference('search_inputs').getEl();
inputs.setOpacity(0);
inputs.slideOut('r', { duration: 5 });
me.lookupReference('search_button').setControlledCmp(inputs);
}

Fail to catch tab change event

I'm using button to move between tabs. But for that I have to remember the user's tab position. So my buttons keep working when the user leaves the screen and returns later.
The tabchange event should be the event to use for that, however I cannot get it to trigger.
View:
Ext.define('MyApp1.view.Home',
{
extend: 'Ext.form.Panel',
requires:
[
'Ext.tab.Panel'
],
xtype: 'home',
config:
{
itemId: 'home',
layout: 'fit',
items:
{
xtype: 'tabpanel',
tabBarPosition: 'top',
height: 500,
renderTo: document.body,
listeners:
{
beforetabchange: function (tabs, newTab, oldTab)
{
console.log('tab is going to change');
},
tabchange: function ()
{
console.log('recorded tab change from listener');
},
change: function ()
{
console.log('change of tab from listener');
}
},
items:
[
{
title: 'one'
},
{
title: 'two'
}
]
}
}
});
Controller:
Ext.define('MyApp1.controller.HomeController',
{
extend: 'Ext.app.Controller',
requires:
[
'MyApp1.view.Main'
],
config:
{
refs:
{
home: 'home'
},
control:
{
home:
{
beforetabchange: 'onTabChange',
tabchange: 'onTabChange',
change: 'onTabChange'
}
}
},
init: function()
{
console.log('HomeController initialized');
},
onTabChange: function ()
{
console.log('active tab changed');
}
});
So I see the initialization text in the log but none of the tab change events when I click the tab buttons.
First off it seems you can only implement these listeners on the tabBar of the tabPanel
Having looked through the source code though it seems that this never get's fired even though it is documented. http://docs-origin.sencha.com/touch/2.4/2.4.1-apidocs/source/Bar3.html#Ext-tab-Bar-event-tabchange
What I could suggest is either as you pointed out to hook into the activeitemchange event on the panel or activetabchange (which strangely is firing twice) event of the tabbar as activeitemchange also seems not to work as intended.
https://fiddle.sencha.com/#fiddle/g44
Turns out I was looking at the ExtJs 5 docs, instead of the Sencha 2.4.1 docs...
Which only has the 'activeitemchange' event.

handle click on Ext.js panel header

I am trying to handle clicks on ext.js panel header (living inside of an accordion with other panels..), now the header is an extended header, and it contains a number of items (not tools) in it. Problem is that when I set titleCollapse:true, clicks on my items are propagated to the header, which collapses.
I want to set titleCollapse:true so I the users will be able to collapse/expand by clicking the header and not only the collapse tool. But, then, this problem..
let me answer myself...
Ext.define("WebPhone.view.CallLogListHeader", {
extend: 'Ext.panel.Header',
xtype: 'callLogListHeader',
layout:
{
type: 'hbox',
align: 'middle',
pack: 'end'
},
//titlePosition: 0,
items:
[
{
xtype: 'button',
text: '',
cls: 'ClearCallLogButtonCls',
handler: function () {
var me = this;
me.container.component.handledByTool = true;
var view = Ext.create('WebPhone.view.ApproveClearLogs');
view.show();
}
}
],
initComponent: function()
{
var me = this;
me.callParent( arguments );
me.handledByTool = false;
},
listeners:
{
click: function()
{
var me = this;
if( me.handledByTool )
{
me.handledByTool = false;
return;
}
var parent = me.findParentByType( 'contact-list-view' );
if( parent.collapsed )
parent.expand();
else
parent.collapse();
}
}
});

SenchaTouch2 - Listening to store load event, set tab panel item "badgeText"

I'am trying to build my first little Sencha Touch 2 app. I've created some stuff that is working as expected and now I could like to create some event handling stuff.
I've created the following store:
Ext.define('Mobile.store.Blogs', {
extend: 'Ext.data.Store',
config: {
},
listeners: {
'load' : function(store,records,options) {
store.loaded = true;
console.log("fired blogCountAvailable");
store.fireEvent("blogCountAvailable");
},
'blogCountAvailable': function(store, records, options) {
console.log("blogCountAvailable has been fired");
}
}
});
This stuff works as expected, but now comes the next step.
Here is the code of my tab panel bar:
Ext.create("Ext.tab.Panel", {
xtype:'mainTabPanelBottom',
tabBarPosition: 'bottom',
fullscreen: true,
items: [
{
title: 'Blog',
iconCls: 'home',
xtype:'mainpanel'
},
{
title: 'Users',
iconCls: 'user',
xtype:'userpanel'
}
],
listeners: {
blogCountAvailable: function(tabpanel, newTab) {
var tab = newTab.tab,
badge = 10;
tab.setBadge(badge);
console.log("blogCountAvailable has been fired");
}
}
});
My question now is how I could achieve it to "fire" my custom event blogCountAvailable to the tab panel?
The easiest way is just set an id for your TabPanel and then:
Ext.getCmp('your_TabPanel_id').fireEvent("blogCountAvailable");

Categories