Validating buttons and calling API & checking with the status of it - api

I am new to Vuejs and I wanna know certain things about validating buttons.
I have used two inputs one is for API key and the other one is for SECRET Key, So initially user has to enter the Keys in both the field.
My first question is how do I validate this:
<div class="vx-form-group">
<label class="Inpu1">API Key</label>
<div class="col">
<vs-input v-validate="'required|apiKey'" placeholder="API Key" name="apiKey" />
</div>
</div>
<div class="vx-form-group" style="margin-bottom: 5%">
<label class="Input2">Secret Key</label>
<div class="col">
<vs-input v-validate="'required|secretKey'" placeholder="Secret Key" name="secretKey" />
</div>
</div>
My second question, I have used two buttons:
First in order to save it
Second one for CHECKING those keys entered. So whenever I click the CHECK button it has to call my API and check the status of it, If it returns a 200 then I want to display "connection is OK". If that is a 401 then I want to display "Connection not Ok".
Here s how I tried it:
<vs-button class="btn " #click.prevent="apiform"
style="margin-right: 2%; ">
Check
</vs-button>
<vs-button class="btn">Save</vs-button>
<vs-button class="close"
#click="$refs.modalName.closeModal()" style="margin-left: 2%">Cancel
</vs-button>
//in my script
<script>
methods: {
async apiform() {
const response = await this.$http.post('https://my-api-goes-here',
{
check: this.check
})
console.log(response)
this.keys.push(response)
}
}
// If it returns a 200 then it means connection is OK.
// If it returns 401 then it means connection is Not ok.
</script>
I am new to Vuejs, I have no idea. Please anyone who knows the answer please try explaining me practically by sending the code so that I can understand it clearly.
Thank You.

