skip to Main Content

All @click.stop events in my vue component wont fire and I can’t see where I went wrong, I’m hoping another set of eyes can point out where I went wrong. I’m running npm run watch and I’ve cleared my cache.
Here is all the code you should need:

My app.js

window._ = require("lodash");

// window.Vue = require('vue');
import Vue from "vue";

window.axios = require("axios");

window.axios.defaults.headers.common["X-Requested-With"] = "XMLHttpRequest";

let token = document.head.querySelector('meta[name="csrf-token"]');

if (token) {
  window.axios.defaults.headers.common["X-CSRF-TOKEN"] = token.content;
} else {
  console.error(
    "CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token"
  );
}

// const files = require.context('./', true, /.vue$/i);
// files.keys().map(key => Vue.component(key.split('/').pop().split('.')[0], files(key).default));

import VueSwal from "vue-swal";
Vue.use(VueSwal);

Vue.component(
  "example-component",
  require("./components/ExampleComponent.vue").default
);
//Vue.component('product-attributes', require('./components/ProductAttributes').default);

Vue.component(
  "attribute-values",
  require("./components/AttributeValues.vue").default
);

const app = new Vue({
  el: "#app",
});

My AttributeValues.vue

<template>
  <div id="">
    <div class="tile">
      <h3 class="tile-title">Attribute Values</h3>
      <hr />
      <div class="tile-body">
        <div class="form-group">
          <label class="control-label" for="value">Value</label>
          <input
            class="form-control"
            type="text"
            placeholder="Enter attribute value"
            id="value"
            name="value"
            v-model="value"
          />
        </div>
        <div class="form-group">
          <label class="control-label" for="price">Price</label>
          <input
            class="form-control"
            type="number"
            placeholder="Enter attribute value price"
            id="price"
            name="price"
            v-model="price"
          />
        </div>
      </div>
      <div class="tile-footer">
        <div class="row d-print-none mt-2">
          <div class="col-12 text-right">
            <button
              class="btn btn-success"
              type="submit"
              @click.stop="saveValue()"
              v-if="addValue"
            >
              <i class="fa fa-fw fa-lg fa-check-circle"></i>Save
            </button>
            <button
              class="btn btn-success"
              type="submit"
              @click.stop="updateValue()"
              v-if="!addValue"
            >
              <i class="fa fa-fw fa-lg fa-check-circle"></i>Update
            </button>
            <button
              class="btn btn-primary"
              type="submit"
              @click.stop="reset()"
              v-if="!addValue"
            >
              <i class="fa fa-fw fa-lg fa-check-circle"></i>Reset
            </button>
          </div>
        </div>
      </div>
    </div>
    <div class="tile">
      <h3 class="tile-title">Option Values</h3>
      <div class="tile-body">
        <div class="table-responsive">
          <table class="table table-sm">
            <thead>
              <tr class="text-center">
                <th>#</th>
                <th>Value</th>
                <th>Price</th>
                <th>Action</th>
              </tr>
            </thead>
            <tbody>
              <tr v-for="value in values">
                <td style="width: 25%" class="text-center">{{ value.id }}</td>
                <td style="width: 25%" class="text-center">
                  {{ value.value }}
                </td>
                <td style="width: 25%" class="text-center">
                  {{ value.price }}
                </td>
                <td style="width: 25%" class="text-center">
                  <button
                    class="btn btn-sm btn-primary"
                    @click.stop="editAttributeValue(value)"
                  >
                    <i class="fa fa-edit"></i>
                  </button>
                  <button
                    class="btn btn-sm btn-danger"
                    @click.stop="deleteAttributeValue(value)"
                  >
                    <i class="fa fa-trash"></i>
                  </button>
                </td>
              </tr>
            </tbody>
          </table>
        </div>
      </div>
    </div>
  </div>
</template>
<script type="application/javascript">
export default {
  name: "attribute-values",
  props: ["attributeid"],
  data() {
    return {
      values: [],
      value: "",
      price: "",
      currentId: "",
      addValue: true,
      key: 0,
    };
  },

  created: function () {
    this.loadValues();
  },

  methods: {
    loadValues() {
      let attributeId = this.attributeid;
      let _this = this;
      axios
        .post("/admin/attributes/get-values", {
          id: attributeId,
        })
        .then(function (response) {
          _this.values = response.data;
        })
        .catch(function (error) {
          console.log(error);
        });
    },

    saveValue() {
      if (this.value === "") {
        this.$swal("Error, Value for attribute is required.", {
          icon: "error",
        });
      } else {
        let attributeId = this.attributeid;
        let _this = this;
        axios
          .post("/admin/attributes/add-values", {
            id: attributeId,
            value: _this.value,
            price: _this.price,
          })
          .then(function (response) {
            _this.values.push(response.data);
            _this.resetValue();
            _this.$swal("Success! Value added successfully!", {
              icon: "success",
            });
          })
          .catch(function (error) {
            console.log(error);
          });
      }
    },

    resetValue() {
      this.value = "";
      this.price = "";
    },

    reset() {
      this.addValue = true;
      this.resetValue();
    },

    editAttributeValue(value) {
      this.addValue = false;
      this.value = value.value;
      this.price = value.price;
      this.currentId = value.id;
      this.key = this.values.indexOf(value);
    },

    updateValue() {
      if (this.value === "") {
        this.$swal("Error, Value for attribute is required.", {
          icon: "error",
        });
      } else {
        let attributeId = this.attributeid;
        let _this = this;
        axios
          .post("/admin/attributes/update-values", {
            id: attributeId,
            value: _this.value,
            price: _this.price,
            valueId: _this.currentId,
          })
          .then(function (response) {
            _this.values.splice(_this.key, 1);
            _this.resetValue();
            _this.values.push(response.data);
            _this.$swal("Success! Value updated successfully!", {
              icon: "success",
            });
          })
          .catch(function (error) {
            console.log(error);
          });
      }
    },

    deleteAttributeValue(value) {
      this.$swal({
        title: "Are you sure?",
        text: "Once deleted, you will not be able to recover this attribute value!",
        icon: "warning",
        buttons: true,
        dangerMode: true,
      }).then((willDelete) => {
        if (willDelete) {
          this.currentId = value.id;
          this.key = this.values.indexOf(value);
          let _this = this;
          axios
            .post("/admin/attributes/delete-values", {
              id: _this.currentId,
            })
            .then(function (response) {
              if (response.data.status === "success") {
                _this.values.splice(_this.key, 1);
                _this.resetValue();
                _this.$swal("Success! Option value has been deleted!", {
                  icon: "success",
                });
              } else {
                _this.$swal("Your option value not deleted!");
              }
            })
            .catch(function (error) {
              console.log(error);
            });
        } else {
          this.$swal("Your option value not deleted!");
        }
      });
    },
  },
};
</script>

