var css = 'body {color:red}';
var style = document.createElement('style');
style.setAttribute("type", "text/css");
var head = document.getElementsByTagName('head')[0];
head.appendChild(style);
if (style.styleSheet) { // IE
style.styleSheet.cssText = css;
} else { // modern browser
var node = document.createTextNode(css);
style.appendChild(node);
}
1/05/2016
Loading CSS Styleheet in IE8, E7, and IE6 Dynamically
Since innerHTML doesn't work in IE8 and below.
Here is a hack for inserting CSS Styleheet in IE8 using javascript programmatically.
10/21/2014
[ExtJS] Remove Fake Path in File Field Across Browsers
Here's an example for file uploader with Ext JS. Whenever users pick a file, the file field will fire a change event with the arguments (field, value).
Ext.create('Ext.form.Panel', {
title: 'Upload a Photo',
width: 400,
bodyPadding: 10,
frame: true,
renderTo: Ext.getBody(),
items: [{
xtype: 'filefield',
listeners: {
change: function(field, value) {
console.log('value', value);
}
}
}]
});
According to the document, the getValue method will return a value that is browser-dependent; some have just the file name, some have a full path, some use a fake path.
For example, in Chrome, the output in the snippet above is:
value C:\fakepath\myfile.txt
The same code in Firefox will print:
value myfile.txt
How if we just get want to get the file name instead of the fake path across browsers? That is, we intend to have the following output in all browsers.
value myfile.txt
All you have to do is just override the filefield class with the following code.
In Ext JS 5,
Ext.define('Ext.enhance.form.field.File', {
override: 'Ext.form.field.File',
onFileChange: function(button, e, value) {
this.duringFileSelect = true;
Ext.form.field.File.superclass.setValue.call(this, value.replace(/^.*(\\|\/|\:)/, ''));
delete this.duringFileSelect;
}
});
In Ext JS 4,
Ext.define('Ext.enhance.form.field.File', {
override: 'Ext.form.field.File',
onFileChange: function() {
this.lastValue = null;
Ext.form.field.File.superclass.setValue.call(this, this.fileInputEl.dom.value.replace(/^.*(\\|\/|\:)/, ''));
}
});
Please use Chrome to test this overriding in the fiddle.
10/19/2014
[JavaScript] function scope and block scope
In many languages such as C, C++, and Java, the scope is defined by a block. In the following Java example, the variable x in the inner scope is not accessible by outer scope.
for(int i=0;i<10;++i) {
int x = 1;
}
System.out.println(x); // error
However, in Javascript, scope is defined by a function.
In the following sample, variable x is defined in the loop block which doesn't create a new scope while variable y is defined in a function which create a new scope. So, The foo function is in inner scope and global window is in outer scope.
Since variable x is in the outer scope, the function foo is able to access it. And variable y is in the inner scope, we can't access it in outer scope (window).
var i;
for(i = 0; i < 10; ++i) {
var x = 1;
}
// function will create a new scope
function foo() {
var y = 1;
x++;
}
console.log('x', x); // 1
foo();
console.log('x', x); // 2
console.log('y', y); // Uncaught ReferenceError: y is not defined
10/16/2014
[ExtJS 5] Migrate from ComponentColumn to WidgetColumn
In Ext 4, we use componentcolumn to render Ext component in a grid cell.
{
dataIndex: 'age',
xtype: 'componentcolumn',
renderer: function(value, m, record) {
if (value < 30) {
return {
xtype: 'myWidget1';
};
} else {
return {
xtype: 'myWidget2';
};
}
}
}
In Ext 5, the built-in widgetcolumn have the same ability to do so. But the widgetcolumn have better rendering performance.
{
xtype: 'widgetcolumn',
widget: {
xtype: 'container',
},
onWidgetAttach: function(widget, record) {
var items = [];
if (record.get('age') < 30) {
items.push({
xtype: 'myWidget1'
})
} else {
items.push({
xtype: 'myWidget2'
})
}
widget.removeAll();
widget.add(items);
}
}
Note that onWidgetAttach() is a public but not documented method.
10/10/2014
[Javascript] Event Bubbling and Capturing Propagating Order
Problem
We have three elements in the DOM shown below. When users click on the element3, all of elements' click handler will be executed. But what's the order of executing handler?
<div class="element1">element1
<div class="element2">element2
<div class="element3">element3</div>
</div>
</div>
The W3C Event Bubbling and Capturing Propagating Order
According to W3C standard, there are two major phases for propagating event object.
Capturing phase:
Firstly, The event object will propagate through the target's ancestors from the Window to the target's parent (Note that target in this case is element3.)
Firstly, The event object will propagate through the target's ancestors from the Window to the target's parent (Note that target in this case is element3.)
Bubbling phase:
Then event object propagates through the target's ancestors in reverse order, starting with the target's parent and ending with the Window.
Then event object propagates through the target's ancestors in reverse order, starting with the target's parent and ending with the Window.

