1!function ($) { 2 3 // ------------------------------------------ 4 // PRIVATE 5 // ------------------------------------------ 6 7 var register = function(){ 8 setup(); 9 $(document).on('jalios:refresh', callback); 10 } 11 12 var callback = function(event){ 13 14 var refresh = $.jalios.Event.match(event, 'refresh', 'after') 15 if (!refresh){ return; } 16 if (!refresh.target){ return; } 17 18 setup(refresh.target); 19 } 20 21 var setup = function($container){ 22 23 $container = $container || $(document); 24 25 // Handle generic drag and drop lists 26 $container.find('UL.sortable, OL.sortable').each(function(){ 27 $.jalios.Sortable.buildSortable(this, { 28 'connectWith' : $(this).attr('data-jalios-sortable-connect') 29 }); 30 }); 31 32 var clazz = 'sortable-active'; 33 34 // Handle generic drag and drop container 35 $container.find('DIV.dnd-container').each(function(){ 36 var $this = $(this); 37 var axis = $this.hasClass('dnd-horizontal') ? 'x' : $this.hasClass('dnd-vertical') ? 'y' : false; 38 $.jalios.Sortable.buildSortable(this, { 39 'items': '> DIV', 40 'axis': axis, 41 'revert': true, 42 'handle': '.dnd-header, .dnd-handle', 43 'placeholder' : 'dnd-placeholder', 44 'connectWith': $this.hasClass('dnd-single') || axis ? false : 'DIV.dnd-container' 45 }); 46 }); 47 } 48 49 var hover = function(sortable, on){ 50 var $this = $(sortable); 51 if ( on && $this.hasClass('sortable-active')){ return; } 52 if (!on && !$this.hasClass('sortable-active')){ return; } 53 $this.toggleClass('sortable-active', on); 54 } 55 56 var trigger = function(that, ui){ 57 58 var $that = $(that); 59 60 if ($that.hasClass('dnd-debug')) { 61 // http://stackoverflow.com/questions/3492828/jquery-sortable-connectwith-calls-the-update-method-twice 62 if (that === ui.item.parent()[0]) { 63 // the movement was from one container to another, ui.sender is the reference to original container 64 if (ui.sender !== null) { 65 jQuery.console.log('[jalios-sortable]', ' item' , ui.item, ' moved from container', ui.sender, ' to ', $that); 66 } 67 // the move was performed within the same container 68 else { 69 jQuery.console.log('[jalios-sortable]', ' item ', ui.item, ' moved inside container', $that); 70 } 71 } 72 } 73 74 // If dnd-single-update was specified on container, 75 // Only send one 'jalios:sortable' and DataBroker event for all 'update' event sent by jQuery sortable, 76 // merging all container parameters at once 77 var singleDndUpdate = $that.hasClass('dnd-single-update'); 78 if (singleDndUpdate && that !== ui.item.parent()[0]) { 79 return; 80 } 81 82 // Trigger a document Event 83 var event = jQuery.Event("jalios:sortable"); 84 event.sortable = { 85 'container' : $that, 86 'ui' : ui 87 }; 88 $(document).trigger(event); 89 90 // Trigger DataBroker Event 91 var serialize = $.jalios.Sortable.serialize($that, $that.hasClass('dnd-container') ? 'dnd-sortable' : false); 92 93 // for single update event, also include the serialization of the sender container 94 if (singleDndUpdate && ui.sender !== null) { 95 var senderSerialize = $.jalios.Sortable.serialize(ui.sender, $(ui.sender).hasClass('dnd-container') ? 'dnd-sortable-sender' : 'sortable-sender'); 96 serialize = $.extend(serialize, senderSerialize); 97 } 98 99 event.currentTarget = that; 100 $.jalios.DataBroker.trigger($that, event, { 101 params : serialize 102 }); 103 104 } 105 106 // ------------------------------------------ 107 // PUBLIC 108 // ------------------------------------------ 109 110 // Namespace 111 if (!$.jalios) { $.jalios = {}; } 112 113 /** 114 * Provides mechanisms to handle sortable (drag and drop) of list's items and container's boxes using jQueryUI Sortable Widget. 115 * <br/><br/> 116 * 117 * <h5>List</h5> 118 * List with classes <code>UL.sortable</code> and <code>OL.sortable</code> will trigger this feature. 119 * <ul> 120 * <li><code>.sortable-x</code> constraint horizontal drag</li> 121 * <li><code>.sortable-y</code> constraint vertical drag</li> 122 * <li><code>.sortable-handle</code> define drag handle and must be on sortable</li> 123 * <li><code>.sortable-disable</code> element to bypass</li> 124 * </ul> 125 * 126 * Attribute <code>data-jalios-sortable-connect</code> define the sortable to connect with 127 * 128 * <h5>Boxes</h5> 129 * DIV with classes <code>DIV.dnd-container</code> will trigger this feature. 130 * <ul> 131 * <li><code>.dnd-horizontal</code> constraint horizontal drag</li> 132 * <li><code>
132.dnd-vertical</code> constraint vertical drag</li> 133 * <li><code>.dnd-single</code> prevent a connection with other dnd-container</li> 134 * <li><code>.dnd-single-update</code> will trigger only one jalios:sortable event and databroker event for all connection with other dnd-container</li> 135 * <li><code>.dnd-debug</code> will print update event in browser console</li> 136 * <li><code>.dnd-noresponse</code> for portal ajax refresh, the DOM will not be refresh with the response.</li> 137 * </ul> 138 * 139 * <h5>Events</h5> 140 * An event <code>jalios:sortable</code> is trigged when a drop has been performed. 141 * <ul> 142 * <li>sortable.container: the container element (dnd-sortable forboxes)</li> 143 * <li>sortable.ui: the jQuery sortable ui event</code></li> 144 * </ul> 145 * 146 * A broker event is also performed to trigger listeners: ajax-refresh, modal, ...<br/> 147 * 148 * The options's param is filled with the serialised content 149 * 150 * <h5>FIXME</h5> 151 * <ul> 152 * <li>Handle connectWith on list</li> 153 * <li>Handle nested list</li> 154 * </ul> 155 * 156 * @namespace $.jalios.Sortable 157 * @copyright Jalios SA 158 * @see $.jalios.DataBroker 159 * @see $.jalios.AjaxRefresh 160 * 161 * @example 162 * 163 * Drop will trigger action ajax-refresh on UL with parameters: key=HelloA&key=HelloB&key=HelloC&key=HelloD&sortable=key 164 * 165 * <ul id="key" class='sortable' data-jalios-action="ajax-refresh"> 166 * <li data-value="HelloA"><a href='#'>Hello World 1</a></li> 167 * <li id="HelloB"><a href='#'>Hello World 2</a> Yep</li> 168 * <li data-value="HelloC"><a href='#'>Hello World 3</a></li> 169 * <li data-value="HelloD"><a href='#'>Hello World 4</a></li> 170 * </ul> 171 * 172 * @example 173 * 174 * Drop on first column will trigger an ajax-refresh on dnd-container with parameters: bind1=c_1234&bind1=c_1234&bind1=c_1234&sortable=bind1. 175 * 176 * This behavior simplifed by jalios-sortable-portal.js (data-jalios-action attribute is not required). PortletCollection includes doAjaxHandleSortable.jsp to updates portlet bindings 177 * 178 * <jalios:buffer name="box"> 179 * <div class='box ID_c_1234'> 180 * <div class="box-header dnd-handle"><h3>Box title</h3></div> 181 * <div class="box-body">Box body</div> 182 * <div class="box-footer">Box footer</a></div> 183 * </div> 184 * </jalios:buffer> 185 * 186 * <div class='row-fluid'> 187 * <div id="bind1" class='span4 dnd-container'> 188 * <%= box %> <%= box %> <%= box %> 189 * </div> 190 * <div id="bind2" class='span4 dnd-container'> 191 * <%= box %> <%= box %> <%= box %> 192 * </div> 193 * <div id="bind3" class='span4 dnd-container'> 194 * <%= box %> <%= box %> <%= box %> 195 * </div> 196 * </div> 197 * 198 */ 199 200 $.jalios.Sortable = { 201 202 /** 203 * Serialize a given sortable with serialized children.<br/> 204 * Do not use defaut serialisation because of JcmsID and other custom behavior. 205 * 206 * @param container the selector of the container 207 * @param key optionnal parameter key to be used to send the container id 208 * @return a JSON object representation 209 */ 210 serialize: function(container, key){ 211 212 var key = key || 'sortable'; 213 214 // Perform selector 215 var $container = $(container); 216 217 // Serialize sortable items 218 var serial = $container.children().map(function() { // FIXME: should escape some children 219 var $this = $(this); 220 221 // Retrive data-value ou JcmsId 222 var value = $this.attr('data-value') || $this.getJcmsId(); 223 if (value){ return value; } 224 225 // look into first child (Handle wrappers grid) 226 var $child = $this.children(':first'); 227 value = $child.attr('data-value') || $child.getJcmsId(); 228 if (value){ return value; } 229 230 // At last use ID 231 return $this.attr('id'); 232 }).get(); 233 234 // Build sortable key 235 var sortable = $.jalios.Sortable.getSortableKey($container); 236 237 // Build params 238 var params = {}; 239 240 var additionnalParams = $container.attr('data-sortable-params');
241 try { 242 params = $.extend(params, additionnalParams && JSON.parse( additionnalParams )); 243 } catch ( error ) { 244 jQuery.console.error('Error parsing data-sortable-params on ', $container, error ); 245 } 246 247 params[key || 'sortable'] = sortable; 248 params[sortable] = serial; 249 250 // Returns the serialized representation 251 return params; 252 }, 253 254 getSortableKey: function($sortable){ 255 return $sortable.attr('data-value') || $sortable.attr('id') || $sortable.getJcmsId() || 'sortitem'; 256 }, 257 258 /** 259 * Build a sortable for the given element using css declaration of list (sortable-*).<br/> 260 * Used by sortable-widget.js to lazy kickstart sortable on focusin. 261 * 262 * @param element the element to work with 263 * 264 */ 265 buildSortable: function(element, options){ 266 var $e = $(element); 267 var options = options || {}; 268 $e.sortable({ 269 'items': options.items || '> LI', // Only LI 270 'cancel': options.cancel || '.sortable-disable, :input', 271 'axis': options.axis || ($e.hasClass('sortable-x') ? 'x' : $e.hasClass('sortable-y') ? 'y' : false), 272 'revert' : options.revert || true, 273 'handle': options.handle || ($e.hasClass('sortable-handle') ? '.sortable-handle' : false), 274 'connectWith': options.connectWith || false, 275 'tolerance': options.tolerance || 'intersect', 276 'placeholder': options.placeholder, 277 'update': function(evt, ui){ trigger(this, ui); }, 278 'stop': function(evt, ui){ hover(this, false); }, 279 'sort': function(evt, ui){ hover(this, true); }, 280 'out': function(evt, ui){ hover(this, false); }, 281 'over': function(evt, ui){ hover(this, true); } 282 }); 283 } 284 } 285 286 // ------------------------------------------ 287 // FUNCTION 288 // ------------------------------------------ 289 290 $.fn.sortable = $.fn.sortable || {}; 291 292 $.fn.sortable.add = function(value){ 293 var $elm = $(value); 294 if (!$elm.exists()){ 295 var tag = $(this).hasClass('sortable') ? 'li' : 'div'; 296 $elm = $('<'+tag+' data-value="'+value+'"></'+tag+'>'); 297 } 298 299 return this.each(function() { 300 $(this).append($elm); 301 trigger(this); 302 }); 303 } 304 305 $.fn.sortable.remove = function(elm){ 306 $(elm).remove(); 307 return this.each(function() { 308 trigger(this); 309 }); 310 } 311 312 // ------------------------------------------ 313 // DOM Ready 314 // ------------------------------------------ 315 316 317 // Plugin initialization on DOM ready 318 $(document).ready(function($) { 319 register(); 320 }); 321 322}(window.jQuery); 323 324 325 // ------------------------------------------ 326 // DEPRECATED 327 // ------------------------------------------ 328 329 var Sortable = {}; 330 Sortable.create = function(){ 331 jQuery.console.warn("[Deprecated] JCMS requires the new Sortable framework"); 332 jQuery.console.stacktrace(); 333 } 334 Sortable.destroy = function(){ 335 jQuery.console.warn("[Deprecated] JCMS requires the new Sortable framework"); 336 jQuery.console.stacktrace(); 337 } 338 339 var Droppables = {}; 340 Droppables.add = function(){ 341 jQuery.console.warn("[Deprecated] JCMS requires the new Sortable framework"); 342 jQuery.console.stacktrace(); 343 } 344 345 var PortalSortable = {}; 346 PortalSortable.create = function(){ 347 jQuery.console.warn("[Deprecated] JCMS requires the new Sortable framework"); 348 jQuery.console.stacktrace(); 349 }
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.