How to hide item in Ext menu base on condition when load - javascript

i am trying to hide an item in Ext.menu.Menu base on condition but, i cannot find the trigger load event of menu. Can you give me advice.
//var lala //= 1 2 or 3
var menu = Ext.create('Ext.menu.Menu', {
id: 'mainMenu',
items: [
{
text: 'I like Ext',
checked: true, // condition 1
checkHandler: onItemCheck
}, {
text: 'Choose a Date',
iconCls: 'calendar',
menu: dateMenu // <-- condition 2
},{
text: 'Choose a Color',
menu: colorMenu // <-- condition 3
}
]
});
Example: only show checkbox in menu if lala = 1.
Thank you.

You can use the afterRender listener on menu items:
{
text: 'Choose a Date',
iconCls: 'calendar',
menu: dateMenu // <-- condition 2
listeners: {
afterRender: function() {
if (lala == 2)
this.hide();
}
}
}

You can do like this
//var lala //= 1 2 or 3
var menu = Ext.create('Ext.menu.Menu', {
id: 'mainMenu',
items: [
{
text: 'I like Ext',
checked: true, // condition 1
hidden : lala == 1 ? true:false,
checkHandler: onItemCheck
}, {
text: 'Choose a Date',
iconCls: 'calendar',
hidden : lala == 2 ? true:false,
menu: dateMenu // <-- condition 2
},{
text: 'Choose a Color',
hidden : lala == 3 ? true:false,
menu: colorMenu // <-- condition 3
}
]
});

From your code //var lala //= 1 2 or 3, I presume, you know the value of lala when creating the menu. All you need to do then is set the items of the menu, that you want.
Something along the lines of:
var menuItems = [];
if (lala === 1) {
menuItems.push({
text: 'I like Ext',
checked: true, // condition 1
checkHandler: onItemCheck
});
}
else if (lala === 2) {
menuItems.push({
text: 'Choose a Date',
iconCls: 'calendar',
menu: dateMenu // <-- condition 2
});
}
else if (lala === 3) {
menuItems.push({
text: 'Choose a Color',
menu: colorMenu // <-- condition 3
})
}
var menu = Ext.create('Ext.menu.Menu', {
id: 'mainMenu',
items: menuItems
});
You keep talking about 'load'. Your example menu does not have any store, so it does not actually load.
However, if you need to change the menu on the fly, when some store loads (or some other event is fired), you can do it like this:
// Set all menu items in menu
var menu = Ext.create('Ext.menu.Menu', {
id: 'mainMenu',
items: [
{
text: 'I like Ext',
itemId: 'lala1', // Item ID to find the component on the fly
hidden: lala !== 1, // if lala is already initialized
//hidden: true, // if lala is not initialized
checked: true, // condition 1
checkHandler: onItemCheck
},
{
text: 'Choose a Date',
itemId: 'lala2', // Item ID to find the component on the fly
hidden: lala !== 2, // If lala is already initialized
//hidden: true, // if lala is not initialized
iconCls: 'calendar',
menu: dateMenu // <-- condition 2
},
{
text: 'Choose a Color',
itemId: 'lala3', // Item ID to find the component on the fly
hidden: lala !== 3, // If lala is already initialized
//hidden: true, // if lala is not initialized
menu: colorMenu // <-- condition 3
}
]
});
// Your store load (or any other event of your choosing)
yourStore.on({
load: function() {
var newLala = getLalaSomehow(); // Get lala the way you do
// Get menu items by the item IDs set previously
var menuItemLala1 = menu.down('#lala1');
var menuItemLala2 = menu.down('#lala2');
var menuItemLala3 = menu.down('#lala3');
// Show/hide menu items based on a condition
menuItemLala1.setVisible(newLala === 1); // Only show when lala is 1
menuItemLala2.setVisible(newLala === 2); // Only show when lala is 2
menuItemLala3.setVisible(newLala === 3); // Only show when lala is 3
}
});
In the example above, I am using setVisible method, which shows the component when the passed argument is true and hides it, if it's false.

I already found the correct way is that trigger before Ext Menu build. Or else the afterrender on run once.

Related

How to shorten the IF condition in a dynamic list?

