Select2 initialValue

Select2 initialValue

system.bonn@gmail.comsystem.bonn@gmail.com Posts: 28Questions: 4Answers: 1

Hi!

Im still on laravel, laravel-datatables and datatables with datatables Editor.

i have gotten the first steps with select2 to work. The dataTable field ist showing:

[ 'data' => 'facility.name', 'title' => 'Facility'],

The editor field is initialised:

                    {
                      label: "Facility",
                      name:  "facility.name",
                      type:  "select2",
                      opts: {
                        ajax: {
                            url: '{{ route("api.facilities.search") }}',
                            dataType: 'json',
                            initialValue: true
                        },
                        allowClear:         false,
                        language:           "de",
                        minimumInputLength: 0                        
                      }
                   }

The select2's option lists gets populated:

class FacilitiesApiController extends Controller
{
    public function search(Request $request)
    {
        if ($request->input('initialValue') == true) return '{ "id": 20, "text": "foobar" }';

        $facilities = Facility::where('name', 'LIKE', '%'.$request->input('term', '').'%')
            ->get(['id', 'name as text']);
        return ['results' => $facilities];
    }
}

showing all 27 entries.

However, the initialValue is not set. When I click on the field in my table, the text changes to the folded (i.e. just one single line) selectbox, but is not showing 'foobar' as I would expect.

Console shows:

Request: search?initialValue=true&value=%22Mack%22

Response: { "id": 20, "text": "foobar" }

What am I doing wrong?

TIA & cu,
ada

