Extjs - Toolbar button menu dropdown with submenus. It's possible? - javascript

I've already done a toolbar with buttons that have a dropdown menu but I need more submenu levels. It's possible to do that? Example:
toolbarbutton ->
menu 1 lv 1
menu 2 lv 1
menu 3 lv 1->
submenu 1 lv 2
submenu 2 lv 2
menu 4 lv 1
and so on...

Have a look at this example! You can achieve using the Ext.menu.Menu class.
Here is an Example:
{
text: 'Main Menu',
menu: {
xtype: 'menu',
items: [{
text: 'Menu One',
iconCls: 'edit'
}, {
text: 'Menu Two',
menu: {
xtype: 'menu',
items: [{
text: 'Next Level'
},{
text: 'Next Level'
},{
text: 'Next Level'
}]
}
}, {
text: 'Menu Three',
scale: 'small'
}, {
text: 'Menu Four',
scale: 'small'
}]
}
}

Yes it is possible.
This menu is created dynamically with ExtJs, the data is loaded from Json.
See my demo with the code.
Demo Online:
https://fiddle.sencha.com/#view/editor&fiddle/2vcq
Json loaded:
https://api.myjson.com/bins/1d9tdd
Code ExtJs:
//Description: ExtJs - Create a dynamical menu from JSON
//Autor: Ronny Morán <ronney41#gmail.com>
Ext.application({
name : 'Fiddle',
launch : function() {
var formPanelFMBtn = Ext.create('Ext.form.Panel', {
bodyPadding: 2,
waitMsgTarget: true,
fieldDefaults: {
labelAlign: 'left',
labelWidth: 85,
msgTarget: 'side'
},
items: [
{
xtype: 'container',
layout: 'hbox',
items: [
]
}
]
});
var win = Ext.create('Ext.window.Window', {
title: 'EXTJS DYNAMICAL MENU FROM JSON',
modal: true,
width: 680,
closable: true,
layout: 'fit',
items: [formPanelFMBtn]
}).show();
//Consuming JSON from URL using method GET
Ext.Ajax.request({
url: 'https://api.myjson.com/bins/1d9tdd',
method: 'get',
timeout: 400000,
headers: { 'Content-Type': 'application/json' },
//params : Ext.JSON.encode(dataJsonRequest),
success: function(conn, response, options, eOpts) {
var result = Ext.JSON.decode(conn.responseText);
//passing JSON data in 'result'
viewMenuDinamical(formPanelFMBtn,result);
},
failure: function(conn, response, options, eOpts) {
//Ext.Msg.alert(titleAlerta,msgErrorGetFin);
}
});
}
});
//Generate dynamical menu with data from JSON
//Params: formPanelFMBtn - > Panel
// result - > Json data
function viewMenuDinamical(formPanelFMBtn,result){
var resultFinTarea = result;
var arrayCategoriaTareas = resultFinTarea.categoriaTareas;
var containerFinTarea = Ext.create('Ext.form.FieldSet', {
xtype: 'fieldset',
title: 'Menu:',
margins:'0 0 5 0',
flex:1,
layout: 'anchor',
//autoHeight: true,
autoScroll: true,
height: 200,
align: 'stretch',
items: [
]
});
var arrayMenu1 = [];
//LEVEL 1
for(var i = 0; i < arrayCategoriaTareas.length; i++)
{
var categoriaPadre = arrayCategoriaTareas[i];
var nombrePadre = categoriaPadre.nombreCategoria;
var hijosPadre = categoriaPadre.hijosCategoria;
var arrayMenu2 = [];
//LEVEL 2
for(var j = 0; j<hijosPadre.length; j++)
{
var categoriaHijo = hijosPadre[j];
var nombreHijo = categoriaHijo.nombreHijo;
var listaTareas = categoriaHijo.listaTareas;
var arrayMenu3 = [];
//LEVEL 3
for(var k = 0; k < listaTareas.length; k++)
{
var tarea = listaTareas[k];
var nombreTarea = tarea.nombreTarea;
var objFinLTres =
{
text: nombreTarea,
handler: function () {
alert("CLICK XD");
}
};
arrayMenu3.push(objFinLTres);
}
var menuLevel3 = Ext.create('Ext.menu.Menu', {
items: arrayMenu3
});
var objFinLDos;
if(arrayMenu3.length > 0)
{
objFinLDos = {
text: nombreHijo,
menu:menuLevel3
};
}
else
{
//without menu parameter If don't have children
objFinLDos = {
text: nombreHijo
};
}
arrayMenu2.push(objFinLDos);
}
var menuLevel2 = Ext.create('Ext.menu.Menu', {
items: arrayMenu2
});
var objFinLUno;
if(arrayMenu2.length > 0)
{
objFinLUno = {
text: nombrePadre,
menu:menuLevel2
};
}
else
{
//without menu parameter If don't have children
objFinLUno = {
text: nombrePadre
};
}
arrayMenu1.push(objFinLUno);
}
var mymenu = new Ext.menu.Menu({
items: arrayMenu1
});
containerFinTarea.add({
xtype: 'splitbutton',
text: 'Example xD',
menu: mymenu
});
formPanelFMBtn.add(containerFinTarea);
}

