Problems with scripts in a SPA - javascript

This is the script I am using to create a spa.
const route = (event) => {
event = event || window.event;
event.preventDefault();
window.history.pushState({}, "", event.target.href);
handleLocation();
};
const routes = {
404: "./pages/404.html",
"/": "./pages/index.html",
"/vehicles": "./pages/vehicles.html",
"/services": "./pages/services.html",
"/contact": "./pages/contact.html",
"/financing": "./pages/financing.html",
"/locations": "./pages/locations.html",
};
const handleLocation = async () => {
const path = window.location.pathname;
const route = routes[path] || routes[404];
const html = await fetch(route).then((data) => data.text());
document.getElementById("main-page").innerHTML = html;
};
window.onpopstate = handleLocation;
window.route = route;
handleLocation();
<a href="/financing" onclick="route()" class="mainServices-section">
<div class="main-title">
<h2>Financing</h2>
</div>
<img src="../image/financing-image-colored.svg" alt="">
</a>
It worked correctly for me. But in a section of the web, I need a contact form, which through javascript open the Email app and pre complete the corresponding fields.
<section class="contact inset-wrapper">
<form class="form content" id="form" action="">
<h2 class="title"><strong>let's talk</strong></h2>
<h4 class="subtitle">Do not hesitate to contact us for more information about the vehicle you are interested in.</h4>
<label for="name">
<h4>Name</h4>
</label>
<input required name="name" id="name" type="text" placeholder="Juan Lucas López">
<label for="email">
<h4>Email</h4>
</label>
<input required name="email" id="email" type="email" placeholder="Email">
<label for="message">
<h4>Message</h4>
</label>
<textarea required name="message" placeholder="Message" id="message" cols="30" rows="10"></textarea>
<button class="form-button" type="submit">Send Message</button>
<a id="sendMail" href="mailto:mauriciolaratro#gmail.com" ></a>
</form>
</section>
<script>
const $form = document.querySelector('#form')
const $buttonMailto = document.querySelector('#sendMail')
$form.addEventListener('submit', handleSubmit)
function handleSubmit(event) {
event.preventDefault()
const form = new FormData(this)
$buttonMailto.setAttribute('href', `mailto:mauriciolaratro#gmail.com?subjet=${form.get('name')} ${form.get('email')}&body=${form.get('message')}`)
$buttonMailto.click()
}
</script>
This is the code I use to make the form, which works perfectly, when I use it in another project, however, the previous script interferes with this somehow and I do not know how to fix it (Again I clarify that I am new to js).
What happens is that instead of redirecting to the Email app, it tries to redirect the web to a non-existent link.
I would appreciate any contribution, to be able to solve this in the simplest way, I am trying to make this project, without consuming external API, I know that there are simpler and more efficient ways to make the form functional, but the idea is to do everything with vanilla code and without API

Related

How do I make a div element stay on a same position as before after page reload?

