After get API call with a string input attached, I get the result alright. The problem I have is incorporating it to my frontend. I have tried a lot of solutions that I found online but nothing working and cannot understand. So far I have done this:
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script type = text/javascript src = https://cdn.jsdelivr.net/npm/vue/dist/vue.min.js></script>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/vue.resource/1.0.3/vue-resource.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
</head>
<body>
<form action="http://127.0.0.1:1880/" target="_self">
<label for="request"><strong>Please insert the input here:</strong></label><br>
<input type="text" id="request" name="input"><br>
<button v-on:click="getOverview($event)">Submit</button>
</form>
<h1 id="results" v-for="overview in overview">
{{overview}}
</h1>
<script type = text/javascript >
new Vue({
el: "#results",
data() {
return {
overview: []
}
},
methods: {
async getOverview(event) {
try {
const {data:{json:{sub_regions}}} = await axios.get('http://127.0.0.1:1880/');
console.log('results data', sub_regions);
this.overview = sub_regions;
}
catch (error) {
console.log(error);
return [];
}
}
},
created(){
this.getOverview()
}
})
</script>
</body>
</html>
I am a bit lost with javascript as I am new to it, all kinds of help are welcome,
Thank you in advance! :)
EDIT: the file I get from the API is JSON
Looks as though you are trying to call a method outsides of the vue app itself.
You have the el: "results" but you are trying to invoke a vue method within your button outside of its context.
Try something like this:
<div id="results">
<form action="http://127.0.0.1:1880/" target="_self">
<label for="request"><strong>Please insert the input here:</strong></label><br>
<input type="text" id="request" name="input"><br>
<button v-on:click="getOverview($event)">Submit</button>
</form>
<h1 v-for="overview in overview">
{{overview}}
</h1>
</div>
Some problems here...
You're including Vue twice (https://cdn.jsdelivr.net/npm/vue/dist/vue.min.js and https://unpkg.com/vue/dist/vue.js). Don't do that
You cannot use a v-for directive on your root Vue element
Your form is outside your Vue root so you won't be able to use v-on
Your submit button will submit the form normally. There's nothing stopping that from happening
Your input value is never used. You should try binding it to a data property
Change your HTML to
<div id="results">
<form action="http://127.0.0.1:1880/" #submit.prevent="getOverview">
<label for="request">
<strong>Please insert the input here:</strong>
</label>
<br>
<input type="text" id="request" name="input" v-model="input">
<br>
<button type="submit">Submit</button>
</form>
<h1 v-for="item in overview">
{{ item }}
</h1>
</div>
and in your JS, replace data with
data: () => ({
overview: [],
input: ''
})
Then you can use this.input if you ever need to get the value the user types in.
Here's an example using a placeholder API
new Vue({
el: "#results",
data: () => ({
overview: [],
input: ''
}),
methods: {
async getOverview ($event) {
let url = 'https://jsonplaceholder.typicode.com/users'
if (this.input) {
url += `/${encodeURIComponent(this.input)}`
}
try {
const { data: sub_regions } = await axios.get(url)
console.log('results data', sub_regions);
this.overview = Array.isArray(sub_regions) ? sub_regions : [ sub_regions ]
} catch (error) {
console.log(error);
this.overview = []
}
}
},
created() {
this.getOverview()
}
})
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<div id="results">
<form action="http://127.0.0.1:1880/" #submit.prevent="getOverview">
<label for="request">
<strong>Please insert the user ID here:</strong>
</label>
<br>
<input type="number" id="request" name="input" v-model.number="input">
<br>
<button type="submit">Submit</button>
</form>
<h1 v-for="item in overview">
{{ item.name }}
</h1>
</div>
Other notes:
Avoid using the same variable name for your array and iterable.
Bad - v-for="overview in overview"
Good - v-for="thing in things"
VueResource is long dead. Avoid using it or at least update to the latest version (1.5.1)
Related
I am having trouble being able to add user input data. I can get it working when I add in the data myself all the users show up in the console in the array. For people 1-3 I would like them to enter their name and favorite color but I can't seem to be able to store it or at least have it come up in the console. I did remove person 2 and 3 from the array so I can test it easier and quicker. if you were to take the
user: document.getElementById('name').value,
color: document.getElementById('color').value,
and all the comments it would work and show up in console how i want it to but cant seem to do user data. Sorry if this is confusing i am a new to javascript.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<form>
<div class="formBox">
<label for="name">Name</label>
<input type="text" id="name" placeholder="Name"/>
</div>
<div class="formBox">
<label for="color">Favorite color</label>
<input type="text" id="color" placeholder="Color"/>
</div>
<div class="formBox">
<button id="btn">Click to Add</button>
</div>
<div id="msg">
<pre></pre>
</div>
</form>
<script >
const person1 = {
user: document.getElementById('name').value,
color: document.getElementById('color').value,
/* user: "Sarah",
color: "Yellow",*/
};
/* const person2 = {
user: "Aaron",
color: "Yellow"
};
const person3 = {
user: "Sarah",
color: "Green",
};
*/
array = [person1]
sort = array.sort(function(a, b){
if(a.user < b.user) { return -1; }
if(a.user > b.user) { return 1; }
return 0;
})
console.log(sort)
</script>
</body>
</html>
I give you a code matches with your purpose but I recommend you found a course that builds a complete project, that can helps you to understands how to use basics to build some complex things.
// Declare Part
const users = [];
const form = document.getElementById("myForm");
// 1. Add Event Listener to our form
// when form submits the function get called
form.addEventListener("submit", (event) => {
// Stop form from refreshing the page
event.preventDefault();
// Get name field value
const userName = document.getElementById("name").value;
// Get color field value
const userColor = document.getElementById("color").value;
// Create new person
const person = {
user: userName,
color: userColor,
};
// Store new person (Add new person to array of users)
users.push(person);
// Now we sort our users
users.sort(function(a, b) {
if (a.user < b.user) {
return -1;
}
if (a.user > b.user) {
return 1;
}
return 0;
});
// See the result
console.log(users);
});
<form id="myForm">
<div class="formBox">
<label for="name">Name</label>
<input type="text" id="name" placeholder="Name" />
</div>
<div class="formBox">
<label for="color">Favorite color</label>
<input type="text" id="color" placeholder="Color" />
</div>
<div class="formBox">
<button id="btn">Click to Add</button>
</div>
<div id="msg">
<pre></pre>
</div>
</form>
The javascript in your code is running start to finish every time you refresh the page and when you're clicking the click to add button, you're submitting the form, which automatically refreshes the page. You can make a couple of tweaks in your code to fix this...
You can add type="button" as a property of your button to tell the browser that this is a button and not a way of submitting your form. By doing this your page wont refresh when you click it.
You want your javascript code to run when you click the button, not when the page loads. To do this you need to wrap it in a function and add an onclick handler to your button that executes the function when the button is clicked. You'll notice the array is initialised outside the function, this is because we do want the array to be initialised when you load the page, and not when the button is clicked, otherwise we would be overwriting the array every time we added something to it.
const array = []
const addUser = () => {
const person1 = {
user: document.getElementById('name').value,
color: document.getElementById('color').value,
};
array.push(person1)
sort = array.sort(function(a, b){
if(a.user < b.user) { return -1; }
if(a.user > b.user) { return 1; }
return 0;
})
console.log(sort)
}
<form>
<div class="formBox">
<label for="name">Name</label>
<input type="text" id="name" placeholder="Name"/>
</div>
<div class="formBox">
<label for="color">Favorite color</label>
<input type="text" id="color" placeholder="Color"/>
</div>
<div class="formBox">
<button
id="btn"
type="button"
onclick="addUser(this)"
>Click to Add</button>
</div>
<div id="msg">
<pre></pre>
</div>
</form>
I am building a Zendesk app that will post a variety of information to a webhook. Currently, I am running into two issues. The client.invoke() function says it is not a function in the console when the send email button is pressed. Additionally, sometimes the after the button is pressed, the app will successfully post to the webhook, other times it won't post at all. I cannot narrow down what is causing the discrepancies on when it posts. I'm unsure if this is related to the app I've built or an issue interacting with Zendesk.
Here is the app:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link href="https://cdn.jsdelivr.net/bootstrap/2.3.2/css/bootstrap.min.css" rel="stylesheet">
<link href="main.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/jquery/3.2.1/jquery.min.js"></script>
<script type="text/javascript" src="https://assets.zendesk.com/apps/sdk/2.0/zaf_sdk.js"></script>
<script src="https://cdn.jsdelivr.net/handlebarsjs/4.0.8/handlebars.min.js"></script>
</head>
<body>
<script>
var client = ZAFClient.init();
client.invoke('resize', { width: '100%', height: '450px' });
client.get('ticket.brand.subdomain').then(
function(data) {
var subdomain = data['ticket.brand.subdomain'];
console.log('Zendesk Subdomain is ' + subdomain);
document.getElementById('subdomainform').value = subdomain;
}
);
client.get('ticket.organization.id').then(
function(data) {
var org_id = data['ticket.organization.id'];
console.log('Org id is ' + org_id);
document.getElementById('orgidform').value = org_id;
}
);
</script>
<form name="submissionForm">
<div class="formBox">
<label for="title">First Name</label>
<input type="text" id="firstName" placeholder="First Name"/>
</div>
<div class="formBox">
<label for="title">Last Name</label>
<input type="text" id="lastName" placeholder="Last Name"/>
</div>
<div class="formBox">
<label for="title">Email</label>
<input type="text" id="email" placeholder="Email"/>
</div>
<div class="formBox">
<select id="rescom">
<option value="residential">Residential</option>
<option value="commercial">Commercial</option>
</select>
</div>
<div class="formBox">
<button id="btn">Click to Send Email</button>
</div>
<div><p id="explain">The fields below are ready-only and required for submission. If you don't see them, please refresh the app.</p></div>
<div class="formBox">
<input type="text" id="subdomainform" readonly="readonly"/>
</div>
<div class="formBox">
<input type="text" id="orgidform" readonly="readonly"/>
</div>
</form>
<script>
let content = [];
const addDay1 = (ev)=>{
let information = {
id: Date.now(),
firstName: document.getElementById('firstName').value,
lastName: document.getElementById('lastName').value,
email: document.getElementById('email').value,
subdomain: document.getElementById('subdomainform').value,
orgid: document.getElementById('orgidform').value,
rescom: document.getElementById('rescom').value
}
content.push(content);
document.forms[0].reset();
const Url ='{PLACEHOLDER}';
$.ajax({
url: "{WEBHOOK URL}",
type: "POST",
dataType: 'json',
data: {information},
complete: function(){alert("Failure")}
});
}
document.addEventListener('DOMContentLoaded', ()=>{
document.getElementById('btn').addEventListener('click', addDay1);
});
</script>
</body>
</html>
What am I missing? Appreciate any and all help that can be provided.
This was solved my a community manager from Zendesk. See post below:
Make sure ZAFClient is fully registered before attempting to do
subsequent ZAFClient methods. Something like:
client.on('app.registered', e => {
client.get('ticket.brand.subdomain').then(
function(data) {
var subdomain = data['ticket.brand.subdomain'];
console.log('Zendesk Subdomain is ' + subdomain);
document.getElementById('subdomainform').value = subdomain;
}
);
client.get('ticket.organization').then(
function(data) {
var org_id = data['ticket.organization.id'];
console.log('Org id is ' + org_id);
document.getElementById('orgidform').value = org_id;
}
);
}) The "not a function in the console" error is caused from the app's HTML page being resubmitted again when you click the button. In
Zendesk Apps framework, the connection from the app (using
ZAFClient.init()) to the main agent window is done through parameters
that are passed to the app when the framework first loads it. You can
see this in your browser's Network tab if you look for something like
"iframe.html?origin=https%3A%2F%2Fyour_subdomain.zendesk.com&app_guid=ff7133010-abff-4f1c-a7bf-ff7133fff7133"
-- the origin and app_guid params are needed to make the connection. When you resubmit the page, those parameters no longer are passed on
the new page reload and the new call to ZAFClient.init() doesn't
successfully initialize. Thus leading the error when the now invalid
'client' object is attempting to be used to call 'invoke'. You have to
treat these app pages like single-page apps.
Phew! All that said -- you can still use HTML functionality,
just don't have it resubmit the entire page when the button is
pressed. You can do this by adding type="button" to the button tag.
Click to Send Email
See also: HTML button to NOT submit form
Hope this gets you on your way!
In my code I create a lot of elements dynamicly on serverside, store the html of these elements in a javascript object,remove them and dynamicly/conditionally add them to different parts of the page.
For one particular element I want a data binding, such that I can refer to that binding in a v-if directive. However, if I add the v-bind on the server side, it gets lost after I copy the html.
Since I do only add the elements in my javascript code, I can not register the v-bind in my template. Neither can I provide the content in a component, since it is not static but relys on the input from the server.
How do I register the binding?
Sample Code:
Dynamicly generated form elements (server side):
<div id="archive" style="display: none;">
<div><input type="text" name="purpose" v-bind:value="purpose" id="id_purpose"></div> <!-- v-bind has no effect -->
<div><input type="text" name="purpose__iexact" id="id_purpose__iexact"></div>
<div><input type="text" name="purpose__contains" id="id_purpose__contains"></div>
<div><input type="text" name="purpose__icontains" id="id_purpose__icontains"></div>
<div><input type="text" name="purpose__in" id="id_purpose__in"></div>
...
</div>
Code to copy the html:
var input = {};
var archive = document.getElementById('archive');
for(var i = 0; i < archive.children.length; i++) {
var div = archive.children[i];
input[div.firstChild.name] = div.innerHTML
}
archive.parentNode.removeChild(archive);
Template code to display a certain input field dynamicly (client side):
<div class="inline" v-html="input[SOME CONDITIONAL COMPUTATIONS]"></div>
the correct way to rendering vue scene is:
<template>
<div>
<input type="button" value="Add new item" #click="addItem">
<hr>
<div v-for="(item,index) in data" :key="index">
<span v-html="item.html"></span>
<h3>Model data {{item.model}}</h3>
<input type="text" v-model="item.model">
<input type="button" value="Click me" #click="item.action(index)">
<input v-if="item.show" type="button" value="Remove me" #click="removeItem(index)">
</br>
</div>
</div>
</template>
<script>
export default {
data() {
return {
item: {
model: "",
show:true,
html: "<b>mydata html</b>",
action: function(index) {
console.log(`Clicked ${index} element.`);
}
},
data: [
{
model: "",
show:false,
html: "<b>mydata html</b>",
action: function(index) {
alert(`Clicked ${index} element.`);
console.log(`Clicked ${index} element.`);
}
},
{
model: "",
show:true,
html: "<b>mydata html</b>",
action: function(index) {
alert(`Clicked ${index} element.`);
console.log(`Clicked ${index} element.`);
}
}
]
};
},
methods: {
addItem() {
let item = Object.assign({}, this.item); // other way dublicating Observer
this.data.push(item);
},
removeItem(index){
this.data.splice(index,1)
}
}
};
</script>
You can add a show boolean prop to item object and v-if="" atribut to div to hide it.
I hope this example will help you.
<template>
<div>
<form>
<p ref="uploadCvText" #click="openUploadFileDialogueCV(this.$refs.input_file_cv)">+ Upload Your CV (*)</p>
<input ref="input_file_cv" type="file" value="" name="input_file_cv" #change="handleCvUpload()">
</form>
</div>
</template>
<script>
methods: {
openUploadFileDialogueCV(e) {
e.click();
}
}
</script>
the problem is that (ref) is not allowed to be used in template ! so how can i
refer to html element and let openUploadFileDialogueCV() function
works correctly ?
Just don't use this in template, use #click="openUploadFileDialogueCV($refs.input_file_cv) instead
I'm new to meteor and trying to make a simple blog application. But my insert function doesn't seem to be working properly. Here's my code.
This is my template
<template name="addpost">
<div class="container">
<h1> Add New Post</h1>
<form class="new-post">
<label class="title">
Title:
<input type="text" name="title" placeholder="Type to add new tasks" />
</label>
<label class="post-content">
Write here:
<input type="text" name="body" placeholder="Type to add new tasks" />
<button class="add-post">Add Post</button>
</label>
</form>
</div>
</template>
JS file content
Posts = new Meteor.Collection("posts");
if (Meteor.isClient) {
Template.addpost.events({
"submit .new-post": function(event){
var title = event.target.title.value;
var body = event.target.body.value;
Meteor.call("addPost", title, body);
}
});
}
Meteor.methods({
addPost: function(title, body){
Posts.insert({
title: title,
body: body,
createdAt : new Date()
});
}
});
I have not removed autopublish and insecure packages. And below is the mongoDB query output.
By default, when you submit a form it makes another HTTP request which will reload the page and halt whatever meteor was doing. To avoid this, you need to prevent the default action:
Template.addpost.events({
submit: function(event) {
event.preventDefault();
// the rest of your code goes here
}
});
Aside from that, your code worked correctly for me. You can verify it with: Posts.find().fetch() in either the web console or via meteor shell.