Event Bubbling and Capturing Propagating Order
So let's add some event listeners to print out the propagating order of event object. Before that, let's see the arguements of addEventListener.
/**
* @param {String} type The event type
* @param {Function} listener The event handler
* @param {Boolean} useCapture If True, use capturing. Otherwise, use bubbling.
*/
element.addEventListener(type, listener[, useCapture]);
The following code make all elements register a click event for both of bubbling and capturing. Note that registering an event for the same listener
doesn't affect the order of event object propagating.
var element1 = document.getElementsByClassName('element1')[0],
element2 = document.getElementsByClassName('element2')[0],
element3 = document.getElementsByClassName('element3')[0],
foo = function(e) { console.log(this.className); };
element1.addEventListener('click', foo); // bubbling
element1.addEventListener('click', foo, true); // capturing
element2.addEventListener('click', foo);
element2.addEventListener('click', foo, true);
element3.addEventListener('click', foo);
element3.addEventListener('click', foo, true);
When you click element3, it will show
element1 element2 element3 element3 element2 element1
As we expected, the event object will first propagate in capturing phase (top-down) and then bubbling phase (bottom-up).
By the way, you can stop the propagation by calling e.stopPropagation().
var stop = function(e) {
console.log('stop', this.className);
e.stopPropagation();
};
element1.addEventListener('click', foo);
element1.addEventListener('click', foo, true);
element2.addEventListener('click', stop); // Change handler to "stop"
element2.addEventListener('click', foo, true);
element3.addEventListener('click', foo);
element3.addEventListener('click', foo, true);
The output
element1 element2 element3 element3 stop element2
The Playground in JS fiddle.
10/09/2014
[ExtJS] Add Custom CSS Class to Grid Cell
You can make Ext JS 5 gird cell more pretty by applying twitter bootstrap.css to grid cell. It look like:
All you have to do is override the renderer function which returns a span element with bootstrap's label css class.
All you have to do is override the renderer function which returns a span element with bootstrap's label css class.
{
header: 'Status',
dataIndex: 'status',
width: 100,
renderer: function(value, meta, record) {
var cls;
if (value === 'Success') {
cls = 'label label-success';
} else if (value === 'Failure') {
cls = 'label label-important';
} else if (value === 'Processing') {
cls = 'label label-warning';
}
return Ext.String.format('<span class="{0}">{1}</span>', cls, value);
}
}
The code above is tested with Ext JS 5.0.1.
9/28/2014
[gulp] Minify Javascript Files and Add License Notice at Head
Suppose we have source file named "myApp.js" like
1) Create 'LICENSE' file in project. Note that version and build time are variables which will be replaced when we run gulp task.
1) Install nodeJS
2) Install gulp, the streaming build system.
var myApp = (function(){
var x = 1;
})();
We'd like to add license notice and build time at the head of minified file (i.e., "myApp-1.0.min.js") like
/**
* License Notice
* Version: 1.0
* Build: Sun, 28 Sep 2014 02:41:31 GMT
*/
var myApp=(function(){var x=1;})();
In this situation, we can use gulp to automate the process of minifying Javascript files.
1) Create 'LICENSE' file in project. Note that version and build time are variables which will be replaced when we run gulp task.
/** * License Notice * Version: <%= version %> * Build: <%= build %> */2) Create 'VERSION' file in the project like
1.03) Create gulpfile.js in the project.
var gulp = require('gulp'),
uglify = require("gulp-uglify"),
rename = require("gulp-rename"),
fs = require('fs'),
header = require("gulp-header");
var getLicense = function() {
return '' + fs.readFileSync('LICENSE');
};
var getVersion = function() {
return fs.readFileSync('VERSION');
};
gulp.task('minify-js', function() {
var version = getVersion(),
proudctionName = 'myApp-' + version + '.min.js',
dest = './dist',
src = './myApp.js';
gulp.src(src)
.pipe(rename(proudctionName))
.pipe(uglify())
.pipe(header(getLicense(), {
version: version,
build: (new Date()).toUTCString()
}))
.pipe(gulp.dest(dest));
});
4) After running the gulp task, the minified file will be at ./dist/myApp-1.0.min.js
gulp minify-jsIn case you haven't installed gulp, here is quick tips to setup.
1) Install nodeJS
2) Install gulp, the streaming build system.
$ npm install -g gulp $ npm install —-save-dev gulp3) Install gulp-uglify, gulp-rename, and gulp-header
$ npm install --save-dev gulp-uglify $ npm install --save-dev gulp-rename $ npm install --save-dev gulp-headerThis tutorial is based on this github project https://github.com/cwtuan/Locale.js. You can fork it to test if your setup work.
Labels:
gulp
,
Javascript
Subscribe to:
Posts
(
Atom
)