Wrote autocompletion for foreign key field
This commit is contained in:
		@@ -18,6 +18,7 @@ class PackageSerializerNoLink(serializers.ModelSerializer):
 | 
				
			|||||||
        fields = '__all__'
 | 
					        fields = '__all__'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class PackageSerializer(serializers.HyperlinkedModelSerializer):
 | 
					class PackageSerializer(serializers.HyperlinkedModelSerializer):
 | 
				
			||||||
 | 
					    id = serializers.ReadOnlyField()
 | 
				
			||||||
    class Meta:
 | 
					    class Meta:
 | 
				
			||||||
        model = parts_models.Package
 | 
					        model = parts_models.Package
 | 
				
			||||||
        fields = '__all__'
 | 
					        fields = '__all__'
 | 
				
			||||||
@@ -30,7 +31,6 @@ class StorageSerializer(serializers.HyperlinkedModelSerializer):
 | 
				
			|||||||
        fields = ['url', 'id', 'name', 'parent_storage', 'responsible', 'full_path']
 | 
					        fields = ['url', 'id', 'name', 'parent_storage', 'responsible', 'full_path']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ComponentSerializer(serializers.HyperlinkedModelSerializer):
 | 
					class ComponentSerializer(serializers.HyperlinkedModelSerializer):
 | 
				
			||||||
 | 
					 | 
				
			||||||
    package_data = PackageSerializerNoLink(source='package', read_only=True)
 | 
					    package_data = PackageSerializerNoLink(source='package', read_only=True)
 | 
				
			||||||
    ro_manufacturer_name = serializers.ReadOnlyField(source='manufacturer.name')
 | 
					    ro_manufacturer_name = serializers.ReadOnlyField(source='manufacturer.name')
 | 
				
			||||||
    ro_image = serializers.ReadOnlyField(source='get_resolved_image')
 | 
					    ro_image = serializers.ReadOnlyField(source='get_resolved_image')
 | 
				
			||||||
@@ -41,6 +41,7 @@ class ComponentSerializer(serializers.HyperlinkedModelSerializer):
 | 
				
			|||||||
        
 | 
					        
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class StockSerializer(serializers.HyperlinkedModelSerializer):
 | 
					class StockSerializer(serializers.HyperlinkedModelSerializer):
 | 
				
			||||||
 | 
					    id = serializers.ReadOnlyField()
 | 
				
			||||||
    ro_package_name = serializers.ReadOnlyField(source='component.package.name')
 | 
					    ro_package_name = serializers.ReadOnlyField(source='component.package.name')
 | 
				
			||||||
    ro_component_name = serializers.ReadOnlyField(source='component.name')
 | 
					    ro_component_name = serializers.ReadOnlyField(source='component.name')
 | 
				
			||||||
    ro_manufacturer_name = serializers.ReadOnlyField(source='component.manufacturer.name')
 | 
					    ro_manufacturer_name = serializers.ReadOnlyField(source='component.manufacturer.name')
 | 
				
			||||||
@@ -50,6 +51,7 @@ class StockSerializer(serializers.HyperlinkedModelSerializer):
 | 
				
			|||||||
        fields = '__all__'
 | 
					        fields = '__all__'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class DistributorSerializer(serializers.HyperlinkedModelSerializer):
 | 
					class DistributorSerializer(serializers.HyperlinkedModelSerializer):
 | 
				
			||||||
 | 
					    id = serializers.ReadOnlyField()
 | 
				
			||||||
    class Meta:
 | 
					    class Meta:
 | 
				
			||||||
        model = parts_models.Distributor
 | 
					        model = parts_models.Distributor
 | 
				
			||||||
        fields = '__all__'
 | 
					        fields = '__all__'
 | 
				
			||||||
