@@ -88,6 +88,57 @@ impl Event {
8888 }
8989}
9090
91+ /// An event raised by one of the Sortable callbacks. See [the official documentation](https://github.com/SortableJS/Sortable/#move-event-object) for details about the fields.
92+ ///
93+ /// `raw_event` contains the raw JS event, should additional non-documented
94+ /// fields be needed.
95+ #[ derive( Clone , Debug ) ]
96+ pub struct MoveEvent {
97+ pub raw_event : js_sys:: Object ,
98+ pub to : web_sys:: HtmlElement ,
99+ pub from : web_sys:: HtmlElement ,
100+ pub dragged : web_sys:: HtmlElement ,
101+ // TODO: cast fails? pub dragged_rect: web_sys::DomRect,
102+ pub related : web_sys:: HtmlElement ,
103+ // TODO: cast fails? pub related_rect: web_sys::DomRect,
104+ pub will_insert_after : bool ,
105+ }
106+
107+ impl MoveEvent {
108+ fn from_raw_event ( raw_event : js_sys:: Object ) -> MoveEvent {
109+ macro_rules! get {
110+ ( $field: expr) => {
111+ js_sys:: Reflect :: get( & raw_event, & JsValue :: from_str( $field) )
112+ . expect( "failed retrieving field from raw event" )
113+ . dyn_into( )
114+ . expect( "failed casting field of raw event to proper type" )
115+ } ;
116+ }
117+ let will_insert_after =
118+ js_sys:: Reflect :: get ( & raw_event, & JsValue :: from_str ( "willInsertAfter" ) )
119+ . expect ( "failed retrieving field from raw event" )
120+ . as_bool ( )
121+ . expect ( "willInsertAfter was not a boolean" ) ;
122+ MoveEvent {
123+ to : get ! ( "to" ) ,
124+ from : get ! ( "from" ) ,
125+ dragged : get ! ( "dragged" ) ,
126+ // dragged_rect: get!("draggedRect"),
127+ related : get ! ( "related" ) ,
128+ // related_rect: get!("relatedRect"),
129+ will_insert_after,
130+ raw_event,
131+ }
132+ }
133+ }
134+
135+ pub enum MoveResponse {
136+ Cancel ,
137+ InsertBefore ,
138+ InsertAfter ,
139+ InsertDefault ,
140+ }
141+
91142#[ repr( usize ) ]
92143enum CallbackId {
93144 Choose ,
@@ -109,6 +160,7 @@ enum CallbackId {
109160pub struct Options {
110161 options : js_sys:: Object ,
111162 callbacks : [ Option < Rc < Closure < dyn FnMut ( js_sys:: Object ) > > > ; CallbackId :: _Total as usize ] ,
163+ on_move_cb : Option < Rc < Closure < dyn FnMut ( js_sys:: Object , js_sys:: Object ) -> JsValue > > > ,
112164}
113165
114166macro_rules! option {
@@ -148,6 +200,7 @@ impl Options {
148200 Options {
149201 options : js_sys:: Object :: new ( ) ,
150202 callbacks : std:: array:: from_fn ( |_| None ) ,
203+ on_move_cb : None ,
151204 }
152205 }
153206
@@ -208,7 +261,24 @@ impl Options {
208261 callback ! ( on_clone, "onClone" , Clone ) ;
209262 callback ! ( on_change, "onChange" , Change ) ;
210263
211- // TODO: onMove
264+ pub fn on_move (
265+ & mut self ,
266+ mut cb : impl ' static + FnMut ( MoveEvent , js_sys:: Object ) -> MoveResponse ,
267+ ) -> & Options {
268+ let cb = Closure :: new ( move |evt : js_sys:: Object , original_evt : js_sys:: Object | {
269+ match cb ( MoveEvent :: from_raw_event ( evt) , original_evt) {
270+ MoveResponse :: Cancel => JsValue :: FALSE ,
271+ MoveResponse :: InsertBefore => JsValue :: from_f64 ( -1. ) ,
272+ MoveResponse :: InsertAfter => JsValue :: from_f64 ( 1. ) ,
273+ MoveResponse :: InsertDefault => JsValue :: TRUE ,
274+ }
275+ } ) ;
276+ let res = js_sys:: Reflect :: set ( & self . options , & JsValue :: from_str ( "onMove" ) , cb. as_ref ( ) )
277+ . expect ( "setting callback on object failed" ) ;
278+ assert ! ( res, "failed setting callback on object" ) ;
279+ self . on_move_cb = Some ( Rc :: new ( cb) ) ;
280+ self
281+ }
212282
213283 // RevertOnSpill / RemoveOnSpill plugins
214284 option ! ( revert_on_spill, "revertOnSpill" , bool , from_bool) ;
@@ -237,6 +307,7 @@ impl Options {
237307 raw_object,
238308 sortable,
239309 _callbacks : self . callbacks . clone ( ) ,
310+ _on_move_cb : self . on_move_cb . clone ( ) ,
240311 }
241312 }
242313}
@@ -256,6 +327,7 @@ pub struct Sortable {
256327
257328 /// Keep the callbacks alive
258329 _callbacks : [ Option < Rc < Closure < dyn FnMut ( js_sys:: Object ) > > > ; CallbackId :: _Total as usize ] ,
330+ _on_move_cb : Option < Rc < Closure < dyn FnMut ( js_sys:: Object , js_sys:: Object ) -> JsValue > > > ,
259331}
260332
261333impl Drop for Sortable {
0 commit comments