if (!dojo._hasResource["dojox.wire.ml.Action"]) { // _hasResource checks added // by build. Do not use // _hasResource directly in // your code. dojo._hasResource["dojox.wire.ml.Action"] = true; dojo.provide("dojox.wire.ml.Action"); dojo.provide("dojox.wire.ml.ActionFilter"); dojo.require("dijit._Widget"); dojo.require("dijit._Container"); dojo.require("dojox.wire.Wire"); dojo.require("dojox.wire.ml.util"); dojo.declare("dojox.wire.ml.Action", [dijit._Widget, dijit._Container], { // summary: // A base widget to "run" a task on an event or a topic // description: // This widget represents a controller task to be run when an // event // (a function) or a topic is issued. // Sub-classes must implement _run() method to implement their // tasks. // 'trigger' specifies an event scope, an ID of a widget or an // DOM // element, or its property with the optional dotted notation. // If this widget has child ActionFilter widgets, their filter() // methods are called with the arguments to the event or the // topic. // If one of filter() methods returns false, run() won't be // invoked. // This widget also can serve as a composite task to run child // Actions on an event or a topic specified to this widget. // trigger: // An event scope // triggerEvent: // An event (function) name // triggerTopic: // A topic name trigger : "", triggerEvent : "", triggerTopic : "", postCreate : function() { // summary: // Call _connect() // description: // See _connect(). this._connect(); }, _connect : function() { // summary: // Connect run() method to an event or a topic // description: // If 'triggerEvent' and 'trigger' are specified, connect() // is // used to set up run() to be called on the event. // If 'triggerTopic' is specified, subscribe() is used to // set up // run() to be called on the topic. if (this.triggerEvent) { if (this.trigger) { var scope = dojox.wire.ml._getValue(this.trigger); if (scope) { if (!scope[this.triggerEvent]) { // set a dummy function for an anonymous // object scope[this.triggerEvent] = function() { }; } this._triggerHandle = dojo.connect(scope, this.triggerEvent, this, "run"); } } else { var event = this.triggerEvent.toLowerCase(); if (event == "onload") { var self = this; dojo.addOnLoad(function() { self._run.apply(self, arguments); }); } } } else if (this.triggerTopic) { this._triggerHandle = dojo.subscribe(this.triggerTopic, this, "run"); } }, _disconnect : function() { // summary: // Disconnect run() method from an event or a topic // description: // If 'triggerEvent' and 'trigger' are specified, // disconnect() is // used to set up run() not to be called on the event. // If 'triggerTopic' is specified, unsubscribe() is used to // set up // run() not to be called on the topic. if (this._triggerHandle) { if (this.triggerTopic) { dojo.unsubscribe(this.triggerTopic, this._triggerHandle); } else { dojo.disconnect(this._triggerHandle); } } }, run : function() { // summary: // Run a task // description: // This method calls filter() method of child ActionFilter // widgets. // If one of them returns false, this method returns. // Otherwise, _run() method is called. var children = this.getChildren(); for (var i in children) { var child = children[i]; if (child instanceof dojox.wire.ml.ActionFilter) { if (!child.filter.apply(child, arguments)) { return; } } } this._run.apply(this, arguments); }, _run : function() { // summary: // Call run() methods of child Action widgets // description: // If this widget has child Action widgets, their run() // methods // are called. var children = this.getChildren(); for (var i in children) { var child = children[i]; if (child instanceof dojox.wire.ml.Action) { child.run.apply(child, arguments); } } }, uninitialize : function() { // summary: // Over-ride of base widget unitialize function to do some // connection cleanup. this._disconnect(); return true; } }); dojo.declare("dojox.wire.ml.ActionFilter", dijit._Widget, { // summary: // A widget to define a filter for the parent Action to run // description: // This base class checks a required property specified with // 'required' attribute. // If 'message' is specified, the message is set to a property // specified with 'error'. // Subclasses may implement their own filter() method. // required: // A property required // requiredValue: // Optional. A specific value the property is required to have. // If this isn't provided // than any non-false/non-null value of the required propery // will cause this filter // to pass. // type: // Optional. A specific type to compare the values as (if // requiredValue is set) // Valid values for type are boolean, int, string. Default is // string. // message: // An error message to emit if the filter doesn't execute due to // property mismatch. // error: // A property to store an error due to property mismatch. required : "", requiredValue : "", type : "", message : "", error : "", filter : function() { // summary: // Check if a required property is specified. Also, if // provided, check to see // if the required property contains a specific value. // description: // If a value is undefined for a property, specified with // 'required', this method returns false. // If the value for a property is defined, but there isn't a // requiredValue for it // then any non-false value will cause the method to return // true. // if requiredValue is set, then filter compares that value // with the value from // the required property and returns true if and only if // they match. // The type option just allows for a way to convert the // required property values // into a proper form for comparison (boolean, number, etc). // If 'message' is specified, it is set to a proeprty // specified // with 'error' or shown with alert(). // If 'required' starts with "arguments", a property of // the method arguments are checked. // returns: // True if a required property is specified (and if // requiredValue is specified, // that they match), otherwise false if (this.required === "") { return true; // Boolean } else { var value = dojox.wire.ml._getValue(this.required, arguments); if (this.requiredValue === "") { // Just see if there's a value, nothing to compare // it to. if (value) { return true; // Boolean } } else { // See if we need to type convert. var reqValue = this.requiredValue; if (this.type !== "") { var lType = this.type.toLowerCase(); if (lType === "boolean") { if (reqValue.toLowerCase() === "false") { reqValue = false; } else { reqValue = true; } } else if (lType === "number") { reqValue = parseInt(reqValue, 10); } } if (value === reqValue) { return true; // boolean } } } if (this.message) { if (this.error) { dojox.wire.ml._setValue(this.error, this.message); } else { alert(this.message); } } return false; // Boolean } }); }