The listener and callback in Ext - javascript

I'm new in Ext, I see some codes in Ext.onReady(...)
tabItems.push({
id : 'schema-${form.schema.id}',
title : '${form.description}',
tabTip : '${form.description}',
tooltipType: 'title',
xtype : 'ttpanel',
executeScripts : true,
listeners : { load : initObjs, unload : unloadObjs, activate : ... },
autoLoad : { url : 'selection.do',
params : ...,
scripts : true,
callback : cb1
}
}
);
My question is, of:
"load:initObjs",
"callback:cb1",
page is rendered and user can operate it,
which of these three runs first? Why?
Thanks a million!

Related

How come my ExtJS 5 panel cannot resolve a show listener via it's VC? W/ Fiddle

ExtJS 5.1.3 - I'm slightly baffled that a simple Panel cannot resolve its VC on 'show' event. The attached fiddle will work - it has a panel with VC. Click the button to see the VC correctly resolved.
If you un-comment the 'show' event however, the code will fail in the console because the function can't be found (Unable to dynamically resolve scope for "show" listener on mypanel-xxxx). Lots of my code works like this already, am I doing something stupid?
I've tried using add() instead of widget() in case it's some kind of MVC nesting issue but Ext just seeks the function in the wrong VC - the top-level VC applied to the viewport.
Any help very much appreciated. Thx
https://fiddle.sencha.com/#view/editor&fiddle/1kvd
Ext.define('Admin.view.TheController', {
extend : 'Ext.app.ViewController',
alias : 'controller.thecontroller',
doShowStuff : function() {
Ext.Msg.alert('SHOW STUFF!', 'yep, this works');
},
doOkStuff : function() {
Ext.Msg.alert('OK STUFF!', 'yep, this works');
}
});
Ext.define('Admin.view.Panel.MyPanel', {
extend : 'Ext.panel.Panel',
alias : 'widget.mypanel',
autoRender : true,
autoShow : true,
controller : 'thecontroller',
width : 200,
height : 200,
html : 'I am your panel',
buttons : [
{ text : 'OK', handler : 'doOkStuff', scope : 'controller' }
],
listeners : [
// This listener causes an error
//{ show : 'doShowStuff', scope : 'controller' },
]
});
Ext.widget('mypanel');
listeners: {
// This listener causes an error
show:{
fn: 'doShowStuff',
scope: 'controller'
}
}
here's the fiddle
Your listeners are misconfigured, they should be an object, not an array. Also, you should omit the scope, it will be automatically determined:
Ext.define('Admin.view.Panel.MyPanel', {
extend: 'Ext.panel.Panel',
alias: 'widget.mypanel',
autoShow: true,
controller: 'thecontroller',
width: 200,
height: 200,
html: 'I am your panel',
buttons: [{
text: 'OK',
handler: 'doOkStuff'
}],
listeners: {
show: 'doShowStuff'
}
});

Combobox store load after updating form with Model data