Related

Javascript: Create a form with a parametric number of textbox (TinyMCE)

I am not a Web developer, I have to do just a small task once, but I hate copy & paste.
Look at the code below, I'd like to avoid copy and paste (question1, question2 ,..., question[i]). I'd like to create a for statement but I should handle properties with a dynamic name. In c# I would use reflection or dynamic.
Is it possible in Javascript? Is it the correct approach? Should I dynamically generate the code and use Eval()?
tinymce.PluginManager.add('test_containers', function(editor, url) {
editor.addButton('test_containers2', {
title: 'Container 2',
text: 'Container 2',
onclick: function() {
editor.windowManager.open({
title: 'Test Container',
body: [{
type: 'container',
layout: 'stack',
columns: 2,
minWidth: 500,
minHeight: 500,
items: [{
type: 'textbox',
name: 'question1'
}, {
type: 'textbox',
name: 'question2'
}, ]
}],
onsubmit: function(e) {
ed.insertContent(e.data.question1 + e.data.question2);
}
});
}
});
});
tinymce.init({
selector: '#mytextarea',
plugins: 'colorpicker test_containers',
toolbar: 'test_containers2'
});
// Taken from core plugins
var editor = tinymce.activeEditor;
function createColorPickAction() {
var colorPickerCallback = editor.settings.color_picker_callback;
if (colorPickerCallback) {
return function() {
var self = this;
colorPickerCallback.call(
editor,
function(value) {
self.value(value).fire('change');
},
self.value()
);
};
}
}
<script src="https://cdn.tinymce.com/4/tinymce.min.js"></script>
<textarea id="mytextarea">Hello, World!</textarea>
See: https://jsfiddle.net/Revious/gm2phuva/3/
From my understanding, you need to add the items dynamically.
I have added two function on your code.
createArr -> will create the array of list of the specified number (n)
handleQuesData -> will concat the data of all the questions and pass it to onsubmit function
tinymce.PluginManager.add('test_containers', function(editor, url) {
// item creation dynamically
let createArr = (n) => {
let arr = []
for (let i = 0; i < n; i++) {
arr.push({
type: 'textbox',
name: `question{i+1}`
})
}
return arr;
}
// onsubmit handled dynamically
let handleQuesData = (data, n) => {
let quesdata = ''
for (let i = 0; i < n; i++) {
quesdata += data[`question{i+1}`]
}
return quesdata
}
let numItem = 2;
editor.addButton('test_containers2', {
title: 'Container 2',
text: 'Container 2',
onclick: function() {
editor.windowManager.open({
title: 'Test Container',
body: [{
type: 'container',
layout: 'stack',
columns: 2,
minWidth: 500,
minHeight: 500,
items: createArr(numItem)
}],
onsubmit: function(e) {
ed.insertContent(handleQuesData(e.data, numItem));
}
});
}
});
});
tinymce.init({
selector: '#mytextarea',
plugins: 'colorpicker test_containers',
toolbar: 'test_containers2'
});
// Taken from core plugins
var editor = tinymce.activeEditor;
function createColorPickAction() {
var colorPickerCallback = editor.settings.color_picker_callback;
if (colorPickerCallback) {
return function() {
var self = this;
colorPickerCallback.call(
editor,
function(value) {
self.value(value).fire('change');
},
self.value()
);
};
}
}
Here is the demo code : JSFiddle
Hope it helps :)
Yes, you can dynamically generate the list of items.
tinymce.PluginManager.add('test_containers', function(editor, url) {
const totalQuestions = 10;
let questions = [];
for (let i = 1; i < totalQuestions; i++) {
questions.push({
type: 'textbox',
name: 'question' + i
});
}
editor.addButton('test_containers2', {
title: 'Container 2',
text: 'Container 2',
onclick: function() {
editor.windowManager.open({
title: 'Test Container',
body: [{
type: 'container',
layout: 'stack',
columns: 2,
minWidth: 500,
minHeight: 500,
items: questions
}],
onsubmit: function(e) {
ed.insertContent(e.data.question1 + e.data.question2);
}
});
}});
});
//......

