Extjs Override makeButton - javascript

I have a problem with Ext Js 4.2.1. I want to override the makeButton function in Ext.window.MessageBox.
This is my code:
Ext.override(Ext.window.MessageBox,{
makeButton: function(btnIdx) {
var btnId = this.buttonIds[btnIdx];
var buttonIcons = {
ok: 'iewp-icon-ok',
yes: 'iewp-icon-ok',
no: 'iewp-icon-cancel',
cancel: 'iewp-icon-cancel'
};
return new Ext.button.Button(
{
handler : this.btnCallback,
itemId : btnId,
iconCls: buttonIcons[btnId],
scope : this,
text : this.buttonText[btnId],
minWidth : 75
});
}
});
Ext.override is called in the init function of my application and it works at that point for other overrides.
The change works, if I change the function directly in the ext-all-dev file line 127299, but not with an override.
Does anybody know why?

Related

Ext.window override destroy in child class on close button of window in parent class

I have a ext.window in my code which has the default save and close button. On close button click I am hiding the window:
Ext.define('MyPack.template.TemplateWindow', {
extend : 'Ext.Window',
id: 'templateEditorWindow',
closeAction: 'hide',
autoScroll: false,
createTemplateEditor : function() {
// some code
},
initComponent : function() {
this.createTemplateEditor();
Ext.applyIf(this, {
layout : 'border',
modal : true
});
this.items = [ this.templateEditor ];
this.buttons = [
{ text : '#{msgs.button_save}',
window : this,
handler : function () {
if(this.window.templateEditor.save()) {
this.window.hide();
}
}
},
{ text : '#{msgs.button_close}',
cls : 'secondaryBtn',
window : this,
handler : function( ){
this.window.hide();
}
}
];
this.callParent(arguments);
},
});
I have one another window which is extending above window.
Ext.define('MyPack.template.RestfulTemplateWindow', {
extend : 'MyPack.template.TemplateWindow',
createTemplateEditor : function() {
// some code
}
});
I am creating this child class. The window is created properly. But I want to override handler function of close button. On close it should destroy.
How can I override it?
You can define a closeAction on a window
closeAction : String The action to take when the close header tool is
clicked:
destroy :
remove the window from the DOM and destroy it and all descendant
Components. The window will not be available to be redisplayed via the
show method.
hide :
hide the window by setting visibility to hidden and applying negative
offsets. The window will be available to be redisplayed via the show
method. Note: This behavior has changed! setting does affect the close
method which will invoke the approriate closeAction.
Defaults to: 'destroy'
So there is no need to override anything.
Edit >> Remember to call close() not hide()!
{
text : '#{msgs.button_save}',
window : this,
handler : function () {
if(this.window.templateEditor.save()) {
this.window.close(); // call close!
}
}
},
{ text : '#{msgs.button_close}',
cls : 'secondaryBtn',
window : this,
handler : function( ){
this.window.close(); // call close!
}
}
Edit
Disclaimer: the following way is just a workaround
Ext.define('MyPack.template.RestfulTemplateWindow', {
extend : 'MyPack.template.TemplateWindow',
closeAction: 'destroy', // redefine th close action
initComponent: function() {
// all values set would be overrided by the parent
this.callParent(arguments);
// identify the buttons somehow
this.on('beforehide',function(w){w.close();return false;},this);
}
});

Hammer Js Not working with Backbone.js

I have problem in implementing touch events with backbone.js and hammer.js
I have tried implementing the touch in the conventional way i.e defining the touch events in "events" section.But it has not worked for me.
Please find my code below
define(['Backbone','underscore','Handlebars','Hammer'],function(Backbone,_,Handlebars,Hammer) {
//getting the type of device in a variable using "userAgent"
window.MOBILE = navigator.userAgent.match(/mobile/i);
var HeadderView = Backbone.View.extend(
{
el: 'body',
touchPrevents : false,
initialize: function()
{
this.el$ = $(this.el);
},
events: function() {//returning different functions based on the device
return MOBILE ?
{
'tap #headcontent': 'handleTap',
} :
{
'click #headcontent':'clickbackbone',
}
},
//declaring the corresponding functions
handleTap: function(){
alert("tap event");
},
clickbackbone:function(){
alert('backbone click');
},
render: function ()
{
//rendering the template and appending it to the page
var that = this;
require(['text!gaming/gameHeadder/headder.html'],function(HeaderTemplate){
var template = Handlebars.compile(HeaderTemplate);
var context = {title: "Tick Tack Toe", imageURL: "images/logo.jpg"}
var htmlTemplate = template(context);
that.el$.html( htmlTemplate);
});
},
});
return new HeadderView();
}
);
Can some one help me out and correct my code
This is not how Hammer works. Backbone knows nothing about HammerJS.
If you really want to use Backbone-style event delegation with Hammer, you might want to check out the backbone.hammer project.

