Дерево стран-городов в модальном окне

Общие вопросы по использованию второй версии фреймворка. Если не знаете как что-то сделать и это про Yii 2, вам сюда.
Ответить
Yura2017
Сообщения: 9
Зарегистрирован: 2017.04.15, 18:18

Дерево стран-городов в модальном окне

Сообщение Yura2017 »

Необходимо реализовать модальное окно с выбором регионов примерно как сделано, напр., на supl.biz в форме на главной странице поле "В каких регионах?". Сделал дерево с использованием jstree. Данные подгружаются из базы. 235 стран , 3721 регион и более 2 млн населенных пунктов. Все в одной таблице со столбцами id, root, parent_id, lvl, title.
Проблема в том, что осуществляется попытка загрузить в дерево сразу все данные и ошибка "Allowed memory size of 268435456 bytes exhausted (tried to allocate 32 bytes)". Т.е., правильнее, наверное, было бы выводить только список стран, а при клике на страну, аяксом получаю данные для построения поддерева (похоже, на supl.biz именно так и реализовано). Подскажите, как такое реализовать. Наверняка есть какие-то готовые решения, но я не нашел, а сам не соображу как такое реализовать. Если кто знает, буду признателен. Подскажите, если не готовое решение, то хотя бы в какую сторону копать. Заранее спасибо!
skynin
Сообщения: 400
Зарегистрирован: 2017.12.12, 10:09

Re: Дерево стран-городов в модальном окне

Сообщение skynin »

Yura2017 писал(а): 2018.07.27, 21:04 Необходимо реализовать модальное окно с выбором регионов примерно как сделано, напр., на supl.biz в форме на главной странице поле "В каких регионах?". Сделал дерево с использованием jstree. Данные подгружаются из базы. 235 стран , 3721 регион и более 2 млн населенных пунктов. Все в одной таблице со столбцами id, root, parent_id, lvl, title.
покажите как выбираете из базы :) а то как раз сегодня был диспут, и может вам each() вместо all() поможет
или asArray()
хотя, отдать в браузер 2 млн id и названий... около 200 мб, не на всяком компе браузер выдержит :)

если
jstree.com
то нужно цепляться на

Код: Выделить всё

before_open.jstree Event

triggered when a node is about to be opened (if the node is supposed to be in the DOM, it will be, but it won't be visible yet)
    node
    Object the opened node
и дотягивать аджаксом.

при этом выбранные названия запоминать.
и когда опять откроют эту ветку - после дотягивания проставить галочки, как у supl.biz
Не желайте странного, и не будет у вас головной боли чтобы достичь этого странного.
Тем более что окажется что оно вам и не нужно было, странное это.
Yura2017
Сообщения: 9
Зарегистрирован: 2017.04.15, 18:18

Re: Дерево стран-городов в модальном окне

Сообщение Yura2017 »

Кнопка, при клике на которую, открывается окно с деревом стран/регионов/городов

Код: Выделить всё

 <?php echo Html::button(Yii::t('companies','CHOOSE_REGION'),['class'=>'showModalButton btn','id'=>'chooseregions', 'value'=>Url::to(['/regions/getregions']),'data-btnid'=>'tenders-regions','data-title'=>Yii::t("spr", "REGIONS"),'data-target'=>'modal']); ?>
В контроллере:

Код: Выделить всё

public function actionGetregions()
{
return $this->renderAjax('regionlist');
}
В regionlist.php:

Код: Выделить всё

<div id="treeview"></div>
<div class="hiddenn" id="hregionid"></div>
<?php
$script = <<< JS
$('#treeview').jstree({
            'plugins': ["conditionalselect","checkbox"],
            'core' : {
              "themes" : {
                "icons":false
              },
              "checkbox" : {
                "keep_selected_style" : true
              },
              "check_callback" : true,
              'data' : {
                  "url" : '/regions/getregionsdata',
                  "dataType" : "json"
              }
            }
    });
    
$('#treeview').on("changed.jstree", function (e, data) {
  var i, j, k, m, ch = [], r = [];
  for(i = 0, j = data.selected.length; i < j; i++){
    if(data.instance.get_node(data.selected[i]).children_d.length > 0){
      ch.push(data.instance.get_node(data.selected[i]).id);
      r.push(data.instance.get_node(data.selected[i]).id);
    }
  }
  
    for(k = 0, m = data.selected.length; k < m; k++) {
      if($.inArray(data.instance.get_node(data.selected[k]).parent, ch) == -1 && $.inArray(data.instance.get_node(data.selected[k]).id, r) == -1){
        r.push(data.instance.get_node(data.selected[k]).id);
      }
    }
    
    $('#hregionid').html( r.join(', '));

});
JS;
$this->registerJs($script, yii\web\View::POS_READY);
В контроллере:

Код: Выделить всё

public function actionGetregionsdata()
    {
        $data = Regions::find()
            ->select('id, parent_id, title AS text')
            // ->where(['lvl' => 1]) - вот по идее сюда нужно аяксом передавать id выбранного элемента (узла), только как... чё-то я совсем запутался
            ->asArray()
            ->all();
        $result = Regions::getTree($data);
        return $result;

    }
В модели:

Код: Выделить всё

 
 public function getTree($data){
        $tmp = [];
        $tree = [];

        foreach ($data as $id=>$node) {
            $parent_id = $item['parent_id'];
            $id = $item['id'];
            $tmp['id'] = $node['id'];
            $tmp['parent_id'] = $node['parent_id'];
            $tmp['text'] = $node['text'];
            $tmp['title'] = $node['text'];
            $tmp['icon'] = '';
        }

        $itemsByReference = [];
        foreach($data as $key => &$item) {
          $itemsByReference[$item['id']] = &$item;
           $itemsByReference[$item['id']]['nodes'] = [];
        }
    
        // Set items as children of the relevant parent item.
        foreach($data as $key => &$item)
           if($item['parent_id'] && isset($itemsByReference[$item['parent_id']]))
              $itemsByReference[$item['parent_id']]['children'][] = &$item;
     
        // Remove items that were added to parents elsewhere:
        foreach($data as $key => &$item) {
           if($item['parent_id'] && isset($itemsByReference[$item['parent_id']]))
              unset($data[$key]);
        }
        return json_encode(array_values($data));
    }
Последний раз редактировалось Yura2017 2018.07.28, 18:18, всего редактировалось 5 раз.
Loveorigami
Сообщения: 977
Зарегистрирован: 2014.08.27, 21:54

Re: Дерево стран-городов в модальном окне

Сообщение Loveorigami »

Тебе самому нравится читать свое сообщение?
Первый день на форуме?
Ответить