@@ -58,16 +60,19 @@ class StockIncrementDecrementSerializer(serializers.Serializer):
 | 
				
			|||||||
	increment = serializers.IntegerField()
 | 
						increment = serializers.IntegerField()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ManufacturerSerializer(serializers.HyperlinkedModelSerializer):
 | 
					class ManufacturerSerializer(serializers.HyperlinkedModelSerializer):
 | 
				
			||||||
 | 
					    id = serializers.ReadOnlyField()
 | 
				
			||||||
    class Meta:
 | 
					    class Meta:
 | 
				
			||||||
        model = parts_models.Manufacturer
 | 
					        model = parts_models.Manufacturer
 | 
				
			||||||
        fields = '__all__'
 | 
					        fields = '__all__'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ComponentTypeSerializer(serializers.HyperlinkedModelSerializer):
 | 
					class ComponentTypeSerializer(serializers.HyperlinkedModelSerializer):
 | 
				
			||||||
 | 
					    id = serializers.ReadOnlyField()
 | 
				
			||||||
    class Meta:
 | 
					    class Meta:
 | 
				
			||||||
        model = parts_models.ComponentType
 | 
					        model = parts_models.ComponentType
 | 
				
			||||||
        fields = '__all__'
 | 
					        fields = '__all__'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ComponentParameterTypeSerializer(serializers.HyperlinkedModelSerializer):
 | 
					class ComponentParameterTypeSerializer(serializers.HyperlinkedModelSerializer):
 | 
				
			||||||
 | 
					    id = serializers.ReadOnlyField()
 | 
				
			||||||
    class Meta:
 | 
					    class Meta:
 | 
				
			||||||
        model = parts_models.ComponentParameterType
 | 
					        model = parts_models.ComponentParameterType
 | 
				
			||||||
        fields = '__all__'
 | 
					        fields = '__all__'
 | 
				
			||||||
@@ -4,49 +4,65 @@ from django.core.exceptions import ValidationError
 | 
				
			|||||||
from parts import models as parts_models
 | 
					from parts import models as parts_models
 | 
				
			||||||
from shimatta_modules.EngineeringNumberConverter import EngineeringNumberConverter
 | 
					from shimatta_modules.EngineeringNumberConverter import EngineeringNumberConverter
 | 
				
			||||||
import uuid
 | 
					import uuid
 | 
				
			||||||
 | 
					from django.urls import reverse
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class AutoCompleteWidget(widgets.Input):
 | 
					class AutoCompleteWidget(widgets.Input):
 | 
				
			||||||
    template_name = 'widgets/autocomplete-foreign-key.html'
 | 
					    template_name = 'widgets/autocomplete-foreign-key.html'
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    def __init__(self, api_search_url, image_field_name, foreign_model, *args, **kwargs):
 | 
					    def __init__(self, api_search_url, image_field_name, foreign_model, name_field_name, *args, **kwargs):
 | 
				
			||||||
        super().__init__(*args, **kwargs)
 | 
					        super().__init__(*args, **kwargs)
 | 
				
			||||||
        self.image_field_name = image_field_name
 | 
					        self.image_field_name = image_field_name
 | 
				
			||||||
        self.foreign_model = foreign_model
 | 
					        self.foreign_model = foreign_model
 | 
				
			||||||
        self.api_search_url = api_search_url
 | 
					        self.api_search_url = api_search_url
 | 
				
			||||||
 | 
					        self.name_field_name = name_field_name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_context(self, name, value, attrs):
 | 
					    def get_context(self, name, value, attrs):
 | 
				
			||||||
        context = super().get_context(name, value, attrs)
 | 
					        context = super().get_context(name, value, attrs)
 | 
				
			||||||
        if value is not None:
 | 
					        if value is not None:
 | 
				
			||||||
            try:
 | 
					            try:
 | 
				
			||||||
                 instance = self.foreign_model.objects.get(id=uuid.UUID(value))
 | 
					                try:
 | 
				
			||||||
 | 
					                    my_id = uuid.UUID(value)
 | 
				
			||||||
 | 
					                except:
 | 
				
			||||||
 | 
					                    my_id = int(value)
 | 
				
			||||||
 | 
					                instance = self.foreign_model.objects.get(id=my_id)
 | 
				
			||||||
            except Exception as ex:
 | 
					            except Exception as ex:
 | 
				
			||||||
                instance = None
 | 
					                instance = None
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            instance = None
 | 
					            instance = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        image = None
 | 
					        image = None
 | 
				
			||||||
        if instance is not None:
 | 
					        if instance is not None and self.image_field_name is not None:
 | 
				
			||||||
            image = getattr(instance, self.image_field_name)
 | 
					            image = getattr(instance, self.image_field_name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        display_name = None
 | 
				
			||||||
 | 
					        if instance:
 | 
				
			||||||
 | 
					            display_name = getattr(instance, self.name_field_name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        context['custom'] = {
 | 
					        context['custom'] = {
 | 
				
			||||||
            'search_url': self.api_search_url,
 | 
					            'search_url': reverse(self.api_search_url),
 | 
				
			||||||
            'image_field_name': self.image_field_name,
 | 
					            'image_field_name': self.image_field_name,
 | 
				
			||||||
            'current_instance': instance,
 | 
					            'current_instance': instance,
 | 
				
			||||||
            'image': image,
 | 
					            'image': image,
 | 
				
			||||||
 | 
					            'name_field_name': self.name_field_name,
 | 
				
			||||||
 | 
					            'name': display_name,
 | 
				
			||||||
        } 
 | 
					        } 
 | 
				
			||||||
        return context
 | 
					        return context
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
class AutocompleteForeingKeyField(forms.UUIDField):
 | 
					class AutocompleteForeingKeyField(forms.UUIDField):
 | 
				
			||||||
    def __init__(self, foreign_model=None, api_search_url=None, image_field_name='image', **kwargs):
 | 
					    def __init__(self, foreign_model=None, api_search_url=None, image_field_name='image', name_field_name='name', **kwargs):
 | 
				
			||||||
        super().__init__(**kwargs)
 | 
					        super().__init__(**kwargs)
 | 
				
			||||||
        self.widget = AutoCompleteWidget(api_search_url, image_field_name, foreign_model)
 | 
					        self.widget = AutoCompleteWidget(api_search_url, image_field_name, foreign_model, name_field_name)
 | 
				
			||||||
        self.foreign_model = foreign_model
 | 
					        self.foreign_model = foreign_model
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    def clean(self, value):
 | 
					    def clean(self, value):
 | 
				
			||||||
 | 
					        try:
 | 
				
			||||||
            pre_cleaned_uuid = super().clean(value)
 | 
					            pre_cleaned_uuid = super().clean(value)
 | 
				
			||||||
 | 
					        except Exception as ex:
 | 
				
			||||||
 | 
					            try:
 | 
				
			||||||
 | 
					                pre_cleaned_uuid = int(value)
 | 
				
			||||||
 | 
					            except:
 | 
				
			||||||
 | 
					                raise ex
 | 
				
			||||||
        if pre_cleaned_uuid is None and not self.required:
 | 
					        if pre_cleaned_uuid is None and not self.required:
 | 
				
			||||||
            return None
 | 
					            return None
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
@@ -161,9 +177,9 @@ class AddStockForm(forms.Form):
 | 
				
			|||||||
        new_stock.save()
 | 
					        new_stock.save()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ComponentForm(forms.ModelForm):
 | 
					class ComponentForm(forms.ModelForm):
 | 
				
			||||||
    manufacturer = AutocompleteForeingKeyField(api_search_url='foo', foreign_model=parts_models.Manufacturer)
 | 
					    manufacturer = AutocompleteForeingKeyField(api_search_url='manufacturer-list', foreign_model=parts_models.Manufacturer, required=False)
 | 
				
			||||||
    component_type = AutocompleteForeingKeyField(api_search_url='bar', foreign_model=parts_models.ComponentType, required=False, image_field_name=None)
 | 
					    component_type = AutocompleteForeingKeyField(api_search_url='componenttype-list', foreign_model=parts_models.ComponentType, name_field_name='class_name', required=False, image_field_name=None)
 | 
				
			||||||
    package = AutocompleteForeingKeyField(api_search_url='pkgurl', foreign_model=parts_models.Package, required=False)
 | 
					    package = AutocompleteForeingKeyField(api_search_url='package-list', foreign_model=parts_models.Package, required=False)
 | 
				
			||||||
    class Meta:
 | 
					    class Meta:
 | 
				
			||||||
        model = parts_models.Component
 | 
					        model = parts_models.Component
 | 
				
			||||||
        fields = '__all__'
 | 
					        fields = '__all__'
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -0,0 +1,93 @@
 | 
				
			|||||||
 | 
					function clear_foreign_key_field(uuid_field, dflex_container) {
 | 
				
			||||||
 | 
					    dflex_container.innerHTML = '';
 | 
				
			||||||
 | 
					    var span = document.createElement('span');
 | 
				
			||||||
 | 
					    span.setAttribute('class', 'text-secondary');
 | 
				
			||||||
 | 
					    span.appendChild(document.createTextNode('None selected'));
 | 
				
			||||||
 | 
					    dflex_container.appendChild(span);
 | 
				
			||||||
 | 
					    uuid_field.removeAttribute('value')
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function initialize_autocompletion_foreign_key_field(search_element) {
 | 
				
			||||||
 | 
					    var image_field_name = search_element.getAttribute('data-ac-image-field');
 | 
				
			||||||
 | 
					    var name_field_name = search_element.getAttribute('data-ac-name-field');
 | 
				
			||||||
 | 
					    var search_url = search_element.getAttribute('data-ac-url');
 | 
				
			||||||
 | 
					    var base_id = search_element.getAttribute('id');
 | 
				
			||||||
 | 
					    var uuid_field = search_element.parentElement.querySelector('#'+base_id+'-uuid-field');
 | 
				
			||||||
 | 
					    var dflex_container = search_element.parentElement.querySelector('#'+base_id+'-dflex-container');
 | 
				
			||||||
 | 
					    var initial_delete_button = search_element.parentElement.querySelector('[data-ac-delete]');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    console.log(initial_delete_button);
 | 
				
			||||||
 | 
					    console.log(image_field_name);
 | 
				
			||||||
 | 
					    console.log(search_url);
 | 
				
			||||||
 | 
					    console.log(base_id);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    if (initial_delete_button) {
 | 
				
			||||||
 | 
					        initial_delete_button.addEventListener('click', (e) => {
 | 
				
			||||||
 | 
					            clear_foreign_key_field(uuid_field, dflex_container);
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    new AutocompleteCustomUi(
 | 
				
			||||||
 | 
					        base_id, base_id+'-ac-ul', function(search_query, autocomplete_obj) {
 | 
				
			||||||
 | 
					            api_ajax_request_without_send('GET', search_url+`?search=${encodeURIComponent(search_query)}`, function(method, url, json) {
 | 
				
			||||||
 | 
					                if (json.results == undefined || json.results == null)
 | 
				
			||||||
 | 
					                    return;
 | 
				
			||||||
 | 
					                var results = json.results;
 | 
				
			||||||
 | 
					                var nodes = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (image_field_name != '' && image_field_name != null) {
 | 
				
			||||||
 | 
					                    for (var i = 0; i < results.length; i++) {
 | 
				
			||||||
 | 
					                        var res = results[i];
 | 
				
			||||||
 | 
					                        var node = AutocompleteCustomUi.create_media_div(res[image_field_name], [document.createTextNode(res[name_field_name])]);
 | 
				
			||||||
 | 
					                        nodes.push({'ui': node, 'data': {'result': res, 'uuid_field': uuid_field}});
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    for (var i = 0; i < results.length; i++) {
 | 
				
			||||||
 | 
					                        nodes.push({'ui': document.createTextNode(results[i][name_field_name]), 'data': {'result':results[i], 'uuid_field': uuid_field}})
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                autocomplete_obj.show_results(nodes, function(data) {                    
 | 
				
			||||||
 | 
					                    var name = data['result'][name_field_name];
 | 
				
			||||||
 | 
					                    if (image_field_name != '' && image_field_name != null) {
 | 
				
			||||||
 | 
					                        var image = data['result'][image_field_name];
 | 
				
			||||||
 | 
					                        if (image == null) {
 | 
				
			||||||
 | 
					                            image = fallback_img_path;
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                        dflex_content = AutocompleteCustomUi.create_media_div(image, [document.createTextNode(name)]);
 | 
				
			||||||
 | 
					                    } else {
 | 
				
			||||||
 | 
					                        dflex_content = document.createTextNode(name);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    dflex_container.innerHTML = '';
 | 
				
			||||||
 | 
					                    dflex_container.appendChild(dflex_content);
 | 
				
			||||||
 | 
					                    
 | 
				
			||||||
 | 
					                    search_element.value = data['result'][name_field_name];
 | 
				
			||||||
 | 
					                    data['uuid_field'].value = data['result'].id;
 | 
				
			||||||
 | 
					                    
 | 
				
			||||||
 | 
					                    var span = document.createElement('span');
 | 
				
			||||||
 | 
					                    span.setAttribute('class', 'btn-close ms-4');
 | 
				
			||||||
 | 
					                    span.addEventListener('click', (e) => {
 | 
				
			||||||
 | 
					                        clear_foreign_key_field(uuid_field, dflex_container);
 | 
				
			||||||
 | 
					                        search_element.value = '';
 | 
				
			||||||
 | 
					                    });
 | 
				
			||||||
 | 
					                    dflex_container.appendChild(span);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                })   
 | 
				
			||||||
 | 
					            }, function (){});
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function initialize_autocompletion_for_foreign_key_fields() {
 | 
				
			||||||
 | 
					    var autocomplete_searches = document.querySelectorAll("[data-ac-url]");
 | 
				
			||||||
 | 
					    if (autocomplete_searches.length == 0) {
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    autocomplete_searches.forEach(initialize_autocompletion_foreign_key_field);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					document.addEventListener("DOMContentLoaded", function(event) { 
 | 
				
			||||||
 | 
					    initialize_autocompletion_for_foreign_key_fields();
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
@@ -19,7 +19,7 @@ class AutocompleteCustomUi {
 | 
				
			|||||||
        img_div.appendChild(img);
 | 
					        img_div.appendChild(img);
 | 
				
			||||||
        ui.appendChild(img_div);
 | 
					        ui.appendChild(img_div);
 | 
				
			||||||
        var text_div = document.createElement('div');
 | 
					        var text_div = document.createElement('div');
 | 
				
			||||||
        text_div.setAttribute('class', 'flex-grow-1 ms-3');
 | 
					        text_div.setAttribute('class', 'ms-3');
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        if (text_nodes != undefined) {
 | 
					        if (text_nodes != undefined) {
 | 
				
			||||||
            for (var i = 0; i < text_nodes.length; i++) {
 | 
					            for (var i = 0; i < text_nodes.length; i++) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -76,6 +76,7 @@
 | 
				
			|||||||
        </script>
 | 
					        </script>
 | 
				
			||||||
        <script type="text/javascript" src="{% static 'js/kenyusho-api-v1.js' %}"></script>
 | 
					        <script type="text/javascript" src="{% static 'js/kenyusho-api-v1.js' %}"></script>
 | 
				
			||||||
        <script type="text/javascript" src="{% static 'js/autocomplete.js' %}"></script>
 | 
					        <script type="text/javascript" src="{% static 'js/autocomplete.js' %}"></script>
 | 
				
			||||||
 | 
					        <script type="text/javascript" src="{% static 'js/autocomplete-foreign-key-field.js' %}"></script>
 | 
				
			||||||
        {% block custom_scripts %}
 | 
					        {% block custom_scripts %}
 | 
				
			||||||
        {% endblock custom_scripts %}
 | 
					        {% endblock custom_scripts %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -119,11 +119,6 @@
 | 
				
			|||||||
            </div>            
 | 
					            </div>            
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
    <form action="" method="post" enctype="multipart/form-data">
 | 
					 | 
				
			||||||
        {% csrf_token %}
 | 
					 | 
				
			||||||
        {{comp_form|crispy}}
 | 
					 | 
				
			||||||
        <input type="submit" name="submit-edit-component" value="Submit">
 | 
					 | 
				
			||||||
    </form>
 | 
					 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
{% if component.get_resolved_image %}
 | 
					{% if component.get_resolved_image %}
 | 
				
			||||||
@@ -149,7 +144,7 @@
 | 
				
			|||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
{% endif %}
 | 
					{% endif %}
 | 
				
			||||||
{% include 'parts/modals/edit-component-modal.html' with heading="Edit "|add:component.name form=edit_form %}
 | 
					{% include 'parts/modals/edit-component-modal.html' with heading="Edit "|add:component.name form=comp_form %}
 | 
				
			||||||
{% endblock content %}
 | 
					{% endblock content %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
{% block custom_scripts %}
 | 
					{% block custom_scripts %}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -17,58 +17,12 @@ Needs following context:
 | 
				
			|||||||
            <form method="post" enctype="multipart/form-data">
 | 
					            <form method="post" enctype="multipart/form-data">
 | 
				
			||||||
                {% csrf_token %}
 | 
					                {% csrf_token %}
 | 
				
			||||||
                <div class="modal-body">
 | 
					                <div class="modal-body">
 | 
				
			||||||
                    {{form.name|as_crispy_field}}
 | 
					                    {{form|crispy}}
 | 
				
			||||||
                    {{form.datasheet_link|as_crispy_field}}
 | 
					 | 
				
			||||||
                    {{form.description|as_crispy_field}}
 | 
					 | 
				
			||||||
                    <div class="mb-3">
 | 
					 | 
				
			||||||
                        <label class="form-label" for="{{form.manufacturer.id_for_label}}">Manufacturer</label>
 | 
					 | 
				
			||||||
                        <div class="dropdown">
 | 
					 | 
				
			||||||
                            <input autocomplete="off" data-bs-toggle="dropdown" class="form-control{% if form.manufacturer.errors %} is-invalid{% endif %}" type="text" id="{{form.manufacturer.id_for_label}}" name="{{form.manufacturer.name}}" value="{{form.manufacturer.value}}">
 | 
					 | 
				
			||||||
                            <ul id="{{form.manufacturer.id_for_label}}-ac-ul" class="dropdown-menu">
 | 
					 | 
				
			||||||
                            </ul>
 | 
					 | 
				
			||||||
                        </div>
 | 
					 | 
				
			||||||
                    </div>
 | 
					 | 
				
			||||||
                    <div class="mb-3">
 | 
					 | 
				
			||||||
                        <label class="form-label" for="{{form.package.id_for_label}}">Package</label>
 | 
					 | 
				
			||||||
                        <div class="dropdown">
 | 
					 | 
				
			||||||
                            <input autocomplete="off" data-bs-toggle="dropdown" class="form-control{% if form.package.errors %} is-invalid{% endif %}" type="text" id="{{form.package.id_for_label}}" name="{{form.package.name}}" value="{{form.package.value}}">
 | 
					 | 
				
			||||||
                            <ul id="{{form.package.id_for_label}}-ac-ul" class="dropdown-menu">
 | 
					 | 
				
			||||||
                            </ul>
 | 
					 | 
				
			||||||
                        </div>
 | 
					 | 
				
			||||||
                    </div>
 | 
					 | 
				
			||||||
                    <div class="mb-3">
 | 
					 | 
				
			||||||
                        <label class="form-label" for="{{form.component_type.id_for_label}}">Component Type</label>
 | 
					 | 
				
			||||||
                        <div class="dropdown">
 | 
					 | 
				
			||||||
                            <input autocomplete="off" data-bs-toggle="dropdown" class="form-control{% if form.component_type.errors %} is-invalid{% endif %}" type="text" id="{{form.component_type.id_for_label}}" name="{{form.component_type.name}}" value="{{form.component_type.value}}">
 | 
					 | 
				
			||||||
                            <ul id="{{form.component_type.id_for_label}}-ac-ul" class="dropdown-menu">
 | 
					 | 
				
			||||||
                            </ul>
 | 
					 | 
				
			||||||
                        </div>
 | 
					 | 
				
			||||||
                    </div>
 | 
					 | 
				
			||||||
                    <div class="mb-3">
 | 
					 | 
				
			||||||
                        <label class="form-label" for="{{form.pref_distri.id_for_label}}">Preferred Distributor</label>
 | 
					 | 
				
			||||||
                        <div class="dropdown">
 | 
					 | 
				
			||||||
                            <input autocomplete="off" data-bs-toggle="dropdown" class="form-control{% if form.pref_distri.errors %} is-invalid{% endif %}" type="text" id="{{form.pref_distri.id_for_label}}" name="{{form.pref_distri.name}}" value="{{form.pref_distri.value}}">
 | 
					 | 
				
			||||||
                            <ul id="{{form.pref_distri.id_for_label}}-ac-ul" class="dropdown-menu">
 | 
					 | 
				
			||||||
                            </ul>
 | 
					 | 
				
			||||||
                        </div>
 | 
					 | 
				
			||||||
                    </div>
 | 
					 | 
				
			||||||
                    <div class="mb-3">
 | 
					 | 
				
			||||||
                        {{form.image|as_crispy_field}}
 | 
					 | 
				
			||||||
                    </div>
 | 
					 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
                <div class="modal-footer">
 | 
					                <div class="modal-footer">
 | 
				
			||||||
                    <input type="submit" name="submit-edit-comp" class="btn btn-primary" value="Save">
 | 
					                    <input type="submit" name="submit-edit-component" class="btn btn-primary" value="Save">
 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
            </form>
 | 
					            </form>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
<script type="text/javascript">
 | 
					 | 
				
			||||||
    const edit_comp_modal_ids = {
 | 
					 | 
				
			||||||
        'package': '{{form.package.id_for_label}}',
 | 
					 | 
				
			||||||
        'manufacturer': '{{form.manufacturer.id_for_label}}',
 | 
					 | 
				
			||||||
        'component_type': '{{form.component_type.id_for_label}}',
 | 
					 | 
				
			||||||
        'pref_distri': '{{form.pref_distri.id_for_label}}',
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
</script>
 | 
					 | 
				
			||||||
<script type="text/javascript" src="{% static 'js/edit-component-modal.js' %}"></script>
 | 
					 | 
				
			||||||
@@ -1,5 +1,5 @@
 | 
				
			|||||||
<div class="dropdown">
 | 
					<div class="dropdown">
 | 
				
			||||||
    <input autocomplete="off" id="{{widget.attrs.id}}" data-ac-url="{{custom.search_url}}" data-bs-toggle="dropdown" type="text" placeholder="Search..." class="{{widget.attrs.class}}">
 | 
					    <input autocomplete="off" id="{{widget.attrs.id}}" data-ac-url="{{custom.search_url}}" data-ac-name-field="{{custom.name_field_name}}" {% if custom.image_field_name %}data-ac-image-field="{{custom.image_field_name}}"{% endif %} data-bs-toggle="dropdown" type="text" placeholder="Search..." class="{{widget.attrs.class}}">
 | 
				
			||||||
    <ul id="{{widget.attrs.id}}-ac-ul" class="dropdown-menu">
 | 
					    <ul id="{{widget.attrs.id}}-ac-ul" class="dropdown-menu">
 | 
				
			||||||
    </ul>
 | 
					    </ul>
 | 
				
			||||||
    <div class="d-flex align-items-center mt-3 mb-3" id="{{widget.attrs.id}}-dflex-container">
 | 
					    <div class="d-flex align-items-center mt-3 mb-3" id="{{widget.attrs.id}}-dflex-container">
 | 
				
			||||||
@@ -17,7 +17,7 @@
 | 
				
			|||||||
        {% endif %}
 | 
					        {% endif %}
 | 
				
			||||||
        <div class="ms-3">
 | 
					        <div class="ms-3">
 | 
				
			||||||
            {% if custom.current_instance %}
 | 
					            {% if custom.current_instance %}
 | 
				
			||||||
                {{custom.current_instance}}
 | 
					                {{custom.name}}
 | 
				
			||||||
            {% else %}
 | 
					            {% else %}
 | 
				
			||||||
            <span class="text-secondary">None selected</span>
 | 
					            <span class="text-secondary">None selected</span>
 | 
				
			||||||
            {% endif %}
 | 
					            {% endif %}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user