Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Sign In with Google Sign In with OpenID

select multiple in admin

edited August 2013 in Apps

What would be a good way to use select multiple input fields on the admin side? Currently, I have something like this for a "plain old" select:

<select name="type">
    <option value="Type1"{% if type == 'Type1' %} selected{% end %}>Type1</option>
    <option value="Type2"{% if type == 'Type2' %} selected{% end %}>Type2</option>
    <option value="Type3"{% if type == 'Type3' %} selected{% end %}>Type3</option>
</select>

If I stored the choices in a comma or pipe delimited field, could I parse it in a template? I guess what I'm asking is what php the templates can use. Could I check to see if $type was in the array of types they had previously chosen?

Comments

  • Here's an example of a dynamically populated select box:

    https://gist.github.com/jbroadway/6286438

    Let me know if that answers your question.

  • edited August 2013

    I'm not sure if it addresses select multiple type inputs, where they can hold ctrl or cmd to select, say, Type1 and Type3. Then $type will be something like "Type1,Type3" and the edit page will need to preselect Type1 and Type3.

  • Ah I think I understand. Here's a modification of my previous gist for multi-select fields:

    https://gist.github.com/jbroadway/6286885

    I also wrapped it in an Elefant form so you could see the submitted values. Let me know if that works for you!

  • Thank you! I'll try it.

  • Do you have a recommendation for storing the array in the database? In the past I've used MySQL set and/or enum fields, but I get the sense those aren't quite kosher and I'm using sqlite for this site.

    I want urls like /app/foo to find all records that have foo among their types, etc.

    I could implode the array and do LIKE searches, but that seems inefficient.

    I could set up a bitwise function, but that code might get hard to read and maintain.

    I could use a join table, but I'm not quite sure how to integrate joins into elefant's database model.

    Does this give you enough information to answer the question?

  • Googled around a bit and found another option: one boolean column for each type in the database table.

  • Bitwise is generally a good option if you have a finite number of types. You can setup a few simple methods for each type check, then it keeps things fairly clean:

    https://gist.github.com/jbroadway/6296092

    Otherwise a join may be better for managing many-to-many type relationships. Here's an example of setting up a many-many join on two models in Elefant:

    https://gist.github.com/jbroadway/6296487

    Hope that helps!

  • It helps a ton. As always, thank you!

  • What do you make of the arguments against bitwise in some of the answers to this question? http://stackoverflow.com/questions/429104/best-practices-for-bit-flags-in-php

  • I'd say that's a bit of an exaggerated example. Here's a much simpler SQL example based on Unix permissions (read/write/execute):

    -- create the table and index
    create table bitwise (
      name char(32) not null,
      val tinyint not null
    );
    
    create index bitwise_val on bitwise (val);
    
    -- insert each possible value for r+w+e (
    insert into bitwise values ('none',      0);
    insert into bitwise values ('r',         1);
    insert into bitwise values ('w',         2);
    insert into bitwise values ('r + w',     3);
    insert into bitwise values ('e',         4);
    insert into bitwise values ('r + e',     5);
    insert into bitwise values ('w + e',     6);
    insert into bitwise values ('r + w + e', 7);
    
    -- fetch all rows that have no permissions
    select * from bitwise where val = 0;
    
    -- fetch all rows that are readable
    select * from bitwise where val & 1;
    
    -- fetch all rows that are writeable
    select * from bitwise where val & 2;
    
    -- fetch all rows that are executable
    select * from bitwise where val & 4;
    
    -- fetch all rows that are readable and writeable
    select * from bitwise where val & 1 and val & 2;
    
    drop table bitwise;
    

    And the argument that a DBA is going to be forced to understand and manipulate the schema with zero documentation is easily solved by documenting the schema. That's just responsible development IMO :)

    In MySQL you could use something more readable like an enum column, but that's a MySQL-specific column type.

  • What you say makes a lot of sense.

  • Getting back to this...

    I have a join table with a many-many relationship like you outlined above. I want to let the user add and delete relationships. Are there elefant methods for that or should I write SQL queries? I can elaborate on what I'm trying to do if that would be helpful.

  • Elefant's Model currently only offers convenience methods for fetching relationships, not for inserts or updates. I usually just write a custom method on my model that does whatever insert logic I need, usually via DB::execute().

Sign In or Register to comment.