1 // ==========================================================================
  2 // Project:   The M-Project - Mobile HTML5 Application Framework
  3 // Copyright: (c) 2010 M-Way Solutions GmbH. All rights reserved.
  4 //            (c) 2011 panacoda GmbH. All rights reserved.
  5 // Creator:   Dominik
  6 // Date:      02.11.2010
  7 // License:   Dual licensed under the MIT or GPL Version 2 licenses.
  8 //            http://github.com/mwaylabs/The-M-Project/blob/master/MIT-LICENSE
  9 //            http://github.com/mwaylabs/The-M-Project/blob/master/GPL-LICENSE
 10 // ==========================================================================
 11 
 12 /**
 13  * @class
 14  *
 15  * This defines the prototype for any button view. A button is a view element that is
 16  * typically used for triggering an action, e.g. switching to another page, firing a
 17  * request or opening a dialog.
 18  *
 19  * @extends M.View
 20  */
 21 M.ButtonView = M.View.extend(
 22 /** @scope M.ButtonView.prototype */ {
 23 
 24     /**
 25      * The type of this object.
 26      *
 27      * @type String
 28      */
 29     type: 'M.ButtonView',
 30 
 31     /**
 32      * Determines whether this button is active or not.
 33      *
 34      * Note: This property is only used if the button is part of a button group (M.ButtonGroupView).
 35      *
 36      * @type Boolean
 37      */
 38     isActive: NO,
 39 
 40     /**
 41      * Determines whether to display the button ony with an icon but no text or not.
 42      *
 43      * @type Boolean
 44      */
 45     isIconOnly: NO,
 46 
 47     /**
 48      * This property can be used to specify a certain hyperlink type for this button. It only
 49      * works in combination with the hyperlinkTarget property.
 50      *
 51      * @type String
 52      */
 53     hyperlinkType: null,
 54 
 55     /**
 56      * This property can be used to specify a hyperlink target for this button. It only
 57      * works in combination with the hyperlinkType property.
 58      *
 59      * @type String
 60      */
 61     hyperlinkTarget: null,
 62 
 63     /**
 64      * This property can be used to specify a tag, that is independent from the button's
 65      * value. This allows you to identify a button, without having to worry about changes
 66      * to its value.
 67      *
 68      * @type String
 69      */
 70     tag: null,
 71 
 72     /**
 73      * This property specifies the recommended events for this type of view.
 74      *
 75      * @type Array
 76      */
 77     recommendedEvents: ['click', 'tap'],
 78 
 79     /**
 80      * Renders a button as an input tag. Input is automatically converted by jQuery mobile.
 81      *
 82      * @private
 83      * @returns {String} The button view's html representation.
 84      */
 85     render: function() {
 86         this.computeValue();
 87         this.html += '<a data-role="button" id="' + this.id + '"' + this.style() + ' ';
 88 
 89         if(this.hyperlinkTarget && this.hyperlinkType) {
 90             switch (this.hyperlinkType) {
 91                 case M.HYPERLINK_EMAIL:
 92                     this.html += 'rel="external" href="mailto:' + this.hyperlinkTarget + '"';
 93                     break;
 94                 case M.HYPERLINK_WEBSITE:
 95                     this.html += 'rel="external" target="_blank" href="' + this.hyperlinkTarget + '"';
 96                     break;
 97                 case M.HYPERLINK_PHONE:
 98                     this.html += 'rel="external" href="tel:' + this.hyperlinkTarget + '"';
 99                     break;
100             }
101         } else {
102             this.html += 'href="#"';
103         }
104 
105         this.html += '>' + this.value + '</a>';
106 
107         return this.html;
108     },
109 
110     /**
111      * This method is responsible for registering events for view elements and its child views. It
112      * basically passes the view's event-property to M.EventDispatcher to bind the appropriate
113      * events.
114      *
115      * It extend M.View's registerEvents method with some special stuff for list views and their
116      * internal events.
117      */
118     registerEvents: function() {
119         if(!this.internalEvents) {
120             this.internalEvents = {
121                 tap: {
122                     target: this,
123                     action: 'dispatchEvent'
124                 }
125             }
126         }
127         this.bindToCaller(this, M.View.registerEvents)();
128     },
129 
130     /**
131      * Updates the value of the button with DOM access by jQuery.
132      *
133      * @private
134      */
135     renderUpdate: function() {
136         this.computeValue();
137         if(this.parentView && this.parentView.type === 'M.ButtonGroupView') {
138             $('#' + this.id).find('.ui-btn-text').text(this.value);
139         } else {
140             $('#' + this.id).parent().find('.ui-btn-text').text(this.value);
141         }
142     },
143 
144     /**
145      * Sets the button's value and calls renderUpdate() to make the value update visible.
146      *
147      * @param {String} value The button's new value.
148      */
149     setValue: function(value) {
150         this.value = value;
151         this.renderUpdate();
152     },
153 
154     /**
155      * Triggers the rendering engine, jQuery mobile, to style the button.
156      *
157      * @private
158      */
159     theme: function() {
160         /* theme only if not already done */
161         if(!$('#' + this.id).hasClass('ui-btn')) {
162             $('#' + this.id).button();
163         }
164     },
165 
166     /**
167      * Applies some style-attributes to the button.
168      *
169      * @private
170      * @returns {String} The button's styling as html representation.
171      */
172     style: function() {
173         var html = '';
174         if(this.isInline) {
175             html += ' data-inline="true"';
176         }
177         if(this.icon) {
178             html += ' data-icon="' + this.icon + '"';
179         }
180         if(this.cssClass) {
181             html += ' data-theme="' + this.cssClass + '"';
182         }
183         if(this.isIconOnly) {
184             html += ' data-iconpos="notext"';
185         }
186         if(this.cssStyle) {
187             html += 'style="' + this.cssStyle + '"';
188         }
189         return html;
190     },
191 
192     /**
193      * This method is called right before the page is loaded. If a beforeLoad-action is defined
194      * for the page, it is now called.
195      *
196      * @param {String} id The DOM id of the event target.
197      * @param {Object} event The DOM event.
198      * @param {Object} nextEvent The next event (external event), if specified.
199      */
200     dispatchEvent: function(id, event, nextEvent) {
201         if(this.isEnabled && nextEvent) {
202             M.EventDispatcher.callHandler(nextEvent, event, YES);
203         }
204     },
205 
206     /**
207      * This method can be used to disable the button. This leads to a visual 'disabled' look and
208      * disabled the buttons tap/click events.
209      */
210     disable: function() {
211         if(this.isEnabled) {
212             var html = $('#' + this.id).html();
213             html = '<div data-theme="c" class="ui-shadow ui-disabled" aria-disabled="true">' + html + '</div>';
214             $('#' + this.id).html(html);
215             this.isEnabled = NO;
216         }
217     },
218 
219     /**
220      * This method can be used to enable a disabled button and make it usable again.
221      */
222     enable: function() {
223         if(!this.isEnabled) {
224             var html = $('#' + this.id + ' div').html();
225             $('#' + this.id).html(html);
226             this.isEnabled = YES;
227         }
228     }
229 
230 });