Attack all links with an ajax request - javascript

I've been trying create a pure function without jQuery or any other libraries to transform all links on my web app in an ajax request. But as you should know without success.
Can someone tell me where I'm going wrong?
function ajaxify() {
var content = document.getElementsByTagName('body');
var links = document.body.querySelectorAll('a');
[].forEach.call(links, function (link) {
console.log(link);
link.addEventListener('click', function (event) {
var url = link.href;
// Manipulate history
window.history.pushState({}, '', url);
var request = new XMLHttpRequest();
request.open('GET', url, true);
request.onload = function () {
if (request.status == 200) {
content[0].innerHTML = request.responseText;
} else {
alert('Request failed. Returned status of' + request.status);
}
};
request.send();
event.preventDefault();
});
});
}
Edit
One of pages that above script does not works
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" href="img/favicon.png" type="image/png">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<link rel="stylesheet" href="css/authentication.css" type="text/css">
<title>Web APP</title>
</head>
<body>
<div class="wrapper">
<div class="conteiner">
<i class="material-icons custom-arrow-back">arrow_back</i>
<img class="logomarca" src="img/logo.png">
<form name="form" id="form" action="ForgotPassword" method="POST">
<div class="align-form">
<div class="input-conteiner">
<input class="btn-material-style" type="email" id="email" name="email" maxlength="37" value="" pattern="[a-z0-9._%+-]+#[a-z0-9.-]+\.[a-z]{2,3}$" autocomplete="off" required>
<label>Email</label>
<span class="bar"></span>
</div>
<p class="input-subscribe feedback"></p>
<div class="input-subscribe" style="margin-top: 2.4em">
<input class="btn-material-style" id="btn-submit-email" type="submit" name="submit" value="Request new password" style="border: 0">
</div>
</div>
</form>
</div>
</div>
<footer class="footer">
<p><span id="copyleft">©</span> 2016 - <span class="custom-color">Web APP</span></p>
</footer>
<script src="js/authentication.js"></script>
ajaxify();
</script>
</body>
Solved
The only problem is XMLHttpRequest does not let send script as DOM text for security reasons. So I gave up and now I'm using jQuery to do that. :(

