I am trying to assign a boolean to change when a class .ion-ios-pause is clicked. And if it is clicked then it should not run the player.skipTo(player.playlist.length-1); line afterwards. However, the invalid variable is always false (besides when i console.log inside the .click(). I thought that since I declared my variable outside the scope of both statements, that the variable should change states outside of the scope of the .click() function as well, but it doesn't. What am I missing?
function clickSongPlay(artist, title, url, imageURL) {
//debugger;
player.playlist.push(
{
title: title,
artist: artist,
file: url,
imageURL: imageURL,
howl: null
}
);
////HERE IS THE CODE SNIPPET/////
var invalid = false;
$(".ion-ios-pause").click(function () {
player.pause();
invalid = true;
});
if (invalid === false) {
player.skipTo(player.playlist.length - 1);
}
//////END RELEVANT CODE SNIPPET///////
}
HTML:
<div><i class="icon ion-ios-play music-control" onclick="clickSongPlay('#song.Artist','#song.Title','#song.URL','#song.Album.ImageURL', this);"></i></div>
I am not sure what you are trying to achieve but when your main function is called clickSongPlay it sets the variable invalid to false attaches the click() listener to $(".ion-ios-pause") but it does not execute it at this point and then it checks the if statement.
Your if statement is only executed when the main function is called and not after a click and whenever you call that function it will reset the value to false, so you will always end up with the if statement executing.
The easiest fix is to get the var invalid = false; and place it outside of your function. You might also want to put the whole click listener outside of the function scope.
your problem is that after click event has fired you should do your validation check too. you can do some thing like code bellow:
var invalid = false;
function clickSongPlay(artist, title, url, imageURL) {
//debugger;
player.playlist.push(
{
title: title,
artist: artist,
file: url,
imageURL: imageURL,
howl: null
}
);
$(".ion-ios-pause").click(function () {
player.pause();
invalid = true;
validationCheck();
});
validationCheck();
}
function validationCheck()
{
if (invalid === false)
{
player.skipTo(player.playlist.length - 1);
}
}
Related
guys are am having an issue that should be easy but it doesn't seem like anything is working, I have a simple site that I am trying to register an on click for a table row with. The content is dynamically generated from Javascript and gets it from firebase :
var tableRow = document.createElement('tr');
var tableData = document.createElement('td');
tableData.addEventListener("click", draftRider(doc.data().name))
tableData.innerHTML = "<p class='test'> click me </p>"
tableRow.appendChild(tableData);
document.getElementById("draftingStartBlock").appendChild(tableRow);
I have tried an escaped string, onclick on event and now add event listener. Also when the page first load the function appears to fire.
Here is the function I want to call on click :
function draftRider(riderName) {
showSnackBar(riderName)
if (playersTurn) {
var riderQuery = firebase.firestore().collection("leagues").doc(userLeagueId).collection("rider_list")
riderQuery.get().then(function (doc) {
if (doc.exists) {
var currentRiderName = doc.data().rider_name;
var draftedBy = doc.data().drafted_by;
if (riderName === currentRiderName && draftedBy === "") {
database.collection("leagues")
.doc(userLeagueId)
.collection("rider_list")
.doc(doc.id)
.update("Drafted_By", userId)
setNextPlayerAsPickingPlayer()
}
} else {
// doc.data() will be undefined in this case
console.log("No such document!");
}
}).catch(function (error) {
console.log("Error getting document:", error);
});
} else {
showSnackBar("Its currently not your turn");
}
}
This line in your code is the issue:
tableData.addEventListener("click", draftRider(doc.data().name))
addEventListener is a function that expects an event type as the first argument and a function as the second. In your case, you aren't passing the function as the second argument, you are actually calling the function and passing the value it returns (undefined in this case) as the second argument. Which is why you are seeing your function called once when the page loads.
Based on the code in your post, you could solve it with:
tableData.addEventListener("click", function() {
draftRider(doc.data().name)
})
it('AddnewSupplier1',function() {
var i =0;
var isenabled=false;
var count=0;
element(by.css("path[d*='M20.995']")).click();
element(by.cssContainingText('div[class="mat-step-text-label ng-star-inserted"]','Supplier Maintenance')).getText().then(function(text) {
console.log(text);
}).then(function() {
do {
if (i>0) {
console.log("Clicking on NextButton");
element(by.css("button[class='mat-paginator-navigation-next mat-icon-button']")).click();
}
(element.all(by.xpath("//table[#class='mat-table']/tbody/tr/td[1]"))).each(function(webelement) {
webelement.getText().then(function(text) {
if(text=="IACE") {
count++;
console.log("Element is found");
//break;
}
});
});
var nextbutton = element(by.css("button[aria-label='Next page']"));
nextbutton.isEnabled().then(function(isEnabled) {
var isenabled=isEnabled;
console.log(isenabled);
}).then(function() {
i++;
console.log(i);
});
}
while(isenabled);
})
});
I have to check if Supplier ID "IACE" is present in the table.
For that I have written code taking all the values in the first column of the table and check using "each".
If the element is present in the first page the code works. But if it is in second page or third then I have to click on the next button. Before clicking on the next button I need to check if the button is enabled or disabled. If the button is enabled, then I click on the next button and check if the element is present in that page and so on. If the button is disabled, then it means element is not present and I have to fail the testcase.
For this I have written code below. I have used Do ...while because i the first page it has to check without condition (i.e next button is enabled or not).
The issue happening is:
I have stored the isEnabled() value in isenabled variable.I have initialised this variable to false.
But when I run the testcase, though my value is in second page, it is not going to second page. Instead it checks in the first page and stops the test. This is happening because in while(isenabled), isenabled is stored as false. I think before executing the isEnabled() function while(isenabled) is getting executed. Therefor while(isenabled) is getting false value which is initialised value.
I am unable to find where and how to resolve the promise here.
I tried adding async and await ,But when i add these it shows error (red cross mark).Di need to import anything before i add these async and await to my protractor scripts. I have done (SELENIUM_PROMISE_MANAGER: false, ) this in my configuration file.What else i need to do other than this to add async and await.
Still not sure what it is you are trying to accomplish but resolving the promise should work if you change your code like this:
}).then(async function() { //add async
do {
// your code here up until var nextbutton = see next line
var nextbutton = element(by.css("button[aria-label='Next page']"));
isenabled = await nextbutton.isEnabled(); // await isEnabled and store result in isenabled variable
console.log(isenabled);
i++;
console.log(i);
}
while(isenabled);
if you can't use async/await you could also do the following:
.then(function() {
function repeatMe() { // replace do with a function
if (i>0) {
console.log("Clicking on NextButton");
element(by.css("button[class='mat-paginator-navigation-next mat-icon-button']")).click();
}
(element.all(by.xpath("//table[#class='mat-table']/tbody/tr/td[1]"))).each(function(webelement) {
webelement.getText().then(function(text) {
if(text=="IACE") {
count++;
console.log("Element is found");
//break;
}
});
});
var nextbutton = element(by.css("button[aria-label='Next page']"));
nextbutton.isEnabled().then(function(isEnabled) {
console.log(isEnabled); // no need for isenabled variable anymore
i++;
console.log(i);
if (isEnabled) {
repeatMe(); // call repeatMe if isEnabled is true
}
});
}
repeatMe(); // replace while with calling function repeatMe once
})
I am trying to write a simple banking app to learn basic DOM manipulation stuff. This will be a single page website with lots of function calls and hiding/displaying containers.
Once I click the register button on the main screen, it calls registerScreen() function which then hides the main screen elements and shows a form group with text boxes and a submit button that saves the filled in information. However, saveCustomer() function calls itself as soon as I bring up the register screen. Obviously, it submits a blank form which is a problem.
I have tried different event listener methods like submit, click, getElementById().onclick, and so on. I did not want to call saveCustomer() function on HTML because I do not know how I can pass the info with that approach.
function registerScreen() {
document.getElementById("welcome-container").style.display = "none";
document.getElementById("registerScreen").style.display = "block";
let customerFirstName = document.getElementById('firstName').value;
let customerLastName = document.getElementById('lastName').value;
let customerPassword = document.getElementById('password').value;
let randomID = document.getElementById("randomID");
let ID = Math.floor((Math.random() * 999) + 100);
randomID.innerHTML += ID;
//This is the line I am having problems with
document.getElementById("submitInfo").addEventListener("click", saveCustomer(ID, customerFirstName, customerLastName, customerPassword));
}
function saveCustomer (ID, customerFirstName, customerLastName, customerPassword) {
let customer = {
id: ID,
firstname: customerFirstName,
lastname: customerLastName,
password: customerPassword,
cashAmount: 0,
}
if (localStorage.getItem("customers") === null) {
let customers = [];
customers.push(customer);
localStorage.setItem("customers", JSON.stringify(customers));
} else {
let customers = JSON.parse(localStorage.getItem("customers"));
customers.push(customer);
localStorage.setItem("customers", JSON.stringify(customers));
}
alert("Registration successful.");
}
Try wrapping saveCustomer in an anonymous callback function like so:
document.getElementById("submitInfo").addEventListener("click", () => {saveCustomer(ID, customerFirstName, customerLastName, customerPassword)});
The issue is that you are not registering a function to be called when #submitInfo is clicked, but the event listener is malformed and you are calling another function from withing the declaration. Instead, you should register a new anonymous function when clicking #submitInfo and only call the saveCustomer() from withing that anonymous function.
Below is the wrong way that you are using in your case.
<button id="btn">Click</button>
<script>
document.getElementById("btn").addEventListener("click", alertSomething("test"));
function alertSomething(text) {
alert("Inside here, alerting "+text);
}
</script>
When initializing the eventListener, it is making a call to the alertSomething() function. This will trigger the alertSomething() function as soon as the document has loaded.
What you want instead is to define a new anonymous function that will get called once the button has been clicked and only call the alertSomething() function from inside this new function. It is called anonymous function because it doesn't have a name like an ordinary function.
The correct way to accomplish this:
<button id="btn">Click</button>
<script>
document.getElementById("btn").addEventListener("click", function() {
alertSomething("test")
});
function alertSomething(text) {
alert("Inside here, alerting "+text);
}
</script>
I've been messing around with YouTube API to make a button that copies the video ID on click using jQuery. I have no idea why, I don't get any Javascript errors and after hours (actually been working on this problem for 2 days), I still haven't figured out why does the eventListener doesn't fire.
The eventListener is bound at the end of the function, which is fired when you hit a search button. Each time you click on the search button or on the next page/ previous page buttons, they fire the makeRequest function. Somehow, though, the function triggered by the eventListener never fires (the function code isn't in this parcel of code itself, but it's actually just console.log's). Can anyone help? Would be really appreciated <3
function makeRequest(e) {
$('#search-container')[0].innerHTML = '';
ytSearchResults = [];
var q = $('#query').val();
var request = gapi.client.youtube.search.list({
q: q,
part: 'snippet',
maxResults: 15,
pageToken: ytPage,
type: 'video',
safeSearch: 'none',
videoSyndicated: 'true'
});
request.execute(function(response) {
var str = response.result;
ytNextPage = str.nextPageToken;
ytPrevPage = str.prevPageToken;
for(i=0;i<str.items.length;i++){
$('#search-container')[0].innerHTML += '<br><image src='+str.items[i].snippet.thumbnails.default.url+'></image><br><button id="'+str.items[i].id.videoId+'" class="NCScopiable">'+str.items[i].snippet.title+'</button>';
ytSearchResults.push(str.items[i].id.videoId);
}
$('#search-container')[0].innerHTML += '<br><div id="button-changePage"><span id="button-prevPage" style="color:blue;cursor:pointer;margin:5px"><u>Previous Page</u></span><span id="button-nextPage" style="color:blue;cursor:pointer;margin:5px"><u>Next Page</u></span>';
if(e&&ytCurPage>0){
$('#button-prevPage')[0].style.display = 'block';
$('#button-nextPage')[0].style.display = 'block';
} else {
ytCurPage = 0;
$('#button-prevPage')[0].style.display = 'none';
}
$('#button-prevPage').on('click',function(){ytCurPage-=1;ytPage=ytPrevPage;makeRequest(true);});
$('#button-nextPage').on('click',function(){ytCurPage+=1;ytPage=ytNextPage;makeRequest(true);});
console.log('Current ytCurPage value: '+ytCurPage);
});
$('.NCScopiable').on('click',cTWI);
}
The problem is that the line
$('.NCScopiable').on('click',cTWI);
Is being executed before the code inside the callback passed to request.execute has fired, so those elements don't exist yet. Thus $('.NCScopiable') is returning nothing.
Move that line into the last line of your callback code and you should be good to go, for example:
request.execute(function(response) {
var str = response.result;
ytNextPage = str.nextPageToken;
ytPrevPage = str.prevPageToken;
// ...code removed for brevity...
// this was the code that is actually creating the elements with
// the NCScopiable class
console.log('Current ytCurPage value: '+ytCurPage);
$('.NCScopiable').on('click',cTWI);
});
I've created a Backbone, Marionette and Require.js application and am now trying to add smooth transitioning between regions.
To do this easily* ive decided to extend the marionette code so it works across all my pages (theres a lot of pages so doing it manually would be too much)
Im extending the marionette.region open and close function. Problem is that it now doesnt call the onClose function inside each of my views.
If I add the code directly to the marionette file it works fine. So I'm probably merging the functions incorrectly, right?
Here is my code:
extendMarrionette: function () {
_.extend(Marionette.Region.prototype, {
open : function (view) {
var that = this;
// if this is the main content and should transition
if (this.$el.attr("id") === "wrapper" && document.wrapperIsHidden === true) {
this.$el.empty().append(view.el);
$(document).trigger("WrapperContentChanged")
} else if (this.$el.attr("id") === "wrapper" && document.wrapperIsHidden === false) {
$(document).on("WrapperIsHidden:open", function () {
//swap content
that.$el.empty().append(view.el);
//tell router to transition in
$(document).trigger("WrapperContentChanged");
//remove this event listener
$(document).off("WrapperIsHidden:open", that);
});
} else {
this.$el.empty().append(view.el);
}
},
//A new function Ive added - was originally inside the close function below. Now the close function calls this function.
kill : function (that) {
var view = this.currentView;
$(document).off("WrapperIsHidden:close", that)
if (!view || view.isClosed) {
return;
}
// call 'close' or 'remove', depending on which is found
if (view.close) {
view.close();
}
else if (view.remove) {
view.remove();
}
Marionette.triggerMethod.call(that, "close", view);
delete this.currentView;
},
// Close the current view, if there is one. If there is no
// current view, it does nothing and returns immediately.
close : function () {
var view = this.currentView;
var that = this;
if (!view || view.isClosed) {
return;
}
if (this.$el.attr("id") === "wrapper" && document.wrapperIsHidden === true) {
this.kill(this);
} else if (this.$el.attr("id") === "wrapper" && document.wrapperIsHidden === false) {
//Browser bug fix - needs set time out
setTimeout(function () {
$(document).on("WrapperIsHidden:close", that.kill(that));
}, 10)
} else {
this.kill(this);
}
}
});
}
Why don't you extend the Marionette.Region? That way you can choose between using your custom Region class, or the original one if you don't need the smooth transition in all cases. (And you can always extend it again if you need some specific behavior for some specific case).
https://github.com/marionettejs/backbone.marionette/blob/master/docs/marionette.region.md#region-class
var MyRegion = Marionette.Region.extend({
open: function() {
//Your open function
}
kill: function() {
//Your kill function
}
close: function() {
//Your close function
}
});
App.addRegions({
navigationRegion: MyRegion
});
Perhaps your issue is that you are not passing a function to your event listener, but instead calling the code directly in the code below.
setTimeout(function(){
$(document).on("WrapperIsHidden:close", that.kill(that));
}, 10)
It is likely that you want something like this:
setTimeout(function(){
$(document).on("WrapperIsHidden:close", function (){ that.kill(that); });
}, 10)
Another possible problem is that you are mixing up your references to this/that in your kill function. It seems like you probably want var view to either be assigned to that.view or to use this rather than that throughout the method.
Answer to your additional problems:
You should try passing the view variable from the close function directly into your kill function because the reference to currentView is already changed to the new view object when you actually want to old view object. The reason this is happening is that you are setting a timeout before executing the kill function. You can see this if you look at the show source code. It expects close, open and then currentView assignment to happen synchronously in order.