Selectize.js with Tags, reload key and value in edit form

12
  

I asked the same question in SO Gringo too .

I'm doing a search form ( action=GET ) where a field uses Selectize.js:

$("#selectize").each(function () {
        $(this).selectize({
            plugins: ['remove_button'],
            valueField: 'AdvogadoId',
            labelField: 'Descricao',
            searchField: ['AdvogadoId', 'Descricao'],
            create: false,
            persist: false,
            preload: true,
            initUrl: "/Advogados/PesquisarJson/",
            initData: true,
            load: function (query, callback) {
                $.ajax({
                    url: "/Advogados/PesquisarJson/",
                    type: 'GET',
                    error: function () {
                        callback();
                    },
                    success: function (res) {
                        callback(res);
                    }
                });
            }
        });
    });

With the empty form, I type the name and the acronym of the lawyer. Comes all filled out correctly. When submitting the search, the values go to the backend correctly, separated by commas.

When the form is reloaded with GET values, what happens is that each tag appears only with the acronym of the lawyer filled in without the name. When checking the options, the options chosen appear only as the acronym, the correct one being "Acronym - Name".

I tried some solutions like this (it does not work, as well as being complex to what I need) and this (I do not use data-data : I use only form values).

Is there any way (preferably performative) to load these values correctly into each selected screen tag?

Code in the Backend:

    public JsonResult PesquisarJson(String termo = "")
    {
        // Aqui não é EF. É Dapper em cima de Oracle.
        using (var repositorio = new AdvogadoRepositorio())
        {
            var registros = repositorio.Condicao(a => a.DataSaida == null).OrdenarPor(a => a.AdvogadoId).Selecionar();
            return Json(registros.Select(a => new { AdvogadoId = a.AdvogadoId, Descricao = a.AdvogadoId + " - " + a.Nome }).ToList(), 
                JsonRequestBehavior.AllowGet);
        }
    }

HTML:

<div class="selectize-control form-control selectize multi plugin-remove_button">
    <div class="selectize-input items not-full">
        <input type="text" autocomplete="off" tabindex="" style="width: 4px; opacity: 1; position: relative; left: 0px;">
    </div>
    <div class="selectize-dropdown multi form-control selectize plugin-remove_button" style="display: none;">
        <div class="selectize-dropdown-content">
        </div>
    </div>
</div>

Rest Result:

[
  {
    "AdvogadoId": "A1",
    "Descricao": "A1 - Fulano de Araujo"
  },
  {
    "AdvogadoId": "A2",
    "Descricao": "A2 - Beltrano de Lima"
  },
  {
    "AdvogadoId": "A3",
    "Descricao": "A3 - Ciclano da Silva"
  },
  {
    "AdvogadoId": "A4",
    "Descricao": "A4 - Herculano Junior"
  },
  ...
]
    
asked by anonymous 07.12.2015 / 18:46

2 answers

2

This is because <input> while selecting is populated with AdvogadoId and not with Descricao , when you select for example:

Whatyou"see" (gray button with side ox) is actually the label and not the value of <input> , in this case the label uses Descricao and the input uses AdvogadoId see valueField: 'AdvogadoId',

The only way to "practice" what I see doing as you wish would be this and put valueField also as Descricao :

 $("#selectize").each(function () {
    $(this).selectize({
        plugins: ['remove_button'],
        valueField: 'Descricao', //Adicionar descrição aqui também
        labelField: 'Descricao',
        searchField: ['AdvogadoId', 'Descricao'],
        create: false,
        persist: false,
        preload: true,
        initUrl: "/Advogados/PesquisarJson/",
        initData: true,
        load: function (query, callback) {
            $.ajax({
                url: "/Advogados/PesquisarJson/",
                type: 'GET',
                error: function () {
                    callback();
                },
                success: function (res) {
                    callback(res);
                }
            });
        }
    });
});

If you really want to send the ids ( AdvogadoId ) you will have to redo the query on the next page using the ids to bring the descriptions back.

However you may be able to use sessionStorage next to the Selectize.js API to keep the options and add them automatically, an example:

$(function() {
    var target = $("#selectize");
    var keySession = "selectizeData2";

    var update = function(a,b) {
        var opts = this.options;
        setTimeout(function() {//Requer timeout
            var values = target.val().split(",");
            console.log(values);

            var list = [];
            for (var k in opts) {
                current = opts[k];
                if (values.indexOf(current.AdvogadoId) !== -1) {
                    list.push({ AdvogadoId: current.AdvogadoId, Descricao: current.Descricao });
                }
            }

            console.log(JSON.stringify(list));
            sessionStorage.setItem(keySession, JSON.stringify(list));
        }, 1);
    };

    var getTarget = function(selectize) {
        var data = sessionStorage.getItem(keySession);
        var parsedData = JSON.parse(data);
            console.log(parsedData);
        if (parsedData) {
            for (var k in parsedData) {
                var current = parsedData[k];
                selectize.addOption([current]);
                selectize.addItem(current.AdvogadoId);
            }
        }
    };

    target.each(function () {
        var handler = $(this).selectize({
            plugins: ['remove_button'],
            valueField: 'AdvogadoId', //Veja que mantive o ID como value
            labelField: 'Descricao',
            searchField: ['AdvogadoId', 'Descricao'],
            create: false,
            persist: false,
            preload: true,
            initUrl: "test.php",
            initData: true,
            "onItemAdd": update, //Adiciona o evento
            "onItemRemove": update, //Adiciona o evento
            load: function (query, callback) {
                $.ajax({
                    url: "test.php",
                    type: 'GET',
                    error: function () {
                        callback();
                    },
                    success: function (res) {
                        callback(res);
                    }
                });
            }
        });

        getTarget(handler[0].selectize);
    });
});

Following the example of @Felipe can also use a pre-query (although for performance this does not seem good when increasing the number of registered clients), it would be like this (it is necessary to clean the input first because if not the Selectize .js thinks ids already exist):

$(function() {
    var target = $("#selectize");
    var currentValue = target.val();

    target.val("");

    target.each(function () {
        $(this).selectize({
            plugins: ['remove_button'],
            valueField: 'AdvogadoId',
            labelField: 'Descricao',
            searchField: ['AdvogadoId', 'Descricao'],
            create: false,
            persist: false,
            preload: true,
            initUrl: "test.php",
            initData: true,
            onInitialize: function() {
                var self = this;
                var value = "," + currentValue + ",";

                $.ajax({
                  url: "test.php",
                  type: 'GET',
                  success: function(res) {
                    res.forEach(function(existingOption) {
                        self.addOption(existingOption);
                        if (value.indexOf("," + existingOption.AdvogadoId + ",") !== -1) {
                            self.addItem(existingOption.AdvogadoId);
                        }
                    });
                  }
                });
            },
            load: function (query, callback) {
                $.ajax({
                    url: "test.php",
                    type: 'GET',
                    error: function () {
                        callback();
                    },
                    success: function (res) {
                        callback(res);
                    }
                });
            }
        });
    });
});
    
01.03.2016 / 17:17
1

To solve this problem you will need to make a fix using the onInitialize method. The solution is not pretty, but it solves this library deficiency:

$(this).selectize({
  plugins: ['remove_button'],
  valueField: 'Sigla',
  labelField: 'Nome',
  searchField: ['Sigla', 'Nome'],
  create: false,
  persist: false,
  preload: true,
  initUrl: "/Advogados/PesquisarJson/",
  initData: true,
  load: function(query, callback) {
    $.ajax({
      url: "/Advogados/PesquisarJson/",
      type: 'GET',
      error: function() {
        callback();
      },
      success: function(res) {
        callback(res);
      }
    });
  },
  // Bugfix
  onInitialize: function() {

    var self = this;
    var value = self.getValue();

    $.ajax({
      url: "/Advogados/PesquisarJson/",
      type: 'GET',
      success: function(res) {

        res.forEach(function(existingOption) {
          self.addOption(existingOption);
          self.addItem(existingOption[self.settings.valueField]);
        });

        self.setValue(value);
        self.blur();
      }
    });

  }
});
    
26.02.2016 / 22:05