Maciej Wiśniowski avatar Maciej Wiśniowski committed 4ec972f

autocomplete for manufacturer field

Comments (0)

Files changed (6)

lfs/manage/urls.py

     url(r'^edit-product-manufacturer/(?P<manufacturer_id>\d*)/(?P<product_id>\d*)$', "edit_product", name="lfs_manufacturer_edit_product"),
     url(r'^category-state-manufacturer/(?P<manufacturer_id>\d*)/(?P<category_id>\d*)$', "category_state", name="lfs_manufacturer_category_state"),
     url(r'^manufacturer-inline/(?P<manufacturer_id>\d*)/(?P<category_id>\d*)$', "manufacturer_inline", name="lfs_manufacturer_inline"),
+    url(r'^manufacturers-ajax/$', "manufacturers_ajax", name="lfs_manufacturers_ajax"),
 )
 
 # Marketing

lfs/manage/views/manufacturer.py

 from django.utils import simplejson
 from django.utils.translation import ugettext_lazy as _
 from django.views.decorators.http import require_POST
+from django.views.decorators.cache import never_cache
 
 # lfs imports
 import lfs.core.utils
 from lfs.catalog.models import Product
 from lfs.core.utils import LazyEncoder
 from lfs.manufacturer.models import Manufacturer
-from lfs.manufacturer.models import Manufacturer
 
 
 class ManufacturerDataForm(ModelForm):
         klass = ""
 
     return (checked, klass)
+
+
+@never_cache
+@permission_required("core.manage_shop", login_url="/login/")
+def manufacturers_ajax(request):
+    #[ { label: "Choice1", value: "value1" }, ... ]
+    """ Returns list of manufacturers for autocomplete
+    """
+    term = request.GET.get('term', '')
+    manufacturers = Manufacturer.objects.filter(name__istartswith=term)[:10]
+
+    out = []
+    for man in manufacturers:
+        out.append({'label': man.name,
+                    'value': man.pk})
+
+    result = simplejson.dumps(out, cls=LazyEncoder)
+    return HttpResponse(result)

lfs/manage/views/product/product.py

 from django.utils import simplejson
 from django.utils.translation import ugettext_lazy as _
 from django.views.decorators.http import require_POST
+from django.forms.widgets import HiddenInput
 
 # lfs imports
 import lfs.core.utils
     def __init__(self, *args, **kwargs):
         super(ProductDataForm, self).__init__(*args, **kwargs)
         self.fields["template"].widget = SelectImage(choices=PRODUCT_TEMPLATES)
+        self.fields["manufacturer"].widget = HiddenInput()
 
     class Meta:
         model = Product
 
     product = lfs_get_object_or_404(Product, pk=product_id)
     products = _get_filtered_products_for_product_view(request)
