Nightmare JS cannot get Button Element - javascript

I am trying to do some simple nightmare.js.
The problem is that I cannot get one specific button.
const Nightmare = require('nightmare')
const nightmare = Nightmare({ show: true })
nightmare
.goto('https://account.parkmobile.com/login')
.wait(3000)
.type('#username', '')
.wait(2000)
.type('#login_password', '')
.wait(2000)
.evaluate(function() {
let loginBtns = document.getElementsByClassName("btn btn-primary btn-block")
for (let loginBtn of loginBtns) loginBtn.click()
})
.wait(4000)
.evaluate(function() {
let newSessions = document.getElementsByClassName("btn btn-primary add-button close-panel-margin ng-star-inserted")
for (let newSession of newSessions) newSession.click()
})
.wait(4000)
.type("#zone > div > input", "21789")
.wait(3000)
.click("#zone > div > div > div > div")
.wait(4000)
.evaluate(function() {
let newStarts= document.getElementsByClassName("btn btn-primary btn-block ng-tns-c36-26")
for (let newStart of newStarts) newStart.click()
})
.wait(3000)
.end()
.then(console.log)
.catch(error => {
console.error('Search failed:', error)
})
I am talking about this line:
.evaluate(function() {
let newStarts= document.getElementsByClassName("btn btn-primary btn-block ng-tns-c36-26")
for (let newStart of newStarts) newStart.click()
})
Could it be that it has to do something with this text:
_ngcontent-uei-c203
after the <button
Maybe someone can help clicking on "Start this parking" button. :)
Thanks for the help!

Related

why check is undefined in my code? 'pure js'

** I want when to click on the active button if the checkbox is checked to add filtered class in HTML element but it doesn't work and give me an undefined error in this line check.parentElement.classList.add("filtered"); **
<ul class="ul-list"></ul>
</section>
</main>
<footer class="footer">
<button class="all footer-btn">All</button>
<button class="active footer-btn">Active</button>
<button class="complete footer-btn">Complete</button>
</footer>
let check = document.querySelectorAll(".complete-txt");
let complete_btn = document.querySelector(".complete");
let active_btn = document.querySelector(".active");
let all_btn = document.querySelector(".all");
let edit_list = document.querySelector(".edit-list");
let main_text = document.querySelector(".main-text");
let list_item = document.querySelector(".list-item");
let footer = document.querySelector(".footer");
const generateTemplate = (todo) => {
const html = `
<li class="list-item">
<input type="checkbox" class="complete-txt" name="" id="check"><span class="main-text">${todo}</span><div class="edit-list"></div><div class="delete-list"></div>
</li>
`;
list.innerHTML += html;
};
// add todos event
addForm.addEventListener("submit", (e) => {
e.preventDefault();
const todo = addForm.add.value.trim();
if (todo.length) {
generateTemplate(todo);
addForm.reset();
}
});
active_btn.addEventListener("click", function () {
let check_id = document.querySelector(".complete-txt");
// check.forEach(function () {
debugger;
if (check.checked !== "true") {
check.parentElement.classList.add("filtered");
console.log("hi");
}
// });
// console.log("hi");
console.log("hi");
// console.log(check.checked.value);
});
if the larger document fixes all other inconcistencies you should be able to change the eventlistener to
active_btn.addEventListener("click", function () {
let check_id = document.querySelector(".complete-txt");
if (check_id.checked !== "true") {
check_id.parentElement.classList.add("filtered");
}
});
BUT!!! this will not "fix" all of your errors, like defining let check before the checkbox is created with generateTemplate

Posting Comment to Backend

Attempting to post a comment on a portrait correctly using a JavasScript Frontend with a Rails backend. The comment is posting, however on the frontend its showing it incorrectly. When the user creates a comment, the comment does show however it always shows on the first portrait comment section when its posted. However once you re-fresh the page it shows under the correct portrait. I assume this is something to do with the way I am posting it to my backend in my POST. This is what my current portraits code looks like used to build the portraits...
const buildPortrait = (portrait) => {
let div = document.createElement('div')
div.className = 'card'
div.id = portrait.id
div.innerHTML = `
<i class="far fa-window-close fa-1x" id="delete"></i>
<img src= ${portrait.attributes.img_url} class="profile" alt="Avatar" >
<div class="container">
<h5 class='description'>Caption: ${portrait.attributes.description}</h5>
<form data-portrait=${portrait.id} class="comment-form">
<input
class="comment-input"
type="text"
name="comment"
placeholder="Add a comment..."
/>
<button class="comment-button" type="submit">Post</button>
</form>
<div class="likes-section">
<button class="like-button"> ${portrait.attributes.like} likes ♥</button>
</div>
</div>
`
cardContainer.appendChild(div)
listenForLikes(portrait)
commentSection(portrait)
listenForComment(portrait)
listenForEditComment(portrait)
listenForDelete(portrait)
}
Below is the code I am attempting to use to build the comment and the have the POST correctly...
//create comments
function commentSection(portrait){
const newUl = document.createElement('ul')
newUl.className = 'comments'
portrait.attributes.comments.map(comment => {
let li = document.createElement('li')
li.textContent = comment.content
newUl.appendChild(li)
const editBtn = document.createElement('button')
// editBtn.className = 'edit-button'
editBtn.dataset.commentId = comment.id
editBtn.innerHTML = `
<i class="fas fa-pen-square"></i>`
// li.appendChild(editBtn)
})
const currentCard= document.getElementById(portrait.id)
const description = currentCard.querySelector('.description')
description.after(newUl)
}
//event listen for comments
function listenForComment(portrait){
const portraitComment = document.getElementById(portrait.id)
const commentForm = portraitComment.querySelector('.comment-form')
commentForm.addEventListener('submit', (e)=> {
e.preventDefault()
postComments(e)
commentForm.reset()
})
}
//fetch comments
function postComments(e){
console.log()
data = {
content: e.target[0].value,
portrait_id: e.target.dataset.portrait
}
console.log(data)
fetch(`http://localhost:3000/comments`,{
method: 'POST',
headers: {
'Content-Type': 'application/json',
Accept: "application/json"
},
body: JSON.stringify(data)
})
.then(res => res.json())
.then(json => {
const ul = document.querySelector('ul')
const li = document.createElement('li')
li.textContent = json["data"].attributes.content
console.log(ul)
ul.appendChild(li)
})
}
Any advice is gratefully appreciated!!
Thanks!!