Add a tab(item) to tabpanel by button clicking, extjs

I have a tabpanel, that initially has 1 tab and a button. But the user should be able to add more tabs by clicking on the button. Here is the code so far:
var tabPan = Ext.create('Ext.TabPanel', {
listeners: {
beforetabchange: function(tabs, newTab, oldTab, eOpts) {
if (newTab.title=='Add') { // Or some other condition
return false;
}
}
},
items:[
{
title: 'Default Tab',
html: innerHtml
},
{
xtype: 'button',
title : 'Add',
},
]
})
Your approach is right, All you need is to create a panel and add it to the TabPanel.
var i = 1;
var onAddTab = function(tabPanel) {
var newTab = {
xtype: 'panel',
title: 'Untitled Tab ' + (i++)
};
var index = tabPanel.items.length - 1;
var newTabItem = tabPanel.insert(index, newTab);
tabPanel.setActiveTab(newTabItem);
};
var tabPanel = Ext.create('Ext.TabPanel', {
listeners: {
beforetabchange: function(tabs, newTab, oldTab, eOpts) {
if (newTab.title == 'Add') {
onAddTab(tabPanel);
return false;
}
}
},
items: [{
title: 'Default Tab',
html: 'Hello World'
}, {
xtype: 'button',
title: 'Add',
}],
renderTo: Ext.getBody()
});

Sencha touch scroll is not working

