1

I am making a pet project, an html website with some tables generated via vue.js I feel like my code can be a lot simpler by refractoring it but I don't know what and where to put see my problem in the following code

var players = [
    { ID: 1, NAME: "Chandler Bing", TEL: '305-917-1301', rank: '3 dan' }
];
var criteria = ["ID", "NAME", "TEL", "rank"];
let crit = [
    {
        name: "ID",
        show: true
    },
    {
        name: "NAME",
        show: true
    },
    {
        name: "TEL",
        show: false
    },
    {
        name: "rank",
        show: true
    }
]
const Standings = {
    template: `<div v-cloak id="editable" style="background-color:#adb8ff">
    <div id="form">
        <label for="pname">Player:</label>
        <input v-model="pname" v-on:keyup.enter="playerSubmit" type="text" 
        id="pname" name="pname">
        <label for="rank">Rank:</label>
        <input v-model="rank" v-on:keyup.enter="playerSubmit" type="text" 
        id="rank" name="rank" size="2">
        <select id="rankT" name="RankType">
            <option value="dan">dan</option>
            <option value="kyu">kyu</option>
        </select>
        <button v-on:click="playerSubmit">Enter</button>
    </div>
    <div>
        <button v-on:click="previousRound" id="button">Previous Round</button>
        <button v-on:click="addRound" id="button">Next Round</button>
    </div>
    <table class="fixed" id="tournament">
       <!--  <col width="5px" />
        <col width="50px" />
        <col width="10px" /> -->
        <thead>
            <tr>
                <th v-for="col in columns">{{col.name}}</th>
            </tr>
        </thead>
        <tbody>
            <tr v-for="row in rows">
                <td v-for="col in columns">{{row[col.name]}}</td>
            </tr>
        </tbody>
    </table>
    <table class="settings">
        <col width="20px" />
        <thead>
            <tr>
                <th>SETTINGS</th>
            </tr>
        </thead>
        <tr>
            <td>Stuff</td>
        </tr>
    </table>
</div>`,
    props: [],
    methods: {
        playerSubmit: function () {
            players.push({
                ID: i,
                NAME: this.pname,
                TEL: "placeholder",
                rank: this.rank + " " + document.getElementById("rankT").value
            });
            i++
            this.pname = "";
            this.rank = "";
            return false;
        },
        addRound: function () {
            var pushActive = {};
            var counterT = counter.toString();
            players.forEach(p => p[counter] = "");
            pushActive = { name: counterT, show: true };
            activeCriteria.push(pushActive);
            var found = false;
            found = crit.filter(c => c.name == counterT).length > 0;

            if (!found) {
                crit.push(pushActive);

            }
            counter = counter + 1;

            found = false;
        },
        previousRound: function () {
            var l = crit.length - 1;
            if (counter > 1) {
                crit[l].show = false;
                activeCriteria.pop(activeCriteria[l]);
                counter = counter - 1;
            }

        }

    },
    data: function() {
        return {
        pname: "",
        rank: "",
        rows: players,
        columns: activeCriteria
    }
    }

}
const Pairings = {
    template: `<div v-cloak id="editable" style="background-color:#aaabca">
    <table class="fixed" id="tournament">
    <!--  <col width="5px" />
     <col width="50px" />
     <col width="10px" /> -->
     <thead>
         <tr>
            test
         </tr>
     </thead>
     <tbody>

     </tbody>
 </table>
 </div>`
}
const router = new VueRouter({
    routes: [
        { path: '/standings', component: Standings },
        { path: '/pairings', component: Pairings },
        { path: '*', redirect: '/standings' }
    ]
})
var activeCriteria = crit.filter(c => c.show);
var i = 1;
var counter = 1;
/* const app = new Vue({ router }).$mount('#app') */
var editable = new Vue({
    router,
    el: '#editable',
    data: {
        pname: "",
        rank: "",
        rows: players,
        columns: activeCriteria
    },

    methods: {
        playerSubmit: function () {
            players.push({
                ID: i,
                NAME: this.pname,
                TEL: "placeholder",
                rank: this.rank + " " + document.getElementById("rankT").value
            });
            i++
            this.pname = "";
            this.rank = "";
            return false;
        },
        addRound: function () {
            var pushActive = {};
            var counterT = counter.toString();
            players.forEach(p => p[counter] = "");
            pushActive = { name: counterT, show: true };
            activeCriteria.push(pushActive);
            var found = false;
            found = crit.filter(c => c.name == counterT).length > 0;

            if (!found) {
                crit.push(pushActive);

            }
            counter = counter + 1;

            found = false;
        },
        previousRound: function () {
            var l = crit.length - 1;
            if (counter > 1) {
                crit[l].show = false;
                activeCriteria.pop(activeCriteria[l]);
                counter = counter - 1;
            }

        }
    }
})

you'll notice I have the same methods in both Standings and editable, that's because if I don't declare those methods in both of these my code won't work now I'm not sure and correct me if I'm wrong but I feel like I could put those methods somewhere else so I'll only have one instance of those in my code

1 Answer 1

2

What you can do is create a .js file to host your functions:

YourFunctions.js

export const playerSubmit = () => {
            players.push({
                ID: i,
                NAME: this.pname,
                TEL: "placeholder",
                rank: this.rank + " " + document.getElementById("rankT").value
            });
            i++
            this.pname = "";
            this.rank = "";
            return false;
        };
export const addRound = () => {
            var pushActive = {};
            var counterT = counter.toString();
            players.forEach(p => p[counter] = "");
            pushActive = { name: counterT, show: true };
            activeCriteria.push(pushActive);
            var found = false;
            found = crit.filter(c => c.name == counterT).length > 0;

            if (!found) {
                crit.push(pushActive);

            }
            counter = counter + 1;

            found = false;
        };

export const previousRound = () => {
            var l = crit.length - 1;
            if (counter > 1) {
                crit[l].show = false;
                activeCriteria.pop(activeCriteria[l]);
                counter = counter - 1;
            }

        }

Then at the top of your Vue app you will be able to import these functions like so:

import { playerSubmit, addRound, previousRound} from './YourFunctions.js';

Then you can use them like normal :)

Have a look at some extra reading here: https://forum.vuejs.org/t/how-to-use-helper-functions-for-imported-modules-in-vuejs-vue-template/6266/2

VueJS accessing externaly imported method in vue component

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

3 Comments

Thank you. I did as you said but I got the "cannot use import statement outside a module". I added "type="module"" to my <script src="shogiTournament.js"> but I got the "access to script from origin null". Then I made a local web server to fix that and now it's working. My question is did I do something wrong in the first place so that I got those errors or is it how it is supposed to be?
Glad you got it working, make sure you upvote :) but also you will need to look around for clean vueJs examples, I personally pull out the new Vue() creation into a different folder, and create a file structure for my views, and other components.Also you hsould be hosting your new file you created on the same server, and just make sure your reference path is corect.
So it should be like that after all. Yes I got it to work but now I have some other issues with it. That's a different question tho. Yes I will look for clean examples, that's my next step. Thank you for your help, I upvoted but it says that new users' upvotes are registered but not shown.

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.