How to call a method from controller in extjs - extjs4

I have a bar column chart.. I want when I click on the column then the value of it will be shown and call another function where i will call the database thru ajax.
When I click on the column the value is shown but the 2nd part i.e. the 2nd function call is not done..
here is my controller code...
initializedEvents: false,
init: function() {
this.control({
'#barColumnChart': {
afterlayout: this.afterChartLayout
}
});
},
afterChartLayout: function(){
if(this.initializedEvents==true) return;
this.initializedEvents=true;
Ext.getCmp('barColumnChart').series.items[0].on('itemmousedown',function(obj){
var barData=obj.storeItem.data['source']+ ' &' + obj.storeItem.data['count'];
// I want to call the dataBaseCall function here
});
},
dataBaseCall: function(barData){
alert(barData);
}

Try this
afterChartLayout: function(){
var me = this;
if(this.initializedEvents==true) return;
this.initializedEvents=true;
Ext.getCmp('barColumnChart').series.items[0].on('itemmousedown',function(obj){
var barData=obj.storeItem.data['source']+ ' &' + obj.storeItem.data['count'];
me.dataBaseCall(barDat);
});
},
dataBaseCall: function(barData){
alert(barData);
}
You can also add the controller scope to the event but I personally prefer this.

Related

Jqgrid change nav properties on callback function

i try to change the navbar properties on a jqgrid in a callback function without succes.
The grid is display afeter user is chosing a period. Depend on either the period is open or close user can or cannot edit, add, delete rows. So the navbar need to change properties dynamically.
My code look like that:
$('#mygrid').jqGrid({
// some properties of my grid that works fine
pager : '#gridpager'
});
$("#mygrid").bind("jqGridLoadComplete",function(){
$.ajax({
url: 'checkifperiodopen.php',
data: {
$("#period").val()
},
success: function(data){
if(period==='open'){
jQuery("#mygrid").jqGrid('navGrid','#gridpager',{add:false,edit:false,del:true,search:true,refresh:true});
}
if(period==='close'){
jQuery("#mygrid").jqGrid('navGrid','#gridpager',{add:true,edit:true,del:true,search:true,refresh:true});
}
}
});
});
$('#validChossenPeriod').click(function () {
ajax call to get data on choosen period
success:function(data){
$("#mygrid").jqGrid('clearGridData');
$("#mygrid").jqGrid('setGridParam', { datatype: 'local'});
$("#mygrid").jqGrid('setGridParam', { data: data});
$("#mygrid").trigger('reloadGrid');
}
});
I finally found the answer by show or hide the div that include the navgrid button:
grid = $("#mygrid");
gid = $.jgrid.jqID(grid[0].id);
var $tdadd = $('#add_' + gid);
var $tdedit = $('#edit_' + gid);
var $tddel = $('#del_' + gid);
$("#mygrid").jqGrid('navGrid','#gridpager',{add:true,edit:true,del:true,search:true,refresh:true});
condition if false =
$tdadd.hide();
$tdedit.hide();
$tddel.hide();
if true =
$tdadd.show();
$tdedit.show();
$tddel.show();
Why so complex? There is a other clear way to do this
var view_buttons = true;
if(condition_to_hide) {
view_buttons = false;
}
$("#mygrid").jqGrid('navGrid','#gridpager', { add:view_buttons, edit:view_buttons, del:view_buttons, search:true, refresh:true});

dojox/checkedMultiSelect add option on top AS 'select all'

I am trying to populate the dojox/form/checkedMultiSelect with a top option named: 'select all'.
One way to do this is to use declare function to change the '_addOptionItem' function.
The problem is that this '_addOptionItem' function is using a declared object named: 'formCheckedMultiSelectMenuItem' inside the 'CheckedMultiSelect' widget, AND gives an error with: 'formCheckedMultiSelectMenuItem is not defined'.
How to fix this?
My JS code:
declare_CheckedMultiSelect: function(formCheckedMultiSelectItem){
return declare(CheckedMultiSelect, {
startup: function() {
this.inherited(arguments);
setTimeout(lang.hitch(this, function() {
this.dropDownButton.set("label", this.label);
}));
},
_addOptionItem: function(item){
var item;
if(this.dropDown){
item = new formCheckedMultiSelectMenuItem({
option: option,
parent: this.dropDownMenu
});
c(item)
this.dropDownMenu.addChild(item);
}else{
item = new formCheckedMultiSelectItem({
option: option,
parent: this
});
this.wrapperDiv.appendChild(item.domNode);
}
this.onAfterAddOptionItem(item, option);
}
});
}
Here is working prototype of what you are trying to achieve http://jsfiddle.net/894af/750/ please feel free to ask any follow up question. it is done in different way, but what I simply did is:
1) when create the mutliselect get each check box after creating using
onAfterAddOptionItem
2) listen to the select all checkbox and then override the onclick fucntion and then change the selection of all the checkboxs, based on the selection of the checkbox.
if(option.value == "SA"){
on(item, "click", function(evt){
var optionsToSelect = checkedMultiSelect.getOptions();
for(var i = 0 ; i < optionsToSelect.length;i++){
if(optionsToSelect[i].value == "SA"){
if(optionsToSelect[i].selected){
checkedMultiSelect.set("value",optionsToSelect);
}else{
checkedMultiSelect.set("value",[]);
}
}
}
});
}

