Quantcast
Channel: JavaScriptMVC Forum
Viewing all articles
Browse latest Browse all 3491

Global Helper is called only one time

$
0
0
Hello,

I am a little be lost with my problem so I hope you can help me to solve it ... :)

I want to create my own validation plugin by combining it with the define plugin. Also it should be possible to show the errors easily in the stache template. At the bottom of my post you will find the source code (in a more simple version as I want to use it in the future).

It should be possible to write your own validation function into the define object of the attribute. The validation function will be called automatically everytime you change the attribute and you can show it on your template.

My problem is that the global helper which I wrote is called only one time. I hoped the helper will be called everytime the error list changes.

The helper needs 2 Parameters: 
      First parameter the map 
      Second parameter the attribute name

So it should be possible to show the errors or (if there are any errors) something positive
  1. {{#verror mymap "attributename"}}
  2.       /* SHOW ERRORS */
  3. {{else}}
  4.       /* EVERYTHING IS OK */
  5. {{/verror}}
If the attribute doesn't make any errors at the beginning it shows the second part. When I change the attribute which runs into a validation error it should changes and show the first part. 
When I execute the sourcecode it show the second part even after changing the attribute.

I hope you can help me :-/

Thank you in advanced and I wish you all nice holidays ;)
l.

Here is the code:
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  5. <script src="../steal/steal.js"></script>
  6. <script type="text/javascript">
  7.     steal(
  8.         'can/view/stache',
  9.         'can/map',
  10.         'can/list',
  11.         'can/map/define',
  12.         
  13.         function() {
  14.              can.stache.registerHelper("verror", function(data, prop, options) {
  15.                  var obj = data;
  16.                  // data is a mixin(?) function. I have to execute the function to get the map so I can use it.
  17.                  if(typeof obj == "function") {
  18.                      obj = obj();
  19.                  }
  20.                  else {
  21.                      return arguments[arguments-1].inverse(this);
  22.                  }
  23.                  
  24.                  // write the error list, which will be filled by the validate function, into errorlist
  25.                  errorlist = obj.attr("errorlist").attr(prop);
  26.                  
  27.                  // if the list has items it is positive.
  28.                  if(errorlist.length > 0) {
  29.                      return options.fn(errorlist);
  30.                  }
  31.                  
  32.                  return options.inverse(this);
  33.             });
  34.             
  35.             can.extend(can.Map.prototype, {
  36.                 
  37.                 // my validation function
  38.                 validate: function(prop) {
  39.                     
  40.                     // try to get the errorlist from the map.
  41.                     var errorlist = this.attr("errorlist");
  42.                     // if there is no errorlist (because it is the first call) create a new map
  43.                     if(errorlist === undefined) {
  44.                         errorlist = new can.Map();
  45.                         this.attr("errorlist", errorlist);
  46.                     }
  47.                     
  48.                     // try to get the errorlist for the attribute "prop"
  49.                     var proplist = errorlist.attr(prop);
  50.                     
  51.                     // if there is no list in errorlist (= first call for this prop) create new list
  52.                     if (proplist === undefined) {
  53.                         proplist = new can.List();
  54.                         errorlist.attr(prop, proplist);
  55.                     }
  56.                     // if there is already a list with error they will be erased.
  57.                     else if(proplist.length > 0) {
  58.                         proplist.splice(0,proplist.length);
  59.                     }
  60.                     
  61.                     if(typeof this.define[prop].validate == "function") {
  62.                         var vallist = new can.List();
  63.                         
  64.                         // call the validationplugin and write the erros into the temp. list "vallist"
  65.                         this.define[prop].validate.call(this, vallist);
  66.                 
  67.                         // write every item from vallist into the errorlist
  68.                         for(var i = 0; i < vallist.length; ++i) {
  69.                             var item = new can.Map();
  70.                             item.attr("errorcode", vallist[i]);
  71.                             item.attr("prop", prop);
  72.                             item.attr("other", "stuff");
  73.                             
  74.                             proplist.push(item);
  75.                         }
  76.                         
  77.                     }
  78.                 }
  79.             });
  80.         
  81.             
  82.             mappro = can.Map.prototype;
  83.            
  84.             var odset = mappro.__set;
  85.             mappro.__set = function (prop, value, current, success, error) {
  86.                 odset.call(this, prop, value, current, success, error);
  87.                 
  88.                 // Only if the map has a define map the validation will be executed.
  89.                 if(this.define && this.define[prop] && this.define[prop].validate) {
  90.                     this.validate.call(this, prop);
  91.                 }
  92.                 
  93.                 return this;
  94.             };           
  95.              var ExampleMap = can.Map.extend({
  96.                 define: {
  97.                     valStr: {
  98.                         type: "string",
  99.                         value: "",
  100.                         
  101.                         // my validation function for the attribute
  102.                         validate: function(errors) {
  103.                             if(this.valStr == "foo") {
  104.                                 errors.push("bar");
  105.                             }
  106.                         }
  107.                     },
  108.                     valNum: {
  109.                         type: "number",
  110.                         value: 10,
  111.                         validate: function(errors) {
  112.                             
  113.                             if(this.valNum > 100) {
  114.                                 errors.push("valNumTooHigh");
  115.                             }
  116.                             else if(this.valNum < 0) {
  117.                                 errors.push("valNumTooSmall");
  118.                             }
  119.                             
  120.                             if(this.valNum % 2 == 1) {
  121.                                 errors.push("ohNo");
  122.                             }
  123.                         }
  124.                     }
  125.                 }
  126.             });
  127.             
  128.             
  129.             mymap = new ExampleMap({
  130.                 valStr: "asdf"
  131.                 ,valNum: 123
  132.             });
  133.             
  134.             var data = new can.Map({
  135.                 mymap: mymap,
  136.                 foo: "bar"
  137.             });
  138.             
  139.             $("#div").html(can.view("tpl",data));
  140.         }
  141.     );
  142. </script>


  143. <script type="text/stache" id="tpl">
  144.     <div style="padding-bottom:50px">
  145.         <div>foo: {{foo}}</div>
  146.         <div>mymap: valStr:{{mymap.valStr}} / valNum: {{mymap.valNum}}</div>
  147.     </div>
  148.     
  149.     
  150.     <div> <strong>error list (valStr):</strong></div>
  151.     <div>
  152.         {{#verror mymap "valStr"}}
  153.             {{#each .}}
  154.             <div style="color:red"> errorcode: {{errorcode}}</div>
  155.             {{/each}}
  156.         {{else}}
  157.             <div style="color:green">everything is fine</div>
  158.         {{/verror}}
  159.     </div>
  160.     
  161.     <div> <strong>error list (valNum):</strong></div>
  162.     <div>
  163.         {{#verror mymap "valNum"}}
  164.             {{#each .}}
  165.             <div style="color:red"> errorcode: {{errorcode}}</div>
  166.             {{/each}}
  167.         {{else}}
  168.             <div style="color:green">everything is fine</div>
  169.         {{/verror}}
  170.     </div>
  171.     
  172. </script>
  173. </head>
  174. <body >
  175. <div>
  176.     <div id="div"></div>
  177. </div>
  178. </body>
  179. </html>
P.S.: Sorry for my bad english ;) 

Viewing all articles
Browse latest Browse all 3491

Trending Articles