cellItem.js
6.56 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
/**
* Individual cell view.
*
*/
define( ['views/emptyCell'], function( EmptyCell ) {
var view = Marionette.CollectionView.extend( {
tagname: 'div',
className: 'layouts-cell',
emptyView: EmptyCell,
dropping: false,
initialize: function( options ) {
// Set our collection to the fields within this cell
this.collection = this.model.get( 'fields' );
// Get our field view from Ninja Forms core.
this.childView = nfRadio.channel( 'views' ).request( 'get:fieldItem' );
// Get the collection to which this cell belongs.
this.cellCollection = options.cellCollection;
},
/**
* When we render we need to:
* 1) Set a data attribute on our cell element representing width.
* 2) Set a data attribute on our cell element representing the cell model.
* 3) Set classes on our cell element based upon how many fields it contains.
* 4) Make our cell sortable droppable if we have more than one cell in the collection.
* 5) Init our sortable.
*
* @since version
* @return {[type]} [description]
*/
onRender: function() {
jQuery( this.el ).data( 'width', this.model.get( 'width' ) );
jQuery( this.el ).data( 'model', this.model );
// Used during troubleshooting to add a class to the cell element.
// jQuery( this.el ).addClass( this.model.cid );
// if ( 1 < this.cellCollection.length ) {
// jQuery( this.el ).addClass( 'layouts-droppable nf-fields-sortable' );
// } else { // we want a draggable.
// }
// Set a class based upon how many fields are in our cell.
if ( this.collection.models.length == 1 ) {
jQuery( this.el ).addClass( 'single-field' );
jQuery( this.el ).removeClass( 'multi-field' );
} else {
jQuery( this.el ).addClass( 'multi-field' );
jQuery( this.el ).removeClass( 'single-field' );
}
// Make this cell droppable if we have more than one field.
if ( 1 < this.cellCollection.length ) {
jQuery( this.el ).addClass( 'layouts-droppable' );
// If we have multiple cells in this row, make this cell droppable for new fields
jQuery( this.el ).addClass( 'nf-field-type-droppable' );
} else {
jQuery( this.el ).removeClass( 'nf-field-type-droppable' );
jQuery( this.el ).removeClass( 'layouts-droppable' );
}
// Init our sortable.
this.initSortable();
},
/**
* Initialize our sortable.
* Sends out radio messages when there are sortable events.
*
* @since 3.0
* @return void
*/
initSortable: function() {
var that = this;
jQuery( this.el ).sortable( {
// Don't let the item controls be used as a handle.
cancel: '.nf-item-controls',
// Class name of our placeholder. Adds the green highlight.
placeholder: 'nf-fields-sortable-placeholder',
// Opacity of the draggable
opacity: 0.95,
// Acceptable items.
items: '.nf-field-wrap, .nf-stage',
// We care about the pointer, not an intersection.
tolerance: 'pointer',
// Allows us to drop items from this sortable into others.
connectWith: '.layouts-droppable',
// Update droppable areas as we drag. Important because of the "swell" effect on the builder.
refreshPositions: true,
appendTo: '#nf-main',
/**
* Return a helper that will be used for the drag event of the sortable.
*
* @since 3.0
* @param object e event object
* @return object drag element
*/
helper: function( e ) {
var element = nfRadio.channel( 'layouts' ).request( 'getHelper:cellSortable', e, that, this );
return element;
},
/**
* When we hover over our sortable while dragging, send out a radio message.
*
* @since 3.0
* @param object e event object
* @param object ui jQuery UI object
* @return void
*/
over: function( e, ui ) {
nfRadio.channel( 'layouts' ).trigger( 'over:cellSortable', e, ui, that, this );
},
/**
* When we hover over out of our sortable while dragging, send out a radio message.
*
* @since 3.0
* @param object e event object
* @param object ui jQuery UI object
* @return void
*/
out: function( e, ui ) {
nfRadio.channel( 'layouts' ).trigger( 'out:cellSortable', e, ui, that, this );
},
/**
* When we sort our sortable while dragging, send out a radio message.
*
* @since 3.0
* @param object e event object
* @param object ui jQuery UI object
* @return void
*/
sort: function( e, ui) {
nfRadio.channel( 'layouts' ).trigger( 'sort:cellSortable', e, ui, that, this );
},
/**
* When we receive an item, send out a radio message.
*
* @since 3.0
* @param object e event object
* @param object ui jQuery UI object
* @return void
*/
receive: function( e, ui ) {
if ( ui.item.dropping ) return;
nfRadio.channel( 'layouts' ).trigger( 'receive:cellSortable', e, ui, that, this );
},
/**
* When we start dragging, send out a radio message.
*
* @since 3.0
* @param object e event object
* @param object ui jQuery UI object
* @return void
*/
start: function( e, ui ) {
nfRadio.channel( 'layouts' ).trigger( 'start:cellSortable', e, ui, that, this );
},
/**
* When we stop dragging, send out a radio message.
*
* @since 3.0
* @param object e event object
* @param object ui jQuery UI object
* @return void
*/
stop: function( e, ui ) {
nfRadio.channel( 'layouts' ).trigger( 'stop:cellSortable', e, ui, that, this );
},
/**
* When we update our sortable order, send out a radio message.
*
* @since 3.0
* @param object e event object
* @param object ui jQuery UI object
* @return void
*/
update: function( e, ui ) {
nfRadio.channel( 'layouts' ).trigger( 'update:cellSortable', e, ui, that, this );
}
} );
},
/**
* Template helper functions
*
* @since 3.0
* @return void
*/
templateHelpers: function() {
return {
renderHandleBefore: function() {
return '<div class="layouts-handle"></div>';
},
renderHandleAfter: function() {
return '<div class="layouts-handle"></div>';
}
};
},
/**
* View events
*
* @type {Object}
*/
events: {
'click .delete': 'clickDeleteCell'
},
/**
* When the user clicks to delete a cell, remove the model.
*
* @since 3.0
* @param {Object} e event object
* @return void
*/
clickDeleteCell: function( e ) {
nfRadio.channel( 'layouts' ).trigger( 'click:deleteCell', e, this );
}
} );
return view;
} );