9/13/2016

[SVG] Horizontal Line not Visible in Chrome


<line
  x1="10" y1="1"
  x2="90" y2="1.0001" // hack: horizontal line in SVG not visible in Chrome
  stroke="#FF0000"
  strokeWidth="1"/>


One easy way to fix it is just make it not perfectly horizontal. Adding a little bit offset makes it visible.

SVG Path Percentage Units

  <svg width='100%' height='100%' viewBox="0 0 100 100" preserveAspectRatio="none" style='background-color: whitesmoke'>
   <path  stroke="#000" fill="none" d="M0,0 L50,50" />
  </svg>  
Using percentage in svg tag, then the element inside it will be in percentage unit.

7/02/2016

[React] Don't Use Loop Index as Component Key

var ResultList = React.createClass({
  getInitialState: function() {
    return {results:[{id:1,text:'hello'}]};
  }, 
  onclick: function() {
    this.setState( {results:[{id:1},{id:2}]} );
  }, 
  render: function() {
    return (
      <div> 
   <button onClick={this.onclick} >click me!</button>
      <ul>
        {this.state.results.map(function(result, i) {
           return <ResultItem result={result}/>;
        })}
      </ul>
      </div>
    );
  }
});

var ResultItem = React.createClass({
  getInitialState: function() {
    return {clicked:false};
  },
  onclick: function() {
    this.setState( {clicked: !this.state.clicked } );
  }, 
  render: function() {
    return (
      <li onClick={this.onclick}>{' [clicked state] =  ' + this.state.clicked}</li>
    );
  }
});

ReactDOM.render(<ResultList />, mountNode);
If you render a list of components in a loop, don't forget to add key attribute to each of the component or React will give you a warning message like: "Each child in an array should have a unique "key" prop. Check the render method of undefined. See http://fb.me/react-warning-keys for more information".
To solve this problem, many people may just make a loop index as component key as below. Well, this solution does make the warning message disappear. However, it's an anti-pattern and will make your stateful components have incorrect state.
{this.state.results.map(function(result, i) {
  return <ResultItem key={i} result={result}/>;
})}
React's diff algorithm will try to find the min steps to add, remove, and update component's state in O(n) time. When it detects the component's class name (i.e., ResultItem) is the same and have the same key, it assume the component instance is the same one. Therefore, React will not update this component's state. So when the button is clicked in ResultList, you may think the ResultItem's result props is changed, then ResultItem will be re-inializated with the initial state {clicked: false}. It's not true. Since React think the ResultItem with id = 1 is the old instance, the state still remains the old state.
The correct to add a key to component is just use the unique id in the database like:
{this.state.results.map(function(result, i) {
   return <ResultItem key={result.id} result={result}/>;
})}
It's noted that the key should be added to a component's props instead of added to the children's HTML. Otherwise, React's diff algorithm will not know the children component's id.
// WRONG!
var ResultItem = React.createClass({
  render: function() {
    return (
      <li key={this.props.result.id}></li>
    );
  }
});
Ref: https://facebook.github.io/react/docs/multiple-components.html#dynamic-children

[React] Don't Use Loop Index as Component Key

var ResultList = React.createClass({
  getInitialState: function() {
    return {results:[{id:1,text:'hello'}]};
  }, 
  onclick: function() {
    this.setState( {results:[{id:1},{id:2}]} );
  }, 
  render: function() {
    return (
      <div> 
   <button onClick={this.onclick} >click me!</button>
      <ul>
        {this.state.results.map(function(result, i) {
           return <ResultItem result={result}/>;
        })}
      </ul>
      </div>
    );
  }
});

var ResultItem = React.createClass({
  getInitialState: function() {
    return {clicked:false};
  },
  onclick: function() {
    this.setState( {clicked: !this.state.clicked } );
  }, 
  render: function() {
    return (
      <li onClick={this.onclick}>{' [clicked state] =  ' + this.state.clicked}</li>
    );
  }
});

ReactDOM.render(<ResultList />, mountNode);
If you render a list of components in a loop, don't forget to add key attribute to each of the component or React will give you a warning message like: "Each child in an array should have a unique "key" prop. Check the render method of undefined. See http://fb.me/react-warning-keys for more information".
To solve this problem, many people may just make a loop index as component key as below. Well, this solution does make the warning message disappear. However, it's an anti-pattern and will make your stateful components have incorrect state.
{this.state.results.map(function(result, i) {
  return <ResultItem key={i} result={result}/>;
})}
React's diff algorithm will try to find the min steps to add, remove, and update component's state in O(n) time. When it detects the component's class name (i.e., ResultItem) is the same and have the same key, it assumes the component instance is the same one. Therefore, React will not update this component's state.
So when the button is clicked in ResultList, you may think the ResultItem's result props is changed, then ResultItem will be re-inializated with the initial state {clicked: false}. It's not true. Since React think the ResultItem with id = 1 is the old instance, the state still remains the old one.
The correct to add a key to component is just use the unique id in the database like:
{this.state.results.map(function(result, i) {
   return <ResultItem key={result.id} result={result}/>;
})}
It's noted that the key should be added to a component's props instead of added to the children's HTML. Otherwise, React's diff algorithm will not know the children component's id.
// WRONG!
var ResultItem = React.createClass({
  render: function() {
    return (
      <li key={this.props.result.id}></li>
    );
  }
});

Ref: https://facebook.github.io/react/docs/multiple-components.html#dynamic-children

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.
  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);
  }

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