From ed4c288dccff8197ec17543ab35a5dfaae4592e1 Mon Sep 17 00:00:00 2001 From: mathieu Date: Thu, 21 Apr 2016 14:49:14 +0200 Subject: [PATCH] Suite recherche bool Former-commit-id: 73ac40f8e5abe136735fa384abd9f166b24d6eb5 --- telemeta/forms/boolean_form.py | 22 ++++-- telemeta/templates/search/advanceSearch.html | 74 ++++++++++++++++++-- telemeta/urls.py | 2 + telemeta/views/search.py | 63 ++++++++++++++++- 4 files changed, 149 insertions(+), 12 deletions(-) diff --git a/telemeta/forms/boolean_form.py b/telemeta/forms/boolean_form.py index e7fc94ed..fff4ef15 100644 --- a/telemeta/forms/boolean_form.py +++ b/telemeta/forms/boolean_form.py @@ -2,7 +2,21 @@ from django import forms class BooleanSearch(forms.Form): - boolean = forms.ChoiceField(choices=[('ET', 'ET',), ('OU', 'OU',)], label='') - startBracket = forms.BooleanField(initial=False, label='') - textField = forms.CharField(label='') - endBracket = forms.BooleanField(initial=False, label='') \ No newline at end of file + def getBrackets(dir): + list = [] + for i in range(4): + brackets = "" + for j in range(i): + if dir=="left": + brackets+="( " + elif dir=="right": + brackets+=") " + list.append((brackets,brackets)) + return list + + boolean = forms.ChoiceField(choices=[('ET', 'ET',), ('OU', 'OU',)], label='', required=False) + startBracket = forms.ChoiceField(label='',choices=getBrackets('left'), required=False) + textField = forms.CharField(label='', widget=forms.TextInput(attrs={'required':''})) + endBracket = forms.ChoiceField(label='', choices=getBrackets('right'), required=False) + + diff --git a/telemeta/templates/search/advanceSearch.html b/telemeta/templates/search/advanceSearch.html index e000e74d..289340ed 100644 --- a/telemeta/templates/search/advanceSearch.html +++ b/telemeta/templates/search/advanceSearch.html @@ -21,6 +21,10 @@ z-index: 1000; } + select[name*="startBracket"]{ + text-align: right; + } + {% endblock %} {% block content %} @@ -253,7 +257,7 @@ {{ booleanForm.management_form}} {% for form in booleanForm %} {% if forloop.counter0 == 0 %} - {{ form.startBracket }} + {{ form.startBracket }} {{ form.textField }} {{ form.endBracket }} {% else %} @@ -273,6 +277,10 @@ +

+ +

Pour chaque champ : Mot-clé contenu dans l'instrument (ex "uita" pour "guitare") ou nom entier

