I'm new to Sencha extjs and I have a question.
I have my widget(HeaderRAM.js) with one splitbutton and a menuitemclick listener for every item, and my app.js with menuitemclick listener switch case.
Actually the widget 'Gestione RDA' is opened in the same browser tab. I'd like to open it in a new browser tab.
Could you help me to have Ext.getCmp('gestioneRAM').show() in a new browser tab?
Thanks in advance.
Here's the code:
//headerRAM.js
Ext.define('RAMUI.widget.HeaderRAM', {
extend: 'Ext.toolbar.Toolbar',
initComponent: function () {
codiceUtente = this.codiceUtente;
this.items = [
{
xtype: 'splitbutton',
text : traduci('Main menu' , document.getElementById('hddLingua').value),
id:'mainMenu',
menu: new Ext.menu.Menu({
items: [
// these will render as dropdown menu items when the arrow is clicked:
{ text : traduci('Gestione RAM' , document.getElementById('hddLingua').value),id:'menuGestRAM', iconCls: 'RAM', handler: function () { messaggio( traduci('Gestione RAM' , document.getElementById('hddLingua').value)); }, value: 'GestioneRAM' },
{ text : traduci('Evasione RDA Mat' , document.getElementById('hddLingua').value), id: 'menuGestRDA', iconCls: 'RAM', handler: function () { messaggio( traduci('Gestione RDA' , document.getElementById('hddLingua').value)); }, value: 'GestioneRDA' },
{ text : traduci('Evasione RDA Att' , document.getElementById('hddLingua').value), id: 'menuGestRDAAtt', iconCls: 'RAM', handler: function () { messaggio( traduci('Gestione RDA Att' , document.getElementById('hddLingua').value)); }, value: 'GestioneRDAAtt' },
{ text : traduci('Autorizzazione RDA' , document.getElementById('hddLingua').value), id: 'menuGestRDADIAP', iconCls: 'RAM', handler: function () { messaggio( traduci('Gestione RDA DIAP' , document.getElementById('hddLingua').value)); }, value: 'GestioneRDADIAP' },
{ text : traduci('Report RAM' , document.getElementById('hddLingua').value), id: 'menuReportRAM', iconCls: 'RAM', handler: function () { messaggio( traduci('Report RAM' , document.getElementById('hddLingua').value)); }, value: 'ReportRAM' },
{ text : traduci('Gestione Utenti' , document.getElementById('hddLingua').value), id: 'menuGestUtenti', iconCls: 'utenti', handler: function () { messaggio( traduci('Gestione utenti' , document.getElementById('hddLingua').value)); }, value: 'GestioneUtenti' }
],
listeners: {
scope: this,
'click': function (menu, item, e) {
//Lancio un evento dell'header
menu.up().up().fireEvent('menuclick', menu, item, e);
}
}
})
},...
//app.js
var intestazione = Ext.create('RAMUI.widget.HeaderRAM', {
id: 'intestazione',
codiceUtente: this.codiceUtente,
listeners: {
scope: this,
'menuclick': function (menu, item, e) {
switch (item.value) {
case 'GestioneRDA':
//Se non esiste genero la maschera di gestione delle ram
if (Ext.getCmp('gestioneRDA') == null) {
Ext.create('RAMUI.widget.GestioneRDA', {
id: 'gestioneRDA',
societaUtente: this.societaUtente,
codiceUtente: this.codiceUtente,
flex: 1
});
}
else {
//Ext.getCmp('gestioneRDA').reset();
Ext.getCmp('gestioneRDA').show();
}
//Aggiungo la mappa di gestione delle RAM
Ext.getCmp('mainViewport').items.add(Ext.getCmp('gestioneRDA'));
break;
....
}
//mainViewport
Ext.create('Ext.container.Viewport', {
id: 'mainViewport',
layout: {
type: 'vbox',
align: 'stretch',
pack: 'start'
},
border: false,
items: [
intestazione,
corpo
],
listeners: {
'resize': function () {
this.doLayout();
}
}
});
ExtJS is particularly good for writing on-page applications where you do not need another "browser tab/window". Also, typical Ext application does not assume that any HTML markup exists but it creates one. Therefore, you rarely need to go down to DOM and if you do need it in a special case, you do not use the low-level calls such as getElementById.
Related
I am working with ckeditor4-react plugin to use Text editor inside react app. Now I want to add a string dropdown inside my text editor, for this I have followed the "add custom plugin" documentation and added "strinsert" custom plugin.
Inside "node-modules/ckeditor4-react/" folder I have created a folder with name "plugins" and placed "strinsert" folder inside this.
Now my path of custom plugins is "node-modules/ckeditor4-react/plugins/strinsert/plugin.js"
Code of "plugin.js":
CKEDITOR.plugins.add('strinsert',
{
requires : ['richcombo'],
init : function( editor )
{
// array of strings to choose from that'll be inserted into the editor
var strings = [];
strings.push(['##FAQ::displayList()##', 'FAQs', 'FAQs']);
strings.push(['##Glossary::displayList()##', 'Glossary', 'Glossary']);
strings.push(['##CareerCourse::displayList()##', 'Career Courses', 'Career Courses']);
strings.push(['##CareerProfile::displayList()##', 'Career Profiles', 'Career Profiles']);
// add the menu to the editor
editor.ui.addRichCombo('strinsert',
{
label: 'Insert Content',
title: 'Insert Content',
voiceLabel: 'Insert Content',
className: 'cke_format',
multiSelect:false,
panel:
{
css: [ editor.config.contentsCss, CKEDITOR.skin.getPath('editor') ],
voiceLabel: editor.lang.panelVoiceLabel
},
init: function()
{
this.startGroup( "Insert Content" );
for (var i in strings)
{
this.add(strings[i][0], strings[i][1], strings[i][2]);
}
},
onClick: function( value )
{
editor.focus();
editor.fire( 'saveSnapshot' );
editor.insertHtml(value);
editor.fire( 'saveSnapshot' );
}
});
}
});
After adding this I have used this plugin inside Text editor by using "extraPlugins" config prop. This is a code of my TextEditor plugin file(which is inside the "src" folder of )
class TextEditor extends React.Component {
constructor(props) {
super(props);
this.state = {
editorData: this.props.data
}
}
/** lifecycle method */
componentDidMount() {
this.isMount = true;
this.setState({editorData: this.props.data})
}
componentWillUnmount() {
this.isMount = false;
}
/** function to detect the editor changes */
onEditorChange(event) {
let data = event.editor.getData()
this.props.onChange(data)
}
// main function
render() {
const { editorData } = this.state;
return (
<CKEditor
data={editorData}
onChange={(e) => this.onEditorChange(e)}
config={{
toolbar: [
{ name: 'basicstyles', items: ['Bold', 'Italic', 'Underline', 'Strike'] },
{ name: 'editing', items: ['SelectAll'] },
{ name: 'clipboard', items: ['Undo', 'Redo'] },
{ name: 'links', items: ['Link', 'Unlink', 'Anchor'] },
{ name: 'insert', items: [ 'Image', 'Table', 'HorizontalRule', 'Smiley', 'SpecialChar' ] },
{ name: 'document', items: [ 'Templates', 'Preview', '-', 'Source'] },
{ name: 'paragraph', items: ['NumberedList', 'BulletedList', '-', 'Outdent', 'Indent', 'Blockquote', '-', 'JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock', '-', 'BidiLtr', 'BidiRtl', 'Language'] },
{ name: 'styles', items: [ 'Styles', 'Format', 'Font', 'FontSize' ] },
{ name: 'colors', items: [ 'TextColor', 'BGColor' ] },
{ name: 'tools', items: [ 'Maximize', 'ShowBlocks' ] },
],
removePlugins: ['language'],
extraPlugins: "strinsert",
}}
/>
);
}
}
export { TextEditor };
After adding this when I am opening the text editor it shows me an error inside console::
Error::
ckeditor.js:98 GET https://cdn.ckeditor.com/4.15.1/standard-all/plugins/strinsert/plugin.js?t=KA9B
ckeditor.js:258 Uncaught Error: [CKEDITOR.resourceManager.load] Resource name "strinsert" was not found at "https://cdn.ckeditor.com/4.15.1/standard-all/plugins/strinsert/plugin.js?t=KA9B".
at window.CKEDITOR.window.CKEDITOR.dom.CKEDITOR.resourceManager.<anonymous> (ckeditor.js:258)
at n (ckeditor.js:253)
at Array.v (ckeditor.js:254)
at y (ckeditor.js:254)
at HTMLScriptElement.CKEDITOR.env.ie.g.$.onerror (ckeditor.js:255)
Please suggest how can I add "strinsert" custom plugin inside ckeditor4-react text editor.
Is there a solution to extend the KeyMap of the ItemSelector?
I would like to add a keymap(like pageUp and pageDown keyEvent in itemselector) that when I press the letter 'A-Z' will take me to the item that starts with the letter pressed and select it.
You can use the following override (fiddle sample) to achieve it. It will not work correctly on view sore reload. And you will have to define the record search record field. In case of complicated view templates you can remove hardcoded search function and use it as a setting.
Ext.define('overrides.view.NavigationModel', {
override: 'Ext.view.NavigationModel',
searchRecordField: false,
initKeyNav: function (view) {
var me = this;
// Drive the KeyNav off the View's itemkeydown event so that beforeitemkeydown listeners may veto.
// By default KeyNav uses defaultEventAction: 'stopEvent', and this is required for movement keys
// which by default affect scrolling.
var keyNavConfig = {
target: view,
ignoreInputFields: true,
eventName: 'itemkeydown',
defaultEventAction: 'stopEvent',
processEvent: me.processViewEvent,
up: me.onKeyUp,
down: me.onKeyDown,
right: me.onKeyRight,
left: me.onKeyLeft,
pageDown: me.onKeyPageDown,
pageUp: me.onKeyPageUp,
home: me.onKeyHome,
end: me.onKeyEnd,
space: me.onKeySpace,
enter: me.onKeyEnter,
A: {
ctrl: true,
// Need a separate function because we don't want the key
// events passed on to selectAll (causes event suppression).
handler: me.onSelectAllKeyPress
},
F: me.onAlphabetKeyPress,
scope: me
};
if(this.view.searchRecordField) {
keyNavConfig = Ext.Object.merge(keyNavConfig, this.getAdditionalKeyNav());
}
me.keyNav = new Ext.util.KeyNav(keyNavConfig);
},
getAdditionalKeyNav: function() {
var keyNav = {};
this.view.getStore().each(function(record) {
var firstLetter = record.get(this.view.searchRecordField)[0].toUpperCase();
if(!keyNav[firstLetter]) {
keyNav[firstLetter] = this.onAlphabetKeyPress
}
}, this);
return keyNav;
},
onAlphabetKeyPress: function(keyEvent) {
const key = keyEvent.event.key;
var foundRecordIndex = this.view.getStore().findBy(function(record) {
return record.get('title').toLowerCase().indexOf(key) === 0;
}, this);
if(foundRecordIndex > -1) {
this.setPosition(foundRecordIndex, keyEvent);
}
}
});
Ext.application({
name: 'Fiddle',
launch: function () {
Ext.define('ListItem', {
extend: 'Ext.data.Model',
fields: [{
name: 'src',
type: 'string'
}, {
name: 'caption',
type: 'string'
}]
});
Ext.create('Ext.data.Store', {
id: 'ListItemsStore',
model: 'ListItem',
data: [{
title: "One"
}, {
title: "Two"
}, {
title: "Three"
}, {
title: "Four"
}, {
title: "Three"
}, ]
});
var imageTpl = new Ext.XTemplate(
'<tpl for=".">',
'<div style="margin-bottom: 10px;" class="thumb-wrap">',
'<span>{title}</span>',
'</div>',
'</tpl>'
);
Ext.create('Ext.view.View', {
store: Ext.data.StoreManager.lookup('ListItemsStore'),
tpl: imageTpl,
itemSelector: 'div.thumb-wrap',
emptyText: 'No images available',
// Search Record Field
searchRecordField: 'title',
renderTo: Ext.getBody()
});
}
});
need your help on the following problem. I have an Extjs application, and I need to get some data from database at the begining of all, I mean, before everything loads (mostly views). This is because this data I need to load will be used to create a form in a specific view.
So the question is: where should I put the function that gets the data and stores it in a global variable? I tried to put that function in launch function on app.js, but the behavior is weird (sometimes loads the data before the view renders, and sometimes does it after).
Please see above the code:
Function that gets the data (placed in App.js and invoked inside launch function):
cargarItemsEvaluacion: function()
{
AppGlobals.itemsCargarFormEvaluacion = [];
Ext.Ajax.request(
{
url : 'app/proxy.evaluacion.php',
method: 'GET',
params :{
act: 'getEvalItemsForm'
},
success : function(response)
{
var obj = Ext.decode(response.responseText);
Ext.each(obj.results, function(item)
{
//console.log(item);
var tempItem = {
xtype: 'container',
layout: 'anchor',
flex: 1,
items: [
{
//xtype: 'fieldset',
title: item.nombre,
items: [
{
id: 'item_'+item.id,
xtype: 'textfield',
fieldLabel: item.descripcion,
name: 'item_'+item.id,
allowBlank: false,
blankText: 'Este campo es obligatorio',
maskRe: /^[0-9]{1}/,
maxLenght: 2,
validateOnChange: 'true',
emptyText: 'Nota (1 al 10)',
submitEmptyText: false,
validator: function(value)
{
if(value.length>2 || value>10)
{
return 'Complete con nota del 1 al 10';
}
var stringPad=/^[1-9]{1}[0-9]{0,1}/;
if (!stringPad.test(value))
{
return 'Complete con nota del 1 al 10';
}
else
{
return true;
}
}
}]
}]
};
AppGlobals.itemsCargarFormEvaluacion.push(tempItem);
});//End Ext.each
if(AppGlobals.itemsCargarFormEvaluacion.length>0)
{
var itemObservacion = {
xtype: 'container',
layout: 'anchor',
flex: 1,
items: [
{
title: 'Observaciones',
items: [
/*{
id: 'ascenso',
xtype: 'checkbox',
boxLabel: 'Recomienda ascenso',
name: 'ascenso'
},*/
{
id: 'observaciones',
xtype: 'textareafield',
grow: true,
fieldLabel: 'Agregue observaciones adicionales si lo cree necesario',
name: 'observaciones',
labelAlign: 'top'
}
]
}]
};
AppGlobals.itemsCargarFormEvaluacion.push(itemObservacion);
}
console.log(AppGlobals.itemsCargarFormEvaluacion);
},
failure: function(response)
{
var obj = Ext.decode(response.responseText);
console.log("Entra al failure "+response.responseText);
//Ext.example.msg("Error", "No se pudo comprobar si es posible cargar al evaluador. Error: "+obj.error);
}
});//End Ext.ajax
}
And this is the initComponent function on the view where I need to generate the form using the data I got from the previous function:
initComponent: function(){
var formEvaluacion = this.items[0];
if(AppGlobals.itemsCargarFormEvaluacion.length==0)
{
console.log("Data still no loaded");
}
else
{
console.log("Data loaded!");
}
console.log(AppGlobals.itemsCargarFormEvaluacion);
Ext.apply(formEvaluacion,{items: AppGlobals.itemsCargarFormEvaluacion});
this.callParent(arguments);
}
As you can see, I check if the data loads before the view renders, or after. And sometimes does it before, sometimes after...I don't know what it depends on...
Any help will be appreciated.
Mauro
Think I found the solution. I placed cargarItemsEvaluacion function into init function on app.js. Seem to be working so far.
Thanks!
So the main question is: Does any one know how I need to change my calling method to be compatible with Sencha Touch 2?
Description:
I have a large Extjs application with a C# backend. I already have a mobile site with pages, but none of them require submitted form data. The trouble came when trying to create a login page.
On the desktop, using extjs and Ext.direct, there are login forms and they work fine, but the same coding patterns don't seem to work with Sencha Touch 2.
Ext.define('PF.view.phone.login.Form', {
extend: 'Ext.form.Panel',
alias: 'widget.phoneloginform',
requires: ['Ext.form.FieldSet', 'Ext.form.Password', 'Ext.Label', 'Ext.Img'],
autoheight: true,
initialize: function () {
this.build();
this.callParent();
Ext.apply(this, {
api: {
submit: LoginActionImpl.login
}
});
scope: this
},
config: {
title: 'Login',
items: [
{
xtype: 'label',
html: 'Client Login',
itemId: 'clientLoginLabel',
style: 'text-align: left; font-size: 1.1em',
margin: '10 0 20 0'
}, {
xtype: 'fieldset',
/*Temporary style*/
margin: '10 17% 10 17% ',
items: [
{
xtype: 'textfield',
itemId: 'loginUsername',
name: 'loginUsername',
label: 'Username',
required: true
}, {
xtype: 'passwordfield',
itemId: 'loginPassword',
name: 'loginPassword',
label: 'Password',
required: true
}, {
xtype: 'toolbar',
layout: {
pack: 'right'
},
ui: 'plain',
items: [{
xtype: 'button',
itemId: 'loginButton',
text: 'Login',
ui: 'confirm'
}, {
xtype: 'button',
itemId: 'clearButton',
text: 'Clear',
ui: 'decline'
}]
}
]
}
]
},
build: function () {
this.down('#clearButton').setHandler(this.clear);
this.down('#loginButton').setHandler(this.login);
},
clear: function (btn, evt) {
btn.up('phoneloginform').reset();
},
login: function (btn, evt) {
/* Need help here */
/* Below is what would normally be used in the rest of the application */
this.submit({
success: this.onLoginSuccess,
failure: function (form, action) {
this.onLoginFailure(action.result);
},
scope: this
});
},
onLoginSuccess: function (arguments) {
Ext.dispatch('login/success');
},
onLoginFailure: function (result) {
// Here we need to check the actual results to determine why the login failed.
//
// A return code of -2 indicates account locked - otherwise we just assume an invalid attempt.
//
if (result.returnCode == -2) {
this.getComponent("loginUsername").markInvalid(t('ptl_mbl_user_status_locked_password'));
this.getComponent("loginUsername").markInvalid(t('ptl_mbl_user_status_locked_password'));
}
else {
this.getComponent("loginUsername").markInvalid(t('wms_username_password_incorrect_error'));
this.getComponent("loginPassword").markInvalid(t('wms_username_password_incorrect_error'));
}
Ext.dispatch('login/fail', result.returnCode);
},
getUsername: function () {
if (this.username) {
this.username = this.getValues()['#loginUsername'];
}
},
getPassword: function () {
if (this.password) {
this.password = this.getValues()['#loginPassword'];
}
}
});
The method of the C# method is:
[DirectMethodForm]
public JObject login(HttpRequest request)
{
String username = request["loginUsername"];
String password = request["loginPassword"];
this.setDB(request["db"]);
int loginReturnCode = this.getUserDetailsService().login(username, password, this.getDB(), true);
JObject jsonObject;
if (loginReturnCode == 0)
{
jsonObject = new JObject(
new JProperty("loginUsername", username),
new JProperty("loginPassword", password),
new JProperty("db", this.getDB()),
new JProperty("success", true));
}
else
{
jsonObject = new JObject(
new JProperty("errors", new JArray(new[] { loginReturnCode.ToString() })),
new JProperty("returnCode", loginReturnCode),
new JProperty("failed", true));
}
return jsonObject;
}
and what I'm trying to reuse so that can't be changed.
Stepping through the code in the browser, the issue comes during the "urlAppend" method in the "sencha-touch-all.js" file where the "url" parameter is null, so the call never reaches the C# code.
urlAppend : function(url, string) {
if (!Ext.isEmpty(string)) {
return url + (url.indexOf('?') === -1 ? '?' : '&') + string;
}
return url;
},
However, I've never needed to set that variable before, in using Ext.direct. I don't have a separate web service, so actual web service calls are not available.
Thanks in advance.
I want to call button click in textfield enter function.
items: [
{
xtype: 'form',
id: 'myForm',
items: [
{
xtype: 'textfield',
id: 'myTextField',
listeners: {
specialkey: function(f,e){
if(e.getKey() == e.ENTER){
console.log('Spacial Key = Enter'); // It's working
// But i wanna click btnSearch button click event
}
}
}
}
],
buttons: [
{
text: 'Search',
id: 'btnSearch',
handlers: function(){
// bla bla
// bla bla
// ...
}
}
]
}
]
var myform = Ext.getCmp('myForm');
myForm.getForm().submit()
It's working but btnSubmit.click function not working
this code working :
{
fieldLabel : 'Password',
name : 'j_password',
inputType : 'password',
allowBlank : false,
listeners : {
'render' : function(cmp) {
cmp.getEl().on('keypress', function(e) {
if (e.getKey() == e.ENTER) {
submitform();
}
});
}
}
}
It will be easier to create a method like doSearch() and call this method from both handlers.
Depending on you scope you can try this:
Ext.getCmp("btnSearch").handler.call(Ext.getCmp("btnSearch").scope);
Ext.getCmp('btnSearch').focus();
I Dont Think It But Its Working For Me :)
Thanks For All