I noticed that there are a lot of ways to populate a form with data.
I want to do it the ExtJS4 MVC style.
However I now see something unwanted happening.
My form has a combobox tied to a store.
The store is filled after populating the form with the model data.
My view / form
Ext.define('WWT.view.settings.Form', {
extend : 'Ext.form.Panel',
alias : 'widget.settingsform',
title : 'WWT Instellingen',
bodyPadding : 5,
defaultType : 'textfield',
initComponent : function() {
var me = this;
me.dockedItems = me.buildToolbars();
me.items = me.buildItems();
me.callParent();
},
buildItems : function() {
var lovEdities = Ext.create('WWT.store.lov.Edities');
return [{
fieldLabel : 'Huidige Editie',
xtype : 'combo',
emptyText : 'Kies een Editie',
name : 'huidige_editie_id',
store : lovEdities,
queryMode : 'local',
displayField : 'naam',
valueField : 'id',
forceSelection : true
}, {fieldLabel : 'Scorebord Slogan',
name : 'scorebord_slogan_regel',
width: 200,
maxLength : 10
}, {
fieldLabel : 'Tijd Offset Scorebord',
name : 'scorebord_tijdoffset'
}];
},
buildToolbars : function() {
return [{
xtype : 'toolbar',
docked : 'top',
items : [{ xtype:'button',
text : 'Save',
iconCls : 'save-icon',
action : 'save'
}]
}];
}
});
My Controller
Ext.define('WWT.controller.settings.Settings', {
extend : 'Ext.app.Controller',
models : ['secretariaat.Settings'],
views : ['settings.Form'],
init : function() {
var me = this;
me.control({
'#settingsId button[action=save]' : {
click : me.save
},
'settingsform' : {
afterrender : function(view) {
Ext.ModelMgr
.getModel('WWT.model.secretariaat.Settings')
.load(1, {
success : function(record) {
view.loadRecord(record);
}
});
}
}
});
},
save : function() {
var form = this.container.down('form');
var model = this.getModel('settings.Settings').set(form.getForm()
.getValues());
model.save();
},
addContent : function() {
this.container.add({
id : 'settingsIDQ',
xtype : 'settingsform',
itemId : 'settingsId'
});
}
});
In my Chrome Network window, I can see that the store request is fired later.
Any thoughts on how to load the store before updating the form ?
I thought of doing it in the afterRender too, but I think that even then the order is not guaranteed.
Seemed that there was nothing wrongs with the (load) mechanism.
There was an issue in the data type of the ID field of the Combobox and the field which was part of the settings. Int vs String.
This caused the issue.
I get around the form loading issue in a few different ways.
If the store is used a lot throughout the application, I load the store early in the loading of the application by looking it up with Ext.getStore('my store name here') and then calling .load() during startup. If you want the store or stores to load only when you reach the form itself, I would hook the component's initialization in initComponent and then you can get the form's fields and with a for-loop can walk through the fields and initialize all stores with .load() before the form component accesses server data.
Here are my edits to your initComponent method. I haven't debugged this code, but it should work great for you.
initComponent() {
var me = this;
// this is where we will load all stores during init
var fields = me.getForm().getFields();
for (var i = 0; i < fields.length; i++) {
var store = fields[i].getStore();
if (store && !store.isLoaded()) {
store.load();
}
}
me.dockedItems = me.buildToolbars();
me.items = me.buildItems();
me.callParent();
},

Jquery plugin make it bind onclick

I have a jquery plugin which i have purchased from code canyon for social sharing.
I have it configured for single item sharing, however I wish to make it connected to multiple instances on a page.
<script>
$('a.shareplus').shareplus({
icons: "facebook,twitter,google",
height : '150px',
width : '150px',
shareurl : '#application.settings.websiteurl#/article/' + $(this).attr('data-href'),
displayTitle : true,
title : 'Share this item from',
sticker : false,
pin : false,
gplus : false,
tweets : false,
fbLikebox : false
});
</script>
This works perfectly for a single item that is shared on a webpage. Ive searched the documentation for this plugin, however I cant find any reference for it to be attached to multiple items on a single page.
What Im wondering is.. Im thinking about using the .bind() method to connect to it on click and using the data-href custom attribute to define the page for it to be connected to.
But this doesnt seem to work.
<script>
$('a.shareplus').bind('click',shareplus({
icons: "facebook,twitter,google",
height : '150px',
width : '150px',
shareurl : '#application.settings.websiteurl#/article/' + $(this).attr('data-href'),
displayTitle : true,
title : 'Share this item from',
sticker : false,
pin : false,
gplus : false,
tweets : false,
fbLikebox : false
});
})</script>
Im not too sure on how to connect the bind api to links that contain functions that have parameters so any help greatly appreciated
Try to write your code in document.ready() and use on() instead of bind() also use data() for data attributes like,
$(function(){
$('a.shareplus').on('click',function(){
$(this).shareplus({
icons: "facebook,twitter,google",
height : '150px',
width : '150px',
shareurl : '#application.settings.websiteurl#/article/'+$(this).data('href'),
displayTitle : true,
title : 'Share this item from',
sticker : false,
pin : false,
gplus : false,
tweets : false,
fbLikebox : false
});
});
});

