0

I am trying to add form inputs for a nested array. I can loop over to show hard coded items to the page, but when I add a form to addto the array, I get a blank screen.

addNewSection

<form v-on:submit.prevent="addNewSection">
  <div class="form-group m-form__group">
    <input v-model="sections.name" placeholder="Name" class="form-control m-input" style="margin-bottom: .5rem"/>
    <textarea v-model="sections.description" placeholder="Description" class="form-control m-input" style="margin-bottom: .5rem"/></textarea>
    <button type="submit" class="btn btn-primary">Add Section</button>
  </div>
</form>

addNewItem

<form v-on:submit="addNewItem">
  <div class="form-group m-form__group">
    <input v-model="sections.items.name" placeholder="Name" class="form-control m-input" style="margin-bottom: .5rem"/>
    <textarea v-model="sections.items.description" placeholder="Description" class="form-control m-input" style="margin-bottom: .5rem"/></textarea>
    <button type="submit" class="btn btn-primary">Add Section</button>
  </div>
</form>

script

    new Vue({
        el: "#main",
        data: {
            sections: [
                {
                    name: "Salad",
                    description: 'Add chicken to any salad for $3.00',
                    items: [

                        {
                            name: 'Antipasto',
                            description: 'Mixed greens, Italian meats, cheeses, giardiniera pickled veggies, tomatoes, roasted peppers, onions with house Italian vinaigrette',
                            price: '$13.00'
                        },
                        {
                            name: 'Basic',
                            description: 'Mixed greens, Italian meats, cheeses, giardiniera pickled veggies, tomatoes, roasted peppers, onions with house Italian vinaigrette.',
                            price: '$5.00 / $7.50'
                        },
                        {
                            name: 'Caesar',
                            description: 'Romaine, Caesar dressing, croutons, shaved parmesan',
                            price: '$5.00 / $7.50'
                        }
                    ]
                },
                {
                    name: "Sandwiches",
                    description: 'Add cheese to any salad for $3.00',
                    items: [

                        {
                            name: 'Sandwich 1',
                            description: 'Mixed greens, Italian meats, cheeses, giardiniera pickled veggies, tomatoes, roasted peppers, onions with house Italian vinaigrette',
                            price: '$13.00'
                        },
                        {
                            name: 'Sandwich 2',
                            description: 'Mixed greens, Italian meats, cheeses, giardiniera pickled veggies, tomatoes, roasted peppers, onions with house Italian vinaigrette.',
                            price: '$5.00 / $7.50'
                        },
                        {
                            name: 'Sandwich 3',
                            description: 'Romaine, Caesar dressing, croutons, shaved parmesan',
                            price: '$5.00 / $7.50'
                        }
                    ]
                },
                {
                    name: "Pizzas",
                    description: 'Add Pepperonis to any salad for $3.00',
                    items: [

                        {
                            name: 'Pizza 1',
                            description: 'Mixed greens, Italian meats, cheeses, giardiniera pickled veggies, tomatoes, roasted peppers, onions with house Italian vinaigrette',
                            price: '$13.00'
                        },
                        {
                            name: 'Pizza 2',
                            description: 'Mixed greens, Italian meats, cheeses, giardiniera pickled veggies, tomatoes, roasted peppers, onions with house Italian vinaigrette.',
                            price: '$5.00 / $7.50'
                        },
                        {
                            name: 'Pizza 3',
                            description: 'Romaine, Caesar dressing, croutons, shaved parmesan',
                            price: '$5.00 / $7.50'
                        }
                    ]
                }
            ]
        },
        methods: {
            deleteSection: function (index) {
                this.sections.splice(index, 1);
            },
            addNewSection(e) {
                this.sections.push(
                    {
                        name: this.sections.name,
                        description: this.sections.description
                    }
                );
                this.sections.name = "";
                this.sections.description = "";
                e.preventDefault();
            },
            addNewItem(e) {
                this.section.items.push(
                    {
                        name: this.section.items.name,
                        description: this.section.items.description
                    }
                );
                this.section.items.name = "";
                this.section.items.description = "";
                e.preventDefault();
            },
            deleteItem: function (index) {
                this.section.items.splice(index, 1);
            },
        }
    });

</script>

If you look at the above code, I have 3 sections and items hard-coded for testing. I am able to loop over and display sections and nested items successfully. Its the addNewItem and deleteItem I am having issues with. If I get help with the add item, I can figure out the delete.

6
  • How are you choosing a section for the new item? Commented Jun 4, 2018 at 19:12
  • @Bert I had <div v-for="s in sections"></div> wrapped around the outer div inside the form, but all it did was repeat the input fields for as many sections, which is how a for loop is supposed to work, so I figured I was doing something wrong Commented Jun 4, 2018 at 19:17
  • 1
    Basically I don't understand whether you just have one add new item form or one for each section. If there is just one, then this is how you might do it. Commented Jun 4, 2018 at 19:21
  • @Bert Works great for adding an item from an existing section. If I add a section and then choose it from the dropdown to add an item to it, the submit doesn't work. I didn't include the form to add new sections in my original post, because it didn't seem relevant, but will add it to the existing thread. Commented Jun 4, 2018 at 19:45
  • I updated the example to handle adding a section. Commented Jun 4, 2018 at 20:03

