首页 > 解决方案 > Kartik Yii2 号码 - 从扩展中获取价值

问题描述

我正在使用Kartik Yii2 号码,但在使用此扩展程序获得价值时遇到问题..

我需要使用onkeypress或调用javascript函数,但这个扩展只允许我使用onkeyup调用javascript函数..onkeydownonchange

这是我的表单代码:

<?= $form->field($target, "[$index]anggaran")->widget(NumberControl::classname(), [
    'maskedInputOptions' => [
        'prefix' => 'Rp. ',
        'groupSeparator' => '.',
        'radixPoint' => ',',
        'allowMinus' => false,
        'digits' => 1000,
    ],
    'options' => ['onkeypress' => 'kalkulasiAnggaran()'],
    'displayOptions' => ['class' => 'form-control kv-monospace'],
])->label(false) ?>

这是我的javascript函数:

function kalkulasiAnggaran()
{
    var total_anggaran = 0;
    total_anggaran = parseFloat($("#anggaran").val());

    console.log(total_anggaran.toFixed(2));
}

有什么办法可以解决这个问题吗???

标签: javascriptyii2

解决方案


You can add your own JavaScript to handle changes, the plugin simply hides the actual input and replaces it with a display input that has the same Id followed by -disp.

For example, if your input was mymodel-attr the generated display input would be:

<input type="text" 
  id="mymodel-attr-disp" 
  class="form-control kv-monospace" 
  name="expense-unit_price-disp" 
  value="250.00" 
  style="text-align: right;"
>

Write some JS to handle update events and add it to the page, for example, if you wanted to add it directly to the view file:

<?php
$js = <<<'JS'
$(document).ready(function () {
  const $input = $('#mymodel-attr-disp');
  $input.keydown(function () {
      const newValue = $(this).val();
      console.log(`(jquery keydown event) I changed to ${newValue}`);
    });
  $input.keyup(function () {
      const newValue = $(this).val();
      console.log(`(jquery keyup event) I changed to ${newValue}`);
    });
  $input.on('input', function () {
      const newValue = $(this).val();
      console.log(`(jquery input event) I changed to ${newValue}`);
    });
});
JS;
$this->registerJs($js);

Update: using a dynamically generated ID

Instead of using nowdoc like on the original example, update the code to use heredoc, then use your PHP variable's value in your JS:

<?php
$inputId = 'model-attribute';
$js = <<<JS
$(document).ready(function () {
  const input = $('#$inputId-disp');
  input.keydown(function () {
      const newValue = $(this).val();
      console.log('(jquery keydown event) I changed to ' + newValue);
    });
  input.keyup(function () {
      const newValue = $(this).val();
      console.log('(jquery keyup event) I changed to ' + newValue);
    });
  input.on('input', function () {
      const newValue = $(this).val();
      console.log('(jquery input event) I changed to ' + newValue);
    });
});
JS;
$this->registerJs($js);

Note that the above code is PHP, the JS is just a string in your PHP code, so you do get a lot of flexibility with what you do with it, at the cost of sending the code on each request.

You have a few ways to optimize this, for example:

  1. Use the options attribute on the widget to assign an ID: 'options' => ['id' => 'my-input-id'] then move all your JS to a file and load it using Yii's assets.
  2. Only output the dynamic ID on the view file, make that JS depend on the file that has the logic that handles the input event.

You can use the following snippet to test what actions triggers different events on the input:

$(document).ready(function() {
  const $input = $('#mymodel-attr-disp');
  $input.keydown(function() {
    const newValue = $(this).val();
    console.log(`(jquery keydown event) I changed to ${newValue}`);
  });
  $input.keyup(function() {
    const newValue = $(this).val();
    console.log(`(jquery keyup event) I changed to ${newValue}`);
  });
  $input.on('input', function() {
    const newValue = $(this).val();
    console.log(`(jquery input event) I changed to ${newValue}`);
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="text" id="mymodel-attr-disp" class="form-control kv-monospace" name="expense-unit_price-disp" value="250.00" style="text-align: right;">

input seems to be what you are looking for, i.e. it will handle paste events, but won't trigger when only ctrl is pressed, but you can use the different event handlers above to test and see which behavior is the one that better fits your needs, then remove the ones you don't need.


推荐阅读