mirror of
				https://github.com/inventree/InvenTree.git
				synced 2025-10-31 05:05:42 +00:00 
			
		
		
		
	More features
- Custom renderers depending on specified model name - Paginate API results
This commit is contained in:
		| @@ -972,4 +972,11 @@ input[type="date"].form-control, input[type="time"].form-control, input[type="da | ||||
|  | ||||
| .select2-container { | ||||
|     width: 100%; | ||||
| } | ||||
|  | ||||
| .select2-thumbnail { | ||||
|     max-width: 24px; | ||||
|     max-height: 24px; | ||||
|     border-radius: 4px; | ||||
|     margin-right: 10px; | ||||
| } | ||||
| @@ -105,6 +105,7 @@ settings_urls = [ | ||||
| dynamic_javascript_urls = [ | ||||
|     url(r'^api.js', DynamicJsView.as_view(template_name='js/api.js'), name='api.js'), | ||||
|     url(r'^forms.js', DynamicJsView.as_view(template_name='js/forms.js'), name='forms.js'), | ||||
|     url(r'^model_renderers.js', DynamicJsView.as_view(template_name='js/model_renderers.js'), name='model_renderers.js'), | ||||
|     url(r'^modals.js', DynamicJsView.as_view(template_name='js/modals.js'), name='modals.js'), | ||||
|     url(r'^barcode.js', DynamicJsView.as_view(template_name='js/barcode.js'), name='barcode.js'), | ||||
|     url(r'^bom.js', DynamicJsView.as_view(template_name='js/bom.js'), name='bom.js'), | ||||
|   | ||||
| @@ -150,6 +150,7 @@ | ||||
| <!-- translated --> | ||||
| <script type='text/javascript' src="{% i18n_static 'api.js' %}"></script> | ||||
| <script type='text/javascript' src="{% i18n_static 'forms.js' %}"></script> | ||||
| <script type='text/javascript' src="{% i18n_static 'model_renderers.js' %}"></script> | ||||
| <script type='text/javascript' src="{% i18n_static 'barcode.js' %}"></script> | ||||
| <script type='text/javascript' src="{% i18n_static 'bom.js' %}"></script> | ||||
| <script type='text/javascript' src="{% i18n_static 'company.js' %}"></script> | ||||
|   | ||||
| @@ -364,7 +364,8 @@ function initializeRelatedField(modal, name, field, options) { | ||||
|  | ||||
|     // TODO: Add 'placeholder' support for entry select2 fields | ||||
|  | ||||
|     // TODO: Add 'pagination' support for the query | ||||
|     // limit size for AJAX requests | ||||
|     var pageSize = options.pageSize || 25; | ||||
|  | ||||
|     select.select2({ | ||||
|         ajax: { | ||||
| @@ -377,31 +378,52 @@ function initializeRelatedField(modal, name, field, options) { | ||||
|             cache: true, | ||||
|             // matcher: partialMatcher, | ||||
|             data: function(params) { | ||||
|  | ||||
|                 if (!params.page) { | ||||
|                     offset = 0; | ||||
|                 } else { | ||||
|                     offset = (params.page - 1) * pageSize; | ||||
|                 } | ||||
|  | ||||
|                 // Re-format search term into InvenTree API style | ||||
|                 return { | ||||
|                     search: params.term, | ||||
|                     offset: offset, | ||||
|                     limit: pageSize, | ||||
|                 }; | ||||
|             }, | ||||
|             processResults: function(data) { | ||||
|             processResults: function(response) { | ||||
|                 // Convert the returned InvenTree data into select2-friendly format | ||||
|                 var rows = []; | ||||
|  | ||||
|                 // Only ever show the first x items | ||||
|                 for (var idx = 0; idx < data.length && idx < 50; idx++) { | ||||
|                     var row = data[idx]; | ||||
|                 var data = []; | ||||
|  | ||||
|                     // Reformat to match select2 requirements | ||||
|                     row.id = row.id || row.pk; | ||||
|                 var more = false; | ||||
|  | ||||
|                     // TODO: Fix me? | ||||
|                     row.text = `This is ${field.api_url}${row.id}/`; | ||||
|                 if ('count' in response && 'results' in response) { | ||||
|                     // Response is paginated | ||||
|                     data = response.results; | ||||
|  | ||||
|                     rows.push(row); | ||||
|                     // Any more data available? | ||||
|                     if (response.next) { | ||||
|                         more = true; | ||||
|                     } | ||||
|  | ||||
|                 } else { | ||||
|                     // Non-paginated response | ||||
|                     data = response; | ||||
|                 } | ||||
|  | ||||
|                 // Each 'row' must have the 'id' attribute | ||||
|                 for (var idx = 0; idx < data.length; idx++) { | ||||
|                     data[idx].id = data[idx].pk; | ||||
|                 } | ||||
|  | ||||
|                 // Ref: https://select2.org/data-sources/formats | ||||
|                 var results = { | ||||
|                     results: rows, | ||||
|                     results: data, | ||||
|                     pagination: { | ||||
|                         more: more, | ||||
|                     } | ||||
|                 }; | ||||
|  | ||||
|                 return results; | ||||
| @@ -442,7 +464,7 @@ function initializeRelatedField(modal, name, field, options) { | ||||
|  * - parameters: The field definition (OPTIONS) request | ||||
|  * - options: Other options provided at time of modal creation by the client | ||||
|  */ | ||||
| function renderModelData(name, model, data, paramaters, options) { | ||||
| function renderModelData(name, model, data, parameters, options) { | ||||
|  | ||||
|     if (!data) { | ||||
|         return '{% trans "Searching" %}...'; | ||||
| @@ -452,20 +474,41 @@ function renderModelData(name, model, data, paramaters, options) { | ||||
|  | ||||
|     var html = null; | ||||
|  | ||||
|     var renderer = null; | ||||
|  | ||||
|     // Find a custom renderer  | ||||
|     switch (model) { | ||||
|         case 'company': | ||||
|             html = `<span>${data.name}</span> - <i>${data.description}</i>`; | ||||
|             renderer = renderCompany; | ||||
|             break; | ||||
|         case 'stockitem': | ||||
|             renderer = renderStockItem; | ||||
|             break; | ||||
|         case 'stocklocation': | ||||
|             renderer = renderStockLocation; | ||||
|             break; | ||||
|         case 'part': | ||||
|             renderer = renderPart; | ||||
|             break; | ||||
|         case 'partcategory': | ||||
|             renderer = renderPartCategory; | ||||
|             break; | ||||
|         default: | ||||
|             break; | ||||
|     } | ||||
|      | ||||
|     if (renderer != null) { | ||||
|         html = renderer(name, data, parameters, options); | ||||
|     } | ||||
|  | ||||
|     if (html != null) { | ||||
|         // Render HTML to an object | ||||
|         var $state = $(html); | ||||
|         return $state; | ||||
|     } else { | ||||
|         console.log(`ERROR: Rendering not implemented for model '${model}'`); | ||||
|         // Simple text rendering | ||||
|         return data.text; | ||||
|         return data.id; | ||||
|     } | ||||
| } | ||||
|  | ||||
|   | ||||
							
								
								
									
										83
									
								
								InvenTree/templates/js/model_renderers.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								InvenTree/templates/js/model_renderers.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,83 @@ | ||||
| /* | ||||
|  * This file contains functions for rendering various InvenTree database models, | ||||
|  * in particular for displaying them in modal forms in a 'select2' context. | ||||
|  *  | ||||
|  * Each renderer is provided with three arguments: | ||||
|  *  | ||||
|  * - name: The 'name' of the model instance in the referring model | ||||
|  * - data: JSON data which represents the model instance. Returned via a GET request. | ||||
|  * - parameters: The field parameters provided via an OPTIONS request to the endpoint. | ||||
|  * - options: User options provided by the client | ||||
|  */ | ||||
|  | ||||
|  | ||||
| // Renderer for "Company" model | ||||
| function renderCompany(name, data, parameters, options) { | ||||
|  | ||||
|     var html = `<span>${data.name}</span> - <i>${data.description}</i>`; | ||||
|  | ||||
|     return html; | ||||
| } | ||||
|  | ||||
|  | ||||
| // Renderer for "StockItem" model | ||||
| function renderStockItem(name, data, parameters, options) { | ||||
|  | ||||
|     // TODO - Include part detail, location, quantity | ||||
|     // TODO - Include part image | ||||
| } | ||||
|  | ||||
|  | ||||
| // Renderer for "StockLocation" model | ||||
| function renderStockLocation(name, data, parameters, options) { | ||||
|  | ||||
|     var html = `<span>${data.name}</span>`; | ||||
|  | ||||
|     if (data.description) { | ||||
|         html += ` - <i>${data.description}</i>`; | ||||
|     } | ||||
|  | ||||
|     if (data.pathstring) { | ||||
|         html += `<p><small>${data.pathstring}</small></p>`; | ||||
|     } | ||||
|  | ||||
|     return html; | ||||
| } | ||||
|  | ||||
|  | ||||
| // Renderer for "Part" model | ||||
| function renderPart(name, data, parameters, options) { | ||||
|  | ||||
|     var image = data.image; | ||||
|  | ||||
|     if (!image) { | ||||
|         image = `/static/img/blank_image.png`; | ||||
|     } | ||||
|  | ||||
|     var html = `<img src='${image}' class='select2-thumbnail'>`; | ||||
|      | ||||
|     html += ` <span>${data.full_name ?? data.name}</span>`; | ||||
|  | ||||
|     if (data.description) { | ||||
|         html += ` - <i>${data.description}</i>`; | ||||
|     } | ||||
|  | ||||
|     return html; | ||||
| } | ||||
|  | ||||
|  | ||||
| // Renderer for "PartCategory" model | ||||
| function renderPartCategory(name, data, parameters, options) { | ||||
|  | ||||
|     var html = `<span>${data.name}</span>`; | ||||
|  | ||||
|     if (data.description) { | ||||
|         html += ` - <i>${data.description}</i>`; | ||||
|     } | ||||
|  | ||||
|     if (data.pathstring) { | ||||
|         html += `<p><small>${data.pathstring}</small></p>`; | ||||
|     } | ||||
|  | ||||
|     return html; | ||||
| } | ||||
		Reference in New Issue
	
	Block a user