In the following code: https://jsfiddle.net/4gfqnyas/ there is a pure java script function that will move the div <div id="btn"></div> to either left or right (and also change the forms) when either Login or Register button is clicked.
How do I make the div stay in the exact same position as I left, after each reload (or after clicking on the register submit button). I don't want the div to reset back to Login position after reload(or after clicking on the register submit button).
For example: Let's say I click on Register, the div will move to the register and the form will also change to register. Now when I click on Register submit button, the div automatically goes to login and so does the form which makes it impossible for me to display any errors in the register form if the user entered invalid information. I want it to stay on the same form after a reload or after clicking the respective submit buttons.
To fix this, you can use localStorage.
Note that some super old browser don't support localStorage, but that is not a big thing, almost nobody has them.
Let me know if it works. :)
Here is a fixed version (CSS stays the same) :
HTML :
<div class="hero">
<div class="form-box">
<div class="button-box">
<div id="btn"></div>
<button type="button" id="loginButton" class="toggle-btn" onclick="login()">Login</button>
<button type="button" id="registerButton" class="toggle-btn" onclick="register()">Register</button>
</div>
<div class="social-icons">
<img src="images/fb.png">
<img src="images/gp.png">
<img src="images/tw.png">
</div>
<form method="POST" action="val_log.php" id="login" class="input-group">
<input name="Lname" type="text" class="input-field" placeholder="User ID" minlength="4" maxlength="15">
<input name="Lpassword" type="password" class="input-field" placeholder="Enter Password" minlength="5" maxlength="60">
<input name="Lrempass" type="checkbox" class="check-box"><span> Remember Password</span>
<button name="Lsubmit" type="submit" class="submit-btn"> Login </button>
</form>
<form method="POST" action="val_reg.php" id="register" class="input-group">
<input name="Rmail" type="email" class="input-field" placeholder="Email ID" >
<input name="Rname" type="text" class="input-field" placeholder="User ID" minlength="4" maxlength="15">
<input name="Rpassword" type="password" class="input-field" placeholder="Enter Password" minlength="5" maxlength="60">
<input name="REpassword" type="password" class="input-field" placeholder="Re-Enter Password" maxlength="60">
<input name="Rterms" value="selected" type="checkbox" class="check-box" ><span> I agree to the terms & conditions</span>
<button name="Rsubmit" type="submit" class="submit-btn" > Register </button>
</form>
</div>
</div>
JS :
var x = document.getElementById("login");
var y = document.getElementById("register");
var z = document.getElementById("btn");
console.log(x)
function register(){
x.style.left = "-400px";
y.style.left = "50px";
z.style.left = "110px";
}
function login(){
x.style.left = "50px";
y.style.left = "450px";
z.style.left = "0";
}
// Added code
if(localStorage){
if(localStorage.getItem('rememberButtonChoice')){
let getChoice = localStorage.getItem('rememberButtonChoice');
if(getChoice == "loginChoice"){
login();
}
else{
register();
}
}
}
let loginButton = document.getElementById('loginButton');
let registerButton = document.getElementById('registerButton');
loginButton.addEventListener('click', function(){
if(localStorage){
localStorage.setItem("rememberButtonChoice", 'loginChoice');
}
});
registerButton.addEventListener('click', function(){
if(localStorage){
localStorage.setItem("rememberButtonChoice", 'registerChoice');
}
});
When your page reload it loose all the data and set itself to default initialize data. You can make use of localStorage for keeping track of what you have clicked. Something similar to below example.
And you said you want to display error on page reload so in the first place why you want to reload . You can show them without reloading the page as well and if you are using server side form submission than you can use url query params to maintain the click history.
var x = document.getElementById("login");
var y = document.getElementById("register");
var z = document.getElementById("btn");
function register(){
x.style.left = "-400px";
y.style.left = "50px";
z.style.left = "110px";
window.localStorage.setItem("cur_page", "register");
}
function login(){
x.style.left = "50px";
y.style.left = "450px";
z.style.left = "0";
window.localStorage.setItem("cur_page", "login");
}
const cur_page = window.localStorage.getItem("cur_page");
switch (cur_page) {
case "login":
login();
break;
case "register":
register();
break;
default:
login();
}

I keep getting the error "TypeError: Cannot read property 'originStackTrace' of null" in electron I can't seem to find out why?

It happened when I tried to submit a form
Javascript
this.submitForm = (formID) => {
let {ipcRenderer} = require("electron");
const myData = $(`#${formID}`).serialize();
ipcRenderer.sendSync("create-form-data",myData);
};
HTML
<div class="col-9">
<form onsubmit="theTemplate.submitForm('createForm')" id="createForm" action="GET" class="tab-content">
<div id="goal" data-tab-content class="active form-group">
<h1>Goal</h1>
<label>What is your desired outcome?</label>
<input name="goalOne" type="text" class="form-control">
<label>What type of person achieves that outcome?</label>
<input name="goalTwo" type="text" class="form-control" >
googling tends not to produce any results. And i have no idea what "origin stack trace" is.
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="col-9">
<form onsubmit="submitForm(event,'createForm')" id="createForm" action="GET" class="tab-content">
<div id="goal" data-tab-content class="active form-group">
<h1>Goal</h1>
<label>What is your desired outcome?</label>
<input name="goalOne" type="text" class="form-control">
<label>What type of person achieves that outcome?</label>
<input name="goalTwo" type="text" class="form-control" >
<input type='submit'/>
</div>
</form>
</div>
<script>
const formToJSON = elements => [].reduce.call(elements, (data, element) => {
if(element.name) //For skip the named value
data[element.name] = element.value;
return data;
}, {})
const submitForm = (event, formID) => {
event.preventDefault()
//let {ipcRenderer} = require("electron");
const myData= formToJSON(event.target)
console.log(myData)
//ipcRenderer.sendSync("create-form-data",myData);
};
</script>
Please check this code snippet. This is just for extract the form data as your needs. I changed some your html and js code. This will extract from data in JSON format.
Then copy this to your project and enable the ipc part. Then this will send the JSON data to main process successfully.
To know how to communicate between main and renderer process. Please check this answer.
how to communicate between react and electron

Zendesk App Error & Delayed/Failed Webhook Post

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!

how to use autocomplete in angularjs