Welcome!
For your first question, I see input fields, but their values are not bound to anything. Best thing to do is bind your inputs to variables using v-model as so:
<div class="vx-form-group">
<label class="Inpu1">API Key</label>
<div class="col">
<vs-input v-model="apiKey" v-validate="'required|apiKey'" placeholder="API Key" name="apiKey" />
</div>
</div>
<div class="vx-form-group" style="margin-bottom: 5%">
<label class="Input2">Secret Key</label>
<div class="col">
<vs-input v-model="secretKey" v-validate="'required|secretKey'" placeholder="Secret Key" name="secretKey" />
</div>
</div>
and in your script
<script>
export default{
name:'myComponentName',
data(){
return{
apiKey:'',
secretKey:''
}
}
That way you can check the values and validate them in your methods by using this.apiKey and this.secretKey.
For your second question, I use axios library, it makes http requests easy.I will assume $http.post returns a response with data and status, if that's the case (someone could correct me) you could check if response.status === 401 and handle it in whatever way you would like.
I hope this helps, happy coding!

Related

How to remove Id using put method

Indexing.vue;
<template>
<div class="row">
<div class="col-md-12">
<card class="card-plain" card-body-classes="table-full-width" header-classes="row">
<template slot="header" :class="row">
<h3 class="card-title">Indexing</h3>
<base-button type="primary" size="sm" #click="addNewIndexing" class="ml-4">Add Indexing</base-button>
</template>
<div class="row indexing-cards-container pl-5">
<div class="col card " v-for="data in indexingList" :key="data.id">
<div class="row">
<p class="pl-4">{{data.indexing_name}}</p>
</div>
<div class="row">
<p class="pl-4">{{data.indexing_url}}</p>
</div>
<div class="row IndexingImage pb-2 ">
<img :src="data.indexing_image_url" class="rounded mx-auto d-block"/>
</div>
<div class="row">
<div class="col pl-4">
<base-switch
class="mt-2"
v-model="data.is_active"
type="primary"
on-text="Active"
off-text="Inactive"
></base-switch>
</div>
<div class="col">
<base-button type="primary" #click="deleteIndexing(data.id)">Delete</base button>
</div>
</div>
</div>
</div>
</card>
<!-- </div>
</div>
</card> -->
</div>
</div>
</template>
<script>
import { Table, TableColumn } from 'element-ui';
import { BaseSwitch } from 'src/components/index';
export default {
components: {
[Table.name]: Table,
[TableColumn.name]: TableColumn,
BaseSwitch
},
data() {
return {
indexingList: [],
};
},
methods: {
addNewIndexing() {
this.$router.push({path: 'addindexing'})
},
deleteIndexing: function() {
this.api.putData('indexing/'+store.state.journalId, ).then((res)=> {
console.log(res.data)
})
},
getIndexingList: function() {
this.api.getDataModule('indexing/'+store.state.journalId, 'journals/v1/').then((res) => {
console.log(res.data)
this.indexingList = res.data.indexingList
}, (err) => {
console.log(err)
})
},
},
mounted: function() {
this.getIndexingList()
}
};
api.js;
putData (action, data) {
let url = `${BASE_URL}`
url += action + '.json'
return instance.put(url, data)
},
Issue :
We have separately created one component called (AddIndexing.vue) to get user details like indexing_name, indexing_url and indexing_image_url. And we wrote post method to post those user datas to the server. That is working fine. In this component (Indexing.vue) I'm showing those received datas from the server, that is also working fine.
I want to implement the delete function in the deleteIndexing method. We wrote the complete API code in api.js file. But I have mentioned only putData function because my boss told me to implement the delete option by putData api function. So now for action parameter in the putData function I passed "indexing/'+store.state.journalId" as an argument through deleteIndexing function and for data parameter in the putData function
I don't know what to pass as an argument. My boss told me to create a temporary object in the name of indexing_id and he asked me to pass as an second argument because indexing_id is the name of the id for each index in the database. But I don't know how to implement exactly. If I click delete option then that button should delete one index data based on the ID.
This is what I need to do. I can post the data and I can get the data but I don't know how to delete. After filling all the fields user entered the submit option means that data will send to the server, and it will create a new index module to have that data for single customer. If we are filling two customer details it means it will create two indexes separately and those two customer details will show in the "indexing.vue" component.
So now by using delete option I want to delete any user details by the ID.' API code everything was working fine but I don't know how to implement. The I do have one toggle button for active state and inactive state for that also I have to write a code by using putData api function.
How to implement this so I can do based on that.
I want to know how to do active and inactive toggle button function also. I tried some ways but that doesn't work for me. I'm quite beginner here so that I'm struggling a lot to do these API's.

Vue.js 3 and Modal with DaisyUI (Tailwind CSS)

I'm tinkering with DaisyUI within Vue.js 3 (porting an existing Vue+Bootstrap application to Tailwind CSS). I liked the idea that DaisyUI doesn't have JS wizardry going on behind the scenes, yet there seems to be some CSS voodoo magic that is doing things more complicated than they need to be (or at least this is my impression).
From the DaisyUI examples, here's the modal I'm trying to integrate:
<input type="checkbox" id="my-modal" class="modal-toggle"/>
<div class="modal">
<div class="modal-box">
<h3 class="font-bold text-lg">Congratulations random Internet user!</h3>
<p class="py-4">You've been selected for a chance to get one year of subscription to use Wikipedia for free!</p>
<div class="modal-action">
<label for="my-modal" class="btn">Yay!</label>
</div>
</div>
</div>
no javascript, yet the problem is that the modal will come and go according to some obscure logic under the hood that tests the value of the my-modal input checkbox at the top. That's not what I want. I want my modal to come and go based on my v-show="showModal" vue3 reactive logic!
Daisy doesn't seem to make that possible. Or at least not easily. What am I missing?
The modal is controller by the input field, so to open or close the modal just toggle the value of that input:
<template>
<!-- The button to open payment modal -->
<label class="btn" #click="openPaymentModal">open modal</label>
<!-- Put this part before </body> tag -->
<input type="checkbox" v-model="paymentModalInput" id="payment-modal" class="modal-toggle" />
<div class="modal modal-bottom sm:modal-middle">
<div class="modal-box">
<h3 class="font-bold text-lg">Congratulations random Internet user!</h3>
<p class="py-4">You've been selected for a chance to get one year of subscription to use Wikipedia for free!</p>
<div class="modal-action">
<label class="btn" #click="closePaymentModal">Yay!</label>
</div>
</div>
</div>
</template>
<script lang="ts" setup>
const paymentModalInput = ref()
const openPaymentModal = () => {
paymentModalInput.value = true
}
const closePaymentModal = () => {
paymentModalInput.value = false
}
</script>

adding component on add button

i am a absolute beginner in vuejs,i have a feature of adding dynamic input fields on click of a button it will keep on adding rows and keeping in mind the counter should be incrementing also so that i can validate on backend, this is my code so far
<div id="settlement_container" class="container-fluid mt-4">
<div class="card rounded-0 shadow-lg">
<div class="card-body p-0">
<div class="card-header px-2">
<div class="row wow fadeIn">
<div class="col-5">
<h3>Add Store Status</h3>
</div>
</div>
</div>
<form class="custom-form-group" action="{{url('stores/addStoreStatusDB')}}" method="POST">
<div class="form-group col-6">
<label for="exampleInputEmail1">Tax</label>
<input type="text" class="form-control" id="exampleInputEmail1" aria-describedby="emailHelp" name="tax" placeholder="Tax" required>
</div>
<div class="display-inline">
<div class="form-group col-md-6">
<button #click="addstatus" class="btn btn-primary">Add Rows</button>
</div>
</div>
<div class="display-inline">
<div class="form-group col-md-6">
<button type="submit" class="btn btn-primary">Update Tax</button>
</div>
</div>
<dynamic-rows/>
</form>
</div>
</div>
</div>
{{-- Main layout --}}
#push('script')
<script src="{{ asset('js/app_vue.js') }}" ></script>
<script>
Vue.component('dynamic-rows',{
//accept data inside template
props:['counter'],
//accept data inside template
template:"<label for='exampleInputEmail1'>counter</label>"
});
const app = new Vue({
el: '#settlement_container',
data: {
counter:0
},
component:['dynamic-rows'],
methods:{
addstatus:function(e){
appendDiv=""
e.preventDefault();
alert("inside");
}
}
});
</script>
now i can do this in jquery in 5 minutes , but as i am beginner in vuejs i cant developer the sense of it of how to do it, i have a component and i want to repeat the component every time the button is clicked,
here is the fiddle! fiddle
OK, so a lot going on here and I think it may be easier to break down some of the points in isolation for you to play with and learn.
To add inputs, I think it makes more sense to have the values being in an array. Using Vue, you can iterate through that array to let each array element have its own <input/> while also simply adding another array element to add a new input:
<template>
<div>
<div v-for="(tax, index) in taxes" :key="index">
<input v-model="taxes[index]" />
</div>
<button type="number" #click="add">Add</button>
<p>Count: {{taxes.length}}</p>
</div>
</template>
<script>
export default {
data(): {
return {
taxes: [0]
}
},
methods: {
add() {
this.taxes.push(0);
}
}
});
</script>
Now with regards to the counter, I don't know what you mean validate on the backend. You could add a watcher on the taxes array and process changes there? Watchers are used sparingly, with computed properties being much preferred, but they may make sense if you need to be sending data to the backend instead of into the DOM.
The counter prop you registered in your code is not really going to work for the pattern I showed. Generally, props are for parent components to pass data to child components. The preferred pattern when sending data from child to parent is to use $emit. Read more here.