I have a main.js
**Ext.define('EDevlet.view.Main', {
viewport: {
autoMaximize: true
},
extend: 'Ext.Container',
xtype: 'mainview',
defaultColumnCount: 2,
config: {
scrollable:"vertical",
cls: "page-content-style page-with-main-buttons",
fullscreen: true,
title: i18n["edevlet_title"],
flex:1,
height:800,
layout: {
type: 'vbox',
align: 'stretch'
},
defaults: {
flex:1
},
items: [{
xtype: "panel",
id: "greeting-message",
cls: "greeting",
docked: "top"
}
]
},**
loadMenu: function () {
Logger.log("#Main::loadMenu");
this.removeAll(true, false);
var services = SegmentUtil.getServiceContent(), // boş olma ihtimali yok, BE den gelmez ise yereldeki DEFAULT segment içeriğini kullanıyor
maxServiceSize = SegmentUtil.getHomePageMaxServiceSize(),
columnCount = this.defaultColumnCount,
rowCount = Math.ceil((maxServiceSize + 1) / columnCount), // +1 diğer servisler düğmesi için !
index,
service,
title,
itemId,
button,
menuRow,
rowIndex,
isLeftSide,
verticalPosition = -1;
Logger.log('services: ' + services);
Logger.log('rowCount: ' + rowCount + ', columnCount: ' + columnCount + ', maxServiceSize: ' + maxServiceSize);
// satırları oluştur
var newCount=rowCount+1;
for (index = 0; index < newCount; index++) {
if(index==0){
**this.add({
id: 'mainRow-' + index,
xtype: 'carousel', flex:3,
layout: 'hbox',
defaults: {
flex:1
}, items: [
{ id: 'Image1',
html: ''
},
{ id: 'Image2',
html: ''
},
{ id: 'Image3',
html: ''
},
{ id: 'Image4',
html: ''
}
]
});
this.requestBackEndForNewsUrl();
}
else{
this.add({
id: 'mainMenuRow-' + index,
xtype: 'container',
flex:2,
layout: 'hbox',
defaults: {
flex:1
}
});
}**
}
}
}
And I have a load function.Load function add items(this items is image).But my scrool seem but not working.I hold scroll but if a release scroll is going up.
I have a vbox.After two hbox is added.But scroll is not working.
Try this. Write this override code in app.js file & then check.
// Fix for scroll
Ext.override(Ext.util.SizeMonitor, {
constructor: function (config) {
var namespace = Ext.util.sizemonitor;
return new namespace.Scroll(config);
}
});
Ext.override(Ext.util.PaintMonitor, {
constructor: function (config) {
return new Ext.util.paintmonitor.CssAnimation(config);
}
});
Change your view's config to this:
scrollable: {
direction: 'vertical',
directionLock: true
},
flex:1,
height: '100%',
This will serve your purpose. Let me know if it helps or not.

How to add content in dynamic tab

I have a jqQrid that I have placed inside a HTML table. Now as per my requirement I have to show this grid inside the dynamic tab which is opened on hyper link click.
Here is the code for dynamic tab creation:
function addTab(title) {
if ($('#tt').tabs('exists', title)) {
$('#tt').tabs('select', title);
}
else {
if (title == "Check in List") {
//Here i have to call jqgrid loading function but how I am not getting !!!
var content = '';
}
else {
var content = '<p>Hii</p>';
}
$('#tt').tabs('add', {
title: title,
content: content,
closable: true
});
}
}
Here is the function to generate the grid:
function CheckInRecordgrid() {
//Grid Codes
}
And here is the HTML table placeholder:
<table id="CheckIngrid"></table>
Now my question is how to call the grid generation function if the clicked tab is as per the condition?
Here is my full grid code..
function CheckInRecordgrid() {
var data = [[48803, "DELUX", "A", "2014-09-12 12:30:00", "Done"], [48804, "NORAML", "V", "2014-09-12 14:30:00", "Pending"]];
$("#CheckIngrid").jqGrid({
datatype: "local",
height: '100%',
autowidth: true,
colNames: ['Room No.', 'Category', ' Guest name', ' Date & Time ', 'Status'],
colModel: [
{
name: 'Room No.', index: 'Room No.', width: 100, align: 'center'
},
{
name: 'Category', index: 'Category', width: 100, align: 'center'
},
{
name: 'Guest name', index: 'Guest name', width: 100, align: 'center'
},
{
name: 'Date & Time', index: 'Date & Time', width: 100, align: 'center'
},
{
name: 'status', index: 'status', width: 100, align: 'center'
}
],
caption: "Check In List"
});
var names = ["Room No.", "Category", "Guest name", "Date & Time", "status"];
var mydata = [];
for (var i = 0; i < data.length; i++) {
mydata[i] = {};
for (var j = 0; j < data[i].length; j++) {
mydata[i][names[j]] = data[i][j];
}
}
for (var i = 0; i <= mydata.length; i++) {
$("#CheckIngrid").jqGrid('addRowData', i + 1, mydata[i]);
}
}
try this
if (title == "Check in List") {
var content = '';
}else {
var content = '<p>Hii</p>';
};
$('#tt').tabs('add', {
title: title,
content: content,
closable: true,
}).tabs({
onAdd: function(title,index){
if (title == "Check in List") {
CheckInRecordgrid();
}
}
});

Sencha Touch 2: How to show a List in a Navigation View?

I am trying to create a list on the fly and then show it dynamically in a navigation view but when I try and Do this, I get no errors and the list doesnt show. I was wondering how one can show a list from within a navigation view.
Ext.define('MyApp.view.Navigation', {
extend: 'Ext.navigation.View',
id: 'NavView',
xtype: 'navigationcard',
config: {
title: 'Schedule',
iconCls: 'settings',
//we only give it one item by default, which will be the only item in the 'stack' when it loads
items: [
{
xtype: 'mainview'
}
]
}
});
Ext.define('MyApp.view.Main', {
extend: 'Ext.TabPanel',
xtype: ['mainview','widget.mainview'],
config: {
title:'MyApp',
fullscreen: true,
tabBarPosition: 'bottom',
defaults: {
styleHtmlContent: true
},
items: [
{ xtype: 'schedulecard' },
{ xtype: 'settingscard' }
]
}
});
var scheduleStore = Ext.create('Ext.data.Store', {
storeId: 'schedulestore',
fields: ['scheduleId', 'templateName', 'startDate', 'times'],
sorters: 'day',
grouper: {
groupFn: function (record) {
var startDate = $.datepicker.formatDate('DD, MM dd', new Date(record.get('startDate')));
return startDate;
},
sortProperty: 'startDate',
}
}); // create()
Ext.define('MyApp.view.Schedule', {
extend: 'Ext.List',
xtype: 'schedulecard',
grouped: true,
config: {
title: 'Schedule',
iconCls: 'time',
store: 'schedulestore',
grouped: true,
itemTpl: '<span style="font-weight:bold;">{templateName}</span><br/>{times}',
listeners: {
itemtap: function (list, index, item, e) {
var self = Ext.getCmp('NavView');
var listRecord = list.getStore().getAt(index);
var scheduleId = listRecord.get('scheduleId');
var scheduleItem = GetScheduleItemById(scheduleId);
var button = Ext.create('Ext.Button', {
iconCls: 'compose',
text:'Forms',
iconMask: true,
handler: function () {
var self = Ext.getCmp('NavView');
var cListStore = Ext.create('MyApp.view.ScheduleFormsList');
var panelForms = Ext.create('Ext.Panel', {
id: 'panelForms',
items: [{ xtype: 'schedulecard' }]
});
var newView = {
title: scheduleItem.AppointmentType.Name,
id: 'ScheduleItemDetailForms',
items: [cListStore]
};
self.push(newView);
}
});
var panelScheduleDetails = Ext.create('Ext.Panel', {
id: 'panel',
html: '<div style="margin:10px;"><span style="font-weight:bold;">' + timesTxt + '</span></div><hr/><div style="float:left;margin:10px;clear:both;">' + locationtxt + '</div><div style="float:left;margin:10px;">' + googleMap + '</div>'
});
var scheduleDetailsContainer = Ext.create('Ext.Container', {
fullscreen: true,
layout: 'vbox',
items: [
{
xtype: 'panel',
flex: 1,
items: [button]
},
{
xtype: 'panel',
flex: 2,
items: [panelScheduleDetails]
}
]
});
var newView = {
title: scheduleItem.AppointmentType.Name,
id: 'ScheduleItemDetailTabs',
items: [scheduleDetailsContainer]
};
self.push(newView);
}
}
}
});
Try adding the xtype of list in the main
Main.js
Ext.define('MyApp.view.Main',{
extend:'Ext.TabPanel',
xtype:'mainView',
id:'idMain',
config:{
tabBar:{
docked:'bottom',
hidden:true
},
items:[
{ xtype: 'schedulecard' }
]
}
});
Schedule.js
Ext.define("MyApp.view.Schedule", {
extend: "Ext.Container",
xtype: 'schedulecard',
config: {
title: 'Schedule',
iconCls: 'time',
layout:'fit',
items: [
{
xtype: 'navigationview',
id:'idScheduleListNavView',
items: [
{
xtype:'list',
onItemDisclosure:true,
loadingText: "Searching ...",
emptyText: "<div class=\"empty-text\">No Places Found.</div>",
id:'idSearchNavList',
store: 'schedulestore',
itemTpl: '<span style="font-weight:bold;">{templateName}</span><br/>{times}',
},
],
}
]
}
});
ScheduleController.js
In your controller create the new view and push it
Ext.define('MyApp.controller.ScheduleController',{
extend:'Ext.app.Controller',
config:{
refs:{
idScheduleList:'schedulecard',
navScheduleList:'#idScheduleListNavView',
},
control:{
'#idScheduleListNavView' : {itemtap:'showScheduleDetails'},
}
},
showScheduleDetails : function(){
var navScheduleList = this.getNavScheduleList();
navScheduleList.push(newView);
}
});

Categories

Resources