Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision 5aec18fe

Von Sven Schöling vor etwa 7 Jahren hinzugefügt

  • ID 5aec18fed79986d088e3a7ed05a9166c48d05b39
  • Vorgänger 891d4ce8
  • Nachfolger 417a6f3f

PartPicker von autocomplete_part.js nach kivi.Part.js verschoben

Unterschiede anzeigen:

js/kivi.Part.js
263 263
    $.post("controller.pl", { action: 'Part/warehouse_changed', warehouse_id: function(){ return $('#part_warehouse_id').val() } },   kivi.eval_json_result);
264 264
  }
265 265

  
266
  ns.Picker = function($real, options) {
267
    // short circuit in case someone double inits us
268
    if ($real.data("part_picker"))
269
      return $real.data("part_picker");
270

  
271
    var KEY = {
272
      ESCAPE: 27,
273
      ENTER:  13,
274
      TAB:    9,
275
      LEFT:   37,
276
      RIGHT:  39,
277
      PAGE_UP: 33,
278
      PAGE_DOWN: 34,
279
      SHIFT:     16,
280
      CTRL:      17,
281
      ALT:       18,
282
    };
283
    var CLASSES = {
284
      PICKED:       'partpicker-picked',
285
      UNDEFINED:    'partpicker-undefined',
286
      FAT_SET_ITEM: 'partpicker_fat_set_item',
287
    }
288
    var o = $.extend({
289
      limit: 20,
290
      delay: 50,
291
      fat_set_item: $real.hasClass(CLASSES.FAT_SET_ITEM),
292
    }, options);
293
    var STATES = {
294
      PICKED:    CLASSES.PICKED,
295
      UNDEFINED: CLASSES.UNDEFINED
296
    }
297
    var real_id = $real.attr('id');
298
    var $dummy             = $('#' + real_id + '_name');
299
    var $part_type         = $('#' + real_id + '_part_type');
300
    var $classification_id = $('#' + real_id + '_classification_id');
301
    var $unit              = $('#' + real_id + '_unit');
302
    var $convertible_unit  = $('#' + real_id + '_convertible_unit');
303
    var state   = STATES.PICKED;
304
    var last_real = $real.val();
305
    var last_dummy = $dummy.val();
306
    var timer;
307

  
308
    function open_dialog () {
309
      kivi.popup_dialog({
310
        url: 'controller.pl?action=Part/part_picker_search',
311
        data: $.extend({
312
          real_id: real_id,
313
        }, ajax_data($dummy.val())),
314
        id: 'part_selection',
315
        dialog: {
316
          title: kivi.t8('Part picker'),
317
          width: 800,
318
          height: 800,
319
        }
320
      });
321
      window.clearTimeout(timer);
322
      return true;
323
    }
324

  
325
    function ajax_data(term) {
326
      var data = {
327
        'filter.all:substr:multi::ilike': term,
328
        'filter.obsolete': 0,
329
        'filter.unit_obj.convertible_to': $convertible_unit && $convertible_unit.val() ? $convertible_unit.val() : '',
330
        no_paginate:  $('#no_paginate').prop('checked') ? 1 : 0,
331
        current:  $real.val(),
332
      };
333

  
334
      if ($part_type && $part_type.val())
335
        data['filter.part_type'] = $part_type.val().split(',');
336

  
337
      if ($classification_id && $classification_id.val())
338
        data['filter.classification_id'] = $classification_id.val().split(',');
339

  
340
      if ($unit && $unit.val())
341
        data['filter.unit'] = $unit.val().split(',');
342

  
343
      return data;
344
    }
345

  
346
    function set_item (item) {
347
      if (item.id) {
348
        $real.val(item.id);
349
        // autocomplete ui has name, use the value for ajax items, which contains displayable_name
350
        $dummy.val(item.name ? item.name : item.value);
351
      } else {
352
        $real.val('');
353
        $dummy.val('');
354
      }
355
      state = STATES.PICKED;
356
      last_real = $real.val();
357
      last_dummy = $dummy.val();
358
      $real.trigger('change');
359

  
360
      if (o.fat_set_item && item.id) {
361
        $.ajax({
362
          url: 'controller.pl?action=Part/show.json',
363
          data: { id: item.id },
364
          success: function(rsp) {
365
            $real.trigger('set_item:PartPicker', rsp);
366
          },
367
        });
368
      } else {
369
        $real.trigger('set_item:PartPicker', item);
370
      }
371
      annotate_state();
372
    }
373

  
374
    function make_defined_state () {
375
      if (state == STATES.PICKED) {
376
        annotate_state();
377
        return true
378
      } else if (state == STATES.UNDEFINED && $dummy.val() === '')
379
        set_item({})
380
      else {
381
        set_item({ id: last_real, name: last_dummy })
382
      }
383
      annotate_state();
384
    }
385

  
386
    function annotate_state () {
387
      if (state == STATES.PICKED)
388
        $dummy.removeClass(STATES.UNDEFINED).addClass(STATES.PICKED);
389
      else if (state == STATES.UNDEFINED && $dummy.val() === '')
390
        $dummy.removeClass(STATES.UNDEFINED).addClass(STATES.PICKED);
391
      else {
392
        $dummy.addClass(STATES.UNDEFINED).removeClass(STATES.PICKED);
393
      }
394
    }
395

  
396
    function update_results () {
397
      $.ajax({
398
        url: 'controller.pl?action=Part/part_picker_result',
399
        data: $.extend({
400
            'real_id': $real.val(),
401
        }, ajax_data(function(){ var val = $('#part_picker_filter').val(); return val === undefined ? '' : val })),
402
        success: function(data){ $('#part_picker_result').html(data) }
403
      });
404
    }
405

  
406
    function result_timer (event) {
407
      if (!$('no_paginate').prop('checked')) {
408
        if (event.keyCode == KEY.PAGE_UP) {
409
          $('#part_picker_result a.paginate-prev').click();
410
          return;
411
        }
412
        if (event.keyCode == KEY.PAGE_DOWN) {
413
          $('#part_picker_result a.paginate-next').click();
414
          return;
415
        }
416
      }
417
      window.clearTimeout(timer);
418
      timer = window.setTimeout(update_results, 100);
419
    }
420

  
421
    function close_popup() {
422
      $('#part_selection').dialog('close');
423
    }
424

  
425
    function handle_changed_text(callbacks) {
426
      $.ajax({
427
        url: 'controller.pl?action=Part/ajax_autocomplete',
428
        dataType: "json",
429
        data: $.extend( ajax_data($dummy.val()), { prefer_exact: 1 } ),
430
        success: function (data) {
431
          if (data.length == 1) {
432
            set_item(data[0]);
433
            if (callbacks && callbacks.match_one) callbacks.match_one(data[0]);
434
          } else if (data.length > 1) {
435
            state = STATES.UNDEFINED;
436
            if (callbacks && callbacks.match_many) callbacks.match_many(data);
437
          } else {
438
            state = STATES.UNDEFINED;
439
            if (callbacks &&callbacks.match_none) callbacks.match_none();
440
          }
441
          annotate_state();
442
        }
443
      });
444
    }
445

  
446
    $dummy.autocomplete({
447
      source: function(req, rsp) {
448
        $.ajax($.extend(o, {
449
          url:      'controller.pl?action=Part/ajax_autocomplete',
450
          dataType: "json",
451
          data:     ajax_data(req.term),
452
          success:  function (data){ rsp(data) }
453
        }));
454
      },
455
      select: function(event, ui) {
456
        set_item(ui.item);
457
      },
458
      search: function(event, ui) {
459
        if ((event.which == KEY.SHIFT) || (event.which == KEY.CTRL) || (event.which == KEY.ALT))
460
          event.preventDefault();
461
      }
462
    });
463
    /*  In case users are impatient and want to skip ahead:
464
     *  Capture <enter> key events and check if it's a unique hit.
465
     *  If it is, go ahead and assume it was selected. If it wasn't don't do
466
     *  anything so that autocompletion kicks in.  For <tab> don't prevent
467
     *  propagation. It would be nice to catch it, but javascript is too stupid
468
     *  to fire a tab event later on, so we'd have to reimplement the "find
469
     *  next active element in tabindex order and focus it".
470
     */
471
    /* note:
472
     *  event.which does not contain tab events in keypressed in firefox but will report 0
473
     *  chrome does not fire keypressed at all on tab or escape
474
     */
475
    $dummy.keydown(function(event){
476
      if (event.which == KEY.ENTER || event.which == KEY.TAB) {
477
        // if string is empty assume they want to delete
478
        if ($dummy.val() === '') {
479
          set_item({});
480
          return true;
481
        } else if (state == STATES.PICKED) {
482
          return true;
483
        }
484
        if (event.which == KEY.TAB) {
485
          event.preventDefault();
486
          handle_changed_text();
487
        }
488
        if (event.which == KEY.ENTER) {
489
          handle_changed_text({
490
            match_one:  function(){$('#update_button').click();},
491
            match_many: function(){open_dialog();}
492
          });
493
          return false;
494
        }
495
      } else if ((event.which != KEY.SHIFT) && (event.which != KEY.CTRL) && (event.which != KEY.ALT)) {
496
        state = STATES.UNDEFINED;
497
      }
498
    });
499

  
500
    $dummy.on('paste', function(){
501
      setTimeout(function() {
502
        handle_changed_text();
503
      }, 1);
504
    });
505

  
506
    $dummy.blur(function(){
507
      window.clearTimeout(timer);
508
      timer = window.setTimeout(annotate_state, 100);
509
    });
510

  
511
    // now add a picker div after the original input
512
    var popup_button = $('<span>').addClass('ppp_popup_button');
513
    $dummy.after(popup_button);
514
    popup_button.click(open_dialog);
515

  
516
    var pp = {
517
      real:              function() { return $real },
518
      dummy:             function() { return $dummy },
519
      part_type:         function() { return $part_type },
520
      classification_id: function() { return $classification_id },
521
      unit:              function() { return $unit },
522
      convertible_unit:  function() { return $convertible_unit },
523
      update_results: update_results,
524
      result_timer:   result_timer,
525
      set_item:       set_item,
526
      reset:          make_defined_state,
527
      is_defined_state: function() { return state == STATES.PICKED },
528
      init_results:    function () {
529
        $('div.part_picker_part').each(function(){
530
          $(this).click(function(){
531
            set_item({
532
              id:   $(this).children('input.part_picker_id').val(),
533
              name: $(this).children('input.part_picker_description').val(),
534
              classification_id: $(this).children('input.part_picker_classification_id').val(),
535
              unit: $(this).children('input.part_picker_unit').val(),
536
              partnumber:  $(this).children('input.part_picker_partnumber').val(),
537
              description: $(this).children('input.part_picker_description').val(),
538
            });
539
            close_popup();
540
            $dummy.focus();
541
            return true;
542
          });
543
        });
544
        $('#part_selection').keydown(function(e){
545
           if (e.which == KEY.ESCAPE) {
546
             close_popup();
547
             $dummy.focus();
548
           }
549
        });
550
      }
551
    }
552
    $real.data('part_picker', pp);
553
    return pp;
554
  };
555

  
266 556
  $(function(){
267 557

  
268 558
    // assortment
......
305 595

  
306 596
    $('#part_warehouse_id').change(kivi.Part.reload_bin_selection);
307 597

  
598
    $('input.part_autocomplete').each(function(i,real){
599
      kivi.Part.Picker($(real));
600
    });
308 601
  });
309
})
602
});

Auch abrufbar als: Unified diff