jQuery dataTables and selecting a row

I am trying to get a jQuery dataTable to behave in such a way that a user can select a row and then click a button (located elsewhere on the page, but not on the table or in it) and have a JS alert pop up.
Here is my dataTable:
$("#my-datatable").dataTable( {
"bProcessing" : true,
// Commenting out next line
//"sDom" : 't',
"sAjaxSource" : "some/url/on/my/server",
"sAjaxDataProp" : "",
"bDestroy" : true,
"fnServerData" : function(sSource, aoData, fnCallback) {
aoData.push({
"name" : "asking",
"value" : "yes"
});
request = $.ajax({
"dataType" : "json",
"type" : "GET",
"url" : sSource,
"data" : aoData,
"success" : fnCallback
});
},
"aoColumns" : [
{
"mDataProp" : "name"
},
{
"mDataProp" : "expr"
},
{
"mDataProp" : "seq"
}
]
});
Here is my button:
<div id="bam-btn-div">
<input type="button" id="bam-btn" value="BAM!" onclick="bam();"/>
</div>
When the user selects a row in the dataTable, and then clicks the button, I want the following function called:
function bam() {
alert("Deleting the selected row");
// Delete the selected row in the dataTable
}
Finally, the HTML table that the jQuery dataTable is attempting to populate:
<div id="datatable-div">
<table id="optconfig-datatable">
<thead>
<tr>
<th>Name</th>
<th>Expression</th>
<th>Sequence</th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
I tried to follow the example here but couldn't get anything to work. Can anybody spot what configurations I need to add (to the dataTable and/or otherwise)? Thanks in advance!
You are using jQuery, you might as well stay on track.
$('#bam-btn').on('click', function(){
alert("BAM!");
});
On a side note, ID's must be unique, but I'm sure you know that, so make sure you're not trying to re-use the same ID over and over.
Moreover, if this element is added into the DOM after .ready() execution, you'll need to attach the event handler to a static parent element so it may delegate the click event properly.
$(document).on('click', '#bam-btn', function(){
alert("BAM");
});
I'll leave the above in place, I don't like to delete entire portions of my answer as you never know who may find it helpful in the future
First, we need to create a variable that's available to all scopes of all functions. This way, we can reference the variable to get a hold of the element we want to remove.
We should place this variable outside of the document ready function
var theRow = '';
$(document).ready(function(){
//existing code here
});
Now that we have a 'global scope' variable prepared, we can modify it and access it anytime.
var theRow = '';
$(document).ready(function(){
$('tr').click(function(){
//we need to store a unique piece of information about this row.
//Without much to go on, I'm going to rely on the index.
theRow = $(this).index();
});
$('#bam-btn').click(function(){
$('tr').eq(theRow).remove();
});
});​
And here is your decent working jsFiddle as an example
For future users, and anyone else whom may find this useful
The :eq() selector provided by jQuery cannot leverage .querySelectorAll() to gain a decently large performance boost. Because of this, and for the time being, you should always use .eq() over :eq().
Please check that your:
function bam() {
alert("BAM!");
}
Is not in this statement:
$(document).ready(function() {
// STATEMENT
});
If your function is in the $(document).ready(), that means it's available only in that scope, in that particular function().
Move your code above or below the $(document).ready() statement, and your onclick event handler in your button will be able to find it and invoke it.
To delete a specific element from your data-table, try with this JavaScript:
$(document).ready(function() {
var oTable = $("#my-datatable").dataTable( {
"bProcessing" : true,
// Commenting out next line
//"sDom" : 't',
"sAjaxSource" : "some/url/on/my/server",
"sAjaxDataProp" : "",
"bDestroy" : true,
"fnServerData" : function(sSource, aoData, fnCallback) {
aoData.push({
"name" : "asking",
"value" : "yes"
});
request = $.ajax({
"dataType" : "json",
"type" : "GET",
"url" : sSource,
"data" : aoData,
"success" : fnCallback
});
},
"aoColumns" : [
{
"mDataProp" : "name"
},
{
"mDataProp" : "expr"
},
{
"mDataProp" : "seq"
}
]
});$("#my-datatable").dataTable( {
"bProcessing" : true,
// Commenting out next line
//"sDom" : 't',
"sAjaxSource" : "some/url/on/my/server",
"sAjaxDataProp" : "",
"bDestroy" : true,
"fnServerData" : function(sSource, aoData, fnCallback) {
aoData.push({
"name" : "asking",
"value" : "yes"
});
request = $.ajax({
"dataType" : "json",
"type" : "GET",
"url" : sSource,
"data" : aoData,
"success" : fnCallback
});
},
"aoColumns" : [
{
"mDataProp" : "name"
},
{
"mDataProp" : "expr"
},
{
"mDataProp" : "seq"
}
]
});
$('button#bam-btn').on('click', function() {
var anSelected = fnGetSelected( oTable );
oTable.fnDeleteRow( anSelected[0] );
} );
});
I had a similar problem with a table with dynamic data load. Every time I was adding contents, the old nodes disappear, losing the events linked.
I solved the problem invoking a function after the data load:
function insertevents(table_id){
var oTable = jQuery('#'+tableid).dataTable( {"bRetrieve": true });
oTable.$('tr').click(function(){
jQuery(this).toggleClass('row_selected');
} );
// Extra code here
}
It's important to add the "bRetrieve" parameter because the table was previously initialized.
Also, I've improved the functionality controlling keyboard events for accessibility:
oTable.$('tr').keyup( function(event) {
if (event.which == 13 || event.which == 32) {
event.preventDefault();
jQuery(this).toggleClass('row_selected');
}
} );
oTable.$('tr').keydown( function(event) {
if (event.which == 13 || event.which == 32) {
event.preventDefault(); // Desactivamos este efecto
}
});
This bunch of lines should replace the comment line of the first example. Now the table can be used from the keyboard, selecting with intro or space key. Remember to add a tabindex=0 to the elements inserted in the table, so we can navigate with the tab key.
http://editor.datatables.net/release/DataTables/extras/Editor/examples/index.html
This is similar to what you want.