How do i increase value by 1 value inside span inside button

My button :
<button class="btn btn-success btn-sm mr-1 mark-complete-btn " id="<%=photo.id %>">
Like <span id="likes-count-<%=photo.id %>"><%= photo.likes_count %></button>
I am using : document.getElementById('likes-count-' + currentElement).textContent++;
But above code giving nothing. I want to be the above span value increase by one. I did any mistake?
You need to update the text of the element. You are also trying to increase a string, not a number. Thirdly, this is not going to update the value on your server, so hopefully you are makings some sort of Ajax/Fetch call to update the backend.
function updateServer(id) {
/*
const data = {
liked: id
};
fetch('https://example.com/profile', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data),
})
.then(response => response.json())
.then(data => {
console.log('Success:', data);
})
.catch((error) => {
console.error('Error:', error);
});
*/
}
document.querySelectorAll('.mark-complete-btn').forEach(function(btn) {
function update() {
var span = btn.querySelector("span");
var cnt = Number(span.textContent) + 1;
span.textContent = cnt;
updateServer(btn.id);
btn.childNodes[0].nodeValue = "Liked ";
btn.removeEventListener("click", update);
}
btn.addEventListener("click", update);
});
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet" />
<button class="btn btn-success btn-sm mr-1 mark-complete-btn" id="photo1">
Like <span id="likes-count-photo1>">1</span></button>
<button class="btn btn-success btn-sm mr-1 mark-complete-btn" id="photo2">
Like <span id="likes-count-photo2>">3</span></button>
I think you are looking for something like this:
(function(window) {
all_btns = document.getElementsByTagName("button");
for(i=0; i< all_btns.length; i++){
btn = all_btns[i];
btn.onclick = function(){
this.childNodes[1].textContent++;
}
}
})(this);
<button id="123">
Like <span id="likes-count">8</span>
</button>
https://jsfiddle.net/yo687rvx/1/

Remove event before when run child event

In this example, when I click button so has two alert, how remove event divExamp when click button and just has one alert.
<button id="abc">sdfsdfsdf</button>
<div id="example">zczczxczxc</div>
<script>
let divExamp = document.querySelector('#example');
document.querySelector('#abc').addEventListener('click', async e =>{
divExamp.insertAdjacentHTML('beforeend', '<button id="click">click</button>');
document.querySelector('#click').addEventListener('click', async e =>{
alert('click!');
})
})
</script>
let divExamp = document.querySelector('#example');
let abc = document.querySelector('#abc');
abc.addEventListener('click', temp);
function temp(e) {
abc.removeEventListener('click', temp);
divExamp.insertAdjacentHTML('beforeend', '<button id="click">click</button>');
document.querySelector('#click').addEventListener('click', e => {
alert('click!');
});
}
<button id="abc">sdfsdfsdf</button>
<div id="example">zczczxczxc</div>

Passing onclick event in template literal

I'm trying to pass url through onclick event, its not working.
there is <body onload="displayBookmarks()"> to initialise displayBookmarks function as soon as the page gets loaded
function deleteBookmark(url){
alert(url);
};
function displayBookmarks(){
bookmarksResults.innerHTML = "";
for (let a in bookmarks){
let name = bookmarks[a].name;
let url = bookmarks[a].url;
bookmarksResults.innerHTML += `<div class="well"> <h3> ${name} <a class="btn btn-default" target="_blank" href=${url} >Visit</a> <a onclick=${deleteBookmark(url)} class="btn btn-danger" >Delete</a></h3></div>`
}
}
The main problem is onclick=${deleteBookmark(url)}
As soon as the page loads it starts displaying the url but I want to to be shown only when delete button is pressed.
I've found that there is another way to do this with encapsulation. I don't know if I would recommend doing it like this at all but since you've asked the question.
const app = document.getElementById("app");
const button = ((app) => {
let _url;
const _log = (data) => {
console.log(data);
}
let _content = `<button onclick="(${_log})('${_url}')">test</button>`;
const _setContent = () => {
_content = `<button onclick="(${_log})('${_url}')">test</button>`;
}
const _setUrl = (url) => {
_url = url;
}
return {
setUrl: (url) => {
_setUrl(url);
_setContent();
},
render: () => {
app.innerHTML = _content;
}
}
})(app)
const url = 'www.something.com';
button.setUrl(url);
button.render();
<section id="app">...</section>
const markUp = `
<button onclick="myFunction()">Click me</button>
`;
document.body.innerHTML = markUp;
window.myFunction = () => {
console.log('Button clicked');
};

Categories

Resources