-    paginator = Paginator(products, 20)
+    paginator = Paginator(products, 25)
     page = paginator.page(request.REQUEST.get("page", 1))
 
     try:
     """
     product = lfs_get_object_or_404(Product, pk=product_id)
     products = _get_filtered_products_for_product_view(request)
-    paginator = Paginator(products, 20)
+    paginator = Paginator(products, 25)
     page = paginator.page(request.REQUEST.get("page", 1))
 
     if product.sub_type == VARIANT:
         del request.session["product_filters"]
 
     products = _get_filtered_products(request)
-    paginator = Paginator(products, 20)
+    paginator = Paginator(products, 25)
     page = paginator.page(request.REQUEST.get("page", 1))
 
     product_id = request.REQUEST.get("product-id", 0)
     """Saves products with passed ids (by request body).
     """
     products = _get_filtered_products(request)
-    paginator = Paginator(products, 20)
+    paginator = Paginator(products, 25)
     page = paginator.page(request.REQUEST.get("page", 1))
 
     if request.POST.get("action") == "delete":
     request.session["product_filters"] = product_filters
 
     products = _get_filtered_products_for_product_view(request)
-    paginator = Paginator(products, 20)
+    paginator = Paginator(products, 25)
     page = paginator.page(request.REQUEST.get("page", 1))
 
     product_id = request.REQUEST.get("product-id", 0)

lfs/static/js/lfs.manage.js

 			// ReferenceError due to undefined tinymce
 	    }
         show_ajax_loading();
+
+        // trigger form-save-start event when form is about to be submitted
+        var form = $(this).closest("form");
+        var form_id = form.get(0).id;
+        var event = jQuery.Event("form-save-start");
+        event.form_id = form_id;
+        $('body').trigger(event);
+
         var action = $(this).attr("name")
-        $(this).parents("form:first").ajaxSubmit({
+        form.ajaxSubmit({
             data : {"action" : action},
             success : function(data) {
                 data = $.parseJSON(data);
                 }
                 hide_ajax_loading();
                 update_editor();
+
+                // trigger form-save-end event when new HTML has already been injected into page
+                var event = jQuery.Event("form-save-end");
+                event.form_id = form_id;
+                $('body').trigger(event);
             }
         })
         return false;
         knot.parent().find(".category-state").html("");
     };
 
-    $(function() {
-        $(".category-ajax-link").live("click", function() {
-            var url = $(this).attr("href");
+    $(".category-ajax-link").live("click", function() {
+        var url = $(this).attr("href");
 
-            // Loads children of clicked category.
-            if ($(this).hasClass("collapsed")) {
-                $.post(url, function(data) {
-                    data = $.parseJSON(data);
-                    for (var html in data["html"])
-                        $(data["html"][html][0]).html(data["html"][html][1]);
-                })
-                $(this).removeClass("collapsed");
-                $(this).addClass("expanded");
-            }
-            // Removes children of clicked category.
-            else {
-                $(this).siblings("div").html("")
-                $(this).removeClass("expanded");
-                $(this).addClass("collapsed");
-            }
-            return false;
-        });
+        // Loads children of clicked category.
+        if ($(this).hasClass("collapsed")) {
+            $.post(url, function(data) {
+                data = $.parseJSON(data);
+                for (var html in data["html"])
+                    $(data["html"][html][0]).html(data["html"][html][1]);
+            })
+            $(this).removeClass("collapsed");
+            $(this).addClass("expanded");
+        }
+        // Removes children of clicked category.
+        else {
+            $(this).siblings("div").html("")
+            $(this).removeClass("expanded");
+            $(this).addClass("collapsed");
+        }
+        return false;
+    });
 
-        $(".export-category-input").live("click", function() {
+    $(".export-category-input").live("click", function() {
 
-            // select / deselect all child nodes
-            var input = $(this);
-            var parent_checked = this.checked;
-            $(this).parent().find("input").each(function() { this.checked = parent_checked; })
+        // select / deselect all child nodes
+        var input = $(this);
+        var parent_checked = this.checked;
+        $(this).parent().find("input").each(function() { this.checked = parent_checked; })
 
-            // Updates child and parent categories of clicked category
-            var url = $(this).attr("data");
-            if (parent_checked == true) {
-                $.post(url, {"action" : "add"}, function(data) {
-                    update_sub_categories(input);
-                    update_parent_categories(input);
-                });
-            }
-            else {
-                $.post(url, {"action" : "remove"}, function(data) {
-                    update_sub_categories(input);
-                    update_parent_categories(input);
-                });
-            }
-        });
+        // Updates child and parent categories of clicked category
+        var url = $(this).attr("data");
+        if (parent_checked == true) {
+            $.post(url, {"action" : "add"}, function(data) {
+                update_sub_categories(input);
+                update_parent_categories(input);
+            });
+        }
+        else {
+            $.post(url, {"action" : "remove"}, function(data) {
+                update_sub_categories(input);
+                update_parent_categories(input);
+            });
+        }
+    });
 
-        $(".export-product-input").live("click", function() {
-            // Add / Remove product
-            var input = $(this);
-            var url = $(this).attr("data");
-            var checked = this.checked;
+    $(".export-product-input").live("click", function() {
+        // Add / Remove product
+        var input = $(this);
+        var url = $(this).attr("data");
+        var checked = this.checked;
 
-            // Updates parent catgories of clicked product
-            if (checked == true) {
-                $.post(url, {"action" : "add"}, function(data) { update_parent_categories(input) } );
-            }
-            else {
-                $.post(url, {"action" : "remove"}, function(data) { update_parent_categories(input) });
-            }
-        });
+        // Updates parent catgories of clicked product
+        if (checked == true) {
+            $.post(url, {"action" : "add"}, function(data) { update_parent_categories(input) } );
+        }
+        else {
+            $.post(url, {"action" : "remove"}, function(data) { update_parent_categories(input) });
+        }
     });
 
     $(".category-variants-options").live("change", function() {

lfs/templates/manage/product/data.html

                             {{ product.get_manufacturer }}
                         {% else %}
                             {{ form.manufacturer }}
+                            <input type="text" id="id_manufacturer_autocomplete" value="{{ form.instance.manufacturer.name }}" />
                         {% endif %}
                     </div>
                 {% endif %}

lfs/templates/manage/product/product.html

 {% block title %}{% trans "Manage Product" %}{% endblock %}
 {% block section %}manage-product{% endblock %}
 
+{% block javascript %}
+    <script type="text/javascript">
+        var MANUFACTURERS_AJAX_URL = '{% url lfs_manufacturers_ajax %}';
+
+        var MANUFACTURER_AUTOCOMPLETE_SETTINGS = {
+                                     source: MANUFACTURERS_AJAX_URL,
+                                     select: function(event, ui){
+                                         $('#id_manufacturer').val(ui.item.value);
+                                         $('#id_manufacturer_autocomplete').val(ui.item.label);
+                                         return false;
+                                     },
+                                     change: function(event, ui){
+                                         if (ui.item === null){
+                                             // only accept items selected from the list
+                                             $('#id_manufacturer').val('');
+                                             $('#id_manufacturer_autocomplete').val('');
+                                         }
+                                         return false;
+                                     },
+                                     minLength: 1}
+
+        $(function() {
+            $('#id_manufacturer_autocomplete').autocomplete(MANUFACTURER_AUTOCOMPLETE_SETTINGS);
+            // when form is reloaded we have to reattach autocomplete
+            $('body').bind('form-save-end', function(evt){
+                if (evt.form_id == 'product-data-form'){
+                    $('#id_manufacturer_autocomplete').autocomplete(MANUFACTURER_AUTOCOMPLETE_SETTINGS);
+                }
+            })
+        })
+    </script>
+{% endblock %}
+
 {% block left_slot %}
     <form action="{% url lfs_set_product_name_filter %}"
           method="post">
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.