Kartik Yii2 Number - 从扩展中获取价值

Kartik Yii2 Number - Getting value from extension

我正在使用 Kartik Yii2 Number 但我在使用此扩展程序获取价值时遇到问题..

我需要使用 onkeypressonkeyuponkeydown 来调用 javascript 函数,但是这个扩展只允许我使用 onchange 来调用 javascript函数..

这是我的表单代码:

<?= $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));
}

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

您可以添加自己的 JavaScript 来处理更改,该插件只是简单地隐藏实际输入并将其替换为具有相同 ID 的 显示 输入-disp.

例如,如果您的输入是 mymodel-attr,则生成的 显示 输入将是:

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

写一些JS处理更新事件,添加到页面中,比如想直接添加到视图文件中:

<?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);

更新:使用动态生成的 ID

而不是使用 nowdoc like on the original example, update the code to use heredoc,然后在 JS 中使用 PHP 变量的值:

<?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);

请注意,上面的代码是 PHP,JS 只是您 PHP 代码中的一个字符串,因此您可以灵活地使用它,但要付出代价在每个请求上发送代码。

您有几种优化方法,例如:

  1. 使用 小部件 options 属性分配一个 ID: 'options' => ['id' => 'my-input-id'] 然后将所有 JS 移动到一个文件并使用 Yii 的资产加载它.
  2. 仅在视图文件上输出动态ID,使该JS依赖于具有处理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 似乎是您要查找的内容,即它将处理 paste 事件,但仅在 ctrl 被按下,但您可以使用上面的不同事件处理程序来测试并查看哪种行为更符合您的需要,然后删除不需要的行为。

在深入研究 Kartik Yii2 Number 代码后,我意识到 extension 已经使用了所有键盘事件(keyupkeydownkeypress)来解析所有输入,所以用户不能直接使用键盘事件来获取值,在 extension 中可以使用的所有事件都是 change 事件,但是我们可以独立启动 JavaScript使用键盘事件 (keyup, keydown, keypress)..

正如我之前提到的,我将 form 与动态 ID 一起使用,因为 formforeach 循环中,而不是像 @RaulSauco 建议的那样捕获动态 ID,我将 class 投射到所有具有相同 class 名称的循环 form,并检查 JavaScript 中包含确切 classform,我需要使用 regex 解析 form 中的所有值,因为它包含 prefixsuffix 以及 extension..[= 中的所有 separator 38=]

这是我所有的代码..

控制器:

$count = 6;
for($i = 1; $i < $count; $i++)
{
    $model[] = new \common\models\Total();
}

return $this->render('form', [
    'model' => $model,
    'count' => $count,
]);

形式:

$this->registerJs("
$(document).ready(function() {
    function kalkulasiAnggaran()
    {
        var count = $count;
        var total_anggaran = 0;

        for(i=0; i<count; i++)
        {
            total_anggaran += parseFloat($('#'+i+'_target_rp-disp').val().replace(/[^0-9,]/g, '').replace(/,/g, '.') );
        }

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

    $('.target_rp').keyup(function() {
        kalkulasiAnggaran();
    });

    kalkulasiAnggaran();
});
");

<?php foreach($model as $index => $target) { ?>
    <?= $form->field($target, "[$index]target_rp")->widget(NumberControl::classname(), [
        'maskedInputOptions' => [
            'prefix' => 'Rp. ',
            'groupSeparator' => '.',
            'radixPoint' => ',',
            'allowMinus' => false,
            'digits' => 1000,
        ],
        'options' => ['value' => $target->isNewRecord ? '0' : $target->target_rp],
        'displayOptions' => ['id' => $index.'_target_rp-disp', 'class' => 'form-control kv-monospace target_rp'],
    ])->label(false) ?>
<?php } ?>

就是这样,我可以使用 keyup 事件在用户输入时获取直接值..

这不是理想的方法,因为我必须捕获所有用户输入并将其解析为实际数字,但它有效..

如果你们有任何简单或快速的方法,post你们的答案..