+ {% endblock %} @@ -325,7 +333,8 @@ $(function() { $('#dialog').dialog({ autoOpen: false, - width: '30%', + width: '40%', + height: 600, }); $('.fieldWrapper a').click(function(){ @@ -334,21 +343,74 @@ $(function() { var supprButton = 'Supprimer champ
'; + var balise = $('#copy').clone(); + $(balise).children().each(function () { + $(this).val('').prop('checked', false).prop('selected', false); + }); + + function suppression(e) { + e.preventDefault(); + var nombre = $('input[name*="textField"]').length; + if(nombre==3){ + $('#suppr').remove(); + } + $('#bloc-'+(nombre-1)).remove(); + $('#id_form-TOTAL_FORMS').attr('value', nombre-1); + + } + function ajout(e) { e.preventDefault(); var nombre = $('input[name*="textField"]').length; - var balise = $('#copy').clone().removeAttr('id').html().replace(/1/g, nombre); + var bal = $(balise).clone().attr('id', 'bloc-'+nombre); if(nombre==2){ $('#ajout').after(supprButton); + $('#suppr').click(suppression); } - $('#ajout').before(balise); + $('#ajout').before(bal); + $('#bloc-'+nombre).html($('#bloc-'+nombre).html().replace(/1/g, nombre)); activerAutocompletion($('#id_form-'+nombre+'-textField'), 'instruments'); - + $('#id_form-TOTAL_FORMS').attr('value', nombre+1); } + $('#ajout').click(ajout); + activerAutocompletion($('#id_form-0-textField, #id_form-1-textField'), 'instruments'); + + var interval = null; + var textInput = ""; + + $('#dialog form').on('submit change', function (e) { + if(e.type!='keypress') e.preventDefault(); + $.ajax({ + url: '/search/booleaninstru/', + dataType: 'json', + data: $(this).serialize(), + success: function(donnees){ + if(e.type=='submit' && donnees.result.match(/Requête formée : /g)){ + $("#dialog").dialog("close"); + $('#id_instruments').val(donnees.result.substr(17)); + } + $('#res').text(donnees.result); + }, + }); + }); - $('#ajout').click(ajout); + $('#dialog input[type="text"]').on('focus', function () { + textInput = $(this).val(); + var self = this; + interval = setInterval(function () { + if($(self).val()!= textInput){ + textInput = $(self).val(); + $('#dialog form').trigger('change'); + } + }, 500); + }); + + $('#dialog input[type="text"]').on('blur', function () { + clearInterval(interval); + textInput = "" + }); }); diff --git a/telemeta/urls.py b/telemeta/urls.py index 5a257615..28b29e35 100644 --- a/telemeta/urls.py +++ b/telemeta/urls.py @@ -45,6 +45,7 @@ playlist_view = PlaylistView() profile_view = ProfileView() geo_view = GeoView() resource_view = ResourceView() +boolean_view = BooleanSearchView() # ID's regular expressions export_extensions = "|".join(item_view.list_export_extensions()) @@ -130,6 +131,7 @@ urlpatterns = patterns('', url(r'^search/quick/(?P[A-Za-z0-9._-]+)/$', HaystackSearch(), name='haystack_search_type'), url(r'^search/advance/$', HaystackAdvanceSearch(form_class=HayAdvanceForm, template='search/advanceSearch.html'), name='haystack_advance_search'), url(r'^search/advance/(?P[A-Za-z0-9._-]+)/$', HaystackAdvanceSearch(form_class=HayAdvanceForm, template='search/advanceSearch.html'), name='haystack_advance_search_type'), + url(r'^search/booleaninstru/$', boolean_view.getBooleanQuery), url(r'^search/playlist_add/(?P[A-Za-z0-9._-]+)/$', NewPlaylistView().display, name='haystack_playlist'), url(r'^search/playlist_confirmation/(?P[A-Za-z0-9._-]+)/$',NewPlaylistView().addToPlaylist, name='add_confirmation'), diff --git a/telemeta/views/search.py b/telemeta/views/search.py index b5920c1d..5c24aa1e 100644 --- a/telemeta/views/search.py +++ b/telemeta/views/search.py @@ -1,4 +1,4 @@ -# -*- coding: utf-8 -*- +# coding: utf-8 # Copyright (C) 2015 Angy Fils-Aimé, Killian Mary @@ -27,6 +27,7 @@ import simplejson as json from django.http import HttpResponse from telemeta.forms.boolean_form import * from django.forms.formsets import formset_factory +from django.utils.encoding import smart_str class HaystackSearch(FacetedSearchView, SavedSearchView): @@ -194,4 +195,62 @@ def autocomplete(request): import unicodedata def escapeAccentAndLower(chaine): - return unicodedata.normalize('NFD', chaine).encode('ascii', 'ignore').lower() \ No newline at end of file + return unicodedata.normalize('NFD', chaine).encode('ascii', 'ignore').lower() + +class BooleanSearchView(object): + + form = formset_factory(BooleanSearch) + + def getBooleanQuery(self, request): + if request.method != 'GET': + return HttpResponse(json.dumps({'result': '[ERROR]:Not Request GET'}), content_type='application/json') + + formset = self.form(request.GET) + if formset.is_valid(): + query = "" + for i in range(len(formset.forms)): + formul = formset.forms[i] + if i!=0: + query+=formul.cleaned_data["boolean"]+" " + query+=formul.cleaned_data["startBracket"] + query+=formul.cleaned_data["textField"].strip()+" " + query+=formul.cleaned_data["endBracket"] + try: + self.isCorrectQuery(query.strip()) + except Erreur as e: + return HttpResponse(json.dumps({'result': e.message}), content_type='application/json') + return HttpResponse(json.dumps({'result': u'Requête formée : '+query.strip()}), content_type='application/json') + else: + return HttpResponse(json.dumps({'result': 'Field(s) missing'}), content_type='application/json') + + def isCorrectQuery(self, query): + tabQuery = query.split() + openBracket = 0 + boolean = False + for mot in tabQuery: + if mot ==")": + if openBracket == 0: + raise Erreur("Open Bracket Is Missing !") + else: + openBracket -= 1 + boolean = False + elif mot=="ET" or mot=="OU": + if boolean: + raise Erreur("Two boolean follow") + else: + boolean = True + elif mot == "(": + openBracket += 1 + else: + boolean = False + if boolean: + raise Erreur("Boolean at the end of query") + elif openBracket != 0: + raise Erreur("Close Bracket Is Missing") + else: + return True + + + +class Erreur(Exception): + pass \ No newline at end of file -- 2.39.5