I have an application with add friend feature, in that feature, user must fill their friend's username in the textbox. this is the html code:
<div content-for="title">
<span>Add Friend</span>
</div>
<form class="form-inline" role="form">
<div class="form-group">
<label class="sr-only" for="exampleInputEmail2">User ID</label>
<input type="text" class="form-control" data-ng-model="add.email" id="exampleInputEmail2" placeholder="User ID">
</div>
<button type="submit" class="btn btn-default" data-ng-click="addfriends()">Add</button>
the interface will be like this
and this is the js code:
// addfriend
$scope.add = {};
$scope.addfriends = function(){
$scope.messages = {
email : $scope.add.email,
userid : $scope.datauser['data']['_id']
};
//event add friend
socket.emit('addfriend',$scope.messages,function(callback){
if(!callback['error']){
$scope.datauser['data']['penddingrequest'].push(callback['data']);
//push pendding request to localstorage user
localStorageService.remove('user');
localStorageService.add('user', $scope.datauser);
$scope.add['email'] = '';
alert('Successfully added friend');
}else{
var msg = callback['error'];
navigator.notification.alert(msg,'','Error Report','Ok');
}
});
};
I want to change this feature little bit, I want to make this textbox showing some suggestion based on the input, like if user input 'a', the textbox will show all user id that start with 'a'. something like twitter's searchbox or instagram searchbox. these user ids is from database.
example searchbox of web instagram
my question is how to change this textbox to be autocomplete but still work like before? thanks very much
There are many ways to do this.
First is this one: You basically create Angular directive for your input.
http://jsfiddle.net/sebmade/swfjT/
Another way to do is to attach onKeyUp event to your input:
<div class="form-group">
<label class="sr-only" for="exampleInputEmail2">User ID</label>
<input type="text" class="form-control" data-ng-model="add.email" id="exampleInputEmail2" placeholder="User ID" ng-keyup="searchFriends()">
<div ng-model="searchFriendsResult" />
</div>
And then, in your controller, you create a searchFriends function that will:
Search your database
Display the result in the view.
Something like this (not a complete code):
$scope.searchFriends = function(value){
// Make Ajax call
var userRes = $resource('/user/:username', {username: '#username'});
userRes.get({username:value})
.$promise.then(function(users) {
$scope.searchFriendsResult = users;
});
};
Use Bootstrap Typeahead
<input type="text" ng-model="asyncSelected"
placeholder="Locations loaded via $http"
uib-typeahead="address for address in getLocation($viewValue)"
typeahead-loading="loadingLocations"
typeahead-no-results="noResults"
class="form-control"/>

Javascript capture HTML form value for Mixpanel

I have a mailchimp form to sign up for my email list, and mixpanel tracking to detect when the form is submitted.
<!-- Begin MailChimp Signup Form -->
<div id="mc_embed_signup"><form id="mc-embedded-subscribe-form" class="validate" action="http://fileoptic.us7.list-manage.com/subscribe/post?u=a1a176055d942403ee4c74a11&id=028333dc80" method="post" name="mc-embedded-subscribe-form" novalidate="" target="_blank"><label for="mce-EMAIL">Subscribe to our mailing list for blog updates:</label>
<input id="mce-EMAIL" class="email" name="EMAIL" required="" type="email" value="" placeholder="email address" />
<!-- real people should not fill this in and expect good things - do not remove this or risk form bot signups-->
<div style="position: absolute; left: -5000px;"><input name="b_a1a176055d942403ee4c74a11_028333dc80" type="text" value="" /></div>
<div class="clear"><input id="mc-embedded-subscribe" class="button" name="subscribe" type="submit" value="Subscribe" /></div>
</form></div>
<!--End mc_embed_signup-->
<script type="text/javascript">
mixpanel.track_forms("#mc-embedded-subscribe-form", "Subscribed to Email List");
</script>
I want to extract the submitted email address from the form and use mixpanel.alias to identify users by their email addresses as they navigate around my site.
What code do I use to extract the email address and call mixpanel.alias with it?
I don't know anything about mixpanel, but here are two ways to get the value of an input and store it in a variable for later use.
With jQuery (I prefer this method):
$('#mc-embedded-subscribe-form').on('submit', function(){
var val = $('input.email').val();
console.log(val); // Use this to test the function
});
Or with plain Javascript. First add this to the form tag in your HTML:
onsubmit="getEmail()"
Then the JS function:
function getEmail() {
var elem = document.getElementById('mce-EMAIL');
var val = elem.value;
console.log(val); // For testing
}
Hope that helps :)

Categories

Resources