2 Answers 2

1

Here is a complete working example of adding and deleting sections and items.

console.clear()
new Vue({
  el: "#main",
  data: {
    sectionName: '',
    sectionDescription: '',
    itemName: '',
    itemDescription: '',
    selectedSection: null,
    sections: [
      {
        name: "Salad",
        description: 'Add chicken to any salad for $3.00',
        items: [

          {
            name: 'Antipasto',
            description: 'Mixed greens, Italian meats, cheeses, giardiniera pickled veggies, tomatoes, roasted peppers, onions with house Italian vinaigrette',
            price: '$13.00'
          },
          {
            name: 'Basic',
            description: 'Mixed greens, Italian meats, cheeses, giardiniera pickled veggies, tomatoes, roasted peppers, onions with house Italian vinaigrette.',
            price: '$5.00 / $7.50'
          },
          {
            name: 'Caesar',
            description: 'Romaine, Caesar dressing, croutons, shaved parmesan',
            price: '$5.00 / $7.50'
          }
        ]
      },
      {
        name: "Sandwiches",
        description: 'Add cheese to any salad for $3.00',
        items: [

          {
            name: 'Sandwich 1',
            description: 'Mixed greens, Italian meats, cheeses, giardiniera pickled veggies, tomatoes, roasted peppers, onions with house Italian vinaigrette',
            price: '$13.00'
          },
          {
            name: 'Sandwich 2',
            description: 'Mixed greens, Italian meats, cheeses, giardiniera pickled veggies, tomatoes, roasted peppers, onions with house Italian vinaigrette.',
            price: '$5.00 / $7.50'
          },
          {
            name: 'Sandwich 3',
            description: 'Romaine, Caesar dressing, croutons, shaved parmesan',
            price: '$5.00 / $7.50'
          }
        ]
      },
      {
        name: "Pizzas",
        description: 'Add Pepperonis to any salad for $3.00',
        items: [

          {
            name: 'Pizza 1',
            description: 'Mixed greens, Italian meats, cheeses, giardiniera pickled veggies, tomatoes, roasted peppers, onions with house Italian vinaigrette',
            price: '$13.00'
          },
          {
            name: 'Pizza 2',
            description: 'Mixed greens, Italian meats, cheeses, giardiniera pickled veggies, tomatoes, roasted peppers, onions with house Italian vinaigrette.',
            price: '$5.00 / $7.50'
          },
          {
            name: 'Pizza 3',
            description: 'Romaine, Caesar dressing, croutons, shaved parmesan',
            price: '$5.00 / $7.50'
          }
        ]
      }
    ]
  },
  methods: {
    deleteSection: function (section) {
      this.sections.splice(this.sections.findIndex(s => s === section), 1);
    },
    addNewSection() {
      this.sections.push({
        name: this.sectionName,
        description: this.sectionDescription,
        items:[]
      })
    },
    addNewItem() {
      const section = this.sections.find(s => s.name === this.selectedSection)
      section.items.push({
        name: this.itemName,
        description: this.itemDescription
      })
    },
    deleteItem: function (section, item) {
      section.items.splice(section.items.findIndex(i => i === item), 1)
    },
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.min.js"></script>
<div id="main">
  <ul>
    <li v-for="section in sections" :key="section.name">
      {{section.name}} <a href="#" @click="deleteSection(section)">Delete</a>
      <ul>
        <li v-for="item in section.items" :key="item.name">
          {{item.name}}
          <a href="#" @click="deleteItem(section, item)">Delete</a>
        </li>
      </ul>
    </li>
  </ul>
  <hr>
  <h1>Add New Section</h1>
  <form v-on:submit.prevent="addNewSection">
  <div>
    <input v-model="sectionName" placeholder="Name" /><br>
    <textarea v-model="sectionDescription" placeholder="Description" ></textarea><br>
    <button type="submit" class="btn btn-primary">Add Section</button>
  </div>
</form>
  <h1>Add New Item</h1>
  <form v-on:submit.prevent="addNewItem">
  <div>
    <select v-model="selectedSection">
      <option v-for="section in sections" :value="section.name">{{section.name}}</option>
    </select><br>
    <input v-model="itemName" placeholder="Name" /><br>
    <textarea v-model="itemDescription" placeholder="Description"></textarea><br>
    <button type="submit" class="btn btn-primary">Add Section</button>
  </div>
</form>
</div>

Sign up to request clarification or add additional context in comments.

Comments

0

I am not sure, but I think that the problem is in addNewItem function, as well as deleteItem. You are pushing it to and splicing from section while you have sectionS array.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.