Recursively display dropdown in vue js












2















i have a table name called articles



id   parent_id  title
1 0 Profile
2 1 About Us
3 1 Why Us?
4 0 Kbow Us


now I want to create dropdown menu on vue laravel such that it recursively displays child category under parent category with proper indentation or - mark as per depth.E.g.:



<select>
<option value="1">Profile</option>
<option value="2">-About Us</option>
<option value="3">--Why Us</option>
<option value="4">Kbow Us</option>
</select>


I want to generate dropdown structure dynamically as like above recursively for any depth of child category in vue js.










share|improve this question





























    2















    i have a table name called articles



    id   parent_id  title
    1 0 Profile
    2 1 About Us
    3 1 Why Us?
    4 0 Kbow Us


    now I want to create dropdown menu on vue laravel such that it recursively displays child category under parent category with proper indentation or - mark as per depth.E.g.:



    <select>
    <option value="1">Profile</option>
    <option value="2">-About Us</option>
    <option value="3">--Why Us</option>
    <option value="4">Kbow Us</option>
    </select>


    I want to generate dropdown structure dynamically as like above recursively for any depth of child category in vue js.










    share|improve this question



























      2












      2








      2








      i have a table name called articles



      id   parent_id  title
      1 0 Profile
      2 1 About Us
      3 1 Why Us?
      4 0 Kbow Us


      now I want to create dropdown menu on vue laravel such that it recursively displays child category under parent category with proper indentation or - mark as per depth.E.g.:



      <select>
      <option value="1">Profile</option>
      <option value="2">-About Us</option>
      <option value="3">--Why Us</option>
      <option value="4">Kbow Us</option>
      </select>


      I want to generate dropdown structure dynamically as like above recursively for any depth of child category in vue js.










      share|improve this question
















      i have a table name called articles



      id   parent_id  title
      1 0 Profile
      2 1 About Us
      3 1 Why Us?
      4 0 Kbow Us


      now I want to create dropdown menu on vue laravel such that it recursively displays child category under parent category with proper indentation or - mark as per depth.E.g.:



      <select>
      <option value="1">Profile</option>
      <option value="2">-About Us</option>
      <option value="3">--Why Us</option>
      <option value="4">Kbow Us</option>
      </select>


      I want to generate dropdown structure dynamically as like above recursively for any depth of child category in vue js.







      vue.js






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Dec 30 '18 at 6:20







      Dipesh Magar

















      asked Dec 30 '18 at 4:13









      Dipesh MagarDipesh Magar

      113




      113
























          1 Answer
          1






          active

          oldest

          votes


















          0














          I would use a filter and a recursive function to walk each option back until no parent is found, keeping tracking of the depth and using that to append the indentation marks.



          Since you're likely passing the articles to a view file (in a PHP array or collection), you can pass the data to a vue component like:



          <my-nested-select :articles='{!! json_encode($articles) !!}'></my-nested-select>


          Here's an example using generated data, the filter being the important part:






          new Vue({
          el: '#app',
          data: () => ({
          items: ,
          selected: null
          }),
          created () {
          // 1. Create some dummy data where each option has an increasing chance of being nested.
          const tmp =

          for (let i = 1; i <= 50; i++) {
          let isChild = !!tmp.length ? Math.random() < ((i / 50) * tmp.length || 1) : null

          let parent_id = isChild ? Math.ceil(Math.random() * tmp.length - 1) : null

          tmp.push({
          id: i,
          parent_id,
          text: `Option ${i}`
          })
          }

          // 2. Sort the generated data so child options are in order following their parent option.
          this.items = tmp.reduce((items, item) => {
          if (!items.length || !item.parent_id) {
          items.unshift(item)
          } else {
          const index = items.findIndex(({ id }) => id === item.parent_id)

          if (index) {
          items.splice(index, 0, item)
          }
          }

          return items
          }, ).reverse()
          },
          filters: {
          depth (option, items) {
          let depth = 0

          // 3. The magic happens here with a recursive function to find the depth to which each option is nested.
          const pad = ({ parent_id }) => {
          if (!!parent_id) {
          depth += 1

          let parent = items.find(({ id }) => id === parent_id)

          if (!parent) {
          return depth
          }

          return pad(parent)
          }

          return depth
          }

          // 4. Call the recursive function above, create an array of hyphens and concat them together with the option's text.
          return Array(pad(option)).fill('-').concat([' ', option.text]).join('')
          }
          }
          })

          <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
          <div id="app">
          <select v-model="selected">
          <option v-for="option in items" :value="option.id" :key="option.id">{{ option | depth(items) }}</option>
          </select>

          <h4>Data</h4>

          <ul>
          <li v-for="item in items" :key="item.id"><pre><code>{{ item }}</code></pre></li>
          </ul>
          </div>








          share|improve this answer

























            Your Answer






            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "1"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














            draft saved

            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53975228%2frecursively-display-dropdown-in-vue-js%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            1 Answer
            1






            active

            oldest

            votes








            1 Answer
            1






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            0














            I would use a filter and a recursive function to walk each option back until no parent is found, keeping tracking of the depth and using that to append the indentation marks.



            Since you're likely passing the articles to a view file (in a PHP array or collection), you can pass the data to a vue component like:



            <my-nested-select :articles='{!! json_encode($articles) !!}'></my-nested-select>


            Here's an example using generated data, the filter being the important part:






            new Vue({
            el: '#app',
            data: () => ({
            items: ,
            selected: null
            }),
            created () {
            // 1. Create some dummy data where each option has an increasing chance of being nested.
            const tmp =

            for (let i = 1; i <= 50; i++) {
            let isChild = !!tmp.length ? Math.random() < ((i / 50) * tmp.length || 1) : null

            let parent_id = isChild ? Math.ceil(Math.random() * tmp.length - 1) : null

            tmp.push({
            id: i,
            parent_id,
            text: `Option ${i}`
            })
            }

            // 2. Sort the generated data so child options are in order following their parent option.
            this.items = tmp.reduce((items, item) => {
            if (!items.length || !item.parent_id) {
            items.unshift(item)
            } else {
            const index = items.findIndex(({ id }) => id === item.parent_id)

            if (index) {
            items.splice(index, 0, item)
            }
            }

            return items
            }, ).reverse()
            },
            filters: {
            depth (option, items) {
            let depth = 0

            // 3. The magic happens here with a recursive function to find the depth to which each option is nested.
            const pad = ({ parent_id }) => {
            if (!!parent_id) {
            depth += 1

            let parent = items.find(({ id }) => id === parent_id)

            if (!parent) {
            return depth
            }

            return pad(parent)
            }

            return depth
            }

            // 4. Call the recursive function above, create an array of hyphens and concat them together with the option's text.
            return Array(pad(option)).fill('-').concat([' ', option.text]).join('')
            }
            }
            })

            <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
            <div id="app">
            <select v-model="selected">
            <option v-for="option in items" :value="option.id" :key="option.id">{{ option | depth(items) }}</option>
            </select>

            <h4>Data</h4>

            <ul>
            <li v-for="item in items" :key="item.id"><pre><code>{{ item }}</code></pre></li>
            </ul>
            </div>








            share|improve this answer






























              0














              I would use a filter and a recursive function to walk each option back until no parent is found, keeping tracking of the depth and using that to append the indentation marks.



              Since you're likely passing the articles to a view file (in a PHP array or collection), you can pass the data to a vue component like:



              <my-nested-select :articles='{!! json_encode($articles) !!}'></my-nested-select>


              Here's an example using generated data, the filter being the important part:






              new Vue({
              el: '#app',
              data: () => ({
              items: ,
              selected: null
              }),
              created () {
              // 1. Create some dummy data where each option has an increasing chance of being nested.
              const tmp =

              for (let i = 1; i <= 50; i++) {
              let isChild = !!tmp.length ? Math.random() < ((i / 50) * tmp.length || 1) : null

              let parent_id = isChild ? Math.ceil(Math.random() * tmp.length - 1) : null

              tmp.push({
              id: i,
              parent_id,
              text: `Option ${i}`
              })
              }

              // 2. Sort the generated data so child options are in order following their parent option.
              this.items = tmp.reduce((items, item) => {
              if (!items.length || !item.parent_id) {
              items.unshift(item)
              } else {
              const index = items.findIndex(({ id }) => id === item.parent_id)

              if (index) {
              items.splice(index, 0, item)
              }
              }

              return items
              }, ).reverse()
              },
              filters: {
              depth (option, items) {
              let depth = 0

              // 3. The magic happens here with a recursive function to find the depth to which each option is nested.
              const pad = ({ parent_id }) => {
              if (!!parent_id) {
              depth += 1

              let parent = items.find(({ id }) => id === parent_id)

              if (!parent) {
              return depth
              }

              return pad(parent)
              }

              return depth
              }

              // 4. Call the recursive function above, create an array of hyphens and concat them together with the option's text.
              return Array(pad(option)).fill('-').concat([' ', option.text]).join('')
              }
              }
              })

              <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
              <div id="app">
              <select v-model="selected">
              <option v-for="option in items" :value="option.id" :key="option.id">{{ option | depth(items) }}</option>
              </select>

              <h4>Data</h4>

              <ul>
              <li v-for="item in items" :key="item.id"><pre><code>{{ item }}</code></pre></li>
              </ul>
              </div>








              share|improve this answer




























                0












                0








                0







                I would use a filter and a recursive function to walk each option back until no parent is found, keeping tracking of the depth and using that to append the indentation marks.



                Since you're likely passing the articles to a view file (in a PHP array or collection), you can pass the data to a vue component like:



                <my-nested-select :articles='{!! json_encode($articles) !!}'></my-nested-select>


                Here's an example using generated data, the filter being the important part:






                new Vue({
                el: '#app',
                data: () => ({
                items: ,
                selected: null
                }),
                created () {
                // 1. Create some dummy data where each option has an increasing chance of being nested.
                const tmp =

                for (let i = 1; i <= 50; i++) {
                let isChild = !!tmp.length ? Math.random() < ((i / 50) * tmp.length || 1) : null

                let parent_id = isChild ? Math.ceil(Math.random() * tmp.length - 1) : null

                tmp.push({
                id: i,
                parent_id,
                text: `Option ${i}`
                })
                }

                // 2. Sort the generated data so child options are in order following their parent option.
                this.items = tmp.reduce((items, item) => {
                if (!items.length || !item.parent_id) {
                items.unshift(item)
                } else {
                const index = items.findIndex(({ id }) => id === item.parent_id)

                if (index) {
                items.splice(index, 0, item)
                }
                }

                return items
                }, ).reverse()
                },
                filters: {
                depth (option, items) {
                let depth = 0

                // 3. The magic happens here with a recursive function to find the depth to which each option is nested.
                const pad = ({ parent_id }) => {
                if (!!parent_id) {
                depth += 1

                let parent = items.find(({ id }) => id === parent_id)

                if (!parent) {
                return depth
                }

                return pad(parent)
                }

                return depth
                }

                // 4. Call the recursive function above, create an array of hyphens and concat them together with the option's text.
                return Array(pad(option)).fill('-').concat([' ', option.text]).join('')
                }
                }
                })

                <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
                <div id="app">
                <select v-model="selected">
                <option v-for="option in items" :value="option.id" :key="option.id">{{ option | depth(items) }}</option>
                </select>

                <h4>Data</h4>

                <ul>
                <li v-for="item in items" :key="item.id"><pre><code>{{ item }}</code></pre></li>
                </ul>
                </div>








                share|improve this answer















                I would use a filter and a recursive function to walk each option back until no parent is found, keeping tracking of the depth and using that to append the indentation marks.



                Since you're likely passing the articles to a view file (in a PHP array or collection), you can pass the data to a vue component like:



                <my-nested-select :articles='{!! json_encode($articles) !!}'></my-nested-select>


                Here's an example using generated data, the filter being the important part:






                new Vue({
                el: '#app',
                data: () => ({
                items: ,
                selected: null
                }),
                created () {
                // 1. Create some dummy data where each option has an increasing chance of being nested.
                const tmp =

                for (let i = 1; i <= 50; i++) {
                let isChild = !!tmp.length ? Math.random() < ((i / 50) * tmp.length || 1) : null

                let parent_id = isChild ? Math.ceil(Math.random() * tmp.length - 1) : null

                tmp.push({
                id: i,
                parent_id,
                text: `Option ${i}`
                })
                }

                // 2. Sort the generated data so child options are in order following their parent option.
                this.items = tmp.reduce((items, item) => {
                if (!items.length || !item.parent_id) {
                items.unshift(item)
                } else {
                const index = items.findIndex(({ id }) => id === item.parent_id)

                if (index) {
                items.splice(index, 0, item)
                }
                }

                return items
                }, ).reverse()
                },
                filters: {
                depth (option, items) {
                let depth = 0

                // 3. The magic happens here with a recursive function to find the depth to which each option is nested.
                const pad = ({ parent_id }) => {
                if (!!parent_id) {
                depth += 1

                let parent = items.find(({ id }) => id === parent_id)

                if (!parent) {
                return depth
                }

                return pad(parent)
                }

                return depth
                }

                // 4. Call the recursive function above, create an array of hyphens and concat them together with the option's text.
                return Array(pad(option)).fill('-').concat([' ', option.text]).join('')
                }
                }
                })

                <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
                <div id="app">
                <select v-model="selected">
                <option v-for="option in items" :value="option.id" :key="option.id">{{ option | depth(items) }}</option>
                </select>

                <h4>Data</h4>

                <ul>
                <li v-for="item in items" :key="item.id"><pre><code>{{ item }}</code></pre></li>
                </ul>
                </div>








                new Vue({
                el: '#app',
                data: () => ({
                items: ,
                selected: null
                }),
                created () {
                // 1. Create some dummy data where each option has an increasing chance of being nested.
                const tmp =

                for (let i = 1; i <= 50; i++) {
                let isChild = !!tmp.length ? Math.random() < ((i / 50) * tmp.length || 1) : null

                let parent_id = isChild ? Math.ceil(Math.random() * tmp.length - 1) : null

                tmp.push({
                id: i,
                parent_id,
                text: `Option ${i}`
                })
                }

                // 2. Sort the generated data so child options are in order following their parent option.
                this.items = tmp.reduce((items, item) => {
                if (!items.length || !item.parent_id) {
                items.unshift(item)
                } else {
                const index = items.findIndex(({ id }) => id === item.parent_id)

                if (index) {
                items.splice(index, 0, item)
                }
                }

                return items
                }, ).reverse()
                },
                filters: {
                depth (option, items) {
                let depth = 0

                // 3. The magic happens here with a recursive function to find the depth to which each option is nested.
                const pad = ({ parent_id }) => {
                if (!!parent_id) {
                depth += 1

                let parent = items.find(({ id }) => id === parent_id)

                if (!parent) {
                return depth
                }

                return pad(parent)
                }

                return depth
                }

                // 4. Call the recursive function above, create an array of hyphens and concat them together with the option's text.
                return Array(pad(option)).fill('-').concat([' ', option.text]).join('')
                }
                }
                })

                <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
                <div id="app">
                <select v-model="selected">
                <option v-for="option in items" :value="option.id" :key="option.id">{{ option | depth(items) }}</option>
                </select>

                <h4>Data</h4>

                <ul>
                <li v-for="item in items" :key="item.id"><pre><code>{{ item }}</code></pre></li>
                </ul>
                </div>





                new Vue({
                el: '#app',
                data: () => ({
                items: ,
                selected: null
                }),
                created () {
                // 1. Create some dummy data where each option has an increasing chance of being nested.
                const tmp =

                for (let i = 1; i <= 50; i++) {
                let isChild = !!tmp.length ? Math.random() < ((i / 50) * tmp.length || 1) : null

                let parent_id = isChild ? Math.ceil(Math.random() * tmp.length - 1) : null

                tmp.push({
                id: i,
                parent_id,
                text: `Option ${i}`
                })
                }

                // 2. Sort the generated data so child options are in order following their parent option.
                this.items = tmp.reduce((items, item) => {
                if (!items.length || !item.parent_id) {
                items.unshift(item)
                } else {
                const index = items.findIndex(({ id }) => id === item.parent_id)

                if (index) {
                items.splice(index, 0, item)
                }
                }

                return items
                }, ).reverse()
                },
                filters: {
                depth (option, items) {
                let depth = 0

                // 3. The magic happens here with a recursive function to find the depth to which each option is nested.
                const pad = ({ parent_id }) => {
                if (!!parent_id) {
                depth += 1

                let parent = items.find(({ id }) => id === parent_id)

                if (!parent) {
                return depth
                }

                return pad(parent)
                }

                return depth
                }

                // 4. Call the recursive function above, create an array of hyphens and concat them together with the option's text.
                return Array(pad(option)).fill('-').concat([' ', option.text]).join('')
                }
                }
                })

                <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
                <div id="app">
                <select v-model="selected">
                <option v-for="option in items" :value="option.id" :key="option.id">{{ option | depth(items) }}</option>
                </select>

                <h4>Data</h4>

                <ul>
                <li v-for="item in items" :key="item.id"><pre><code>{{ item }}</code></pre></li>
                </ul>
                </div>






                share|improve this answer














                share|improve this answer



                share|improve this answer








                edited Dec 30 '18 at 8:03

























                answered Dec 30 '18 at 6:39









                DigitalDrifterDigitalDrifter

                8,1852523




                8,1852523






























                    draft saved

                    draft discarded




















































                    Thanks for contributing an answer to Stack Overflow!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53975228%2frecursively-display-dropdown-in-vue-js%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    Mossoró

                    Error while reading .h5 file using the rhdf5 package in R

                    Pushsharp Apns notification error: 'InvalidToken'