Disclaimer: ExtJS - intermediate level;
jQuery - beginner
I've looked for a solution for this but had not found anything yet.
I have both ExtJS and jQuery in one file and I want to be able to execute the jQuery right after the ExtJS is done building a page (is this even possible).
Example:
function renderPage(){
// ExtJS goes here
}
How do I call jQuery after renderPage() is completed?
I tried the following:
$(document).ready(function() {
$("tr").css("background-color", "yellow");
});
$(document).ready(function(renderPage) {
$("tr").css("background-color", "yellow");
});
function renderPage(){
// ExtJS goes here
// ...
$("tr").css("background-color", "yellow");
}
but it doesn't work. I assume it is because the ExtJS is not done rendering the page when jQuery is getting called and it is not finding anything to select.
Additional information:
I know my jQuery works and is connected to the library because I was able to select HTML elements that are rendered before any script ExtJS or jQuery script is run and modify their style.
Thanks!
Ext components fire an afterrender event that you can hook into, but you have to be careful here because it can fire more than once if you render more than once (which is easy to do accidentally). This is an example of a simple app that fires afterrender once for a panel.
Ext.application({
name : 'Fiddle',
launch : function() {
var panel = Ext.create('Ext.Panel',{
renderTo:Ext.getBody(),
title:'myPanel',
items: [
Ext.create('Ext.Button', {
text: 'Click me!!!!',
handler: function() {
alert('You clicked the button!');
}
}),
{
xtype:'toolbar',
items: [{text:'Button 1'}, {text:'Button 2'}],
listeners: {
afterrender: function () {
Ext.Msg.alert('Fiddle', 'done with ext rendering, do jQuery stuff');
}
}
}
]
});
}
});
sencha fiddle: https://fiddle.sencha.com/#fiddle/eqg
I would recommend not mixing these two libraries without a really good reason - Ext has virtually the same DOM helper functionality as jQuery - if you are just changing a class something like Ext.dom.Element.addCls might be more appropriate (http://docs-origin.sencha.com/extjs/4.2.2/#!/api/Ext.dom.Element)
Related
I added a listener in the code like:
listen: {
afterLayout: function(){
doSomething...
}
}
the function is to render the html tags. But it does not work when the page loaded. I need to force rendering the page like change the size of browser will it work. I wanna know why. "afterLayout" should work automatically after the page loaded right? Or do I miss something?
You are using a wrong config. Instead of listen: { use listeners: {
Here is an example for you: https://fiddle.sencha.com/#fiddle/16gu
Ext.application({
name : 'afterRender Test',
launch : function() {
Ext.create('Ext.container.Container', {
renderTo: Ext.getBody(),
listeners: {
afterRender: function() {
this.update('<div style="width:300px; background-color:red; padding:10px;">Added via afterRender listener</div>');
}
}
});
}
});
I think the event your searching is afterrender.
Afterlayout only fires when the window size change and not on the load.
afterrender event match after the layout of the interested component is loaded.
so you should try with this:
listen: {
afterrender: function(){
doSomething...
}
}
If you must call the same function in all the cases call it on afterrender and on afterlayout
I think your problem can solve viewport.
wrap your application in this component. viewport will listen to window size change and automatically re size it's child elements (your application)
I am designing a custom widget using DIJIT and DOJO 1.10.
Basically my custom widget needs to have some behavior like a button, so when user click on it something can happen. I need to make sure other developers can add custom code when onClick it is fired on that widget.
After reading this guide I understood that my custom widget should implement extension points. I have notice in the source code in DIJIT for Button.js and I see they using a special mixin called dijit._OnDijitClickMixin.
Below code for my widget, so far it works fine, but I would like to know:
Is extension point the right way? Does a better alternative exists?
Reading at the documentation I see the following code.
_onButtonClick: function( /*Event*/ e){
... // Trust me, _onClick calls this._onClick
},
_onClick: function( /*Event*/ e){
...
return this.onClick(e);
},
onClick: { // nothing here: the extension point!
}
My custom widget does not implement any of these functions and seems working fine.
Shall I include these functions? What is the reason for that?
Widget
define([
'dojo/_base/declare',
'dijit/_WidgetBase',
'dijit/_OnDijitClickMixin',
'dijit/_TemplatedMixin',
'dojo/text!./templates/template.html'
], function (
declare,
_WidgetBase,
_OnDijitClickMixin,
_TemplatedMixin,
template
) {
return declare([_WidgetBase, _TemplatedMixin, _OnDijitClickMixin], {
templateString: template
});
});
HTML template
<div data-dojo-attach-event="ondijitclick:onClick"> </div>
Initialize the widget
this._iconPage = new IconPages({
id: 'iconPage',
onClick: function () {
//do smt
}.bind(this)
}).placeAt('content');
What you have is fine as the onClick method is meant to be overwritten to hook into events. What you can also do is hook into your IconPages "click" event using dojo/on by doing something like this:
on(this._iconPage, "click", /*function here*/);
I'm not sure why I can't get the button element using my UI hash. This is what my Layout looks like:
Layout: App.Base.Objects.BaseLayout.extend({
// Rest of the code left out for brevity
ui: {
btnSave: "#btnSave"
},
events: {
"click #ui.btnSave": "onSave"
},
onInitialize: function () {
this.listenTo(App.vent, "DisableSaveButton", function(val) {
this.disableSaveButton(val);
},this);
},
disableSaveButton: function () {
this.ui.btnSave.prop("disabled",val).toggleClass("ui-state-disabled",val);
},
onSave: function () {
alert("saved!");
}
})
In VS2013, when my breakpoint hits the line inside disableSaveButton method, I entered $("#btnSave") into the Watch window and I was able to get the element back. I could tell because it had a length of 1. From this, I know the button is rendered. However, if I enter this.ui.btnSave into the Watch window, I would get an element with length of 0.
My BaseLayout object is basically a custom object extended from Marionette.Layout
Marionette version: 1.8.8
Any ideas why I can't find the button element using this.ui.btnSave?
Thanks in advance!
Got some help from a coworker and the issue might be because the element is out of scope. Basically, inside the Layout object, 'this' does not contain the element. We were able replace 'this.ui.btnSave' with '$("#btnSave",this.buttonset.el)' and that works fine. buttonset is the region that actually contains the html element.
This seems like an inconsistency because even though the ui hash didn't work, the click event utilizing the ui hash did work.
UPDATE 6/3/2015:
Another coworker of mine provided a better solution. Basically, in my Layout I use a display function to display my view. It looks something like this:
Layout: App.Base.Objects.BaseLayout.extend({
// Rest of the code left out for brevity
display: function() {
$(this.buttonset.el).html(_.template($("#buttonset-view").html(), {"viewType": viewType}));
}
})
Basically, I'm saying to set the html of my region, which is this.buttonset.el, to my template's html. As of now, my layout doesn't know any of the elements inside the region. It just contains a region which displays the elements. So there is some sort of disconnect between my layout and the elements in my region.
The correct solution, as opposed to my earlier workaround, is to simply add the following line of code at the end:
this.bindUIElements();
From Marionette Annotated Source:
This method binds the elements specified in the “ui” hash inside the
view’s code with the associated jQuery selectors.
So this final code looks like this:
Layout: App.Base.Objects.BaseLayout.extend({
// Rest of the code left out for brevity
display: function() {
$(this.buttonset.el).html(_.template($("#buttonset-view").html(), {"viewType": viewType}));
this.bindUIElements();
}
})
With this, I was able to finally able to retrieve my element using this.ui.btnSave.
What hook can I use in ember that will only run after all of the content has been loaded?
I'm using zurb foundation's top-bar fixed and once a view is rendered I want to do something like this to dynamically space my body:
$(window).load(function() {
$("body").css("padding-top", parseInt($(".top-bar").css("height")) - 2);
});
The closest solution I've found here is:
Ember.View.reopen({
didInsertElement : function(){
this._super();
Ember.run.scheduleOnce('afterRender', this, this.afterRenderEvent);
},
afterRenderEvent : function(){
// implement this hook in your own subclasses and run your jQuery logic there
}
});
This almost works except for the fact that all of the content is not yet loaded i.e. images have not yet been loaded and therefore calculation above is wrong.
Inside the afterRenderEvent you can use some jQuery logic that waits for the image to be fully loaded
afterRenderEvent : function(){
$(photo).bind('load',doSomething());
}
i have an custom widget in dojo. My Problem is to check some kind of access rules wich are passed to the widget.
if check the rules after the widget is fully loaded everything works fine. But i have to remove some text and buttons before it is displayed.
I've tryted the startup, and postcreate hook (-: is there something like "aftercreate" ?
The first solution I can think of is to begin with hiding the restricted elements and then remove them.
In css:
.hidden{ display: none }
In widget's template for all permissions-sensitive elements:
<div class="${permissionsSensitiveElementsClass}">...</div>
In widget's code:
permissionsSensitiveElementsClass: "",
postMixInProperties: function(){
if(!this.hasPermissions()){
this.permissionsSensitiveElementsClass = "hidden";
}
this.inherited(arguments);
},
startup: function(){
// remove elements if necessary
},
hasPermissions: function(){
// permissions check
},
The final rendering function would be startup(). For widgets which are initially hidden, startup gets called automatically when call is made to show(). dijit.layout.Container has 'addChild(widget)' functionality, which will fire widget.startup() when a/multiple child(ren) are added.
You would benifit from:
http://dojotoolkit.org/documentation/tutorials/1.6/understanding_widget/
Widget lifecycle:
([widget].constructor());
[widget].postscript();
[widget].create();
[widget].postMixinProperties();
[widget].buildRendering();
[widget].postCreate(); // this is the most important one!
[widget].startup();
The true answer to your question lies here;
dojo.declare("mydijit", ["dijit/_Widget"], {
startup: function() {
// call superclass functionality before applying hide on specific elements
this.inherited(arguments);
if(foo) dojo.destroy(this.fooNode);
if(bar) dojo.destroy(this.barNode);
},
onShow: function() {
if(foo.changed || bar.changed) {
// act upon it
}
}
}