querySelectorAll returns a NodeList, in order to add an event listening onto each HTMLElement within the NodeList you'll need to convert the NodeList to an array and loop through it:
var links= content[0].querySelectorAll('a');
[].forEach.call(links, function(link) {
link.addEventListener('click', function(event) { //code });
});
Also, have you tried this:
document.body.querySelectorAll('a');

querySelectorAll('a') will return an array of anchors. You need to iterate over that and then addEventListener to each one.

Related

How can I access DOM elements in Electron Js App?

I am creating a Electron JS webapp with multiple pages for a project.
So far I have created a new page in a different folder for my To Do list feature.
I am running into a problem because when I enter a new task in the form It does not appear when I click submit.
Here is what is supposed to look like after I clicl Add New Task.
[![enter image description here][1]][1]
Here is what my task list looks like when I try to add a new task.
[![enter image description here][2]][2]
Here is my script.js file and html file. I appreciate any help you can give me!
SCRIPT.JS
//Uses ids that was created in html
const form = document.querySelector("#new-task-form");
const input = document.querySelector("#new-task-input");
const list_el = document.querySelector("#tasks");
form.addEventListener('submit', (e) => {
e.preventDefault();//stop the page from refreshing after submitting task
const task = input.value;
//Prevent user from submitting a empty task
if (!task) {
alert("Please enter out the task!");
}
else {
console.log("Success");
return;
}
//Getting task elements to display on page by creating DOM nodes
const task_el = document.createElement("div");
task_el.classList.add("task");
const task_content_el = document.createElement("div");
task_content_el.classList.add("content");
//Set inner value to task
task_actions_el.innerText = task;
task_content_el.appendChild(task_content_el);
task_content_el.appendChild(task_el);
})
})
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>Task List</title>
<link rel="stylesheet" href="styles.css" />
</head>
<div class="datetime">
<div class="time"></div>
<div class="date"></div>
</div>
<body>
<header>
<h1>Task List</h1>
<form id="new-task-form">
<input
type="text"
name="new-task-input"
id="new-task-input"
placeholder="What do you have planned?" />
<input
type="submit"
id="new-task-submit"
value="Add task" />
</form>
</header>
<main>
<section class="task-list">
<h2>Tasks</h2>
<div id="tasks">
<!-- <div class="task">
<div class="content">
<input
type="text"
class="text"
value="A new task"
readonly>
</div>
<div class="actions">
<button class="edit">Edit</button>
<button class="delete">Delete</button>
</div>
</div> -->
</div>
</section>
</main>
<script src="script2.js"></script>
</body>
</html>```
[1]: https://i.stack.imgur.com/aeUhW.png
[2]: https://i.stack.imgur.com/fZYrM.png

Javascript: Unable to access response object and dynamically generated html elements outside the function

I am creating a todo app with Django + Ajax. On load I am loading all the tasks from the db and displaying it and when user clicks on any task i want to mark it as completed. The problems i am facing are
I am unable to access the dynamically generated html elements and
the response object, outside the buildList() function.
When i add event listener to a task (span element with class = title) i am unable to access the task object so i can send it to backend using ajax request and work with it.
todo.js
buildList()
function buildList(){
var wrapper = document.querySelector("#list-wrapper")
wrapper.innerHTML = ''
var xhr = new XMLHttpRequest()
xhr.open('GET', 'http://127.0.0.1:8000/api/task-list/', true)
xhr.onload = function(){
if(this.status==200){
var list = JSON.parse(this.response)
for (var i in list){
var item = `
<div id="data-row-${i}", class="task-wrapper flex-wrapper">
<div style="flex:7">
<span class="title">${list[i].title}</span>
</div>
<div style="flex:1">
<button class="btn btn-sm btn-outline-info edit">Edit</button>
</div>
<div style="flex:1">
<button class="btn btn-sm btn-outline-dark delete">-</button>
</div>
</div>
`
wrapper.innerHTML += item
}
for(i in list){
var tasks = document.querySelectorAll('.title')
tasks.forEach(function(el, list){
el.addEventListener('click',()=>{
console.log(list[i])
})
})
}
}
}
xhr.send()
}
// Addding a Task //
var form = document.querySelector("form")
form.addEventListener('submit', (e)=>{
e.preventDefault()
var title = document.getElementById('title').value
var xhr = new XMLHttpRequest()
xhr.open('POST', 'http://127.0.0.1:8000/api/task-create/', true)
xhr.setRequestHeader('Content-type','application/json')
xhr.setRequestHeader('X-CSRFToken',csrftoken)
xhr.onload = function(){
if(this.status==200){
buildList()
document.getElementById('form').reset()
}
}
xhr.send(JSON.stringify({"title":title}))
}
)
// Marking a task as complete //
function taskComplete(e){
console.log(e.target)
}
index.html
<!DOCTYPE html>
{% load static %}
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
<link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
<link rel="stylesheet" href="{% static 'styles.css' %}">
<title>To Do</title>
</head>
<body>
<div class="container">
<div id="task-container">
<div id="form-wrapper">
<form id="form">
<div class="flex-wrapper">
<div style="flex: 6">
<input id="title" class="form-control" type="text" name="title" placeholder="Add task">
</div>
<div style="flex: 1">
<input id="submit" class="btn" type="submit" >
</div>
</div>
</form>
</div>
<div id="list-wrapper">
</div>
</div>
</div>
</body>
<script src="{% static 'todo.js' %}"></script>
</html>
It looks like when you add the event listener you want to access a variable named list with your fetched data, however in that lexical scope list is being assigned to a callback argument. My suggestion is to rename the callback argument. Then you can access list from the parent scope.
tasks.forEach(function(el, index){

How can I join together values in submit text box into a url API call?

I'm working on a project where you ask the National Parks API for info of parks based on the state abbreviation you enter, as in OR(Oregon) or WA (Washington), etc. I understand how to write it for one value, using template literals, but if I search for more than one state at a time, that when writing the code gets tricky. Im looking to get it to send a call to the api like this:
https://developer.nps.gov/api/v1/parks?stateCode=or%2Cwa
I would be putting "or,wa" into my search box
(Documentation for National Parks API endpoint I'm using:
https://www.nps.gov/subjects/developer/api-documentation.htm#/parks/getPark)
JS:
'use strict'
$(watchForm());
function watchForm(){
$('form').submit(event => {
event.preventDefault();
getParkInfo();
})
}
function getParkInfo(){
var searchBox = $('.inputBox').val();
var numResults = $('.numPerPage').val();
const url = *** How do I write this???***
fetch(url)
.then(response => response.json())
.then(response => {
console.log(response)
displayResults(response);
})
}
function displayResults(response){
$('#results-list').empty();
for(let i = 0; i < response.data.length; i++){
$('#results-list').append(
`<li>
<h3>${response.data[i].fullName}</h3>
<p>${response.data[i].description}</p>
<p>${response.data[i].addresses[i]}</p>
<a href="${response.data[i].directionsUrl}"<p>Address</p></a>
</li>`
)
}
$('#results').removeClass('hidden');
}
HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Search Your Favorite National Parks</title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="container">
<h1>NPS Search Up</h1>
<form>
<input class="inputBox" type="text" required> Search for Park
<br><br>
<input class="numPerPage" type="text" value="10" required> Results per page
<br><br>
<input class="submitBox" type="submit">
</form>
<section id="results" class="hidden">
<h2>Search Results</h2>
<ul id="results-list">
</ul>
</section>
</div>
<script
src="https://code.jquery.com/jquery-3.4.1.js"
integrity="sha256-WpOohJOqMqqyKL9FccASB9O0KwACQJpFTUBLTYOVvVU="
crossorigin="anonymous"></script>
<script src="script.js" async defer></script>
</body>
</html>
Create a new URL instance with your base url.
var url = new URL("https://developer.nps.gov/api/v1/parks");
and then add your query parameters to this URL instance like this
url.searchParams.append('stateCode', searchBox)
url.searchParams.append('limit', numResults);
var joinedSearchEntry = searchBox.split(',').join('%2C')
var url = `https://developer.nps.gov/api/v1/parks?stateCode=${joinedSearchEntry}`
or save a line
var url = `https://developer.nps.gov/api/v1/parks?stateCode=${searchBox.split(',').join('%2C')}`
Let me know if I'm missing something but this should be fine.