Run assert inside event

I have the following:
casper.then(function addToBag(){
this.evaluate(function (){
//register sub method - then emit custom event
mns.msg.sub("/ajax/success/addToCart" + $("[name=productCode]").val(), function (response) {
casper.emit('addToCart.loaded');
});
//trigger add to cart click
$('.product-selection input[type=submit]').click();
});
});
The click trigger activates the emit, inside the event function:
casper.on("addToCart.loaded", function checkAddToCartResponse(){
console.log("Added");
test.assert(true,'Add to cart successful');
}),
However, it doesn't seem to run - is this the correct way of running a test when an event has finished?
The event is not emitted because there is no casper instance inside the page context (inside the evaluate context).
You would need to set some flag that the event was emitted.
casper.then(function addToBag(){
this.evaluate(function (){
//register sub method - then emit custom event
window.casperEventEmitted = null;
mns.msg.sub("/ajax/success/addToCart" + $("[name=productCode]").val(), function (response) {
window.casperEventEmitted = 'addToCart.loaded';
});
//trigger add to cart click
$('.product-selection input[type=submit]').click();
});
});
// wait here
and then wait for the event to be set
var timeout = 10000; // msec, some sensible timeout for your event
casper.waitFor(function check() {
return this.getGlobal('casperEventEmitted') == 'addToCart.loaded';
}, function then() {
return this.evaluate(function() {
window.casperEventEmitted = null; // reset for next time
});
this.test.pass("Event triggered");
}, function onTimeout(){
this.test.fail("Event triggered");
}, timeout);
Of course it would be nicer to manage the events in a queue and not as a single string.
The good thing is that there is no break out from the control flow as it would happen with a custom event like in the case of the other answer.
Use inside the evaluate callback:
console.log("casper-event:add:[1234]");
then can do it like this (not tested):
casper.on('remote.message', function(msg) {
if(msg.indexOf("casper-event:" == 0))
{
var event = msg.replace(/^casper-event:/, '').replace(/:.*$/, '');
var result = JSON.parse(msg.replace(/^casper-event:.*?:/, ''));
this.emit(event, result);
}
});
casper.on('add'........

this.store.create wont fire inside ajax call

I simply am trying to update local storage but inside the Ext.Ajax.request I cant call this.store.create(). How do I call the this.store.create function inside the success: area of the Ajax call. Many thanks for your help.
login: function(params) {
params.record.set(params.data);
var errors = params.record.validate();
if (errors.isValid()) {
var myMask = new Ext.LoadMask(Ext.getBody(), {msg:"Please wait..."});
myMask.show();
//now check if this login exists
Ext.Ajax.request({
url: '../../ajax/login.php',
method: 'GET',
params: params.data,
form: 'loginForm',
success: function(response, opts) {
var obj = Ext.decode(response.responseText);
myMask.hide();
//success they exist show the page
if(obj.success == 1){
//this doesn't work below
this.store.create(params.data);
this.index();
}
else{
Ext.Msg.alert('Incorrect Login');
}
},
failure: function(response, opts) {
alert('server-side failure with status code ' + response.status);
myMask.hide();
}
});
}
else {
params.form.showErrors(errors);
}
},
In Javascript, 'this' keyword changes its meaning with the context it appears in.
When used in a method of an object, 'this' refers to the object the method immediately belong to. In your case, it refers to the argument you passed to Ext.Ajax.request.
To work around this, you need to keep an reference of the upper level 'this' in order to access its 'store' property in an inner context. Specifically, it looks like this:
var me = this,
....;
Ext.Ajax.Request({
...
success: function(response, opts) {
var obj = Ext.decode(response.responseText);
myMask.hide();
//success they exist show the page
if(obj.success == 1){
me.store.create(params.data);
this.index();
}
else{
Ext.Msg.alert('Incorrect Login');
}
},
});

My Dijit DateTimeCombo widget doesn't send selected value on form submission

i need to create a Dojo widget that lets users specify date & time. i found a sample implementation attached to an entry in the Dojo bug tracker. It looks nice and mostly works, but when i submit the form, the value sent by the client is not the user-selected value but the value sent from the server.
What changes do i need to make to get the widget to submit the date & time value?
Sample usage is to render a JSP with basic HTML tags (form & input), then
dojo.addOnLoad a function which selects the basic elements by ID, adds dojoType
attribute, and dojo.parser.parse()-es the page.
Thanks in advance.
The widget is implemented in two files. The application uses Dojo 1.3.
File 1: DateTimeCombo.js
dojo.provide("dojox.form.DateTimeCombo");
dojo.require("dojox.form._DateTimeCombo");
dojo.require("dijit.form._DateTimeTextBox");
dojo.declare(
"dojox.form.DateTimeCombo",
dijit.form._DateTimeTextBox,
{
baseClass: "dojoxformDateTimeCombo dijitTextBox",
popupClass: "dojox.form._DateTimeCombo",
pickerPostOpen: "pickerPostOpen_fn",
_selector: 'date',
constructor: function (argv) {},
postMixInProperties: function()
{
dojo.mixin(this.constraints, {
/*
datePattern: 'MM/dd/yyyy HH:mm:ss',
timePattern: 'HH:mm:ss',
*/
datePattern: 'MM/dd/yyyy HH:mm',
timePattern: 'HH:mm',
clickableIncrement:'T00:15:00',
visibleIncrement:'T00:15:00',
visibleRange:'T01:00:00'
});
this.inherited(arguments);
},
_open: function ()
{
this.inherited(arguments);
if (this._picker!==null && (this.pickerPostOpen!==null && this.pickerPostOpen!==""))
{
if (this._picker.pickerPostOpen_fn!==null)
{
this._picker.pickerPostOpen_fn(this);
}
}
}
}
);
File 2: _DateTimeCombo.js
dojo.provide("dojox.form._DateTimeCombo");
dojo.require("dojo.date.stamp");
dojo.require("dijit._Widget");
dojo.require("dijit._Templated");
dojo.require("dijit._Calendar");
dojo.require("dijit.form.TimeTextBox");
dojo.require("dijit.form.Button");
dojo.declare("dojox.form._DateTimeCombo",
[dijit._Widget, dijit._Templated],
{
// invoked only if time picker is empty
defaultTime: function () {
var res= new Date();
res.setHours(0,0,0);
return res;
},
// id of this table below is the same as this.id
templateString:
" <table class=\"dojoxDateTimeCombo\" waiRole=\"presentation\">\
<tr class=\"dojoxTDComboCalendarContainer\">\
<td>\
<center><input dojoAttachPoint=\"calendar\" dojoType=\"dijit._Calendar\"></input></center>\
</td>\
</tr>\
<tr class=\"dojoxTDComboTimeTextBoxContainer\">\
<td>\
<center><input dojoAttachPoint=\"timePicker\" dojoType=\"dijit.form.TimeTextBox\"></input></center>\
</td>\
</tr>\
<tr><td><center><button dojoAttachPoint=\"ctButton\" dojoType=\"dijit.form.Button\">Ok</button></center></td></tr>\
</table>\
",
widgetsInTemplate: true,
constructor: function(arg) {},
postMixInProperties: function() {
this.inherited(arguments);
},
postCreate: function() {
this.inherited(arguments);
this.connect(this.ctButton, "onClick", "_onValueSelected");
},
// initialize pickers to calendar value
pickerPostOpen_fn: function (parent_inst) {
var parent_value = parent_inst.attr('value');
if (parent_value !== null) {
this.setValue(parent_value);
}
},
// expects a valid date object
setValue: function(value) {
if (value!==null) {
this.calendar.attr('value', value);
this.timePicker.attr('value', value);
}
},
// return a Date constructed date in calendar & time in time picker.
getValue: function() {
var value = this.calendar.attr('value');
var result=value;
if (this.timePicker.value !== null) {
if ((this.timePicker.value instanceof Date) === true) {
result.setHours(this.timePicker.value.getHours(),
this.timePicker.value.getMinutes(),
this.timePicker.value.getSeconds());
return result;
}
} else {
var defTime=this.defaultTime();
result.setHours(defTime.getHours(),
defTime.getMinutes(),
defTime.getSeconds());
return result;
}
},
_onValueSelected: function() {
var value = this.getValue();
this.onValueSelected(value);
},
onValueSelected: function(value) {}
});
It sounds like you want to use getValue. The convention now is to use _getValueAttr and then call attr("value") but I think that started in Dojo 1.4 and this code would need to be ported to use those new patterns.
Noe that value should be a Javascript Date object which would best be sent to the server using dojo.date.stamp.toISOString()
This began to work fine after i added a "serialize" method to DateTimeCombo.js which builds exactly the output format i want.
This seems odd to me, since there is already a serialize implementation in _DateTimeTextBox.js that should output the value in the required ISO format.