data.js 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. /*
  2. Copyright (c) 2004-2012, The Dojo Foundation All Rights Reserved.
  3. Available via Academic Free License >= 2.1 OR the modified BSD license.
  4. see: http://dojotoolkit.org/license for details
  5. */
  6. if(!dojo._hasResource["dojox.dtl.contrib.data"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  7. dojo._hasResource["dojox.dtl.contrib.data"] = true;
  8. dojo.provide("dojox.dtl.contrib.data");
  9. dojo.require("dojox.dtl._base");
  10. (function(){
  11. var dd = dojox.dtl;
  12. var ddcd = dd.contrib.data;
  13. var first = true;
  14. ddcd._BoundItem = dojo.extend(function(item, store){
  15. this.item = item;
  16. this.store = store;
  17. },
  18. {
  19. get: function(key){
  20. var store = this.store;
  21. var item = this.item;
  22. if(key == "getLabel"){
  23. return store.getLabel(item);
  24. }else if(key == "getAttributes"){
  25. return store.getAttributes(item);
  26. }else if(key == "getIdentity"){
  27. if(store.getIdentity){
  28. return store.getIdentity(item);
  29. }
  30. return "Store has no identity API";
  31. }else{
  32. if(!store.hasAttribute(item, key)){
  33. if(key.slice(-1) == "s"){
  34. if(first){
  35. first = false;
  36. dojo.deprecated("You no longer need an extra s to call getValues, it can be figured out automatically");
  37. }
  38. key = key.slice(0, -1);
  39. }
  40. if(!store.hasAttribute(item, key)){
  41. return;
  42. }
  43. }
  44. var values = store.getValues(item, key);
  45. if(!values){
  46. return;
  47. }
  48. if(!dojo.isArray(values)){
  49. return new ddcd._BoundItem(values, store);
  50. }
  51. values = dojo.map(values, function(value){
  52. if(dojo.isObject(value) && store.isItem(value)){
  53. return new ddcd._BoundItem(value, store);
  54. }
  55. return value;
  56. });
  57. values.get = ddcd._get;
  58. return values;
  59. }
  60. }
  61. });
  62. ddcd._BoundItem.prototype.get.safe = true;
  63. ddcd.BindDataNode = dojo.extend(function(items, query, store, alias){
  64. this.items = items && new dd._Filter(items);
  65. this.query = query && new dd._Filter(query);
  66. this.store = new dd._Filter(store);
  67. this.alias = alias;
  68. },
  69. {
  70. render: function(context, buffer){
  71. var items = this.items && this.items.resolve(context);
  72. var query = this.query && this.query.resolve(context);
  73. var store = this.store.resolve(context);
  74. if(!store || !store.getFeatures){
  75. throw new Error("data_bind didn't receive a store");
  76. }
  77. if(query){
  78. var sync = false;
  79. store.fetch({
  80. query: query,
  81. sync: true,
  82. scope: this,
  83. onComplete: function(it){
  84. sync = true;
  85. items = it;
  86. }
  87. });
  88. if(!sync){
  89. throw new Error("The bind_data tag only works with a query if the store executed synchronously");
  90. }
  91. }
  92. var list = [];
  93. if(items){
  94. for(var i = 0, item; item = items[i]; i++){
  95. list.push(new ddcd._BoundItem(item, store));
  96. }
  97. }
  98. context[this.alias] = list;
  99. return buffer;
  100. },
  101. unrender: function(context, buffer){
  102. return buffer;
  103. },
  104. clone: function(){
  105. return this;
  106. }
  107. });
  108. dojo.mixin(ddcd, {
  109. _get: function(key){
  110. if(this.length){
  111. return (this[0] instanceof ddcd._BoundItem) ? this[0].get(key) : this[0][key];
  112. }
  113. },
  114. bind_data: function(parser, token){
  115. // summary: Turns a list of data store items into DTL compatible items
  116. // example:
  117. // `contextItems` and `contextStore` should be an item list
  118. // and a data store that get assigned to `newVariable`
  119. //
  120. // | {% bind_data contextItems to contextStore as newVariable %}
  121. var parts = token.contents.split();
  122. if(parts[2] != 'to' || parts[4] != 'as' || !parts[5]){
  123. throw new Error("data_bind expects the format: 'data_bind items to store as varName'");
  124. }
  125. return new ddcd.BindDataNode(parts[1], null, parts[3], parts[5]);
  126. },
  127. bind_query: function(parser, token){
  128. // summary: Queries a data store and makes the returned items DTL compatible
  129. // example:
  130. // You can only use this with data stores that work in a synchronous
  131. // way (meaning that `onComplete` is fired during the `fetch` call).
  132. // A `sync` flag is sent to the fetch call so that stores that usually
  133. // work asynchronously make themselves syncrhonous if possible.
  134. // | {% bind_query contextQuery to contextStore as newVariable %}
  135. var parts = token.contents.split();
  136. if(parts[2] != 'to' || parts[4] != 'as' || !parts[5]){
  137. throw new Error("data_bind expects the format: 'bind_query query to store as varName'");
  138. }
  139. return new ddcd.BindDataNode(null, parts[1], parts[3], parts[5]);
  140. }
  141. });
  142. ddcd._get.safe = true;
  143. dd.register.tags("dojox.dtl.contrib", {
  144. "data": ["bind_data", "bind_query"]
  145. });
  146. })();
  147. }