Backbone click in view triggers all it's events - backbone.js

I'm developing an app where I have a backbone collection view which renders child item views in a loop:
# Collection view:
class Newgvbtool.Views.ProductTypesIndex extends Backbone.View
template: JST['product_types/index']
tagName: 'section'
events: ->
'click .new-item': #newItem
initialize: (options)->
#company_id = options.company_id
Newgvbtool.vent.on 'product_types_index:add:model', #addToCollection
Newgvbtool.vent.on 'product_types_index:edit:model', #editModel
#collection.on 'reset', #render
#collection.on 'add', #appendItem
render: =>
$(#el).html #template()
#collection.each #appendItem
#
newItem: (e) =>
e.preventDefault()
#showForm null
showForm: (model) =>
if #editView? then #editView.remove()
#editView = new Newgvbtool.Views.ProductTypeEdit model: model, company_id: #company_id
$(#editView.render().el).dialog(
show:
title: 'Product type'
effect: 'drop'
direction: "up"
hide: "fade"
autoOpen: true
modal: true
draggable: false
minWidth: 400
height: "auto"
resizable: false
)
appendItem: (model)=>
view = new Newgvbtool.Views.ProductType model: model
$('tbody').append(view.render().el) unless $('#product-types tbody').find("tr[data-id=#{model.id}]").length
addToCollection: (model) =>
#collection.update model
model.trigger('highlight')
$(#editView.el).dialog 'close'
editModel: (model) =>
#showForm model
# Item view
class Newgvbtool.Views.ProductType extends Backbone.View
template: JST['product_types/product_type']
tagName: 'tr'
events:
'click .delete-item': 'deleteItem'
'click .edit-item': 'editItem'
initialize: (options)->
#model.on 'highlight', #highlight
#model.on 'change', #render
render: =>
$(#el).attr('data-id', #model.get('id')).html #template( model: #model)
#
highlight: =>
#$('td').effect 'highlight', 1000
deleteItem: =>
if confirm "Are you sure?"
#model.destroy wait: true
$(#el).remove()
editItem: =>
Newgvbtool.vent.trigger "product_types_index:edit:model", #model
This is the template I use to render each item:
%td
= #model.get 'name'
%td
= #model.get 'description'
%td.opts
%a.edit-item{ href: '#' }
%span.icon-edit
%a.delete-item{ href: '#' }
%span.icon-remove-sign
The thing is that every time a click an item, both the edit and delete item events are triggered.
What am I doing wrong?
Thanks in advance!

The error was the way I was adding the items views to the collection view.
I was doing it this way:
$('tbody').append(view.render().el)
And there was not getting right the reference for the delegation of events, so I I just added the # (or this) and now it works like a charm
#$('tbody').append(view.render().el)

Related

How to solve this error "Uncaught TypeError: Cannot call method 'getForm' of undefined "

I tried to add edit button functionality in grid panel. I want to open an edit window on edit button click for updating grid row record using Ext Window Form which contains fields like (Shift Name, Time, Total, Requirement, Note). The window form is created, but the row values that I have selected in grid are not set in form fields.
I tried to use this code:
Ext.getCmp('shiftWindow').getForm().setValues(selection[0].data);
but it's giving the following error
Uncaught TypeError: Cannot call method 'getForm' of undefined
Here is my code:
var shiftWindow = Ext.create('Ext.window.Window', {
title: 'Edit Shift',
resizable: false,
id: 'shiftwindow',
width: 465, //bodyPadding: 5, modal: true, store: shiftStorePlanner,
items: {
xtype: 'form',
id: 'idFormShift',
bodyPadding: 10,
items: shiftViewModelPlannerData
},
buttons: [{
text: 'Save',
cls: 'planner-save-button',
overCls: 'planner-save-button-over',
handler: function () {
var wi = this.up('.window')
var form = Ext.getCmp('idFormShift');
if (form.isValid()) {
shiftTimemappingarray = [];
getShiftTime();
//this.up('.window').close();
}
}
}, {
text: 'Cancel',
handler: function () {
this.up('.window').close();
}
}]
});
var host1 = Ext.getCmp('plannershifteditor');
var selection = host1._shiftPlannerGrid.getSelectionModel().getSelection();
if (selection.length === 0) {
return;
}
selection[0].data.ShiftName = selection[0].data.ShiftName.replace('(ARCHIVED)', '').trim(); //if edit Archive record then text name show without (ARCHIVED)
//shiftWindow.getForm().setValues(selection[0].data);
Ext.getCmp('shiftWindow').getForm().setValues(selection[0].data);
//Ext.getCmp('shiftWindow').setValue(selection[0].data);
shiftWindow.show();
There's no getForm method in the window. You can get the form using shiftWindow.down('form'). Here's the snippet:
shiftWindow.down('form').form.setValues(selection[0].data)

ViewModel bind record phantom

I want to hide a checkbox depending on wheter a record is phantom. Trying to implement this using viewmodels, but it doesn't seem to work.
See below for the related code. I've left out unrelated code for brevity.
The binding of the viewModel to the view is working as expected. When I try to bind activeRecord.name to the title attribute 2-way data binding is working correctly.
Viewmodel
Ext.define('MyApp.view.content.ContentViewModel', {
extend: 'Ext.app.ViewModel',
alias: 'viewmodel.content',
data: {
activeRecord: null
}
});
Controller
var contentWindow = Ext.widget('content-details');
contentWindow.getViewModel().set('activeRecord', contentBlock);
View
viewmodel: 'content',
items: [
{
xtype: 'checkbox',
boxLabel: 'My checkbox',
bind: {
hidden: '{!activeRecord.phantom}'
}
}
]
We ended up using the following base class for a Model, which is more convenient rather than a formula in a ViewModel.
// Use your own name instead of BaseModel
Ext.define('BaseModel', {
extend: 'Ext.data.Model',
fields: [{
name: 'phantom',
persist: false,
convert: function (v, rec) {
var id = rec.data[rec.idProperty];
return !id || (Ext.isString(id) && id.indexOf(rec.entityName) == 0);
}
}],
commit: function (silent, modifiedFieldNames) {
this.data.phantom = false;
this.callParent(arguments);
}
});
Then you'll be able to use the binding you want
bind: {
hidden: '{!activeRecord.phantom}'
}
Try to use formulas:
data: {
rec: null,
callback: null
},
formulas: {
isNew: function (get) {
return !get('rec') || get('rec').phantom;
}
}
Then in your view:
bind: {
disabled: '{!isNew}'
},

How to customize the UriCell's render of BackGrid

I have the following
name: "id", // The key of the model attribute
label: "User Id", // The name to display in the header
editable: false, // By default every cell in a column is editable, but *ID* shouldn't be
cell: Backgrid.UriCell.extend({
orderSeparator: ''})
}, {
Using the Backgrid.UriCell has
href: formattedValue,
title: formattedValue**,
Is there any way that define href has "session" + formatedValue ? In other words, how to customize the UriCell so I can define href different from title?
Try this:
var UriCell = Backgrid.UriCell.extend({
render: function () {
this.$el.empty();
var rawValue = this.model.get(this.column.get("name"));
var formattedValue = this.formatter.fromRaw(rawValue, this.model);
var href = _.isFunction(this.column.get("href")) ? this.column.get('href')(rawValue, formattedValue, this.model) : this.column.get('href');
this.$el.append($("<a>", {
tabIndex: -1,
href: href || rawValue,
title: this.title || formattedValue,
target: this.target
}).text(formattedValue));
this.delegateEvents();
return this;
}
});
Then, you can write this:
name: "id",
label: "User Id",
editable: false,
cell: UriCell,
href: function(rawValue, formattedValue, model){
return "session" + formattedValue;
}

TypeError: item is null in EXTJS 4 when using tabpanel

I am newbie. I am working on EXTJS 4,need your help in solving this.
I am encountering an error
"TypeError: item is null
item.on(ename, fn, scope, options); ext-all-debug.js (line 13795)"
when clicking on the link, which calls the function doThis() and the tabpanel associated with function disappear. Below is the function for your reference.
function doThis()
{
var xxtabPanel = Ext.create('Ext.tab.Panel', {
renderTo : Ext.fly('content').update(""),
autoHeight:true,
id:'xxtabPanel',
tabHeight:200,
activeTab:0,
items : [ {
id:'tab1',
itemId:'Tab1',
frame:true,
title : 'Tab one Details',
items :item1 //FormPanel
}, {
id:'tab2',
frame:true,
itemId:'Tab2',
title : 'Tab two Details',
items:item2 //FormPanel
}, {
id:'tab3',
frame:true,
itemId:'Tab3',
title : 'Tab three Details',
items :item3 //FormPanel
} ],
listeners: {
'tabchange': function(tp, p) {
tp.doLayout();
}
}
});}
Thanks in advance..Looking forward to hear from you.

Yes/No buttons in Confirm box in Sencha touch

I have put a confirm box on the logout option of my application. Code for the same is as follows:
var abc = Ext.Msg.confirm('Confirm logout', 'Are you sure you want to logout?', function(e)
{
if(e == 'yes')
{
// logout code
}
}
);
No button of the confirm box is visible before the yes button.
How can I display Yes button before the No Button?
Any help is appreciated.
According to the sencha touch source code ( http://docs.sencha.com/touch/1-1/source/MessageBox.html#Ext-MessageBox-method-confirm )
YESNO is defined as "no, yes":
(function(){
var B = Ext.MessageBox;
Ext.apply(B, {
OK : {text : 'OK', itemId : 'ok', ui : 'action' },
CANCEL : {text : 'Cancel', itemId : 'cancel'},
YES : {text : 'Yes', itemId : 'yes', ui : 'action' },
NO : {text : 'No', itemId : 'no'},
// Add additional(localized) button configs here
// ICON CSS Constants
INFO : 'x-msgbox-info',
WARNING : 'x-msgbox-warning',
QUESTION : 'x-msgbox-question',
ERROR : 'x-msgbox-error'
});
Ext.apply(B, {
OKCANCEL : [B.CANCEL, B.OK],
YESNOCANCEL : [B.CANCEL, B.NO, B.YES],
YESNO : [B.NO, B.YES]
// Add additional button collections here
});
})();
You can use Ext.override to override this functionality in your own app:
Ext.override(Ext.MessageBox, {
YESNO: [Ext.MessageBox.YES, Ext.MessageBox.NO]
});
You can override like the below code in ST2.1, Can also implement localization in YES/NO buttons using this.
Ext.MessageBox.override({
confirm: function(title, message, fn, scope) {
return this.show({
title : title || null,
message : message || null,
buttons : [
{text: 'Yes', itemId: 'yes', ui: 'action'},
{text: 'No', itemId: 'no'}
],
promptConfig: false,
scope : scope,
fn: function() {
if (fn) {
fn.apply(scope, arguments);
}
}
});
}
});
It is Very easy Try this
Ext.Msg.confirm("Logout", "Are you Sure u want to LogOut?", function(btn){
if (btn == 'yes'){
Ext.Viewport.setActiveItem({xtype:"Home"}); // which page wants to redirect
}
});
I tried this, and works for me:
Try this solution:
<script type="text/javascript">
(function () {
Ext.override(Ext.MessageBox, {
buttonText: { yes: "Sí", no: "No", cancel: "Cancelar" }
});
})();
</script>
Ext.Msg.show({
title: '提示',
message: '是否继续?',
width: 300,
buttons: [
{text: '是', itemId: 'yes', ui: 'action'},
{text: '否', itemId: 'no'}
],
fn: function (buttonId) {
alert('You pressed the "' + buttonId + '" button.');
}
});

Resources