Replies

  • system.bonn@gmail.comsystem.bonn@gmail.com Posts: 28Questions: 4Answers: 1

    I have refined the ajax response:

    public function search(Request $request)
    {
        if ($request->input('initialValue') == true) {
    
            $facilities = Facility::where('id', '=', '21')
                ->get(['id', 'name as text']);
    
        } else {
    
            $facilities = Facility::where('name', 'LIKE', '%'.$request->input('term', '').'%')
                ->get(['id', 'name as text']);
    
        }
    
        return ['results' => $facilities];
    }
    

    So now I have a valid result for the initialValue's response as well. Still it is not working :-(

  • allanallan Posts: 61,743Questions: 1Answers: 10,111 Site admin

    I think the issue is the response from the server for the initial value. As the docs note:

    The server must respond with { "id": value, "text": "Label to show" }.

    So return $facilities[0]; I think should do it on line 7 in the above.

    Allan

  • system.bonn@gmail.comsystem.bonn@gmail.com Posts: 28Questions: 4Answers: 1

    Hi Allan!

    Thank you very much for your reply, but I already got the result as you are proposing in the first version (Response: { "id": 20, "text": "foobar" }). I modified this to your proposal and to return '{ "id": 21, "text": "Singer" }'.

    Still, the selectbox doesnt show the text 'Singer' in its edit line.

    Please do you have a working example of 2 joined tables with a select box?

    cu,
    ada

  • allanallan Posts: 61,743Questions: 1Answers: 10,111 Site admin

    Yes, there is an example here but it doesn't use Select2, just a regular Select.

    Can you give me a link to your page so I can debug it directly please?

    Allan

  • system.bonn@gmail.comsystem.bonn@gmail.com Posts: 28Questions: 4Answers: 1

    I managed to get a tiny little bit further.

    In the first case, i got a single Select2-field operating on a foreign key. When the modal dialog is opened, it fires

    search?initialValue=true&value=%222%22

    i.e.:

    search?initialValue=true&value="2"

    2 is the content of the foreign key, my serverside responds with

    { "id": "2", "text": "some text" }

    effectively repeating the id from the query (2) and responding with the text for that id. If the responded id doesn't match the queried id, nothing is displayed.

    Now, I have a multiple Select2. This one sends:

    search?initialValue=true&value=[{%22id%22:%226%22,%22name%22:%22UnitUser%22,%22created_at%22:%222019-10-26%2017:26:19%22,%22updated_at%22:%222019-10-26%2017:26:19%22,%22pivot%22:{%22user_id%22:%2219%22,%22role_id%22:%226%22,%22created_at%22:%222019-11-17%2012:44:54%22,%22updated_at%22:%222019-11-17%2012:44:54%22}}]

    ie.:

    [
     {
      "id":"6",
      "name":"Text1",
      "created_at":"2019-10-26%2017:26:19",
      "updated_at":"2019-10-26%2017:26:19",
      "pivot":
        {
          "user_id":"19",
          "role_id":"6",
          "created_at":"2019-11-17%2012:44:54",
          "updated_at":"2019-11-17%2012:44:54"
        }
      }
    ]
    

    in case of a single selected item.

    I tried responding with (notice, that you defintely do have to repeat the complete, otherwise nothing gets displayed):

    { "id": [{
                "id":"6",
                "name":"Text1",
                "created_at":"2019-10-26 17:26:19",
                "updated_at":"2019-10-26 17:26:19",
                "pivot":
                  {
                    "user_id":"19",
                    "role_id":"6",
                    "created_at":"2019-11-17 12:44:54",
                    "updated_at":"2019-11-17 12:44:54"
                  }
              }],
      "text": "Text1"
    }
    

    I don't understand why there is a need for the initialValue query at all, since, it does know the initial value already: id:6, text: "Text1"

    But alas, this initial value doesn't affect the initial value at all. it just displays the initial value – it's not in any way set to selected. For example you can still select "Text1" a second time and it will appear a second time. Also, this preselected valu throws an error, wehen trying to save it:

    Server Error: SQLSTATE[22007]: Invalid datetime format: 1366 Incorrect integer value: '[object Object]' for column table.role_user.role_id at row 1 (SQL: insert into role_user (created_at, role_id, updated_at, user_id) values (2019-11-17 14:33:10, [object Object], 2019-11-17 14:33:10, 19))

    Please: how does this plugin work? And no, an example without this plugin used at all is not an example.

  • system.bonn@gmail.comsystem.bonn@gmail.com Posts: 28Questions: 4Answers: 1

    Anyone?

  • allanallan Posts: 61,743Questions: 1Answers: 10,111 Site admin

    Could you try making:

    { "id": "2", "text": "some text" }
    

    an array please - e.g.:

    [
      { "id": "2", "text": "some text" }
    ]
    

    As you'll see from the "general" Select2 response it uses an array of values.

    I don't understand why there is a need for the initialValue query at all, since, it does know the initial value already: id:6, text: "Text1"

    The field only has a single value - that will be 6 or [6] or similar depending on the configuration. Select2 doesn't see the data from the rest of the row, hence why it needs to query the server to get the remainder of the data. It could optionally have some kind of callback to get it from the client-side data (i.e. the DataTable row) - but the server-side call was the way I implemented it.

    Thanks,
    Allan

  • system.bonn@gmail.comsystem.bonn@gmail.com Posts: 28Questions: 4Answers: 1

    Hi!

    Since your are refering to

    { "id": "2", "text": "some text" }

    I assume, you are talking about the multiple: false case.

    It is pretty simple. I can respond to the initialValue request with either

    {"results":[{"id":2,"text":"Fast Banana"}]}

    or

    {"results":[
    {"id":1,"text":"Beauty Box"},
    {"id":2,"text":"Fast Banana"},
    {"id":3,"text":"Weidner"},
    {"id":4,"text":"Engel AG & Co. KG"},
    {"id":5,"text":"Heck AG"},
    {"id":6,"text":"Fr\u00f6hlich e.G."},
    {"id":7,"text":"Ke\u00dfler"},
    {"id":8,"text":"Wieland"},
    {"id":9,"text":"Langer"},
    {"id":10,"text":"Merz e.V."},
    {"id":11,"text":"Janssen"},
    {"id":12,"text":"Heinze"},
    {"id":13,"text":"Wolf Berndt e.V."},
    {"id":14,"text":"D\u00f6ring Forster e.V."},
    {"id":15,"text":"Winkler"},
    ]}
    

    or

    [{"id":2,"text":"Fast Banana"}]

    or

    [
    {"id":1,"text":"Beauty Box"},
    {"id":2,"text":"Fast Banana"},
    {"id":3,"text":"Weidner"},
    {"id":4,"text":"Engel AG & Co. KG"},
    {"id":5,"text":"Heck AG"},
    {"id":6,"text":"Fr\u00f6hlich e.G."},
    {"id":7,"text":"Ke\u00dfler"},
    {"id":8,"text":"Wieland"},
    {"id":9,"text":"Langer"},
    {"id":10,"text":"Merz e.V."},
    {"id":11,"text":"Janssen"},
    {"id":12,"text":"Heinze"},
    {"id":13,"text":"Wolf Berndt e.V."},
    {"id":14,"text":"D\u00f6ring Forster e.V."},
    {"id":15,"text":"Winkler"},
    ]
    

    Yes, they all setup the topline of the select2 correctly as long as the queried id is part of the result set.

    However, when the select2 gets a click, DTE sends a second query to populate the dropdown list. The response to this second query needs the

    {"results":[ ... ]}
    

    wrapped around to function properly.

    For code hygenic reasons, I decided to implement it (in laravel) like so:

    class FacilitiesApiController extends Controller
    {
        public function search(Request $request)
        {
            if ($request->has('initialValue'))
            {
                $facilities = Facility::where('id', '=', filter_var($request->input('value'), FILTER_SANITIZE_NUMBER_INT))
                    ->get(['id', 'name as text']);
    
            } else {
    
                $facilities = Facility::get(['id', 'name as text']);
            }
            return ['results' => $facilities];
        }
    }
    

    Any reasons I shouldn't do this?

    Now, how about the multiple:true case?

  • system.bonn@gmail.comsystem.bonn@gmail.com Posts: 28Questions: 4Answers: 1

    Now, I'd need the

    if ($request->has('initialValue'))
            {
                $facilities = Facility::where('id', '=', filter_var($request->input('value'), FILTER_SANITIZE_NUMBER_INT))
                    ->get(['id', 'name as text']);
     
            }
    

    part for multiple initial values.

    TIA!

  • system.bonn@gmail.comsystem.bonn@gmail.com Posts: 28Questions: 4Answers: 1

    Anyone?

  • allanallan Posts: 61,743Questions: 1Answers: 10,111 Site admin

    Any reasons I shouldn't do this?

    No - I don't see any. It isn't ideal, I know. We are going to work on better integration with Select2 in the new year and publish working examples for it.

    Now, how about the multiple:true case?

    Basically the same thing, but you'd need to take account of the fact that value for the initialValue request will be a stringified array of values. So you'd need to JSON decode it and then loop over the resulting array to build up the where condition.

    Allan

This discussion has been closed.