【问题标题】:How to prepopulate a cascaded drop down and attachment on validation failure如何在验证失败时预填充级联下拉列表和附件
【发布时间】:2019-09-06 13:48:19
【问题描述】:

我有 2 个下拉菜单,为了简单起见,假设它们是国家/地区。

<select id="country_id" name = "country_id">
  <option value="">Select...</option>
  <?php foreach ($countries as $country): ?>
  <option value="<?php echo $country->id; ?>" <?php if (null !== set_value("country_id") && set_value("country_id") == $country->id) : echo ' selected '; ?>>$country->name;
  <?php endforeach?>
</select>

<select id="state_id" name = "state_id">
  <option value="">Select...</option>
</select>

<input type="file" name="attachment_id" value="" />

我所做的是在选择国家/地区时填充各州。这是我使用 AJAX 和“.change”做的,效果很好

我遇到的问题是当我执行 form_validation 和

$this->form_validation->run() == FALSE

然后我使用 set_value 重新加载所有控件,这对于第一个下拉列表(国家)确实有效,但是第二个下拉列表保持为空(因为没有在“country_id”上触发“.change”来填充“state_id”。

同样,我被要求重新附加文件

所以我需要并且不工作的是在 form_validation 失败之后

  1. 使用数据加载第二个下拉菜单 => 已解决,请参阅下面的 .trigger 事件
  2. 在第二个下拉菜单中选择上一个选择 => 几乎解决了,但是只有当我使用警报时:)
  3. 在表单被关闭或成功提交之前,附件仍应保持连接状态 => 未解决

我觉得我需要手动触发数据更改以获得 (1) 但在我的情况下,我有一个 foreach(见上文),我只添加行,如果选择相同,我只需设置为“已选择” " 但之后什么都没有发生。

这里是 AJAX 部分

<script>
            $(document).ready(function(){
                $("#country_id").change(function(){
                    $.ajax({
                        url:"<?php echo base_url(); ?>location/getCountries",
                        data: {country_id: $(this).val()},
                        type: "POST",
                        success: function(data){
                            $("#state_id").html(data);
                            $("#state_id").val(null);    
                        }
                    });
                });

                <?php if (!empty(set_value('country_id'))) : ?>
                var value = "<?php echo set_value('country_id'); ?>";
                $('#country_id').val(value);
                $('#country_id').trigger('change');                    

                <?php endif; ?>
                <?php if (!empty(set_value('state_id'))) : ?>
                var value = "<?php echo set_value('state_id'); ?>";
                //without this alert the selection doesn't work
                alert(value);
                $('#state_id').val(value);
                $('#state_id').trigger('change');
                <?php endif; ?>
            });

        </script>

所以我只有在使用警报时才会保存这些值。这似乎是一个异步执行,其中第二个下拉菜单的选择是在填充之前完成的,所以最后要做的是弄清楚如何等待。

还要做附件部分

提前致谢!

【问题讨论】:

  • 对于select,你可以将选中的状态值存储在本地存储中,重定向后,检查该值是否存在于本地存储中,然后通过jquery设置选中状态。为此,您需要在准备好的文档上调用 ajax 以获取所选国家/地区的状态。但是您应该使用 ajax 提交表单,以便输入保持选中状态。
  • @Marius 你能分享你的代码,比如 ajax 和其他人吗
  • 我在问题中也添加了 ajax 部分

标签: codeigniter


【解决方案1】:

在查看页面末尾添加此代码

国家下拉菜单

<?php if (!empty(set_value('country_id'))) : ?>
    <script type="text/javascript">
        var value = "<?php echo set_value('country_id'); ?>";

        $('select[name="country_id"]').find('option[value="'+value+'"]').attr("selected",true);
    </script>
<?php endif; ?>

状态下拉菜单

<?php if (!empty(set_value('state_id'))) : ?>
    <script type="text/javascript">
        var value = "<?php echo set_value('state_id'); ?>";

        $('select[name="state_id"]').find('option[value="'+value+'"]').attr("selected",true);
    </script>
<?php endif; ?>