In future I have many if condition, any idea to shorten the if condition for (Render Badge items)?
Today I just only have 4 item if in the future I have 20 or maybe 100 item, is it i need to code the if for 20 or 100 times?
I have tried many method, but I don't know how to make it.
Render Dynamic List
const medals = productItem.goldmedal || productItem.newitem || productItem.freedelivery;
if (medals) {
const iconBadge = $("<ul>", { class: 'icons' });
function createMedal(src, text) {
const badge =
$("<li>", { class: 'icon' })
.append($('<a>', { class: 'tpsTooltip skeleton_hide', href: '###', 'data-tippy-content': text })
.append($('<img>', { src: src, alt: text })))
.append($('<div>', { class: 'pl-placeholder_skeleton pl-placeholder_liIcon' }));
iconBadge.append(badge);
}
createFeatureIcon.append(iconBadge);
//Render Badge items (Below is the if condition code)
if (productItem.goldmedal) {
createMedal(plSettings.goldMetalSrc, plSettings.goldMetalText)
}
if (productItem.newitem) {
createMedal(plSettings.newItemSrc, plSettings.newItemText)
}
if (productItem.newshop) {
createMedal(plSettings.newShopSrc, plSettings.newShopText)
}
if (productItem.freedelivery) {
createMedal(plSettings.freeDeliverySrc, plSettings.freeDeliveryText)
}
}
Settings
//Settings
var plSettings = $.extend({
mainClass: 'item-wrapper',
itemWrapperClass: 'item ripple-effect ripple-joya itemShadowLight',
goldMetalSrc: '/img/tps/gold.png',
goldMetalText: 'Gold Medal sellers stand out from millions of sellers, bringing more trust and peace of mind to your shopping experience',
newItemSrc: '/img/tps/new.png',
newItemText: 'New item',
sellermedalSrc: '/img/tps/seller.png',
sellermedalText: 'Top Seller',
newShopSrc: '/img/tps/newshop.png',
newShopText: 'New Shop In Joyacart',
freeDeliverySrc: '/img/tps/freedelivery.png',
freeDeliveryText: 'Free Delivery'
});
example data is below:
var data = {
productList: [
{
id: "62276197-6059-4c21-9b40-c5b1d277e85d",
link: "javascript:void(0)",
imgurl: "/img/upload/png/joyacart_000001_12032019.png",
text: 'Product 001',
goldmedal: false,
newitem: true,
newshop: true,
freedelivery: true
},
{
id: "59de8216-052d-4e51-9f7d-7e96642ded62",
link: "javascript:void(0)",
imgurl: "/img/upload/png/joyacart_000002_12032019.png",
text: 'Product 002',
goldmedal: true,
newitem: false,
newshop: true,
freedelivery: true
}]
}
So you have a product item that looks like this(I assume you can't change that):
{
id: "62276197-6059-4c21-9b40-c5b1d277e85d",
link: "javascript:void(0)",
imgurl: "/img/upload/png/joyacart_000001_12032019.png",
text: 'Product 001',
goldmedal: false,
newitem: true,
newshop: true,
freedelivery: true
},
Let's create an array of keys from that object that tell you if you should show a medal for it:
const medalItems = ['goldmedal', 'newitem', 'newshop', 'freedelivery'];
Now instead of multiple if statements you can iterate over these keys and call createMedal for all these that are true in productItem. Passing that medal key(eg. "goldmedal" or "freedelivery") to createMedal function
for (const medal of medalItems) {
if(productItem[medal]) {
createMedal(medal);
}
}
Now in createMedal you can get src and text based on that medal key, but you'll need to adjust settings accordingly (eg. src for goldmedal should be under plSettings.goldmedalSrc)
function createMedal(medal) {
const src = plSettings[medal + "Src"];
const text = plSettings[medal + "Text"];
...
}
Not perfect because you'll need to keep plSettings in sync with productItems but it should work with your current data structures. And all you need to do to get new one to work is to add it to settings and medalItems array

Adding options programmatically to plugin function

Say I had the following code:
framework7.actions([
// First buttons group
[
// Group Label
{
text: 'Here comes some optional description or warning for actions below',
label: true
},
// First button
{
text: 'Alert',
onClick: function () {
framework7.alert('He Hoou!');
}
},
// Another red button
{
text: 'Nice Red Button ',
red: true,
onClick: function () {
framework7.alert('You have clicked red button!');
}
},
],
// Second group
[
{
text: 'Cancel',
bold: true
}
]
]);
In the above instance, how would I only add the option/code for "First button" if a certain condition was true. eg (if (need_first_button) {} ). If the condition is false then we don't pass that button to the plugin.
And the same goes for "Another red button". How could I only include that option when ( if (need_red_button) {} ) was true?
Hope that makes sense.
Thanks.
Create the argument first, then modify it as needed, finally pass it to the framework function:
var params = [
// First buttons group
[
// Group Label
{
text: 'Here comes some optional description or warning for actions below',
label: true
}
],
// Second group
[
{
text: 'Cancel',
bold: true
}
]
];
if(needFirstButton){
params[0].push({
text: 'Alert',
onClick: function () {
framework7.alert('He Hoou!');
}
});
}
if(needRedButton){
params[0].push({
text: 'Nice Red Button ',
red: true,
onClick: function () {
framework7.alert('You have clicked red button!');
}
});
}
framework7.actions(params);
You can easily add new groups, just by pushing an array to params instead of params[x]
params.push([
{
text: 'New group button 1',
red: true,
onClick: function () {
framework7.alert('You have clicked red button!');
}
}
]);
The above adds a new group containing one button, but you could add more buttons to it by comma separating the objects.

Extjs handler passes parameter but cannot use the specific parameter even though it's in the button class

I have a panel which represents a 'group' with a button for creating a 'proposal' for that group.
I am passing the current group name in a handler.
When the button is clicked it calls onAddProposalBtn.
items: [
{
xtype: 'panel',
cls: 'currentproposal-container',
id: 'AddProposalPanel',
items: [
{
xtype: 'button',
margins: '0 0 0 20',
cls: 'addproposal-btn green-btn',
hidden: false,
id: 'AddProposalBtn',
scale: 'small',
text: 'Create Proposal',
handler: function(AddProposalBtn) {
var group = me.group;
AddProposalBtn.group = group;
}
}
]
},
The problem is that when the button is clicked the button class is populated but I can't get the group. The output of the console is the 'button' class which includes a populated 'group'. But the actual groupname displays 'undefined'.
onAddProposalBtn: function(button, e, eOpts) {
var groupname = button.group;
console.log(button);
console.log(groupname);
this.groupname = groupname;
this.showCreateWindow();
},
What is strange is if I close the proposal window then click the proposal button again it fills in the group name.

Ext.AbstractManager.register(): Registering duplicate id "btnLogout" with this manager

I have did one common view, this view is required in all the pages. so wherever i need, i am calling this view of xtype . Within this common view have some components with defined by id value.
As per requirement depends on pages i need to hide some button from common view again need to show. These activities will come depending on pages. While first launching time screen will come. once i navigating to another page it will show error like Ext.AbstractManager.register(): Registering duplicate id "btnLogout" with this manager.
If i changed componets id value to name value or itemId value. then it will navigate fine but problem is not able to hide and show the buttons because showing undefined sysntax is var a = Ext.getCmp('btnBackID'); console.log(a);, it will be undefined. once the component returns as object, i can do hide show functionality.
Can any one tell how resolve this issue else give me alternate ways to achieve. great appreciate. Thank you. i have given my code below
Common View
Ext.define('abc.view.GlobalNavigationView', {
extend:'Ext.panel.Panel',
alias:'widget.globalNavigationView',
id:'globalNavigationId',
layout: {
type: 'vbox',
align:'stretch'
},
items:
[
{
xtype: 'toolbar',
layout: 'hbox',
flex: 1,
items:
[
{
xtype: 'button',
flex: .1,
text: 'Back',
id: 'btnBackID',
},
{
xtype: 'button',
flex:.1,
id: 'btnSave',
cls: 'saveCls'
},
{
xtype: 'button',
flex:.1,
id: 'btnEmail',
text: 'Email'
},
{
xtype: 'button',
flex:.1,
id: 'btnPrint',
text: 'Print'
},
{
xtype: 'button',
flex:.1,
itemId: 'btnFilter',
text: 'Filter'
},
{
xtype: 'button',
flex:.1,
id: 'btnLogout',
cls: 'logoutCls'
}
]
}
]
});
HomeView1
Ext.define('GulfMark.view.WeeklyHomeView1', {
extend:'Ext.panel.Panel',
alias:'widget.weeklyfcastView',
id:'weeklyfcastId',
layout: 'fit',
items:
[
{
xtype: 'globalNavigationView',
id: 'globalNavigationWeekly1',
flex: 1,
docked:"top",
scrollable:false
},
{
my componets of this view
.........................
}
]
});
HomeView2
Ext.define('GulfMark.view.WeeklyHomeView1', {
extend:'Ext.panel.Panel',
alias:'widget.weeklyfcastView',
id:'weeklyfcastId',
layout: 'fit',
items:
[
{
xtype: 'globalNavigationView',
id: 'globalNavigationWeekly2',
flex: 1,
docked:"top",
scrollable:false
},
{
my componets of this view
-----------------------
}
]
});
Controller Code:
init:function(){
this.control({
'globalNavigationView ':{
click:this.onbtnBackClick,
render: this.onbtnBackrender,
},
'weeklyfcastView':{
show:this.onShowweeklyfcastView,
render:this.onRenderweeklyfcastView
}
});
},
onShowweeklyfcastView: function(){
var btnFilter = Ext.getCmp('btnFilter');
console.log(btnFilter); // if i used components id to name or itemId, here will show undefined
btnFilter.setHidden(true);
//btnFilter .hide();
}
If your view is not a singleton, you cannot give IDs to its components - IDs must be unique, or you get the duplicate id error.
What you really need is some reference to the view from which you are trying to show/hide buttons. When you have that reference, you can use the down method to find your buttons. For example:
var iPanel = // Create new panel here.
iPanel.down('button[text="Email"]').hide();
This code works in EXTJS 6 for multiple buttons in the same view, having the same itemId (not id - ids will throw an error, as noted above)
View:
{
xtype : 'button',
text : 'Save and Come Back Button 1',
itemId : 'saveAndComeBackButton',
handler : 'saveAndComeBack'
},
{
xtype : 'button',
text : 'Save and Come Back Button 2',
itemId : 'saveAndComeBackButton',
handler : 'saveAndComeBack'
},
Controller:
this.__setButtons('#saveAndComeBackButton','disable');
__setButtons: function (buttonItemId,state) {
Ext.Array.forEach(
Ext.ComponentQuery.query(buttonItemId),
function (button){
if (state === 'enable'){
button.enable();
}else{
button.disable();
}
}
);
}

How to change model of a combobox (Ext JS) from outside its definition

i have two Ext Combo boxes here, i need to change values of second combobox when select event of combobox1 invokes, my problem is i don't know how to change model of a combobox.
items: [{
xtype:'combo',
fieldLabel: 'Course',
afterLabelTextTpl: required,
store: new Ext.data.SimpleStore({
data: [
[1, 'Bsc CS'],
[2, 'MSc CS'],
],
id: 0,
fields: ['value', 'text']
}),
name: 'first',
listeners:{
select: function( combo, records, eOpts )
{
if(this.getValue()=="Bsc CS")
{
// Ext.get('semcombo').getStore.loadData(msc);
}
else if(this.getValue()=="MSc CS")
{
}
}
},
editable:false,
allowBlank: false
},{
xtype:'combo',
fieldLabel: 'Semester',
id : 'semcombo',
afterLabelTextTpl: required,
name: 'last',
allowBlank: false,
}
For the second combobox, configure a combobox for each model type. Hide or show the appropriate combobox as a selection is made in the first combobox.
If you need to change the data completely (JSFiddle)
select: function(checkbox,records) {
comp.clearValue();
comp.bindStore(Ext.StoreMgr.lookup(records[0].data.store));
// you can change the value field if needed
comp.displayField = 'petname';
// you can change the display field if needed
comp.valueField = 'id';
// you can change the display template if needed
comp.displayTpl = new Ext.XTemplate(
'<tpl for=".">' +
'{[typeof values === "string" ? values : values["' + comp.displayField + '"]]}' +
'<tpl if="xindex < xcount">' + comp.delimiter + '</tpl>' +
'</tpl>'
);
comp.picker = null;
}
If you just need to filter (load) the data in second combox you can do something like this
On the select event of the first combobox prepare the second one to filter the data
combobox2.queryData = [{ property: 'fieldName', value: value}];
combobox2.reset();
combobox2.doQuery(combobox.queryData);
where combobox2 is a reference to the activated combo and value a propertyvalue from the combo. To ensure the use of your new query use
combobox2.on('beforequery', function (e) {
e.query = e.combo.queryData;
});

Categories