1 /** 2 * @fileOverview JavaScript representation of the Finesse MediaPropertiesLayout object 3 * 4 * @name finesse.restservices.MediaPropertiesLayout 5 * @requires finesse.clientservices.ClientServices 6 * @requires Class 7 * @requires finesse.FinesseBase 8 * @requires finesse.restservices.RestBase 9 */ 10 11 var finesse = finesse || {}; 12 finesse.restservices = finesse.restservices || {}; 13 14 /** @private */ 15 finesse.restservices.MediaPropertiesLayout = finesse.restservices.RestBase.extend(/** @lends finesse.restservices.MediaPropertiesLayout.prototype */{ 16 17 /** 18 * @class 19 * JavaScript representation of a MediaPropertiesLayout object. Also exposes 20 * methods to operate on the object against the server. 21 * 22 * @param {Object} options 23 * An object with the following properties:<ul> 24 * <li><b>id:</b> The id of the object being constructed</li> 25 * <li><b>onLoad(this): (optional)</b> when the object is successfully loaded from the server</li> 26 * <li><b>onChange(this): (optional)</b> when an update notification of the object is received</li> 27 * <li><b>onAdd(this): (optional)</b> when a notification that the object is created is received</li> 28 * <li><b>onDelete(this): (optional)</b> when a notification that the object is deleted is received</li> 29 * <li><b>onError(rsp): (optional)</b> if loading of the object fails, invoked with the error response object:<ul> 30 * <li><b>status:</b> {Number} The HTTP status code returned</li> 31 * <li><b>content:</b> {String} Raw string of response</li> 32 * <li><b>object:</b> {Object} Parsed object of response</li> 33 * <li><b>error:</b> {Object} Wrapped exception that was caught:<ul> 34 * <li><b>errorType:</b> {String} Type of error that was caught</li> 35 * <li><b>errorMessage:</b> {String} Message associated with error</li> 36 * </ul></li> 37 * </ul></li> 38 * <li><b>parentObj: (optional)</b> The parent object</li></ul> 39 * @constructs finesse.restservices.MediaPropertiesLayout 40 **/ 41 init: function (options) { 42 this._super(options); 43 }, 44 45 /** 46 * @private 47 * Gets the REST class for the current object - this is the MediaPropertiesLayout object. 48 */ 49 getRestClass: function () { 50 return finesse.restservices.MediaPropertiesLayout; 51 }, 52 53 /** 54 * @private 55 * Gets the REST type for the current object - this is a "MediaPropertiesLayout". 56 */ 57 getRestType: function () { 58 return "MediaPropertiesLayout"; 59 }, 60 61 /** 62 * @private 63 * Overrides the parent class. Returns the url for the MediaPropertiesLayout resource 64 */ 65 getRestUrl: function () { 66 return ("/finesse/api/User/" + this.getId() + "/" + this.getRestType()); 67 }, 68 69 /** 70 * @private 71 * Returns whether this object supports subscriptions 72 */ 73 supportsSubscriptions: false, 74 75 /** 76 * Retrieve the media properties layout 77 * @returns {finesse.restservices.MediaPropertiesLayout} 78 * This MediaPropertiesLayout object to allow cascading 79 */ 80 get: function () { 81 this._synchronize(); 82 83 return this; //Allow cascading 84 }, 85 86 /** 87 * Gets the data for this object. 88 * 89 * Performs safe conversion from raw API data to ensure that the returned layout object 90 * always has a header with correct entry fields, and exactly two columns with lists of entries. 91 * 92 * @returns Object which are contained in data 93 */ 94 getData: function () { 95 96 var layout = this._data, result, _addColumnData; 97 98 result = this.getEmptyData(); 99 100 /** 101 * @private 102 */ 103 _addColumnData = function (entryData, colIndex) { 104 105 if (!entryData) { 106 //If there's no entry data at all, rewrite entryData to be an empty collection of entries 107 entryData = {}; 108 } else if (entryData.mediaProperty) { 109 //If entryData contains the keys for a single entry rather than being a collection of entries, 110 //rewrite it to be a collection containing a single entry 111 entryData = { "": entryData }; 112 } 113 114 //Add each of the entries in the list to the column 115 jQuery.each(entryData, function (i, entryData) { 116 117 //If the entry has no displayName specified, explicitly set it to the empty string 118 if (!entryData.displayName) { 119 entryData.displayName = ""; 120 } 121 122 result.columns[colIndex].push(entryData); 123 124 }); 125 126 }; 127 128 //The header should only contain a single entry 129 if (layout.header && layout.header.entry) { 130 131 //If the entry has no displayName specified, explicitly set it to the empty string 132 if (!layout.header.entry.displayName) { 133 layout.header.entry.displayName = ""; 134 } 135 136 result.header = layout.header.entry; 137 138 } else { 139 140 throw "MediaPropertiesLayout.getData() - Header does not contain an entry"; 141 142 } 143 144 //If the column object contains an entry object that wasn't part of a list of entries, 145 //it must be a single right-hand entry object (left-hand entry object would be part of a list.) 146 //Force the entry object to be the 2nd element in an otherwise-empty list. 147 if (layout.column && layout.column.entry) { 148 layout.column = [ 149 null, 150 { "entry": layout.column.entry } 151 ]; 152 } 153 154 if (layout.column && layout.column.length > 0 && layout.column.length <= 2) { 155 156 //Render left column entries 157 if (layout.column[0] && layout.column[0].entry) { 158 _addColumnData(layout.column[0].entry, 0); 159 } 160 161 //Render right column entries 162 if (layout.column[1] && layout.column[1].entry) { 163 _addColumnData(layout.column[1].entry, 1); 164 } 165 166 } 167 168 return result; 169 170 }, 171 172 /** 173 * Empty/template version of getData(). 174 * 175 * Used by getData(), and by callers of getData() in error cases. 176 */ 177 getEmptyData: function () { 178 179 return { 180 header : { 181 displayName: null, 182 mediaProperty: null 183 }, 184 columns : [[], []] 185 }; 186 187 }, 188 189 /** 190 * Set the layout of this MediaPropertiesLayout. 191 * @param {String} layout 192 * The layout you are setting 193 * @param {Object} handlers 194 * An object containing the following (optional) handlers for the request:<ul> 195 * <li><b>success(rsp):</b> A callback function for a successful request to be invoked with the following 196 * response object as its only parameter:<ul> 197 * <li><b>status:</b> {Number} The HTTP status code returned</li> 198 * <li><b>content:</b> {String} Raw string of response</li> 199 * <li><b>object:</b> {Object} Parsed object of response</li></ul> 200 * <li>A error callback function for an unsuccessful request to be invoked with the 201 * error response object as its only parameter:<ul> 202 * <li><b>status:</b> {Number} The HTTP status code returned</li> 203 * <li><b>content:</b> {String} Raw string of response</li> 204 * <li><b>object:</b> {Object} Parsed object of response (HTTP errors)</li> 205 * <li><b>error:</b> {Object} Wrapped exception that was caught:<ul> 206 * <li><b>errorType:</b> {String} Type of error that was caught</li> 207 * <li><b>errorMessage:</b> {String} Message associated with error</li> 208 * </ul></li> 209 * </ul> 210 * @returns {finesse.restservices.MediaPropertiesLayout} 211 * This MediaPropertiesLayout object to allow cascading 212 */ 213 setLayout: function (layout, handlers) { 214 215 var contentBody = {}; 216 217 contentBody[this.getRestType()] = layout; 218 219 //Protect against null dereferencing of options allowing its (nonexistant) keys to be read as undefined 220 handlers = handlers || {}; 221 222 this.restRequest(this.getRestUrl(), { 223 method: 'PUT', 224 success: handlers.success, 225 error: handlers.error, 226 content: contentBody 227 }); 228 229 return this; // Allow cascading 230 } 231 232 }); 233