@@ -89,16 +89,35 @@ django.jQuery(function ($) {
89
89
}
90
90
}
91
91
} ,
92
+ getRelevantTemplateUrl = function ( orgID , backend ) {
93
+ // Returns the URL to fetch relevant templates
94
+ var baseUrl = window . _relevantTemplateUrl . replace ( "org_id" , orgID ) ;
95
+ var url = new URL ( baseUrl , window . location . origin ) ;
96
+
97
+ // Get relevant templates of selected org and backend
98
+ if ( backend ) {
99
+ url . searchParams . set ( "backend" , backend ) ;
100
+ }
101
+ if ( isDeviceGroup ( ) && ! $ ( ".add-form" ) . length ) {
102
+ // Get the group id from the URL
103
+ // TODO: This is fragile, consider using a more robust way to get the group id.
104
+ var pathParts = window . location . pathname . split ( "/" ) ;
105
+ url . searchParams . set ( "group_id" , pathParts [ pathParts . length - 3 ] ) ;
106
+ } else if ( $ ( 'input[name="config-0-device"]' ) . length ) {
107
+ url . searchParams . set (
108
+ "device_id" ,
109
+ $ ( 'input[name="config-0-device"]' ) . val ( ) ,
110
+ ) ;
111
+ }
112
+ return url . toString ( ) ;
113
+ } ,
92
114
showRelevantTemplates = function ( ) {
93
115
var orgID = $ ( orgFieldSelector ) . val ( ) ,
94
116
backend = isDeviceGroup ( ) ? "" : $ ( backendFieldSelector ) . val ( ) ,
95
117
selectedTemplates ;
96
118
97
119
// Hide templates if no organization or backend is selected
98
- if (
99
- ( orgID && orgID . length === 0 ) ||
100
- ( ! isDeviceGroup ( ) && backend . length === 0 )
101
- ) {
120
+ if ( ! orgID || ( ! isDeviceGroup ( ) && backend . length === 0 ) ) {
102
121
resetTemplateOptions ( ) ;
103
122
updateTemplateHelpText ( ) ;
104
123
return ;
@@ -109,77 +128,24 @@ django.jQuery(function ($) {
109
128
// when the user has changed any of organization or backend field.
110
129
// selectedTemplates will be an empty string if no template is selected
111
130
// ''.split(',') returns [''] hence, this case requires special handling
112
- selectedTemplates = isDeviceGroup ( )
113
- ? parseSelectedTemplates ( $ ( "#id_templates" ) . val ( ) )
114
- : parseSelectedTemplates (
115
- django . _owcInitialValues [ templatesFieldName ( ) ] ,
116
- ) ;
117
- }
118
-
119
- var url = window . _relevantTemplateUrl . replace ( "org_id" , orgID ) ;
120
- // Get relevant templates of selected org and backend
121
- url = url + "?backend=" + backend ;
122
- if ( ! isDeviceGroup ( ) ) {
123
- var deviceID = $ ( 'input[name="config-0-device"]' ) . val ( ) ;
124
- url = url + "&device=" + deviceID ;
125
- } else {
126
- // Get the group id from the URL
127
- var pathParts = window . location . pathname . split ( "/" ) ;
128
- url = url + "&group=" + pathParts [ pathParts . length - 3 ] ;
131
+ selectedTemplates = parseSelectedTemplates (
132
+ $ ( 'input[name="' + templatesFieldName ( ) + '"]' ) . val ( ) ,
133
+ ) ;
129
134
}
135
+ var url = getRelevantTemplateUrl ( orgID , backend ) ;
130
136
$ . get ( url ) . done ( function ( data ) {
131
137
resetTemplateOptions ( ) ;
132
138
var enabledTemplates = [ ] ,
133
139
sortedm2mUl = $ ( "ul.sortedm2m-items:first" ) ,
134
140
sortedm2mPrefixUl = $ ( "ul.sortedm2m-items:last" ) ;
135
141
136
- // Adds "li" elements for templates that are already selected
137
- // in the database. Select these templates and remove their key from "data"
138
- // This maintains the order of the templates and keep
139
- // enabled templates on the top
140
- if ( selectedTemplates !== undefined ) {
141
- selectedTemplates . forEach ( function ( templateId , index ) {
142
- // corner case in which backend of template does not match
143
- if ( ! data [ templateId ] ) {
144
- return ;
145
- }
146
- var element = getTemplateOptionElement (
147
- index ,
148
- templateId ,
149
- data [ templateId ] ,
150
- true ,
151
- false ,
152
- ) ,
153
- prefixElement = getTemplateOptionElement (
154
- index ,
155
- templateId ,
156
- data [ templateId ] ,
157
- true ,
158
- true ,
159
- ) ;
160
- sortedm2mUl . append ( element ) ;
161
- if ( ! isDeviceGroup ( ) ) {
162
- sortedm2mPrefixUl . append ( prefixElement ) ;
163
- }
164
- delete data [ templateId ] ;
165
- } ) ;
166
- }
167
-
168
- // Adds "li" elements for templates that are not selected
169
- // in the database.
170
- var counter =
171
- selectedTemplates !== undefined ? selectedTemplates . length : 0 ,
172
- deviceTemplates = [ ] ;
142
+ // Adds "li" elements for templates
173
143
Object . keys ( data ) . forEach ( function ( templateId , index ) {
174
- // corner case in which backend of template does not match
175
- if ( ! data [ templateId ] ) {
176
- return ;
177
- }
178
- index = index + counter ;
179
144
var isSelected =
180
- data [ templateId ] . default &&
181
- selectedTemplates === undefined &&
182
- ! data [ templateId ] . required ,
145
+ data [ templateId ] . selected ||
146
+ ( data [ templateId ] . default &&
147
+ selectedTemplates === undefined &&
148
+ ! data [ templateId ] . required ) ,
183
149
element = getTemplateOptionElement (
184
150
index ,
185
151
templateId ,
@@ -199,9 +165,6 @@ django.jQuery(function ($) {
199
165
if ( isSelected === true ) {
200
166
enabledTemplates . push ( templateId ) ;
201
167
}
202
- if ( element . children ( ) . children ( "input" ) . prop ( "checked" ) === true ) {
203
- deviceTemplates . push ( templateId ) ;
204
- }
205
168
sortedm2mUl . append ( element ) ;
206
169
if ( ! isDeviceGroup ( ) ) {
207
170
sortedm2mPrefixUl . append ( prefixElement ) ;
@@ -210,30 +173,20 @@ django.jQuery(function ($) {
210
173
if ( firstRun === true && selectedTemplates !== undefined ) {
211
174
updateTemplateSelection ( selectedTemplates ) ;
212
175
}
213
- // this runs on first load and sets the name of hidden input field which tracks
214
- // the selected templates.
215
- if ( selectedTemplates === undefined ) {
216
- if ( ! isDeviceGroup ( ) ) {
217
- $ (
218
- `#config-0 .field-templates .sortedm2m-container input[type="hidden"]` ,
219
- )
220
- . first ( )
221
- . attr ( "name" , templatesFieldName ( ) ) ;
222
- // set the initial value of the hidden input field
223
- // to the selected templates
224
- django . _owcInitialValues [ templatesFieldName ( ) ] =
225
- deviceTemplates . join ( "," ) ;
226
- } else {
227
- $ (
228
- `.field-templates .sortedm2m-container input[type="hidden"]` ,
229
- ) . attr ( "name" , templatesFieldName ( ) ) ;
230
- }
231
- }
232
176
updateTemplateHelpText ( ) ;
233
177
updateConfigTemplateField ( enabledTemplates ) ;
234
178
} ) ;
235
179
} ,
180
+ initTemplateField = function ( ) {
181
+ // sortedm2m generates a hidden input dynamically using rendered input checkbox elements,
182
+ // but because the queryset is set to None in the Django admin, the input is created
183
+ // without a name attribute. This workaround assigns the correct name to the hidden input.
184
+ $ ( '.sortedm2m-container input[type="hidden"][id="undefined"]' )
185
+ . first ( )
186
+ . attr ( "name" , templatesFieldName ( ) ) ;
187
+ } ,
236
188
bindDefaultTemplateLoading = function ( ) {
189
+ initTemplateField ( ) ;
237
190
var backendField = $ ( backendFieldSelector ) ;
238
191
$ ( orgFieldSelector ) . change ( function ( ) {
239
192
// Only fetch templates when backend field is present
@@ -246,11 +199,13 @@ django.jQuery(function ($) {
246
199
addChangeEventHandlerToBackendField ( ) ;
247
200
} else if ( isDeviceGroup ( ) ) {
248
201
// Initially request data to get templates
202
+ initTemplateField ( ) ;
249
203
showRelevantTemplates ( ) ;
250
204
} else {
251
205
// Add view: backendField is added when user adds configuration
252
206
$ ( "#config-group > fieldset.module" ) . ready ( function ( ) {
253
207
$ ( "div.add-row > a" ) . one ( "click" , function ( ) {
208
+ initTemplateField ( ) ;
254
209
addChangeEventHandlerToBackendField ( ) ;
255
210
} ) ;
256
211
} ) ;
0 commit comments