Thursday, October 11, 2007

Up Function

ใน Prototype (javascript library) มันมี function อยู่อันหนึ่งที่ผมชอบ ก็คือ "up"
function นี้ช่วยให้เรา search หา parent element ได้ง่ายขึ้น
ช่วยให้ลดความซับซ้อนของบาง feature ลง

ลองดูตัวอย่างการใช้แบบง่ายๆ
  <ul>
<li>xxx</li>
<li>yyy</li>
<li class="item">
zzz
<!-- กดแล้วจะ remove item ที่เป็นพ่อของปุ่มนี้ออก -->
<input type='button' value="remove"
onclick='this.up(".item").remove()'/>
</li>
</ul>

ตัวอย่างนี้ simple มากจนไม่จำเป็นต้องใช้ function up ช่วยก็ได้
แต่ใน app ที่เป็นพวก Rich client ตัว DOM จะซ้อนกันสลับซับซ้อนกว่ากว่าตัวอย่างนี้มาก
มี up ก็ช่วยให้เราทำอะไรหลายอย่างได้ง่ายขึ้น

แต่ถึงจะชอบอย่างไร, project ปัจจุบันผม ก็ไม่ได้ใช้ Prototype แต่ใช้ Dojo,
ซึ่งลองความหาใน code แล้วยังหา function แบบนี้ไม่เจอ (code base มันใหญ่, อาจจะมีอยู่แล้วแต่หาไม่เจอ)
ดังนั้นปฏิบัติการลอกเลียนแบบ ก็เลยเกิดขึ้นดังนี้
dojo.provide("orangegears.dom.Util");

orangegears.dom.Util.up = function(node, expression) {
var ancestors = orangegears.dom.Util.ancestors(node);
for (var i = 0; i < ancestors.length; i++) {
var tmp = dojo.query(expression, ancestors[i]);
if (tmp.length > 0) {
return tmp[0];
}
}
return [];
}

orangegears.dom.Util.ancestors = function(node) {
return orangegears.dom.Util.recursivelyCollect(node, "parentNode");
}

orangegears.dom.Util.recursivelyCollect = function(element, property) {
var elements = [];
while (element = element[property])
if (element.nodeType == 1)
elements.push(element);
return elements;
}

namespace ยาวไปนิด แต่ไว้ไปสร้าง shortcut ทีหลังได้
ตัวอย่างเวลานำไปใช้จริง
dijit.byId(orangegears.dom.Util.up(this, '.dojoxGrid').id).setAll(this.checked);

Related link from Roti

1 comment:

tofu said...

เนื้อหาน่าสนใจดีครับ กำลังสนใจเรื่อง javascript library อยู่ด้วย