【讨论】:

  • 您的回答为我指明了正确的方向,所以我已经非常接近了。我还需要的一件事是 .trigger 事件(请参阅我编辑的问题),它固定了第二个下拉列表的数量。现在问题是紧急情况,因为它试图在第二个下拉列表获取值之前选择值。为了证明我在第二个下拉填充和第二个下拉选择之间使用了一个警告语句,它确实有效。所以最后要做的是弄清楚如何在第二个下拉列表中选择值之前等待数据群发生(因为它来自数据库)
  • 在第二个下拉菜单中添加设置超时功能 例如:setTimeout(function(){ }, 1000 );
  • 它与超时一起工作,我唯一担心的是系统是否需要超过 1 秒的时间来加载。我知道我可以增加间隔,但理想情况下,我的函数将在第一个函数完成后立即执行。谢谢玛尼!
  • 你不需要延长时间,因为 $(document).ready(function() { }) 是一旦页面加载完成,函数就会调用...
【解决方案2】:

遵循以下几点

1) 对于select 标签,使用set_select(),像这样

<select name="myselect">
    <option value="one" <?php echo  set_select('myselect', 'one', TRUE); ?> >One</option>
    <option value="two" <?php echo  set_select('myselect', 'two'); ?> >Two</option>
    <option value="three" <?php echo  set_select('myselect', 'three'); ?> >Three</option>
</select>

2) 如果表单验证失败,请调用您的 ajax 函数设置第二个下拉菜单。

3) 对于附件,无论表单验证的结果如何,首先上传图片并将图片路径保存在会话变量中。表单验证成功后,将数据保存到数据库中并销毁会话变量。

【讨论】:

  • 对于下拉菜单,我真的很接近,我认为稍微推动一下以找出紧急情况(请参阅我的 cmets)它将得到解决。对于附件,我认为这是一个好主意,不确定 code igniter 是否为这种情况提供了内置的东西或最佳实践。但是没有任何其他想法,我将开始实施您的建议
【解决方案3】:

编辑>>>

**html**
<?php 
if (isset($edit) && !empty($edit)) {  //while editing 
     $StateID = $edit['StateID'];
     $CountryID = $edit['CountryID'];
} else {                             // while adding
     $StateID = set_value('StateID');
     $CountryID = set_value('CountryID');
   } ?>
 <div class="col-3">
            <div class="form-group">
                <label class="mb-0">Country</label>
                <select class="form-control Country" id="country" name="CountryID" data_state_value="<?php echo $StateID; ?>" >
                    <option value="">Select Country</option>
                    <?php
                    foreach ($country as $row) {
                        $selected = ($row->id == $CountryID) ? 'selected' : '';
                        echo '<option value="' . $row->id . '"' . $selected . '>' . $row->country_name . '</option>';
                    }
                    ?>
                </select>
                <span class="text-danger font9"><?php echo form_error('CountryID'); ?></span>
            </div>
        </div>
        <div class="col-3">
            <div class="form-group">
                <label class="mb-0">State</label>
                <select class="form-control State" id="State" name="StateID">
                </select>
                <span class="text-danger font9"><?php echo form_error('StateID'); ?></span>
            </div>
        </div>

**script**  

 $(document).on('change', '.Country', function () {
    var country_id = $(this).val();
    var state_id = $(this).attr('data_state_value');
    url = $("body").attr('b_url');
    $.ajax({
        url: url + "Education/fetch_state",
        method: "POST",
        data: {
            country_id: country_id,
            state_id: state_id
        },
        success: function (res) {
            var response = $.parseJSON(res);
            $('#State').html('<option value="">Select State</option>' + response.view);
            $('.State').trigger('change');
        }
    });
});
$('.Country').trigger('change');

**controller** 
public function fetch_state() {
    $data = array();
    if (isset($_POST['country_id']) && !empty($_POST['country_id'])) {
        $states = $this->Location_model->fetch_state($this->input->post('country_id')); // array of states 
        $view = array();
        if (!empty($states)) {
            foreach ($states as $val) {
                $selected = (isset($_POST['state_id']) && !empty($_POST['state_id']) && $_POST['state_id'] == $val['id']) ? 'selected' : '';
                $view[] = "<option value='" . $val['id'] . "'" . $selected . ">" . $val['states_name'] . "</option>";
            }
            $data['view'] = $view;
            $data['status'] = 0;
        } else {
            $data['status'] = 0;
            $data['view'] = '<option value="">No State Found</option>';
        }
    } else {
        $data['status'] = 0;
        $data['view'] = '<option value="">Select State</option>';
    }

    echo json_encode($data);
}

【讨论】:

  • @Marius 请检查答案
猜你喜欢
  • 1970-01-01
  • 2023-03-07
  • 2013-02-28
  • 1970-01-01
  • 1970-01-01
  • 2015-07-31
  • 2016-12-14
相关资源
最近更新 更多