Using vuejs with existing html

I have a list of elements, rendered server-side.
Each item has a button that changes its status.
<div class="list">
<div class="list-item" data-is-published="1" data-item-id="11">
<div class="item-link">Item 1</div>
<form method="post" class="list-item-form">
<div class="vue-mount">
<input type="submit" name="changeStatus" class="button-unpublish" value="Unpublish">
<!-- some hidden fields -->
</div>
</form>
</div>
<div class="list-item" data-is-published="1" data-item-id="12">
<div class="item-link">Item 2</div>
<form method="post" class="list-item-form">
<div class="vue-mount">
<input type="submit" name="changeStatus" class="button-unpublish" value="Unpublish">
<!-- some hidden fields -->
</div>
</form>
</div>
</div>
I'm using the following code to replace each item with a vue component
var ms = document.querySelectorAll('.vue-mount')
for (var i = 0; i < ms.length; i++) {
new Vue({
render: h => h(SubscriptionButton)
}).$mount(ms[i])
}
And on the component i get the values of data-is-published and data-item-id and set them on the component
<template>
<input
type="submit"
#click.prevent="changeStatus()"
:value="isPublished === 1 ? 'Unpublish' : 'Publish'">
</template>
<script>
export default {
....
created: function () {
const el = this.$root.$el.parentNode.parentNode
const status = el.dataset.isPublished
this.isPublished = parseInt(status)
this.itemID = el.dataset.itemID
}
}
I'm doing it this way to ensure that it works even if javascript is disabled, but the part this.$root.$el.parentNode.parentNode doesn't feel right.
Is the way I'm doing it ok? Are there better ways to achieve the same?
EDIT
I can put the data attributes on the element that vue will mount to and access them with this.$root.$el.dataset.
What I'm not sure about is how compliant to the best practices the use of this.$root.$el is.
You could use Element.closest (with a polyfill if IE support is required)
const el = this.$root.$el.closest("*[data-is-published]");
That avoids having to know the hierarchy depth of the DOM.
Info on MDN
Edited to add:
The appropriateness of using this.$root.$el depends on how you plan to structure the code. If the element you're trying to find is guaranteed to be a parent of the Vue application, then starting the search from $root is fine. If that bothers you, though, starting the search from this.$el instead would work.
The less conventional part of your approach is that it effectively creates a separate Vue application for each .vue-mount