More than one events are added to an inner view backbone?

So here I have two views addBook and showBooks , the idea is, as I click on a button it should add a book name and author to the DOM its an , and I should be able to click it. But the problem is for each element more than one event handlers are added. that is for each new inner view more than one click events are added, I am quite new in backbone and I am still in Dark
here is my code , first the outer view
var addBook = Backbone.View.extend({
el : $('#addbook'),
model : bookmodel,
template : _.template(addbookTemplate,{}),
initialize : function(val){
this.el.html(this.template);
bookcollection.bind('add', this.showOff)
},
render : function(){
},
events : {
'click #addbookbutton' : 'addHandler'
},
addHandler : function(){
var book = new this.model;
book.addValues($('#bookname').val(), $('#bookauthor').val());
bookcollection.add(book);
},
showOff : function(buk){
this.xx = new showval({model: buk});
$('#fatman').append((this.xx.render().el));
}
});
return addBook;
Now the second and inner view
var showbooks = Backbone.View.extend({
events : {
'click .individual' : 'deleteHandler'
},
initialize : function(values){
_.bindAll(this);
/*if(values){*/
//return this.template;
//}
//values = (values == "") ? {} : values;
this.el.append(this.template);
},
render : function(){
this.el = _.template(show, {name : "Max", author : "jk"});
this.delegateEvents();
return this;
},
deleteHandler : function(e){
alert("this kills me")
}
});
return showbooks;
Now here is the problem as I click the button is added to DOM button but for each new li one more alert is fired ... Help is highly appreciated , I know I am missing some crucial point .. !!
I have taken your code and changed it slightly. I have created 2 Backbone.View's, one as the container and one for book items. It's crude, but hopefully will give you an idea of where you have gone wrong. http://jsfiddle.net/cQEu2/

onClick event of Button inside DataGrid

Here's my DataGrid:
// $ is a reference to `this` as it lies in an anonymous function
$.grid = new DataGrid({
store : $.dataStore,
query : {id : "*"},
structure : [
{
noscroll : true,
cells : [{ name : "Recipe", field : 'name', width : '200px' }],
},
{
cells : [
[
{ name : 'ID#', field : 'id', width : '50px'},
{ name : 'Category', field : 'category', width : '100px'},
{ name : 'Status', field : 'status', width : '100px'},
{ name: "Actions", width : '200px', type: dojox.grid.cells._Widget, formatter : $._actionButtons}
]
] // end cells
}
]
}, $.targetNode)
$.grid.startup();
$.grid.on("RowClick", function(e){
console.log(this.getItem(e.rowIndex))
})
And my formatter object for the Actions cell:
_actionButtons : function(){
var _self = this;
var _args = arguments;
this.group = new Pane()
var full = new Button({
label: 'View Full',
style : { fontSize : '80%'},
onClick : function(){
try {
_self.grid.onRowClick.apply(this, arguments)
}catch(e){}
}
});
full._destroyOnRemove = true;
var edit = new Button({
label : 'Edit',
style : {fontSize: '80%'}
});
edit._destroyOnRemove = true;
construct.place(full.domNode, this.group.containerNode)
construct.place(edit.domNode, this.group.containerNode)
return this.group;
}
I'm trying to get access to the event object that would be passed by a normal onRowClick event on the DataGrid. As it sits now this kinda works, but on the on("RowClick"...) block I get multiple logs. Without the try...catch block I get an error as the rowIndex doesn't exist in e, then 2 more logs where it does exist.
This is the 4th or so idea I've had included pub/sub, emit(), etc. I have a feeling that the multiple logs are caused by the bubbling behavior (Button -> Row -> DataGrid or somesuch), but getting the onRowClick's event object to get passed into the Buttons created in the formatter seems impossible.
I just want to access the rowIndex (and other DataGrid-esque properties) from the Button widget's onClick event to process according to the button pressed.
Along the same lines, but here's what I came up with that seems to be working in a direction where what I'm envisioning will happen. Adjusted cell where the buttons will be:
{ name: "Actions", width : '200px', type: dojox.grid.cells._Widget, formatter :
function(){
return $._actionButtons.call($, arguments);
}
}
Adjusted onClick function in the returned Button widget:
_actionButtons : function(){
var _index = arguments[0][1],
_item = this.grid.getItem(_index)
_self = this;
// some code removed
onClick : function(){
console.log(_self.dataStore.getValue(_item, 'name'), "clicked")
}
}
I'll probably end up extending Button to handle this a bit better, but for now, voila!
Sometimes it just helps to write it down and put it out there for your brain to panic and figure out the solution before anyone else does :)
Minor update...
There is the formatterScope parameter for the DataGrid, but it applies to all formatter's and would therefore mess up anything requiring cell scope and not DataGrid scope. The above method allows me to access everything I need.