Blade that has contains the vue component

 <div class="tab-pane" id="values">
   <attribute-values :attributeid="{{ $attribute->id }}"></attribute-values>
</div>

           
@endsection
        @push('scripts')
        <script type="application/javascript" src="{{ asset('js/app.js') }}"> </script>
           
@endpush

My Composer Json

{
  "name": "laravel/laravel",
  "type": "project",
  "description": "The Laravel Framework.",
  "keywords": ["framework", "laravel"],
  "license": "MIT",
  "require": {
    "php": "^7.3|^8.0",
    "fruitcake/laravel-cors": "^2.0",
    "guzzlehttp/guzzle": "^7.0.1",
    "laravel/framework": "^8.75",
    "laravel/helpers": "^1.5",
    "laravel/sanctum": "^2.11",
    "laravel/tinker": "^2.5",
    "laravel/ui": "^2.0",
    "typicms/nestablecollection": "*"
  },
  "require-dev": {
    "facade/ignition": "^2.5",
    "fakerphp/faker": "^1.9.1",
    "laravel/sail": "^1.0.1",
    "mockery/mockery": "^1.4.4",
    "nunomaduro/collision": "^5.10",
    "phpunit/phpunit": "^9.5.10"
  },
  "autoload": {
    "psr-4": {
      "App\": "app/",
      "Database\Factories\": "database/factories/",
      "Database\Seeders\": "database/seeders/"
    }
  },
  "autoload-dev": {
    "psr-4": {
      "Tests\": "tests/"
    }
  },
  "scripts": {
    "post-autoload-dump": [
      "Illuminate\Foundation\ComposerScripts::postAutoloadDump",
      "@php artisan package:discover --ansi"
    ],
    "post-update-cmd": [
      "@php artisan vendor:publish --tag=laravel-assets --ansi --force"
    ],
    "post-root-package-install": [
      "@php -r "file_exists('.env') || copy('.env.example', '.env');""
    ],
    "post-create-project-cmd": ["@php artisan key:generate --ansi"]
  },
  "extra": {
    "laravel": {
      "dont-discover": []
    }
  },
  "config": {
    "optimize-autoloader": true,
    "preferred-install": "dist",
    "sort-packages": true
  },
  "minimum-stability": "dev",
  "prefer-stable": true
}

Package Json

{
  "private": true,
  "scripts": {
    "dev": "npm run development",
    "development": "mix",
    "watch": "mix watch",
    "watch-poll": "mix watch -- --watch-options-poll=1000",
    "hot": "mix watch --hot",
    "prod": "npm run production",
    "production": "mix --production"
  },
  "devDependencies": {
    "axios": "^0.21",
    "bootstrap": "^4.0.0",
    "cross-env": "^5.1",
    "jquery": "^3.2",
    "laravel-mix": "^6.0.43",
    "lodash": "^4.17.19",
    "popper.js": "^1.12",
    "postcss": "^8.1.14",
    "resolve-url-loader": "^2.3.1",
    "sass": "^1.20.1",
    "sass-loader": "^8.0.0",
    "vue": "^2.5.17",
    "vue-loader": "^15.9.7",
    "vue-template-compiler": "^2.6.10"
  },
  "dependencies": {
    "vue-swal": "^0.1.0"
  }
}

There are no errors or warnings. Apart from this

Uncaught TypeError: document.getElementById(...) is null
    <anonymous> http://127.0.0.1:8000/back-assets/js/index2.js:121
    jQuery 2

Any help would be appreciated, I hope I gave all the info you might need, if not, please ask.

2

Answers


  1. Some tips, that can help you!

    1. Make sure the scripts are included in your view, and are not conflicted.

    2. remove unnecessary imports from your app.js

    3. Make sure you really need to handle your button as submit. If you do not need that, you can stop submitting using, https://v2.vuejs.org/v2/guide/events.html

    4. Try @click="console.log('I can be triggered') to see if you can trigger.

    Login or Signup to reply.
  2. You can edit @click.stop="Method()"
    to @click.stop.prevent="Method()"
    And Try It

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search