vue js navigate to url with question mark

my Vue js project login template click button it redirects to like this
http://localhost:8080/#/login to http://localhost:8080/?#/login
both Url show interface.
1st Url not set the local storage variable 'token'.
2nd Url is set the local storage variable 'token'.
how to solve it?
Login.vue
<template>
<div class="row col-sm-12">
<form>
<div class="form-group">
<label>Email address:</label>
<input type="email" class="form-control" v-model="email">
</div>
<div class="form-group">
<label>Password:</label>
<input type="password" class="form-control" v-model="password">
</div>
<div class="checkbox">
<label><input type="checkbox"> Remember me</label>
</div>
<button #click="login" type="submit" class="btn btn-success">Submit</button>
</form>
</div>
</template>
<script>
export default{
data(){
return{
email:'',
password:''
}
},
methods: {
login(){
var data = {
email:this.email,
password:this.password
}
this.$http.post("api/auth/login",data)
.then(response => {
this.$auth.setToken(response.body.token)
// console.log(response)
})
}
}
}
</script>
The form is getting submitted as the button you have provided in the form has type="submit" which is the default behaviour of a button present inside form even if you do not add the attribute type="button"
So replace the type submit to button o prevent form submission like this:
<button #click="login" type="button" class="btn btn-success">Submit</button>
I just faced the same issue, and the provided solution did not worked for me (Vue 2.5.17).
I had to add a modifier to the #click event to prevent the default behavior:
<button class="btn btn-primary" #click.prevent="login">Login</button>
Changing the button type to button, you disable default form behaviour, like pressing enter and release submit event.
Just add a modifier to the #submit or #reset event to prevent default behaviour:
<b-form #submit.prevent="onSubmit" #reset.prevent="onReset">
In order to keep the default behaviour of submitting the form using the "Enter" key on the keyboard as well, another solution is:
to keep the type = 'submit' on the button
handle the event parameter on the callback and process it with event.preventDefault(); like that:
login(event){
event.preventDefault()
var data = {
email:this.email,
password:this.password
}
...
}
Event.preventDefault() will prevent the default behaviour which is here to submit the form on the current url with the issue we are dealing with here.
See https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault