Updating select options after AJAX request

2019-09-17 16:33发布

问题:

I have select field looking like that:

<?= $form->field($place, "[{$index}]id")->widget(Select2::classname(), [
    'data' => ArrayHelper::map(PresentationPlace::find()->all(), 'id', 'displaynew'),
    'class' => 'field',
    'options' => ['placeholder' => Yii::t('app', 'Pick place for presentation')],
    'pluginOptions' => [
        'allowClear' => false
    ],
])->label(Yii::t('app', Yii::t('app', 'Place'))) ?>

And after that field, I have short form for adding new place - you can fill it and send AJAX request. It adds this place to my database. I would like to have my select options updated, after the AJAX request is complete - that options would be up-to-date after every new place added. How can I achieve that in Yii 2?

回答1:

Yii 2 is a PHP framework and thus operates on the server side. You have to change the options in the select on the client side. Looking at the tags of your question, I assume that you are using jQuery. This is how you can update the options in a select, given an array of options. I will assume that you get something along those lines via an AJAX call. If your AJAX call returns JSON, you can get an object using JSON.parse.

jQuery

var options = {
      apple: 'Apple',
      banana: 'Banana',
      pear: 'Pear'
    },
    $select = $('select');

$('button').on('click', function() {
  $select.find('option').remove();
  $.each(options, function(value, name) {
    $select.append($('<option />', {value: value, text: name}));
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select>
  <option value="foo">Foo</option>
  <option value="bar">Bar</option>
  <option value="baz">Baz</option>
</select>
<button>Change options</button>

If you are using select2 then do not forget to call $select.trigger('change') after you have updated the options. This will update the dropdown. In case you are not using jQuery at all, you can use the below code.

vanilla JavaScript

var options = {
      apple: 'Apple',
      banana: 'Banana',
      pear: 'Pear'
    },
    select = document.querySelector('select');

document.querySelector('button').addEventListener('click', function() {
  // remove current options
  while (select.firstChild) {
    select.removeChild(select.firstChild);
  }
  
  // insert new ones
  Object.keys(options).forEach(function(value) {
    var option = document.createElement('option');
    option.setAttribute('value', value);
    option.innerHTML = options[value];
    select.appendChild(option);
  });
});
<select>
  <option value="foo">Foo</option>
  <option value="bar">Bar</option>
  <option value="baz">Baz</option>
</select>
<button>Change options</button>

On the server side, you only need to be sure to query your database for the options that have been stored there and pass that as the options instead of the placeholder that you have there now.

Hope that helps.