Button won't execute Javascript no matter what I do

The following code below is supposed to work as follows, the user is suppose to input a URL, Proxy IP & Proxy port once they click "test" it would grab the response code and replace the html h5 "awaiting test" with the new status code text. I made another version of this same exact script and it worked via client but when you run via electron app and click test button all you get is an error how do I get the button "test" to execute the script? Any help would be greatly appreciated.
Index HTML
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>Simple Tester</title>
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.3.3/semantic.min.css"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.3.3/semantic.min.js"></script>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1 id="header">Simple Tester v1.00</h1>
<div class="content">
<div class="proxytesturls">
<h3 id="url" style="color:#4a04de;" >Site URL:</h3>
<div class="ui large input">
<input type="text" placeholder="Google.com" id="siteurltext">
</div>
</div>
<div class="proxyip">
<h3 id="ip" style="color:#4a04de;">Proxy IP:</h3>
<div class="ui large input" id="proxyinput">
<input type="text" placeholder="1.1.1.1" id="proxyipinput">
</div>
</div>
<div class="proxyport">
<h3 id="port" style="color:#4a04de;">Proxy Port:</h3>
<div class="ui large input">
<input type="text" placeholder="8080" id="proxyportinput">
</div>
</div>
<input type="button" id="btnclick" value="test" onclick="pingProxy();">
<div class="ui raised segment" id="logger">
<h2 style="color:#4a04de;" id="logstext">Logger</h2>
<h5 id="awaitingtest">Awaiting test...</h5>
</div>
</div>
<script src="tester.js" type="text/javascript"></script>
</body>
</html>
tester.js
const request = require('request');
var pingProxy = require('ping-proxy');
var url = document.getElementById("siteurltext").value;
var proxyip = document.getElementById("proxyipinput").value;
var proxyport = document.getElementById("proxyportinput").value;
pingProxy({
proxyHost: proxyip,
proxyPort: proxyport,
proxyTestUrl: 'https://', url
},
function (err, options, statuscode) {
if (statuscode == 407) {
document.getElementById('awaitingtest').innerHTML = ('Status: Proxy Authentication Required');
}
if (statuscode == 200) {
document.getElementById('awaitingtest').innerHTML = ('Status: Valid Proxy!');
}
if (statuscode == 403) {
document.getElementById('awaitingtest').innerHTML = ('Status: Banned Proxy!');
}
if (statuscode == 401) {
document.getElementById('awaitingtest').innerHTML = ('Status: Unauthorized!');
}
}
);
Main.js
const electron = require('electron')
const {app, BrowserWindow} = require('electron')
function createWindow () {
// Create the browser window.
win = new BrowserWindow({width: 800, height: 600})
// and load the index.html of the app.
win.loadFile('index.html')
}
app.on('ready', createWindow)
Errors:
Uncaught TypeError: callback is not a function
at pingProxyAsync (C:\Users***********\proxytester\node_modules\ping-proxy\ping-proxy.js:21)
at HTMLInputElement.onclick (index.html:37)
You may need to concatenate the proxyTestUrl. Replace the comma with a plus sign.
pingProxy({
proxyHost: proxyip,
proxyPort: proxyport,
proxyTestUrl: 'https://' + url
},

how to solve the error " Uncaught TypeError: Cannot call method 'changePage' of undefined"

I am just a beginner in phonegap as well as in javascript so while making a simple app for example, i wrote the following code in the index.html head and my main.js file is not getting included while i run the code. I hope anyone could help me out with the problem.
<!DOCTYPE HTML>
<html>
<head>
<meta name="viewport" content="width=320; user-scalable=no" />
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>Auth Demo</title>
<link rel="stylesheet" href="jquery.mobile/jquery.mobile-1.0rc2.css" type="text/css" charset="utf-8" />
<script type="text/javascript" src="js/jquery-1.7.min.js"></script>
<script type="text/javascript" charset="utf-8" src="cordova-2.7.0.js"></script>
<script src="jquery.mobile/jquery.mobile-1.0rc2.js"></script>
<script type="text/javascript" charset="utf-8" src="assests/www/main.js"></script>
</head>
<body onload="init()">
<div id="loginPage" data-role="page">
<div data-role="header">
<h1>Welcome to Phonegap</h1>
</div>
<div data-role="content">
<form id="loginForm">
<div data-role="fieldcontain" class="ui-hide-label">
<label for="username">Username:</label>
<input type="text" name="username" id="username" value="" placeholder="Username" />
</div>
<div data-role="fieldcontain" class="ui-hide-label">
<label for="password">Password:</label>
<input type="password" name="password" id="password" value="" placeholder="Password" />
</div>
<input type="submit" value="Login" id="submitButton">
</form>
</div>
<script>
$("#loginPage").live("pageinit", function(e) {
checkPreAuth();
});
</script>
</body>
</html>
here is the main.js file code as well.I just want only a particular login id to be valid.
function init() {
document.addEventListener("deviceready", deviceReady, true);
delete init;
}
function checkPreAuth() {
console.log("checkPreAuth");
var form = $("#loginForm");
if(window.localStorage["username"] != undefined && window.localStorage["password"] != undefined) {
$("#username", form).val(window.localStorage["username"]);
$("#password", form).val(window.localStorage["password"]);
navigator.notification.alert("You entered a username and password");
handleLogin();
}
}
function handleLogin() {
var form = $("#loginForm");
//disable the button so we can't resubmit while we wait
$("#submitButton",form).attr("disabled","disabled");
var u = $("#username", form).val();
var p = $("#password", form).val();
var str1 = "burden123";
var str2 = "game1234";
var n1 = str1.localeCompare(u);
var n2 = str1.localeCompare(p);
if(u != '' && p!= '') {
$.post("http://www.coldfusionjedi.com/demos/2011/nov/10/service.cfc? method=login&returnformat=json", {username:u,password:p}, function(res) {
if(n1==0 && n2==0) {
$.mobile.changePage("some.html");
} else {
navigator.notification.alert("Your login failed", function() {});
}
$("#submitButton").removeAttr("disabled");
},"json");
} else {
navigator.notification.alert("You must enter a username and password", function() {});
$("#submitButton").removeAttr("disabled");
}
return false;
}
function deviceReady() {
console.log("deviceReady");
$("#loginPage").on("pageinit",function() {
console.log("pageinit run");
$("#loginForm").on("submit",handleLogin);
checkPreAuth();
});
$.mobile.changePage("#loginPage");
}
<script type="text/javascript" charset="utf-8" src="assests/www/main.js"></script>
this line in your code should be changed to
<script type="text/javascript" charset="utf-8" src="main.js"></script>
as main js is in same folder of index.html page.
<script type="text/javascript" charset="utf-8" src="assests/www/main.js"></script>
in above check you path in src also try putting it above and place a alert at top in main.js
check if all scripts above this is including or not.
Thanks

Categories