http://www.w3school.com.cn/js/index.asp
http://www.w3school.com.cn/html/index.asp
下面网站介绍了OOP(Object oriented programming)和BOM(Browser object model):
http://www.dreamdu.com/javascript/
· 在看node.js的例子时发现有很多类似这样的调用:
db.query('select * from todo order by finished asc, id asc limit 50', function(err, rows) {
if(err) return next(err);
res.render('index', {todos: rows});
});
这是使用了javascript里面的callback function(回调函数)的概念,我们可以看Client.query()的定义:
Client.prototype.query = function(sql, params, cb){....
其中参数db便是一个回调函数。
网站http://recurial.com/programming/understanding-callback-functions-in-javascript/较好的解释了callback function.
· 怎么使用javascript将数据库的某个表呈现给用户呢?带着这个问题,我了解了一些常用的表格控件:
http://recurial.com/programming/understanding-callback-functions-in-javascript/
http://www.hotscripts.com/blog/15-javascript-data-grids-enhance-html-tables/
其中DataTables(http://datatables.net/)是一个常用的表格控件,它基于JQuery.
若要使用DataTables,需要先下载JQuery:D:\Study_2012\jquery\jquery-1.7.1.js, 它只是一个文件,若要使用它,可以将下列语句加入到<head></head>
<script src="jquery-1.7.1.js" type="text/javascript"></script>
其中src=<relative location of jquery-1.7.1.js>
然后下载DataTables.然后将下列语句加入到<head></head>
<script type="text/javascript" src="DataTables-1.9.0\media\js\jquery.dataTables.js"></script>
<link rel="stylesheet" href="DataTables-1.9.0\media\css\jquery.dataTables.css" type="text/css"></link>
· 下面是使用DataTables的一个例子:
Reference: http://www.codeproject.com/Articles/194916/Enhancing-HTML-tables-using-a-JQuery-DataTables-pl
首先我们定一个一个table:
<table id="myDataTable" class="display">
<thead>
<tr>
<th>engine</th>
<th>browser</th>
<th>platform</th>
<th>version</th>
<th>grade</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
然后我们使用下面DataTables API $('table#myDataTable').dataTable()来初始化这个表格:
<script type="text/javascript">
$(document).ready(function() {
$('table#myDataTable').dataTable( {
bJQueryUI: true,
sPaginationType: "full_numbers",
"sAjaxSource": 'arrays.txt',
"aoColumns": [
{ "mDataProp": "engine" },
{ "mDataProp": "browser" },
{ "mDataProp": "platform" },
{ "mDataProp": "version" },
{ "mDataProp": "grade" }
]
} );
} );
</script>
· 然后我学习了如何更好的理解javascript的OOP
http://blog.jobbole.com/11691/
http://killdream.github.com/blog/2011/10/understanding-javascript-oop/
· 是否可以使用DataTables将MongoDb里面的数据以表格的方式展现给用户?
三. 弹出式窗口
1. 如果弹出式窗口很简单,只是一个提示信息的功能,那么可以使用prompt方法:
<script type="text/javascript">
var name=prompt( "提示文字 ", "预设值 ");
</script>
2. 如果prompt无法满足您的要求,比如您想要一个能够输入用户名/密码的弹出式窗口,那么可以使用window.open()方法,比如:
window.open ('page.html')
首先您需要先完成page.html, 然后调用window.open().
3. 而通常我们并不使用window.open(), 因为弹出式窗口和父窗口之间的通信很不便。比如在node.js中我们使用ejs作为view engine,如果弹出式的窗口中某个控件也需要ejs传入值进行渲染,使用window.open()是无法实现的。这时可以考虑使用css z-index属性。
z-index 属性设置元素的堆叠顺序。拥有更高堆叠顺序的元素总是会处于堆叠顺序较低的元素的前面。
比如我将弹出式窗口定义于下面form中:
<form id="editform" name="editform" style="display:none;left:300px;top:100px;" class="assign_user">
通过style="display:none..."来初始化此form最初不显示,并且定义它的z-index为1,即它如果显示时将显示在最前面。
<style>
.assign_user{
position:absolute;
z-index:1;
width:700px;
height:500px;
background-color:blue;
}
</style>
我们通过一个下面label实现当单击"Assign a New User"时,将弹出显示editform。
<label class='control-label' ><a href="javascript:void(null);" οnclick="assign_user_show();">Assign a New User</a></label>
下面方法将修改editform的display为空,即显示editform。
function assign_user_show(){
document.getElementById("editform").style.display="";
}
四. 修改HTML中部分页面
1. 如果你想修改HTML中部分页面,但不希望刷新整个页面,可以使用HTML DOM相关技术。
比如我们页面中有下面这个表格,初始时表格里没有任何内容。
<table id="UserListTable" name="UserListTable" class="UserListTable">
<thead>
<tr>
<th class = single-form-content>Username</th>
<th class = single-form-content>First Name</th>
<th class = single-form-content>Last Name</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
我们可以通过下面的javascript来在上面的表格中增加几行记录。
for (var i=0; i<selectedList.getLength(); ++i){
var x=document.getElementById("UserListTable").insertRow(1);
var username=x.insertCell(0);
var first_name=x.insertCell(1);
var last_name=x.insertCell(2);
username.innerHTML=selectedList[i].name;
first_name.innerHTML=selectedList[i].first_name;
last_name.innerHTML=selectedList[i].last_name;
}
参考:HTML DOM http://www.w3school.com.cn/htmldom/index.asp
2. 还可以使用AJAX更新部分网页
a) 例子1:
<html>
<head>
<script type="text/javascript">
function loadXMLDoc()
{
var xmlhttp;
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.open("GET","/ajax/test1.txt",false);
xmlhttp.send();
document.getElementById("myDiv").innerHTML=xmlhttp.responseText;
}
</script>
</head>
<body>
<div id="myDiv"><h2>Let AJAX change this text</h2></div>
<button type="button" οnclick="loadXMLDoc()">通过 AJAX 改变内容</button>
</body>
</html>
b)例子2
<html>
<head>
<script type="text/javascript">
var xmlhttp;
function loadXMLDoc(url)
{
xmlhttp=null;
if (window.XMLHttpRequest)
{// code for IE7, Firefox, Mozilla, etc.
xmlhttp=new XMLHttpRequest();
}
else if (window.ActiveXObject)
{// code for IE5, IE6
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
if (xmlhttp!=null)
{
xmlhttp.onreadystatechange=onResponse;
xmlhttp.open("GET",url,true);
xmlhttp.send(null);
}
else
{
alert("Your browser does not support XMLHTTP.");
}
}
function onResponse()
{
if(xmlhttp.readyState!=4) return;
if(xmlhttp.status!=200)
{
alert("Problem retrieving XML data");
return;
}
txt="<table border='1'>";
x=xmlhttp.responseXML.documentElement.getElementsByTagName("CD");
for (i=0;i<x.length;i++)
{
txt=txt + "<tr>";
xx=x[i].getElementsByTagName("TITLE");
{
try
{
txt=txt + "<td>" + xx[0].firstChild.nodeValue + "</td>";
}
catch (er)
{
txt=txt + "<td> </td>";
}
}
xx=x[i].getElementsByTagName("ARTIST");
{
try
{
txt=txt + "<td>" + xx[0].firstChild.nodeValue + "</td>";
}
catch (er)
{
txt=txt + "<td> </td>";
}
}
txt=txt + "</tr>";
}
txt=txt + "</table>";
document.getElementById('copy').innerHTML=txt;
}
</script>
</head>
<body>
<div id="copy">
<button οnclick="loadXMLDoc('/example/xmle/cd_catalog.xml')">Get CD info</button>
</div>
</body>
</html>
五. 通过一个Link实现修改部分页面和提交表单两个功能
if(method == 'post'){
res.render('project/edit', { action:'/project/edit', error:'Incomplete information.', title: 'Edit a Project', project_name: project_name, project_leader: project_leader,
project_desc: project_desc, project_id: project_id, assign_users:assign_users, user_list:user_list});
}
可惜这种方法有些弊端:
1. 需要页面返回所有的需要渲染页面的信息,并且服务器端需向客户端传入所有用户已经输入的信息,并且需要从新刷新整个页面
2. 如果传入的信息是个数组,比如上面例子中的user_list就是一个数组,那么如何使页面返回这个数组,也是个问题,因为它无法像Text控件一样直接返回字符串,它需要返回的是一个数组,而页面是无法返回这个数组的,只能你在页面端将这个数组按照某个格式拼装成一个字符串,比如以'|'分割每个记录。然后服务器端再将这个字符串转换成数组。这种方法显然也比较复杂。
HTML DOM可以在页面端实现修改部分页面,而不需要重新刷新整个页面,它通过οnclick="functionCall()"来描述某个link: 如下:
<label class='control-label' ><a href="javascript:void(null);" οnclick="functionCall();">Save</a></label>
然后我们通过functionCall()来检验字段是否为空,若检验失败,可以设置显示error的label的值为相应的error message。
如果检验成功,我们应该提交post,那么这时我们又需要使用提交表单的功能如下:
<form action='/project/edit' method='post'>
<input type='submit' class='btn' value='Save'/>
</form>
问题是怎么将修改部分页面和提交表单这两个功能统一实现在某个link或者button上呢?
学了AJax,不知道下面的Ajax方法是否可行:
var xml = XMLHttpRequest();
xml.open("POST", "url", true);
//-------app.js
app.get('/', routes.index);
app.post('/', routes.index);
app.get('/page1', routes.page1);
app.post('/page1', routes.page1);
//-------routes/index.js
exports.index = function(req, res){
var method = req.method.toLowerCase();
if(method == 'get'){
res.render('index', { title: 'Express' });
}
if(method == 'post'){
console.log("In post /");
res.redirect('/page1');
}
};
exports.page1 = function(req, res){
console.log("In get page1");
res.render('page1', { title: 'page1' });
};
//-------index.ejs
<h1><%= title %></h1>
<script language="Javascript">
function functionCall()
{
var project_name = document.getElementById("project_name").value;
if(project_name){
var xml = XMLHttpRequest();
xml.open("POST", "/", true);
xml.send();
}else{
document.getElementById("error_message").value = 'Incomplete information';
}
}
</script>
<p>Welcome to <%= title %></p>
<input class='input-xlarge' id='project_name' name='project_name' size='30' />
<label class='control-label' ><a id='href_id' οnclick="functionCall();">Save</a></label>
<input id='error_message' name='error_message'/>
//-------page1.ejs
<h1><%= title %></h1>
<p>Welcome to <%= title %></p>
测试的功能是界面上有个输入框,当输入为空时,在屏幕上显示错误消息,如果不为空,则在后台打印一条消息"In post /",并跳转到page1页面。
测试后发现当输入不为空时,node.js后台打印了下面的消息:
In post /
In get page1
说明node.js尝试了跳转到page1页面,但是页面上却一直hang在"GET http://localhost:3000/page1",而无法打开页面page1
有个解决方法是在index.ejs的代码'xml.send();'之后添加代码:
function functionCall()
{
var project_name = document.getElementById("project_name").value;
if(project_name){
var xml = XMLHttpRequest();
xml.open("POST", "/", true);
xml.send();
document.getElementById("href_id").href = '/page1';
}else{
document.getElementById("error_message").value = 'Incomplete information';
}
}
经过测试Save链接可以实现修改部分页面和提交表单。现在问题是目前是使用一个输入框显示的error message:
<input id='error_message' name='error_message'/>
我尝试使用Label,可是无法修改内容。