【问题标题】:CakePHP 4 multiple checkboxesCakePHP 4 多个复选框
【发布时间】:2020-08-25 21:21:28
【问题描述】:

我想用数组 JournalEntry[strategy][strategies_conditions] 填充一个复选框组

然后我希望选中包含在 JournalEntry[journal_entries_strategy_conditions] 中的复选框

我的复选框显示但未正确链接到 nameid 的正确字段

这是我在edit.php中的代码

<?php
    echo $this->Form->control('journal_id', ['options' => $journals]);
    echo $this->Form->control('ticket_number');
    echo $this->Form->control('strategy_id', ['options' => $strategies, 'empty' => true, 'onChange' => 'getComboA(this)']);
    debug($journalEntry);
    ?>
    <div id="stategy-condition">
        <?php echo $this->Form->control('journal_entries_strategy_conditions.strategies_condition_id', 
            [
                'type' => 'select',
                'multiple' => 'checkbox', 
                'options' => $journalEntry[strategy][strategies_conditions],
                'selected' => $journalEntry[journal_entries_strategy_conditions] 
            ]); ?>
    </div>

有了这个我得到了这个输出,你可以看到它使用object作为&lt;label&gt;&lt;input value="1"设置为id

<div class="input select">
    <label for="strategy-id">Strategy</label>
        <input type="hidden" name="strategy_id" value="">
        <div class="checkbox">
            <label for="strategy-id-0">
                <input type="checkbox" name="strategy_id[]" value="0" id="strategy-id-0">{
    "id": 1,
    "strategy_id": 5,
    "name": "zxcasd",
    "level": "0",
    "created": "2020-08-01T21:21:11+00:00",
    "modified": "2020-08-01T21:21:11+00:00"
}</label>
       </div>
       <div class="checkbox">
            <label for="strategy-id-1">
                <input type="checkbox" name="strategy_id[]" value="1" id="strategy-id-1">{
    "id": 2,
    "strategy_id": 5,
    "name": "zxcasd",
    "level": "0",
    "created": "2020-08-01T21:21:11+00:00",
    "modified": "2020-08-01T21:21:11+00:00"
}</label>
         </div>
         <div class="checkbox">
             <label for="strategy-id-2">
                  <input type="checkbox" name="strategy_id[]" value="2" id="strategy-id-2">{
    "id": 3,
    "strategy_id": 5,
    "name": "zxcad",
    "level": "0",
    "created": "2020-08-01T21:21:11+00:00",
    "modified": "2020-08-01T21:21:11+00:00"
}</label></div></div>

这是数据:

object(App\Model\Entity\JournalEntry) {

'id' => (int) 20,
'journal_id' => (int) 1,
'ticket_number' => 'sdfsdfsdf',
'strategy_id' => (int) 5,
'timeframe' => '',
'created' => object(Cake\I18n\FrozenTime) {

    'time' => '2020-08-25 20:51:42.000000+00:00',
    'timezone' => 'UTC',
    'fixedNowTime' => false

},
'modified' => object(Cake\I18n\FrozenTime) {

    'time' => '2020-08-25 20:51:42.000000+00:00',
    'timezone' => 'UTC',
    'fixedNowTime' => false

},
'journal_entries_strategy_conditions' => [
    (int) 0 => object(App\Model\Entity\JournalEntriesStrategyCondition) {

        'id' => (int) 8,
        'journal_entry_id' => (int) 20,
        'strategies_condition_id' => (int) 1,
        'created' => object(Cake\I18n\FrozenTime) {

            'time' => '2020-08-25 20:51:42.000000+00:00',
            'timezone' => 'UTC',
            'fixedNowTime' => false
        
        },
        'modified' => object(Cake\I18n\FrozenTime) {

            'time' => '2020-08-25 20:51:42.000000+00:00',
            'timezone' => 'UTC',
            'fixedNowTime' => false
        
        },
    
    }
],
'strategy' => object(App\Model\Entity\Strategy) {

    'id' => (int) 5,
    'user_id' => (int) 1,
    'name' => 'zxcasd',
    'description' => 'zxcasd',
    'one_hundred_trades' => (int) 0,
    'created' => object(Cake\I18n\FrozenTime) {

        'time' => '2020-08-01 21:21:11.000000+00:00',
        'timezone' => 'UTC',
        'fixedNowTime' => false
    
    },
    'modified' => object(Cake\I18n\FrozenTime) {

        'time' => '2020-08-01 21:21:11.000000+00:00',
        'timezone' => 'UTC',
        'fixedNowTime' => false
    
    },
    'strategies_conditions' => [
        (int) 0 => object(App\Model\Entity\StrategiesCondition) {

            'id' => (int) 1,
            'strategy_id' => (int) 5,
            'name' => 'zxcasd',
            'level' => '0',
            'created' => object(Cake\I18n\FrozenTime) {

                'time' => '2020-08-01 21:21:11.000000+00:00',
                'timezone' => 'UTC',
                'fixedNowTime' => false
            
            },
            'modified' => object(Cake\I18n\FrozenTime) {

                'time' => '2020-08-01 21:21:11.000000+00:00',
                'timezone' => 'UTC',
                'fixedNowTime' => false
            
            },
            '[new]' => false,
            '[accessible]' => [
                'strategy_id' => true,
                'name' => true,
                'level' => true,
                'created' => true,
                'modified' => true,
                'strategy' => true
            ]
        
        },
        (int) 1 => object(App\Model\Entity\StrategiesCondition) {

            'id' => (int) 2,
            'strategy_id' => (int) 5,
            'name' => 'zxcasd',
            'level' => '0',
            'created' => object(Cake\I18n\FrozenTime) {

                'time' => '2020-08-01 21:21:11.000000+00:00',
                'timezone' => 'UTC',
                'fixedNowTime' => false
            
            },
            'modified' => object(Cake\I18n\FrozenTime) {

                'time' => '2020-08-01 21:21:11.000000+00:00',
                'timezone' => 'UTC',
                'fixedNowTime' => false
            
            }
        
        },
        (int) 2 => object(App\Model\Entity\StrategiesCondition) {

            'id' => (int) 3,
            'strategy_id' => (int) 5,
            'name' => 'zxcad',
            'level' => '0',
            'created' => object(Cake\I18n\FrozenTime) {

                'time' => '2020-08-01 21:21:11.000000+00:00',
                'timezone' => 'UTC',
                'fixedNowTime' => false
            
            },
            'modified' => object(Cake\I18n\FrozenTime) {

                'time' => '2020-08-01 21:21:11.000000+00:00',
                'timezone' => 'UTC',
                'fixedNowTime' => false
            
            },
            
        }
    ],

},
'[new]' => false,

这是edit.php的请求日期

[
    'journal_id' => '1',
    'ticket_number' => 'test con',
    'pair' => '',
    'buy_sell' => '',
    'personal_notes' => '',
    'entry_date_time' => '',
    'entry_price' => '',
    'strategy_id' => '5',
    'journal_entries_strategy_conditions' => [
        'strategies_condition_id' => [
            (int) 0 => '1'
        ]
    ],
    'timeframe' => '',
    'position_size' => '',
    'sl' => '',
    'tp' => '',
    'market_conditions' => '',
    'entry_toughts' => '',
    'close_date_time' => '',
    'close_price' => '',
    'profit' => '',
    'fees' => '',
    'high_price' => '',
    'low_price' => '',
    'exit_thoughts' => '',
    'feeling_before' => '',
    'feeling_after' => ''
]

添加.php

[
    'journal_id' => '1',
    'ticket_number' => 'sdfdsf',
    'pair' => '',
    'buy_sell' => '',
    'personal_notes' => '',
    'entry_date_time' => '',
    'entry_price' => '',
    'strategy_id' => '5',
    'journal_entries_strategy_conditions' => [
        (int) 0 => [
            'strategies_condition_id' => '1'
        ],
        (int) 1 => [
            'strategies_condition_id' => '2'
        ]
    ],
    'timeframe' => '',
    'position_size' => '',
    'sl' => '',
    'tp' => '',
    'market_conditions' => '',
    'entry_toughts' => '',
    'close_date_time' => '',
    'close_price' => '',
    'profit' => '',
    'fees' => '',
    'high_price' => '',
    'low_price' => '',
    'exit_thoughts' => '',
    'feeling_before' => '',
    'feeling_after' => ''
]

【问题讨论】:

    标签: cakephp cakephp-4.x


    【解决方案1】:

    没有selected 选项,为选择提供值的选项名为valvalue,与options 选项一样,它需要一个平坦的key =&gt; value 数组(如果您想要为&lt;option&gt; 元素提供属性,在这种情况下,您可以使用带有textvalue 键的嵌套数组。

    对于options,数组键将用于&lt;option&gt;元素的value属性,数组值将用于元素的内容。

    对于value,数组值将用于匹配options 数组的键,即AFAICT,您需要一个strategies_condition_id 数组。

    通常使用list finder 准备选择控件的值,您会在烘焙控制器中看到这一点。但是,由于您有嵌套关联,这不一定可行,而且您最好在事后转换数据,这可以使用集合轻松完成。

    例如在您的视图模板中:

    <div id="stategy-condition">
        <?php echo $this->Form->control('journal_entries_strategy_conditions', [
            'type' => 'select',
            'multiple' => 'checkbox',
            'options' =>
                collection($journalEntry['strategy']['strategies_conditions'])
                    ->combine('id', 'name')
                    ->toArray(),
            'value' =>
                collection($journalEntry['journal_entries_strategy_conditions'])
                    ->extract('strategies_condition_id')
                    ->toArray()
        ]); ?>
    </div>
    

    combine() 调用应该构建一个像这样的集合:

    [
        1 => 'zxcasd',
        2 => 'zxcasd',
        3 => 'zxcad',
    ]
    

    extract() 应该会产生一个包含以下内容的集合:

    [
        0 => 1
    ]
    

    这应该会导致第一个复选框被选中。

    就您的控件名称问题而言,有很多方法可以解决这个问题,例如,您可以使用自定义模板来硬编码输入名称:

    echo $this->Form->control('journal_entries_strategy_conditions', [
        'type' => 'select',
        // ...
        'templates' => [
            'checkbox' =>
                '<input
                    type="checkbox"
                    name="journal_entries_strategy_conditions[][strategies_condition_id]"
                    value="{{value}}"
                    {{attrs}}>',
        ]
    ]);
    

    或者在编组(修补)之前转换数据,使用 JournalEntriesTable 类中的 beforeMarshal 回调:

    public function beforeMarshal(
        \Cake\Event\EventInterface $event,
        \ArrayObject $data,
        \ArrayObject $options
    ) {
        if (isset($data['journal_entries_strategy_conditions']['strategies_condition_id']) {
            $ids = $data['journal_entries_strategy_conditions']['strategies_condition_id'];
            
            $conditions = [];
            foreach ($ids as $id) {
                $conditions[] = [
                    'strategies_condition_id' => $id,
                ];
            }
            
            $data['journal_entries_strategy_conditions'] = $conditions;
        }
    }
    

    这会将数据转换为:

    'journal_entries_strategy_conditions' => [
        'strategies_condition_id' => [
            '1',
            '2'
        ],
    ],
    

    到:

    'journal_entries_strategy_conditions' => [
        [
            'strategies_condition_id' => '1'
        ],
        [
            'strategies_condition_id' => '2'
        ]
    ],
    

    或者甚至手动创建单独的复选框,您可以在其中适当控制每个表单控件的各个方面,包括名称:

    echo $this->Form->label('journal_entries_strategy_conditions');
    echo $this->Form->hidden('journal_entries_strategy_conditions', ['value' => '']);
    
    $selectedIds = collection($journalEntry['journal_entries_strategy_conditions'])
        ->extract('strategies_condition_id')
        ->toArray();
    
    foreach ($journalEntry['strategy']['strategies_conditions'] as $index => $condition) {
        echo $this->Form->control(
            "journal_entries_strategy_conditions.{$index}.strategies_condition_id",
            [
                'type' => 'checkbox',
                'hiddenField' => false,
                'label' => $condition['name'],
                'value' => $condition['id'],
                'checked' => in_array($condition['id'], $selectedIds, true),
            ]
        );
    }
    

    这将创建名称属性,例如:

    journal_entries_strategy_conditions[0][strategies_condition_id]
    journal_entries_strategy_conditions[1][strategies_condition_id]
    ...
    

    【讨论】:

    • 感谢@ndm 一如既往地为您的回答所做的努力,这确实解释了这一点。我现在有一个问题,那就是我无法保存。每个输入的 name 属性应该是 name="journal_entries_strategy_conditions[0][strategies_condition_id] 和 name="journal_entries_strategy_conditions[1][strategies_condition_id]` 等,但我只得到name="journal_entries_strategy_conditions[strategies_condition_id][ ] 为每个输入。我错过了升序的数字。还有一个旁注. 如果我取消选中一个复选框,我不确定 CakePHP 将如何处理删除相关记录。
    • @KeithPower 好吧,这与最初的问题有很大不同。使用未选中的复选框进行保存时,您究竟在寻找什么行为?
    • 抱歉,我问了两个问题可能会混淆这个问题。为了简单起见并完全关闭这个问题,我只需要解决复选框名称name="journal_entries_strategy_conditions[strategies_condition_id] 的格式问题,它们应该是name="journal_entries_strategy_conditions[0][strategies_condition_id] 的格式,这是保存时的原因和错误。未选中复选框的保存/删除是一个单独的问题。
    • 我为add.php 添加了$this-&gt;request-&gt;getData(),我对复选框进行了硬编码。这样可以节省。如果您查看edit.php 的输出,您会发现'journal_entries_strategy_conditions' 结构是错误的。我试过&lt;?php echo $this-&gt;Form-&gt;control('journal_entries_strategy_conditions[]strategies_condition_id'
    • 查看文档 api.cakephp.org/3.8/… * - name` 要创建的输入的名称属性。 69: * [] 将被附加到名称中。`我想知道如何覆盖它,因为它不适用于关联数据
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-23
    • 2018-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多