How do I set doubleClick function to call custom function in jqGrid

I have added a custom edit button control on the jqGrid navigator as follows:
jQuery("#grid").navButtonAdd('#pager',
{
caption:"Edit",
buttonicon:"ui-icon-pencil",
onClickButton: editSelectedRow,
position: "last",
title:"click to edit selected row",
cursor: "pointer",
id: "edit-row"
}
);
So that rather than use the default function: editGridRow, it uses my custom function editSelectedRow. However, I also want to add the doubleClick function to so that it calls editSelectedRow on doubleClick.
using the default editGridRow function works as such
ondblClickRow: function()
{
var rowid = jQuery("#grid").jqGrid('getGridParam','selrow');
jQuery(this).jqGrid('editGridRow', rowid);
}
However, when I replace the default editGridRow function with my default function editSelectedRow as such,
ondblClickRow: function()
{
var rowid = jQuery("#grid").jqGrid('getGridParam','selrow');
jQuery(this).jqGrid('editSelectedRow', rowid);
}
I get the following error within firebug:
uncaught exception: jqGrid - No such method: editSelectedRow
The function editSelectedRow however does exist and works with clicking the custom edit button. Please help, thanks.
UPDATE:
#Oleg: As requested here's the code defining method: editSelectedRow
function editSelectedRow(rowid)
{
var rowid = jQuery("#grid").jqGrid('getGridParam','selrow');
if( rowid != null )
{
var dialogId = '#edit-form-dialog';
var dialogTitle = 'Edit Customer';
$(dialogId).load('/customer/edit/id/' + rowid, function ()
{
$(this).dialog(
{
modal: false,
resizable: true,
minWidth: 650,
minHeight: 300,
height: $(window).height() * 0.95,
title: dialogTitle,
buttons:
{
"Save": function ()
{
var form = $('form', this);
$(form).submit();
$("#grid").trigger("reloadGrid");
},
"Cancel": function ()
{
$("#grid").trigger("reloadGrid");
$(this).dialog('close');
}
}
});
LaunchEditForm(this);
});
}
else
{
jQuery( "#dialogSelectRow" ).dialog();
}
return false;
}
#Oleg: Thanks, you advised against using a custom method editSelectedRow in place of method editGridRow. The reason I am using this is that my forms are Zend Forms and I need all the bells and whistles of Zend Form to be available. The server generates this form and it's loaded into a dialog form. If there's a way to still achieve this without resorting to my editSelectedRow custom method, I'd be glad to learn it. Thanks.
You question is pure JavaScript question.
If you define the function editSelectedRow as
function editSelectedRow(rowid)
{
...
}
you can call it as editSelectedRow(rowid) and not as jQuery(this).jqGrid('editSelectedRow', rowid);.
Another problem is that you use this inside of he body of editSelectedRow function. It's not correct. You can define editSelectedRow function in a little another way
var editSelectedRow = function (rowid) {
...
};
In the case editSelectedRow will be able to bind this to any value. To do this you need use another form of invocation of the function. Inside of ondblClickRow it will be
ondblClickRow: function () {
var rowid = jQuery("#grid").jqGrid('getGridParam','selrow');
editSelectedRow.call(this, rowid);
}
In the above example the first parameter of call is the value used as this inside of the function. We forward just the current this value forward to editSelectedRow. If we would use the form editSelectedRow(rowid); for the invocation of the function the value of this inside of function will be initialized to window object.
The usage of editSelectedRow inside of navButtonAdd can stay unchanged.

Categories