[~/srcPLgrado/csv(master)]$ pwd -P /Users/casiano/local/src/javascript/PLgrado/csv
Véase https://bitbucket.org/casiano/pl-grado-csv/src y https://github.com/crguezl/csv.
Véase Comma Separated Values en la Wikipedia:
A comma-separated values (CSV) file stores tabular data (numbers and text) in plain-text form. A CSV file consists of any number of records, separated by line breaks of some kind; each record consists of fields, separated by a comma. All records have an identical sequence of fields.
Véase la página en http://crguezl.github.io/csv/. Pruebe a dar como entrada cualquiera de estas dos
[~/srcPLgrado/csv(gh-pages)]$ cat input.txt "producto", "precio" "camisa", "4,3" "libro de O\"Reilly", "7,2"
[~/srcPLgrado/csv(gh-pages)]$ cat input2.txt "producto", "precio" "fecha" "camisa", "4,3", "14/01" "libro de O\"Reilly", "7,2" "13/02"
Pruebe también a dar alguna entrada errónea.
split
por las comas:
> x = '"earth",1,"moon",9.374' '"earth",1,"moon",9.374' > y = x.split(/,/) [ '"earth"', '1', '"moon"', '9.374' ]
Esta solución deja las comillas dobles en los campos entrecomillados.
Peor aún, los campos entrecomillados pueden contener comas, en cuyo
caso la división proporcionada por split
sería errónea:
> x = '"earth, mars",1,"moon, fobos",9.374' '"earth, mars",1,"moon, fobos",9.374' > y = x.split(/,/) [ '"earth', ' mars"', '1', '"moon', ' fobos"', '9.374' ]
La siguiente expresión regular reconoce cadenas de comillas dobles con secuencias de escape seguidas opcionalmente de una coma:
> x = '"earth, mars",1,"moon, fobos",9.374' '"earth, mars",1,"moon, fobos",9.374' > r = /"((?:[^"\\]|\\.)*)"\s*,?/g /"((?:[^"\\]|\\.)*)"\s*,?/g > w = x.match(r) [ '"earth, mars",', '"moon, fobos",' ]If your regular expression uses the
g
flag, you can use the exec
or match
methods
multiple times to find successive matches in the same string. When
you do so, the search starts at the substring of string specified by the
regular expression's lastIndex
property.
Javascript sub-matches stop working when the g
modifier is set:
> text = 'test test test test' 'test test test test' > text.match(/t(e)(s)t/) [ 'test', 'e', 's', index: 0, input: 'test test test test' ] > text.match(/t(e)(s)t/g) [ 'test', 'test', 'test', 'test' ]Sin embargo el método
exec
de las expresiones regulares si que
conserva las subexpresiones que casan con los paréntesis:
> r = /t(e)(s)t/g /t(e)(s)t/g > text = 'test test test test' 'test test test test' > while (m = r.exec(text)) { ... console.log(m); ... } [ 'test', 'e', 's', index: 0, input: 'test test test test' ] [ 'test', 'e', 's', index: 5, input: 'test test test test' ] [ 'test', 'e', 's', index: 10, input: 'test test test test' ] [ 'test', 'e', 's', index: 15, input: 'test test test test' ] undefinedAnother catch to remember is that
exec()
doesn't return the matches in
one big array: it keeps returning matches until it runs out, in which
case it returns null
.
Véase
Esta otra expresión regular /([^,]+),?|\s*,/
actúa de forma parecida al split
.
Reconoce secuencias no vacías de caracteres que no contienen comas seguidas opcionalmente
de una coma o bien una sóla coma (precedida opcionalmente de blancos):
> x = '"earth, mars",1,"moon, fobos",9.374' '"earth, mars",1,"moon, fobos",9.374' > r = /([^,]+),?|\s*,/g /([^,]+),?|\s*,/g > w = x.match(r) [ '"earth,', ' mars",', '1,', '"moon,', ' fobos",', '9.374' ]
La siguiente expresión regular es la unión de dos:
> x = '"earth, mars",1,"moon, fobos",9.374' '"earth, mars",1,"moon, fobos",9.374' > r = /\s*"((?:[^"\\]|\\.)*)"\s*,?|\s*([^,]+),?|\s*,/g /\s*"((?:[^"\\]|\\.)*)"\s*,?|\s*([^,]+),?|\s*,/g > w = x.match(r) [ '"earth, mars",', '1,', '"moon, fobos",', '9.374' ]El operador
|
trabaja en circuito corto:
> r = /(ba?)|(b)/ /(ba?)|(b)/ > r.exec("ba") [ 'ba', 'ba', undefined, index: 0, input: 'ba' ] > r = /(b)|(ba?)/ /(b)|(ba?)/ > r.exec("ba") [ 'b', 'b', undefined, index: 0, input: 'ba' ]
Si usamos exec
tenemos:
> x = '"earth, mars",1,"moon, fobos",9.374' '"earth, mars",1,"moon, fobos",9.374' > r = /\s*"((?:[^"\\]|\\.)*)"\s*,?|\s*([^,]+),?|\s*,/g /\s*"((?:[^"\\]|\\.)*)"\s*,?|\s*([^,]+),?|\s*,/g > while (m = r.exec(x)) { console.log(m); } [ '"earth, mars",', 'earth, mars', undefined, index: 0, input: '"earth, mars",1,"moon, fobos",9.374' ] [ '1,', undefined, '1', index: 14, input: '"earth, mars",1,"moon, fobos",9.374' ] [ '"moon, fobos",', 'moon, fobos', undefined, index: 16, input: '"earth, mars",1,"moon, fobos",9.374' ] [ '9.374', undefined, '9.374', index: 30, input: '"earth, mars",1,"moon, fobos",9.374' ] undefined
Es necesario tener en cuenta el caso de los campos vacíos, especialmente al principio y al final:
> w = ',"earth, mars",1,"moon,fobos", ,9.374,' ',"earth, mars",1,"moon,fobos", ,9.374,'Al analizar
w
debería haber un campo vacío al principio, uno en medio
y otro al final.
Para resolverlo hemos usado lookahead (^|,)(?=\s*(,|$))
que dice que una coma seguida de una coma o el final da lugar a un nuevo campo (y que si al comienzo de la cadena
hay una coma también se produce un nuevo campo):
> r /\s*"((?:[^"\\]|\\.)*)"\s*|\s*([^,]+)|(^|,)(?=\s*(,|$))/g > w.match(r) [ '', '"earth, mars"', '1', '"moon,fobos"', ',', ' ', '9.374', ',' ]
The RegExp
constructor creates a regular expression object for matching text with a pattern.
Literal and constructor notations are possible:
/pattern/flags; new RegExp(pattern [, flags]);
new RegExp("ab+c")
, provides runtime compilation of the regular
expression.
\
when included in a string) are
necessary. For example, the following are equivalent:
var re = /\w+/; var re = new RegExp("\\w+");
The exec()
method executes a search for a match in a specified string. Returns a result array, or null
.
If you are executing a match simply to find true
or false
,
use the RegExp.prototype.test()
method or the String.prototype.search()
method.
str.search(regexp)
If successful, search
returns the index of the regular expression inside
the string. Otherwise, it returns -1
.
When you want to know whether a pattern is found in a string use search
(similar to the regular expression test
method); for more information
(but slower execution) use match
(similar to the regular expression
exec
method).
The replace()
method returns a new string with some or all matches of
a pattern replaced by a replacement.
The pattern can be a string or a RegExp
,
and the replacement can be a string or a function to be called
for each match.
> re = /apples/gi /apples/gi > str = "Apples are round, and apples are juicy." 'Apples are round, and apples are juicy.' > newstr = str.replace(re, "oranges") 'oranges are round, and oranges are juicy.'
The replacement string can be a function to be invoked to create the
new substring (to put in place of the substring received from parameter
#1
). The arguments supplied to this function are:
Possible name | Supplied value |
match | The matched substring. (Corresponds to $& .) |
p1, p2, ... | The nth parenthesized submatch string, provided the first argument to replace was a RegExp object. (Corresponds to $1 , $2 , etc.)
For example, if /(\a+)(\b+)/ , was given, p1 is the match for
\a+ , and p2 for \b+ . |
offset | The offset of the matched substring within the total string being examined.
(For example, if the total string was abcd , and the
matched substring was bc , then this argument will
be 1 .) |
string | The total string being examined |
[~/javascript/learning]$ pwd -P /Users/casiano/local/src/javascript/learning [~/javascript/learning]$ cat f2c.js #!/usr/bin/env node function f2c(x) { function convert(str, p1, offset, s) { return ((p1-32) * 5/9) + "C"; } var s = String(x); var test = /(\d+(?:\.\d*)?)F\b/g; return s.replace(test, convert); } var arg = process.argv[2] || "32F"; console.log(f2c(arg));
[~/javascript/learning]$ ./f2c.js 100F 37.77777777777778C [~/javascript/learning]$ ./f2c.js 0C
index.html
son el uso de las librerías
jquery
, underscore
y el uso de un elemento textarea
en vez de un input
para la entrada:
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>CSV Analyzer</title> <link href="global.css" rel="stylesheet" type="text/css"> <script type="text/javascript" src="../../underscore/underscore.js"></script> <script type="text/javascript" src="../../jquery/starterkit/jquery.js"></script> <script type="text/javascript" src="csv.js"></script> </head> <body> <h1>Comma Separated Value Analyzer</h1> <div> <i>Write a CSV string. Click the table button. The program outputs a table with the specified data.</i> </div> <table> <tr> <th>CSV string:</th> <!-- autofocus attribute is HTML5 --> <td><textarea autofocus cols = "80" rows = "5" id="original"></textarea></td> </tr> </table> <button type="button">table:</button><br> <span class="output" id="finaltable"></span> </body> </html>
jQuery is a cross-platform JavaScript library designed to simplify the client-side scripting of HTML.
[~/javascript/jquery(master)]$ pwd -P /Users/casiano/local/src/javascript/jquery
~/javascript/jquery(master)]$ cat index.html <!doctype html> <html> <head> <meta charset="utf-8" /> <title>Demo</title> </head> <body> <a href="http://jquery.com/">jQuery</a> <script src="starterkit/jquery.js"></script> <script> // Your code goes here. </script> </body> </html>
To ensure that their code runs after the browser finishes loading the document, many JavaScript programmers wrap their code in an onload function:
window.onload = function() { alert( "welcome" ); }
Unfortunately, the code doesn't run until all images are finished downloading, including banner ads. To run code as soon as the document is ready to be manipulated, jQuery has a statement known as the ready event:
$( document ).ready(function() { // Your code here. });For
click
and most other events, you can prevent the default
behavior by calling
event.preventDefault()
in the event handler.
If this method is called, the default action of the event will not be triggered.
For example, clicked anchors will not take the browser to a new URL.
[~/javascript/jquery(master)]$ cat index2.html <!doctype html> <html> <head> <meta charset="utf-8" /> <title>Demo</title> </head> <body> <a href="http://jquery.com/">jQuery</a> <script src="starterkit/jquery.js"></script> <script> $( document ).ready(function() { $( "a" ).click(function( event ) { alert( "The link will no longer take you to jquery.com" ); event.preventDefault(); }); }); </script> </body> </html>Borrowing from CSS 1–3, and then adding its own, jQuery offers a powerful set of tools for matching a set of elements in a document.
See jQuery Category: Selectors.
Another common task is adding or removing a class. jQuery also provides some handy effects.
[~/javascript/jquery(master)]$ cat index3.html <!doctype html> <html> <head> <meta charset="utf-8" /> <style> a.test { font-weight: bold; } </style> <title>Demo</title> </head> <body> <a href="http://jquery.com/">jQuery</a> <script src="starterkit/jquery.js"></script> <script> $( document ).ready(function() { $( "a" ).click(function( event ) { $( "a" ).addClass( "test" ); alert( "The link will no longer take you to jquery.com" ); event.preventDefault(); $( "a" ).removeClass( "test" ); $( this ).hide( "slow" ); $( this ).show( "slow" ); }); }); </script> </body> </html>
this
always refers to the owner of the function
we're executing, or rather, to the object that a function is a method of.
tutu()
in a page, its owner is the
page, or rather, the window
object (or global
object) of JavaScript.
onclick
property, though, is owned by the HTML element it belongs to.
className
is a String containing
one or more space-separated classes to be added to the class attribute of each matched element.
This method does not replace a class. It simply adds the class, appending it to any which may already be assigned to the elements.
.removeClass( [className ] )
removes a single class, multiple classes, or all classes from each element in the set of matched elements.
If a class name is included as a parameter, then only that class will be removed from the set of matched elements. If no class names are specified in the parameter, all classes will be removed.
This method is often used with .addClass()
to switch elements' classes from one to another, like so:
$( "p" ).removeClass( "myClass noClass" ).addClass( "yourClass" );
[~/javascript/jquery/how-jquery-works-tutorial(getallparams)]$ cat app.js var express = require('express'); var app = express(); var path = require('path'); app.use(express.static('public')); // view engine setup app.set('views', path.join(__dirname, 'views')); app.set('view engine', 'ejs'); app.get('/', function (req, res) { res.render('index', { title: 'Express' }); }) app.get('/chuchu', function (req, res) { var isAjaxRequest = req.xhr; console.log(isAjaxRequest); if (isAjaxRequest) { console.log(req.query); res.send('{"answer": "Server responds: hello world!"}') } else { res.send('not an ajax request'); } }); var server = app.listen(3000, function () { var host = server.address().address var port = server.address().port console.log('Example app listening at http://%s:%s', host, port) });
jQuery.get( url [, data ] [, success(data, textStatus, jqXHR) ] [, dataType ] )
load data from the server using a HTTP GET request.
url
Type: String
A string containing the URL to which the request is sent.
data
Type: PlainObject or String
A plain object or string that is sent to the server with the request.
success(data, textStatus, jqXHR)
Type: Function()
A callback function that is executed if the request succeeds.
dataType
Type: String
The type of data expected from the server. Default: Intelligent Guess
(xml
, json
, script
, or
html
).
To use callbacks, it is important to know how to pass them into their parent function.
En el directorio views
hemos puesto el template:
[~/javascript/jquery/how-jquery-works-tutorial(getallparams)]$ cat views/index.ejs <!doctype html> <html> <head> <title><%- title %></title> </head> <body> <h1><%- title %></h1> <ul> <li><a href="http://jquery.com/" id="jq">jQuery</a> <li><a href="/chuchu">Visit chuchu!</a> </ul> <div class="result"></div> <script src="https://code.jquery.com/jquery-2.1.3.js"></script> <script> $( document ).ready(function() { $( "#jq" ).click(function( event ) { event.preventDefault(); $.get( "/chuchu", {nombres: ["juan", "pedro"]}, function( data ) { $( ".result" ).html( data["answer"]); console.log(data); }, 'json'); }); }); </script> </body> </html>
req.query
An object containing a property for each query string parameter in the route. If there is no query string, it is the empty object, {}
.
// GET /search?q=tobi+ferret req.query.q // => "tobi ferret" // GET /shoes?order=desc&shoe[color]=blue&shoe[type]=converse req.query.order // => "desc" req.query.shoe.color // => "blue" req.query.shoe.type // => "converse"
Estas son las dependencias:
[~/javascript/jquery/how-jquery-works-tutorial(getallparams)]$ cat package.json { "name": "ajaxjquery", "version": "0.0.0", "description": "", "main": "hello.js", "dependencies": { "express": "*", "ejs": "*", "gulp-shell": "*", "body-parser": "~1.12.0" }, "devDependencies": {}, "scripts": { "test": "node hello.js" }, "author": "", "license": "ISC" }Además hemos instalado a nivel global
gulp
y node-supervisor
.
Podemos arrancar el servidor usando este gulpfile
:
[~/javascript/jquery/how-jquery-works-tutorial(getallparams)]$ cat gulpfile.js var gulp = require('gulp'); var shell = require('gulp-shell'); gulp.task('default', ['server']); // npm install supervisor -g gulp.task('server', function () { return gulp.src('').pipe(shell([ 'node-supervisor app.js' ])); }); gulp.task('open', function() { return gulp.src(''). pipe(shell("open https://github.com/crguezl/how-jquery-works-tutorial/tree/getallparams")); });
Véase:
JavaScript enables you to freely pass functions around to be executed at a later time. A callback is a function that is passed as an argument to another function and is usually executed after its parent function has completed.
Callbacks are special because they wait to execute until their parent finishes or some event occurs.
Meanwhile, the browser can be executing other functions or doing all sorts of other work.
[~/javascript/jquery(master)]$ cat app.rb require 'sinatra' set :public_folder, File.dirname(__FILE__) + '/starterkit' get '/' do erb :index end get '/chuchu' do if request.xhr? "hello world!" else erb :tutu end end __END__ @@layout <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>Demo</title> </head> <body> <a href="http://jquery.com/">jQuery</a> <div class="result"></div> <script src="jquery.js"></script> <%= yield %> </body> </html> @@index <script> $( document ).ready(function() { $( "a" ).click(function( event ) { event.preventDefault(); $.get( "/chuchu", function( data ) { $( ".result" ).html( data ); alert( "Load was performed." ); }); }); }); </script> @@tutu <h1>Not an Ajax Request!</h1>
jQuery.get( url [, data ] [, success(data, textStatus, jqXHR) ] [, dataType ] )
load data from the server using a HTTP GET request.
url
Type: String
A string containing the URL to which the request is sent.
data
Type: PlainObject or String
A plain object or string that is sent to the server with the request.
success(data, textStatus, jqXHR)
Type: Function()
A callback function that is executed if the request succeeds.
dataType
Type: String
The type of data expected from the server. Default: Intelligent Guess
(xml
, json
, script
, or
html
).
To use callbacks, it is important to know how to pass them into their parent function.
Executing callbacks with arguments can be tricky.
This code example will not work:
$.get( "myhtmlpage.html", myCallBack( param1, param2 ) );The reason this fails is that the code executes
myCallBack( param1, param2)
immediately and then passes myCallBack()
's return value as the second
parameter to $.get()
.
We actually want to pass the function myCallBack
,
not myCallBack( param1, param2 )
's return value (which might or might not
be a function).
So, how to pass in myCallBack()
and include arguments?
To defer executing myCallBack()
with its parameters, you can use
an anonymous function as a wrapper.
[~/javascript/jquery(master)]$ cat app2.rb require 'sinatra' set :public_folder, File.dirname(__FILE__) + '/starterkit' get '/' do erb :index end get '/chuchu' do if request.xhr? # is an ajax request "hello world!" else erb :tutu end end __END__ @@layout <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>Demo</title> </head> <body> <a href="http://jquery.com/">jQuery</a> <div class="result"></div> <script src="jquery.js"></script> <%= yield %> </body> </html> @@tutu <h1>Not an Ajax Request!</h1> @@index <script> var param = "chuchu param"; var handler = function( data, textStatus, jqXHR, param ) { $( ".result" ).html( data ); alert( "Load was performed.\n"+ "$data = "+data+ "\ntextStatus = "+textStatus+ "\njqXHR = "+JSON.stringify(jqXHR)+ "\nparam = "+param ); }; $( document ).ready(function() { $( "a" ).click(function( event ) { event.preventDefault(); $.get( "/chuchu", function(data, textStatus, jqXHR ) { handler( data, textStatus, jqXHR, param); }); }); }); </script>El ejemplo en
app2.rb
puede verse desplegado en Heroku:
http://jquery-tutorial.herokuapp.com/
replacer function
is specified, or optionally including only the
specified properties if a replacer array
is specified.
JSON.stringify(value[, replacer [, space]])
value
The value to convert to a JSON string.
replacer
space
Causes the resulting string to be pretty-printed.
See another example of use in http://jsfiddle.net/casiano/j7tsF/. To learn to use JSFiddle wath the YouTube video How to use JSFiddle by Jason Diamond
Underscore: is a utility-belt library for JavaScript that provides a lot of the functional programming support that you would expect in Ruby.
map
, select
, invoke
En ECMAScript 5/JavaScript 1.6. existen los métodos
map
, filter
, forEach
y reduce
similares
a los de Underscore.
[~/javascript/jquery(master)]$ node > 2+3 5 > _ 5 > uu = require('underscore') { [Function] _: [Circular], VERSION: '1.5.2', forEach: [Function], each: [Function], collect: [Function], map: [Function], inject: [Function], reduce: [Function], ................. chain: [Function] }
each
:
> uu.each([1, 2, 3], function(x) { console.log(x*x); }) 1 4 9
map
:
> uu.map([1, 2, 3], function(num){ return num * 3; }) [ 3, 6, 9 ]
invoke
> z = [[6,9,1],[7,3,9]] [ [ 6, 9, 1 ], [ 7, 3, 9 ] ] > uu.invoke(z, 'sort') [ [ 1, 6, 9 ], [ 3, 7, 9 ] ] > uu.invoke(z, 'sort', function(a, b) { return b-a; }) [ [ 9, 6, 1 ], [ 9, 7, 3 ] ]
reduce
:
> uu.reduce([1, 2, 3, 4], function(s, num){ return s + num; }, 0) 10 > uu.reduce([1, 2, 3, 4], function(s, num){ return s * num; }, 1) 24 > uu.reduce([1, 2, 3, 4], function(s, num){ return Math.max(s, num); }, -1) 4 > uu.reduce([1, 2, 3, 4], function(s, num){ return Math.min(s, num); }, 99) 1
filter
: (select
is an alias for filter
)
> uu.filter([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; }) [ 2, 4, 6 ]
isEqual
> a = {a:[1,2,3], b: { c: 1, d: [5,6]}} { a: [ 1, 2, 3 ], b: { c: 1, d: [ 5, 6 ] } } > b = {a:[1,2,3], b: { c: 1, d: [5,6]}} { a: [ 1, 2, 3 ], b: { c: 1, d: [ 5, 6 ] } } > a == b false > uu.isEqual(a,b) true
bind
> func = function(greeting){ return greeting + ': ' + this.name } [Function] > func = uu.bind(func, {name: 'moe'}) [Function] > func('hello') 'hello: moe' > func = uu.bind(func, {name: 'moe'}, 'hi') [Function] > func() 'hi: moe' >Los objetos
Function
disponen de un método bind
nativo en las últimas versiones de JS:
> func = function(){ return 'hola ' + this.name } [Function] > g = func.bind({name: 'Juan'}) [Function] > g() 'hola Juan' > g = func.bind({name: 'Pedro'}) [Function] > g() 'hola Pedro'
_.template(templateString, [data], [settings])
Compiles JavaScript templates into functions that can be evaluated for rendering. Useful for rendering complicated bits of HTML from a JavaScript object or from JSON data sources.
JSON, or JavaScript Object Notation, is an open standard format that uses human-readable text to transmit data objects consisting of attribute–value pairs. It is used primarily to transmit data between a server and web application, as an alternative to XML. Although originally derived from the JavaScript scripting language, JSON is a language-independent data format, and code for parsing and generating JSON data is readily available in a large variety of programming languages.
<%= … %>
,
> compiled = uu.template("hello: <%= name %>") { [Function] source: 'function(obj){ var __t,__p=\'\', __j=Array.prototype.join, i print=function(){__p+=__j.call(arguments,\'\');}; with(obj||{}){ __p+=\'hello: \'+ ((__t=( name ))==null?\'\':__t)+ \'\'; } return __p; }' } > compiled({name: 'moe'}) 'hello: moe'
<% … %>
.
> uu = require('underscore') > list = "\ ... <% _.each(people, function(name) { %>\ ..... <li><%= name %></li>\ ... <% }); %>" '<% _.each(people, function(name) { %> <li><%= name %></li> <% }); %>' > uu.template(list, {people: ['moe', 'curly', 'larry']}) ' <li>moe</li> <li>curly</li> <li>larry</li> '
> uu.template("hello: <%= name %>", { name: 'Mary'}) 'hello: Mary'
<%- … %>
> template = uu.template("<b><%- value %></b>") { [Function] source: 'function(obj){ var __t,__p=\'\',__j=Array.prototype.join,print=function(){__p+=__j.call(arguments,\'\');}; with(obj||{}){ __p+=\'<b>\'+ ((__t=( value ))==null?\'\':_.escape(__t))+ \'</b>\'; } return __p; }' } > template({value: '<script>'}) '<b><script></b>'
settings
argument should be a hash containing
any _.templateSettings
that should be overridden.
_.template("Using 'with': <%= data.answer %>", {answer: 'no'}, {variable: 'data'}); => "Using 'with': no"Another example:
template = uu.template("<b>{{ value }}</b>",{value: 4 }, { interpolate: /\{\{(.+?)\}\}/g }) '<b>4</b>'
You can also use print
from within JavaScript code. This is sometimes
more convenient than using <%= ... %>
.
> compiled = uu.template("<% print('Hello ' + epithet); %>") { [Function] source: 'function(obj){\n var __t,__p=\'\', __j=Array.prototype.join,print=function(){ __p+=__j.call(arguments,\'\');};\n with(obj||{}){\n __p+=\'\';\n print(\'Hello \' + epithet); \n __p+=\'\';\n}\n return __p;\n }' } > compiled({ epithet : 'stooge' }) 'Hello stooge' >
If ERB-style delimiters aren't your cup of tea, you can change Underscore's template settings to use different symbols to set off interpolated code:
interpolate
regex to match expressions that
should be interpolated verbatim,
escape
regex to match expressions
that should be inserted after being HTML escaped, and
evaluate
regex
to match expressions that should be evaluated without insertion into
the resulting string.
Mustache.js
style templating:
_.templateSettings = { interpolate: /\{\{(.+?)\}\}/g }; var template = _.template("Hello {{ name }}!"); template({name: "Mustache"}); => "Hello Mustache!"
escape
:
> uu.templateSettings.escape = /\{\{-(.*?)\}\}/g /\{\{-(.*?)\}\}/g > compiled = uu.template("Escaped: {{- value }}\nNot escaped: {{ value }}") { [Function] source: 'function(obj){\nvar __t,__p=\'\',__j=Array.prototype.join,print=function(){__p+=__j.call(arguments,\'\');};\nwith(obj||{}){\n__p+=\'Escaped: \'+\n((__t=( value ))==null?\'\':_.escape(__t))+\n\'\\nNot escaped: {{ value }}\';\n}\nreturn __p;\n}' } > compiled({value: 'Hello, <b>world!</b>'}) 'Escaped: Hello, <b>world!</b>\nNot escaped: {{ value }}'
> uu.templateSettings = { ..... interpolate: /\<\@\=(.+?)\@\>/gim, ..... evaluate: /\<\@(.+?)\@\>/gim ..... } { interpolate: /\<\@\=(.+?)\@\>/gim, evaluate: /\<\@(.+?)\@\>/gim } > s = " <@ _.each([0,1,2,3,4], function(i) { @> <p><@= i @></p> <@ }); @>" ' <@ _.each([0,1,2,3,4], function(i) { @> <p><@= i @></p> <@ }); @>' > uu.template(s,{}) ' <p>0</p> <p>1</p> <p>2</p> <p>3</p> <p>4</p> '
with
statement. The with
statement adds the given
object to the head of this scope chain during the evaluation of its
statement body:
> with (Math) { ... s = PI*2; ... } 6.283185307179586 > z = { x : 1, y : 2 } { x: 1, y: 2 } > with (z) { ... console.log(y); ... } 2 undefined
However, you can specify a single variable name
with the variable setting
. This improves the speed at
which a template is able to render.
_.template("Using 'with': <%= data.answer %>", {answer: 'no'}, {variable: 'data'}); => "Using 'with': no"
Una CDN que provee underscore
esta en
http://cdnjs.com/:
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.5.2/underscore-min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
A content delivery network or content distribution network (CDN) is a large distributed system of servers deployed in multiple data centers across the Internet. The goal of a CDN is to serve content to end-users with high availability and high performance. CDNs serve a large fraction of the Internet content today, including
Google provee también un servicio CDN para los desarrolladores en https://developers.google.com/speed/libraries/devguide.
The <textarea>
tag defines a multi-line text input control.
A text area can hold an unlimited number of characters, and the text renders in a fixed-width font (usually Courier).
The size of a text area can be specified by the cols
and rows
attributes, or through CSS' height
and width
properties.
cols
and rows
consider the font size.
height
and width
aren't.
The autofocus attribute is a boolean attribute.
When present, it specifies that the text area should automatically get focus when the page loads.
Véase también [1]
The <button>
tag defines a clickable button.
Inside a <button>
element you can put content, like text or images.
Web storage and DOM storage (document object model) are web application software methods and protocols used for storing data in a web browser.
The same-origin policy permits scripts running on pages originating from the same site – a combination of scheme, hostname, and port number – to access each other's DOM with no specific restrictions, but prevents access to DOM on different sites.
Véase:
[~/javascript/local_storage(master)]$ pwd -P /Users/casiano/local/src/javascript/local_storage
While Chrome does not provide a UI for clearing localStorage, there is an API that will either clear a specific key or the entire localStorage object on a website.
//Clears the value of MyKey window.localStorage.clear("MyKey"); //Clears all the local storage data window.localStorage.clear();Once done, localStorage will be cleared. Note that this affects all web pages on a single domain, so if you clear localStorage for
jsfiddle.net/index.html
(assuming that's the page you're on), then it
clears it for all other pages on that site.
html * { font-size: large; /* The !important ensures that nothing can override what you've set in this style (unless it is also important). */ font-family: Arial; } h1 { text-align: center; font-size: x-large; } th, td { vertical-align: top; text-align: right; } /* #finaltable * { color: white; background-color: black; } */ /* #finaltable table { border-collapse:collapse; } */ /* #finaltable table, td { border:1px solid white; } */ #finaltable:hover td { background-color: blue; } tr:nth-child(odd) { background-color:#eee; } tr:nth-child(even) { background-color:#00FF66; } input { text-align: right; border: none; } /* Align input to the right */ textarea { border: outset; border-color: white; } table { border: inset; border-color: white; } table.center { margin-left:auto; margin-right:auto; } #result { border-color: red; } tr.error { background-color: red; } body { background-color:#b0c4de; /* blue */ }
Una pseudo clase es un estado o uso predefinido de un elemento al que se le puede aplicar un estilo independientemente de su estado por defecto. Existen cuatro tipos diferentes de pseudo clases:
In CSS, pattern matching rules determine which style rules apply to elements in the document tree. These patterns, called selectors, may range from simple element names to rich contextual patterns. If all conditions in the pattern are true for a certain element, the selector matches the element.
The universal selector, written *
, matches the name of any element
type. It matches any single element in the document tree.
For example, this rule set will be applied to every element in a document:
* { margin: 0; padding: 0; }
Working with HTML, authors may use the period (.
) notation
as an alternative to the ~=
notation when representing the class
attribute. Thus, for HTML, div.value
and div[class~=value]
have the same
meaning. The attribute value must immediately follow the period (.
).
:nth-child(n)
selector matches every element that is the n
th
child, regardless of type, of its parent.
n
can be a number, a keyword, or a formula.
The CSS border properties allow you to specify the style and color of an element's border.
The border-style property specifies what kind of border to display.
For example, inset:
Defines a 3D inset border
while :outset
defines a 3D outset border.
The effect depends on the border-color value
See CSS: border
// See http://en.wikipedia.org/wiki/Comma-separated_values "use strict"; // Use ECMAScript 5 strict mode in browsers that support it $(document).ready(function() { $("button").click(function() { calculate(); }); }); function calculate() { var result; var original = document.getElementById("original"); var temp = original.value; var regexp = /_____________________________________________/g; var lines = temp.split(/\n+\s*/); var commonLength = NaN; var r = []; // Template using underscore var row = "<%% _.each(items, function(name) { %>" + " <td><%%= name %></td>" + " <%% }); %>"; if (window.localStorage) localStorage.original = temp; for(var t in lines) { var temp = lines[t]; var m = temp.match(regexp); var result = []; var error = false; if (m) { if (commonLength && (commonLength != m.length)) { //alert('ERROR! row <'+temp+'> has '+m.length+' items!'); error = true; } else { commonLength = m.length; error = false; } for(var i in m) { var removecomma = m[i].replace(/,\s*$/,''); var remove1stquote = removecomma.replace(/^\s*"/,''); var removelastquote = remove1stquote.replace(/"\s*$/,''); var removeescapedquotes = removelastquote.replace(/\"/,'"'); result.push(removeescapedquotes); } var tr = error? '<tr class="error">' : '<tr>'; r.push(tr+_.template(row, {items : result})+"</tr>"); } else { alert('ERROR! row '+temp+' does not look as legal CSV'); error = true; } } r.unshift('<p>\n<table class="center" id="result">'); r.push('</table>'); //alert(r.join('\n')); // debug finaltable.innerHTML = r.join('\n'); } window.onload = function() { // If the browser supports localStorage and we have some stored data if (window.localStorage && localStorage.original) { document.getElementById("original").value = localStorage.original; } };
Además de todo lo descrito en los apartados anteriores, la práctica debe cumplir con los siguientes requisitos:
script
en el HTML
Casiano Rodríguez León