No More Posting New Topics!

If you have a question or an issue, please start a thread in our Github Discussions Forum.
This forum is closed for new threads/ topics.

Navigation

    Quasar Framework

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search

    q-select

    Framework
    2
    12
    5967
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • E
      eloy.silva last edited by

      Hi friends

      in the q-select component in the options, I assign it the model array, but it doesn’t show it

      my structure in the model is:

      options: {
      companies: [],
      employess: []
      }

      q-select.jpg

      1 Reply Last reply Reply Quote 0
      • E
        eloy.silva last edited by

        I think it only accepts a defined structure like this
          {
                   label: ‘Uno’,
                   value: ‘1’,
                   description: ‘uno’,
                   category: ‘1’
                 }.

        T 1 Reply Last reply Reply Quote 0
        • T
          tof06 @eloy.silva last edited by tof06

          @eloy-silva Have a look to option-value and option-label props of q-select

          <q-select
            ...
            :options="options.companies"
            option-value="USR_ERP_COMPANY_ID"
            option-label="USR_ERP_NAME"
            ...
          />
          

          These props can also be a function if you need more control.

          E 2 Replies Last reply Reply Quote 0
          • E
            eloy.silva @tof06 last edited by

            @tof06 Thanks

            1 Reply Last reply Reply Quote 0
            • E
              eloy.silva @tof06 last edited by

              @tof06 I tried it and it works … but now the filter function gives error in toLowerCase

              TypeError: Cannot read property ‘toLowerCase’ of undefined"

              T 1 Reply Last reply Reply Quote 0
              • T
                tof06 @eloy.silva last edited by

                @eloy-silva Pretty hard to guess why without viewing the code ! 🙂

                E 2 Replies Last reply Reply Quote 0
                • E
                  eloy.silva @tof06 last edited by eloy.silva

                  @tof06 Hi,

                  Hello, thanks for answering

                  I am new to this framework (vuejs, quasar), and what I want to do is a reusable component, so as not to be repeating the filter functions, I just want to send the json object and that when filtering or selecting the item, it is reflected in my UI and in the model

                  excuse my spelling, I don’t speak english

                  <template>
                    <q-select
                      square
                      dense
                      outlined
                      use-input
                      input-debounce="0"
                      v-model="valuemember"
                      :option-value="optionvalue"
                      :option-label="optionlabel"
                      :options="dataset"
                      :placeholder="placeholder"
                      @filter="filterFn"
                      
                    >
                    </q-select>
                  </template>
                  
                  <script>
                  export default {
                    name: "optimusSelect",
                    props: {
                      dataSource: {
                        type: Array,
                        required: true,
                        twoWay: true
                      },
                      optionvalue: {
                        type: String,
                        required: true
                      },
                      optionlabel: {
                        type: String,
                        required: true
                      },
                      placeholder: {
                        type: String,
                        required: false
                      }
                      // displaymember: {
                      //   type: String,
                      //   required: true,
                      //   twoWay: true
                      // },
                      // valuemember: {
                      //   type: String,
                      //   required: true,
                      //   twoWay: true
                      // }
                    },
                  
                    computed: {
                      dataset: {
                        get() {
                          return this.dataSource;
                        },
                        set(value) {
                          this.dataSource = value;
                        }
                      }
                      // datavalue:{
                      //     get(){
                      //         return this.valuemember;
                      //     },
                      //     set(value){
                      //         this.valuemember = value;
                      //     }
                      // }
                    },
                    data() {
                      return {
                        valuemember: null
                      };
                    },
                    mounted() {},
                    methods: {
                      filterFn(val, update) {
                        
                  
                            var that = this;
                          if (val === "") {
                            update(() => {
                              //this.dataSource = objectOptions
                              // with Quasar v1.7.4+
                              // here you have access to "ref" which
                              // is the Vue reference of the QSelect
                            });
                            return;
                          }
                  
                          update(() => {
                            const needle = val.toLowerCase();
                            let data = that.dataSource;
                            that.dataset   = data.filter(
                              v => v.value.toLowerCase().indexOf(needle) > -1
                            );
                          });
                      }
                    }
                  };
                  </script>
                  
                  <style></style>
                  
                  

                  in my page

                  <template>
                    <q-page padding class="page-normal">
                      <q-form>
                        <q-toolbar>
                          <q-toolbar-title>Nuevo usuario</q-toolbar-title>
                        </q-toolbar>
                        <separatorH caption="Datos generales"></separatorH>
                  
                        <div class="row q-pa-md">
                          <div class="f-v-label col-2">Compañia:</div>
                          <div class="f-v-input col-2">
                            <optimusSelect
                              v-model="oEntity.USR_ERP_COMPANY_ID"
                              :dataSource="options.companies"
                              optionvalue="USR_ERP_COMPANY_ID"
                              optionlabel="USR_ERP_NAME"
                             
                            />
                          </div>
                        </div>
                  
                        <div class="row q-pa-md">
                          <div class="f-v-label col-2">Empleado:</div>
                          <div class="f-v-input col-2">
                            <!-- <lookup :dataSource="cities" :selection.sync="datavalue" placeholder="Buscar empleado"></lookup> -->
                          </div>
                        </div>
                  
                        <div class="row q-pa-md">
                          <!--Label-->
                          <div class="f-v-label col-2">Nombre de usuario:</div>
                          <!--Input-->
                          <div class="f-v-input col-2">
                            <q-input
                              square
                              outlined
                              autofocus
                              dense
                              v-model="datav"
                              placeholder="Nombre de usuario:"
                            >
                            </q-input>
                          </div>
                        </div>
                      </q-form>
                    </q-page>
                  </template>
                  
                  <script>
                  import { mapState, mapActions } from "vuex";
                  import separatorH from "components/separatorH";
                  import lookup from "components/lookup";
                  import optimusSelect from "components/optimus-select";
                  
                  export default {
                    name: "user",
                    data() {
                      return {
                        options: {
                          companies: [
                            {
                            USR_ERP_COMPANY_ID: 100,
                            USR_ERP_NAME: 'ACNE',
                           
                          },
                          {
                            USR_ERP_COMPANY_ID: 200,
                            USR_ERP_NAME: 'SOCONSA',
                          },
                          
                          ]
                        },
                        datav:null,
                        oEntity: {
                          USR_ERP_COMPANY_ID: '',
                          USR_ERP_NAME: ""
                        }
                      };
                    },
                    components: {
                      separatorH,
                      lookup,
                      optimusSelect
                    },
                    computed: {
                      ...mapState("store", ["userDetails", "currentPage"])
                      
                    },
                    methods: {
                      ...mapActions("store", ["load_page"])
                    },
                    mounted() {
                      // this.load_page({
                      //   title: "Usuario",
                      //   IsActive: true
                      // });
                    },
                    destroyed() {
                      // this.load_page({
                      //   title: "",
                      //   IsActive: false
                      // });
                    }
                  };
                  </script>
                  
                  
                  1 Reply Last reply Reply Quote 0
                  • E
                    eloy.silva @tof06 last edited by

                    @tof06

                    toLocaleLowerCase solutions !!!

                    but in the filter function I have an error: 🙁

                    [Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop’s value. Prop being mutated: “dataSource”

                    try to fix it with computed:

                    <template>
                      <q-select
                        square
                        dense
                        outlined
                        v-model="valuemember"
                        :option-value="optionvalue"
                        :option-label="optionlabel"
                        :options="dataSource"
                        :placeholder="placeholder"
                        use-input
                        hide-selected
                        fill-input
                        input-debounce="0"
                        @filter="filterFn"
                        @input-value="setModel"
                        @input="onChange"
                        emit-value
                        map-options
                      >
                        <template v-slot:no-option>
                          <q-item>
                            <q-item-section class="text-grey">
                              No results
                            </q-item-section>
                          </q-item>
                        </template>
                      </q-select>
                    </template>
                    
                    <script>
                    export default {
                      watch: {},
                    
                      computed: {
                          dataset:{
                              get(){
                                return this.dataSource;
                              },
                              set(value){
                                    this.dataSource = value;
                                     this.$emit("dataset", value);
                              }
                          }
                      },
                      data() {
                        return {
                          valuemember: null,
                          
                        };
                      },
                      mounted(){
                          
                      },
                      props: {
                        dataSource: {
                          type: Array,
                          required: true,
                          twoWay: true,
                        },
                        optionvalue: {
                          type: String,
                          required: true,
                        },
                        optionlabel: {
                          type: String,
                          required: true,
                        },
                        placeholder: {
                          type: String,
                          required: false,
                        },
                      },
                      methods: {
                        filterFn(val, update, abort) {
                             if (val === '') {
                            update(() => {
                              //this.dataSource = this.dataset
                    
                              // with Quasar v1.7.4+
                              // here you have access to "ref" which
                              // is the Vue reference of the QSelect
                            })
                            return
                          }
                    
                          update(() => {
                            
                            const needle = val.toLocaleLowerCase();
                            this.dataSource = this.dataset.filter(
                              (v) => v[this.optionlabel].toLocaleLowerCase().indexOf(needle) > -1
                            );
                    
                             this.$emit("dataset", this.dataset);
                          });
                        },
                    
                        setModel(val) {
                          this.model = val;
                        },
                        onChange(value) {
                          //refresh and update model
                          
                          this.$emit("input", value);
                        },
                        getData() {
                          return this.valuemember;
                        },
                        setData(value) {
                          this.valuemember = value;
                          this.$emit("input", value);
                        },
                      },
                    };
                    </script>
                    
                    1 Reply Last reply Reply Quote 0
                    • T
                      tof06 last edited by

                      @eloy-silva As stated in VueJS Documentation, props are only one-way binding from parent to child, so, you can’t update them from child.

                      Depending on the behavior you want, a simple data property will do the trick :

                      export default {
                        props: {
                         dataSource: { type: Array, required: true },
                         // ... 
                        }, 
                        data() {
                          return {
                            // ...
                            _dataSource: this.dataSource
                          }
                        }
                      

                      Then, use _dataSource in your template instead of dataSource

                      If you absolutly need dataSource to be sync in parent component, then, you’ll need to implement an event, and listen to this event on parent

                      E 3 Replies Last reply Reply Quote 0
                      • E
                        eloy.silva @tof06 last edited by

                        @tof06 it worked perfectly.

                        😊

                        Thanks !!!

                        1 Reply Last reply Reply Quote 0
                        • E
                          eloy.silva @tof06 last edited by

                          @tof06
                          the problem with the props, it was overcome
                          but according to what you indicate and following the example in the documentation, the filter function should look like this:
                          and not work

                          filterFn(val, update, abort) {
                               
                               
                                update(() => {
                                  const needle = val.toLocaleLowerCase();
                                  
                                 this._dataSource =  this.dataSource.filter(
                                    (v) => v[this.optionlabel].toLocaleLowerCase().indexOf(needle) > -1
                                  );
                          
                                
                                  
                                });
                              },
                          

                          now in the documentation everything works fine, there it uses a constant of a string array, but when changing to a json object, things get very complicated

                          q-select-filter.jpg

                          1 Reply Last reply Reply Quote 0
                          • E
                            eloy.silva @tof06 last edited by

                            @tof06
                            Follow your advice, check the documentation of props in VueJS and it is already solved
                            I post it here if it serves someone or see how it can be improved.

                            in the component:

                            <!-- select autocomplete -->
                            <template>
                              <q-select
                                v-model="valuemember"
                                use-input
                                hide-selected
                                fill-input
                                input-debounce="0"
                                :option-value="optionvalue"
                                :option-label="optionlabel"
                                :options="dataSource"
                                :placeholder="placeholder"
                                @filter="filterFn"
                                @input-value="setModel"
                                square
                                dense
                                outlined
                                @input="onChange"
                                options-dense
                                emit-value
                                map-options
                              >
                                <template v-slot:no-option>
                                  <q-item>
                                    <q-item-section class="text-grey">
                                      No hay resultados
                                    </q-item-section>
                                  </q-item>
                                </template>
                              </q-select>
                            </template>
                            
                            <script>
                            let filtered;
                            export default {
                              
                              computed: {
                                // _dataSource: {
                                //   get() {
                                //     return this.dataSource;
                                //   },
                                //   set(value) {
                                //     //console.log('set');
                                //     this.$props.dataSource = value
                                //     //this.$emit("dataSource", value);
                                //   },
                                // },
                              },
                              data() {
                                return {
                                  valuemember: 100,
                                   _dataSource : this.dataSource
                                };
                              },
                              watch: {},
                              created() {},
                              mounted() {},
                              props: {
                                dataSource: {
                                  type: Array,
                                  required: true,
                                },
                                optionvalue: {
                                  type: String,
                                  required: true,
                                },
                                optionlabel: {
                                  type: String,
                                  required: true,
                                },
                                placeholder: {
                                  type: String,
                                  required: false,
                                },
                              },
                              methods: {
                                
                                filterFn(val, update, abort) {
                                 filtered = this._dataSource
                                  update(() => {
                                    const needle = val.toLocaleLowerCase();
                            
                                    //
                                    // this.dataSource = this.$data._dataSource.filter(
                                    //   (v) => v[this.optionlabel].toLocaleLowerCase().indexOf(needle) > -1
                                    // );
                            
                                    this._dataSource  = this.$data._dataSource.filter(
                                      (v) => v[this.optionlabel].toLocaleLowerCase().indexOf(needle) > -1
                                    );       
                                  });
                                  this.$emit('update-datasource', this._dataSource)
                                },
                            
                                setModel(val) {
                                  this.valuemember = val;
                                },
                                onChange(value) {
                                  //refresh and update model
                                  this.$emit("input", value);
                                 
                                },
                                getData() {
                                  return this.valuemember;
                                },
                                setData(value) {
                                  this.valuemember = value;
                                  this.$emit("input", value);
                                },
                              },
                            };
                            </script>
                            
                            

                            in the page:

                             <OptimusSelect2 ref="sel2"
                                        v-model="USR_ERP_COMPANY_ID"
                                        :dataSource="options.companies"
                                        optionvalue="USR_ERP_COMPANY_ID"  
                                        optionlabel="USR_ERP_NAME"
                                        @update-datasource="UpdateCompany"
                                      />
                            
                             data() {
                                return {
                                  options: {
                                    companies: [
                                      {
                                      USR_ERP_COMPANY_ID: 100,
                                      USR_ERP_NAME: 'ACME',
                                     
                                    },
                                    {
                                      USR_ERP_COMPANY_ID: 200,
                                      USR_ERP_NAME: 'SOCONSA',
                                    },
                                    
                                    ]
                                  },
                            
                            UpdateCompany(data){
                                 //Update
                                 this.options.companies = data;
                                }
                            

                            your comments helped me research and learn more
                            thank you so much

                            Eloy

                            1 Reply Last reply Reply Quote 1
                            • First post
                              Last post