Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision f16c5520

Von Sven Schöling vor mehr als 10 Jahren hinzugefügt

  • ID f16c552035ab973a9aed4a1dc29d0e16be7ff541
  • Vorgänger a4e4f1a7
  • Nachfolger e42bd22a

CustomerVendor: Picker nach Art von PartPicker

- reinit_widgets fähig
- Tab und Enter atomar
- unterstützt onChange und set_item:CustomerVendorPicker trigger
- unterstützt fat_set_item

Unterschiede anzeigen:

js/autocomplete_customer.js
1
$(function(){
2
  $('input.customer_autocomplete').each(function(i,real){
3
    var dummy = $('#' + real.id + '_name');
4
    $(dummy).autocomplete({
5
      source: function(req, rsp) {
1
namespace('kivi', function(k){
2
  k.CustomerVendorPicker = function($real, options) {
3
    // short circuit in case someone double inits us
4
    if ($real.data("customer_vendor_picker"))
5
      return $real.data("customer_vendor_picker");
6

  
7
    var KEY = {
8
      ESCAPE: 27,
9
      ENTER:  13,
10
      TAB:    9,
11
      LEFT:   37,
12
      RIGHT:  39,
13
      PAGE_UP: 33,
14
      PAGE_DOWN: 34,
15
    };
16
    var CLASSES = {
17
      PICKED:       'customer-vendor-picker-picked',
18
      UNDEFINED:    'customer-vendor-picker-undefined',
19
      FAT_SET_ITEM: 'customer-vendor-picker-fat-set-item',
20
    }
21
    var o = $.extend({
22
      limit: 20,
23
      delay: 50,
24
      fat_set_item: $real.hasClass(CLASSES.FAT_SET_ITEM),
25
    }, options);
26
    var STATES = {
27
      PICKED:    CLASSES.PICKED,
28
      UNDEFINED: CLASSES.UNDEFINED
29
    }
30
    var real_id = $real.attr('id');
31
    var $dummy  = $('#' + real_id + '_name');
32
    var $type   = $('#' + real_id + '_type');
33
    var $unit   = $('#' + real_id + '_unit');
34
    var state   = STATES.PICKED;
35
    var last_real = $real.val();
36
    var last_dummy = $dummy.val();
37
    var timer;
38

  
39
    function ajax_data(term) {
40
      var data = {
41
        'filter.all:substr:multi::ilike': term,
42
        'filter.obsolete': 0,
43
        current:  $real.val(),
44
        type:     $type.val(),
45
      };
46

  
47
      return data;
48
    }
49

  
50
    function set_item (item) {
51
      if (item.id) {
52
        $real.val(item.id);
53
        // autocomplete ui has name, ajax items have description
54
        $dummy.val(item.name ? item.name : item.description);
55
      } else {
56
        $real.val('');
57
        $dummy.val('');
58
      }
59
      state = STATES.PICKED;
60
      last_real = $real.val();
61
      last_dummy = $dummy.val();
62
      last_unverified_dummy = $dummy.val();
63
      $real.trigger('change');
64

  
65
      if (o.fat_set_item && item.id) {
6 66
        $.ajax({
7
          url: 'controller.pl?action=CustomerVendor/ajaj_customer_autocomplete',
8
          dataType: "json",
9
          data: {
10
            term: req.term,
11
            current: function() { real.val },
12
            obsolete: 0,
67
          url: 'controller.pl?action=CustomerVendor/show.json',
68
          data: { id: item.id, db: item.type },
69
          success: function(rsp) {
70
            $real.trigger('set_item:CustomerVendorPicker', rsp);
13 71
          },
14
          success: function (data){ rsp(data) }
15 72
        });
73
      } else {
74
        $real.trigger('set_item:CustomerVendorPicker', item);
75
      }
76
      annotate_state();
77
    }
78

  
79
    function make_defined_state () {
80
      if (state == STATES.PICKED) {
81
        annotate_state();
82
        return true
83
      } else if (state == STATES.UNDEFINED && $dummy.val() == '')
84
        set_item({})
85
      else {
86
        last_unverified_dummy = $dummy.val();
87
        set_item({ id: last_real, name: last_dummy })
88
      }
89
      annotate_state();
90
    }
91

  
92
    function annotate_state () {
93
      if (state == STATES.PICKED)
94
        $dummy.removeClass(STATES.UNDEFINED).addClass(STATES.PICKED);
95
      else if (state == STATES.UNDEFINED && $dummy.val() == '')
96
        $dummy.removeClass(STATES.UNDEFINED).addClass(STATES.PICKED);
97
      else {
98
        last_unverified_dummy = $dummy.val();
99
        $dummy.addClass(STATES.UNDEFINED).removeClass(STATES.PICKED);
100
      }
101
    }
102

  
103
    $dummy.autocomplete({
104
      source: function(req, rsp) {
105
        $.ajax($.extend(o, {
106
          url:      'controller.pl?action=CustomerVendor/ajaj_autocomplete',
107
          dataType: "json",
108
          data:     ajax_data(req.term),
109
          success:  function (data){ rsp(data) }
110
        }));
16 111
      },
17
      limit: 20,
18
      delay: 50,
19 112
      select: function(event, ui) {
20
        $(real).val(ui.item.id);
21
        $(dummy).val(ui.item.name);
113
        set_item(ui.item);
22 114
      },
23 115
    });
24
  });
116
    /*  In case users are impatient and want to skip ahead:
117
     *  Capture <enter> key events and check if it's a unique hit.
118
     *  If it is, go ahead and assume it was selected. If it wasn't don't do
119
     *  anything so that autocompletion kicks in.  For <tab> don't prevent
120
     *  propagation. It would be nice to catch it, but javascript is too stupid
121
     *  to fire a tab event later on, so we'd have to reimplement the "find
122
     *  next active element in tabindex order and focus it".
123
     */
124
    /* note:
125
     *  event.which does not contain tab events in keypressed in firefox but will report 0
126
     *  chrome does not fire keypressed at all on tab or escape
127
     */
128
    $dummy.keydown(function(event){
129
      if (event.which == KEY.ENTER || event.which == KEY.TAB) {
130
        // if string is empty assume they want to delete
131
        if ($dummy.val() == '') {
132
          set_item({});
133
          return true;
134
        } else if (state == STATES.PICKED) {
135
          return true;
136
        }
137
        if (event.which == KEY.TAB) event.preventDefault();
138
        $.ajax({
139
          url: 'controller.pl?action=CustomerVendor/ajaj_autocomplete',
140
          dataType: "json",
141
          data: $.extend( ajax_data($dummy.val()), { prefer_exact: 1 } ),
142
          success: function (data) {
143
            if (data.length == 1) {
144
              set_item(data[0]);
145
              if (event.which == KEY.ENTER)
146
                $('#update_button').click();
147
            } else {
148
            }
149
            annotate_state();
150
          }
151
        });
152
        if (event.which == KEY.ENTER)
153
          return false;
154
      } else {
155
        state = STATES.UNDEFINED;
156
      }
157
    });
158

  
159
    $dummy.blur(function(){
160
      window.clearTimeout(timer);
161
      timer = window.setTimeout(annotate_state, 100);
162
    });
163

  
164
    // now add a picker div after the original input
165
    var pp = {
166
      real:           function() { return $real },
167
      dummy:          function() { return $dummy },
168
      type:           function() { return $type },
169
      set_item:       set_item,
170
      reset:          make_defined_state,
171
      is_defined_state: function() { return state == STATES.PICKED },
172
    }
173
    $real.data('customer_vendor_picker', pp);
174
    return pp;
175
  }
176
});
177

  
178
$(function(){
179
  $('input.customer_vendor_autocomplete').each(function(i,real){
180
    kivi.CustomerVendorPicker($(real));
181
  })
25 182
});

Auch abrufbar als: Unified diff