How to stop Uploadify from displaying progress box

Just as the title says, I can't seem to get Uploadify to stop displaying the progress box during upload. Here is what I have:
$('#imageupload').uploadify({
'swf' : 'scripts/uploadify/uploadify.swf',
'uploader' : 'scripts/uploadify/uploadify.php',
// Put your options here
'buttonText' : 'Select Image',
'uploadLimit' : 999,
'overrideEvents' : ['onUploadProgress'],
'multi' : false,
'formData' : {'yourid' : '<?=#(int)$_SESSION['user']?>'},
'fileSizeLimit' : '2MB',
'fileTypeExts' : '*.gif; *.jpg; *.png; *.JPG; *jpeg',
'fileTypeDesc' : 'Image Files',
'onUploadStart' : function(file) {
$("#imageupload").uploadify("settings", "formData", {'yourid' : $(".userid").attr("id")});
$(".imageuploadbox #imagepercent").css("display", "inline");
},
'onUploadSuccess' : function(file) {
var currenttime = new Date();
$("img#yourprofilepic").attr("src", "images/artist_pictures/thumbs/artist_8.jpg?"+currenttime);
},
'onUploadProgress' : function(file, bytesUploaded, bytesTotal, totalBytesUploaded, totalBytesTotal) {
var percentcomp = (100*(totalBytesTotal/totalBytesUploaded)).toFixed(0);
$('.imageuploadbox #imagepercent #percentcomplete').html(percentcomp);
}
});
It's simple try this:
Remove link to uploadify css and then add this in your css:
.uploadifyQueue
{
display:none;
}
It seems like the names have changed, this one worked for me:
#upload_pc-queue{
display:none;
}

Categories