Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/phabricator
Path: blob/master/webroot/rsrc/js/core/MultirowRowManager.js
12241 views
1
/**
2
* @requires javelin-install
3
* javelin-stratcom
4
* javelin-dom
5
* javelin-util
6
* @provides multirow-row-manager
7
* @javelin
8
*/
9
10
11
/**
12
* Give a MultirowRowManager a table DOM elem to manage.
13
* You can add rows, and provide a given ID if you like.
14
* You can update rows by ID.
15
* Rows are automatically equipped with a removal button.
16
* You can listen to the 'row-removed' event on the Manager to get
17
* notifications of these row removals, with the DOM id of the removed
18
* row as event data.
19
*/
20
JX.install('MultirowRowManager', {
21
/**
22
* @param DOM element <table> root Container for rows
23
*/
24
construct : function(root, minRows) {
25
this._root = root;
26
this._rows = [];
27
28
if (typeof minRows !== 'undefined') {
29
this._minRows = minRows;
30
} else {
31
this._minRows = 1;
32
}
33
34
JX.DOM.listen(
35
this._root,
36
'click',
37
JX.MultirowRowManager._removeSigil,
38
JX.bind(this, this._onrowremoved));
39
},
40
41
members : {
42
_count : 0,
43
_nextID : 0,
44
_root : null,
45
_rows : null,
46
47
_generateRowID : function() {
48
return '' + this._nextID++;
49
},
50
51
_wrapRowContents : function(row_id, row_contents) {
52
var row = JX.$N('tr',
53
{ sigil : JX.MultirowRowManager.getRowSigil(),
54
meta : { multirow_row_manager_row_id : row_id }
55
},
56
row_contents);
57
58
var removeButton = JX.$N(
59
'td',
60
{ className: 'remove-column' },
61
JX.$N(
62
'a',
63
{ className: 'button simple',
64
sigil: JX.MultirowRowManager._removeSigil
65
},
66
'Remove'));
67
68
JX.DOM.appendContent(row, removeButton);
69
return row;
70
},
71
72
getRowID : function(row) {
73
return JX.Stratcom.getData(row).multirow_row_manager_row_id;
74
},
75
/**
76
* @param row_contents [DOM elements] New contents of row
77
* @param row_id row ID to update, will throw if this row has been removed
78
*/
79
updateRow : function(row_id, row_contents) {
80
if (__DEV__) {
81
if (typeof this._rows[row_id] === 'undefined') {
82
throw new Error('JX.MultirowRowManager.updateRow(row_id, ' +
83
'row_contents): provided row id does not exist.' +
84
' Use addRow to create a new row and make sure ' +
85
'not to update rows that have been deleted.');
86
}
87
}
88
var old_row = this._rows[row_id];
89
var new_row = this._wrapRowContents(row_id, row_contents);
90
JX.copy(JX.Stratcom.getData(new_row), JX.Stratcom.getData(old_row));
91
92
JX.DOM.replace(old_row, new_row);
93
this._rows[row_id] = new_row;
94
95
this._oncountchanged(); // Fix the new button.
96
return new_row;
97
},
98
99
addRow : function(row_contents) {
100
var row_id = this._generateRowID();
101
var row = this._wrapRowContents(row_id, row_contents);
102
JX.DOM.appendContent(this._root, row);
103
104
this._count++;
105
this._oncountchanged();
106
107
this._rows[row_id] = row;
108
return row;
109
},
110
_onrowremoved : function(e) {
111
if (!JX.Stratcom.getData(e.getTarget()).enabled) {
112
return;
113
}
114
var row = e.getNode(JX.MultirowRowManager.getRowSigil());
115
var row_id = this.getRowID(row);
116
delete this._rows[row_id];
117
JX.DOM.remove(row);
118
119
this._count--;
120
this._oncountchanged();
121
this.invoke('row-removed', row_id);
122
},
123
124
_oncountchanged : function() {
125
var buttons = JX.DOM.scry(
126
this._root,
127
'a',
128
JX.MultirowRowManager._removeSigil);
129
130
var disable = (this._minRows >= 0 && this._count <= this._minRows);
131
for (var i = 0; i < buttons.length; i++) {
132
var button = buttons[i];
133
JX.DOM.alterClass(button, 'disabled', disable);
134
JX.Stratcom.getData(button).enabled = !disable;
135
}
136
}
137
},
138
events : ['row-removed'],
139
statics : {
140
getRowSigil : function() {
141
return 'tools-multirow-row-manager-row';
142
},
143
_removeSigil : 'tools-multirow-row-manager-row-remove'
144
}
145
});
146
147