I'm trying to create a script on Google Adwords that changes the campaign name. But right now the script is doing nothing. What is wrong?
function main() {
var campaignIterator = AdWordsApp.campaigns()
.withCondition('Name = "teste"')
.get();
if (campaignIterator.hasNext()) {
var campaign = campaignIterator.next();
var newCampaignName = 'teste2';
campaign.setName(newCampaignName);
}
}
A while loop is the most common element used after the Iterator. Try this out instead:
function main() {
var campaignIterator = AdWordsApp.campaigns()
.withCondition('Name = "teste"')
.get();
while (campaignIterator.hasNext()) {
var campaign = campaignIterator.next();
var newCampaignName = 'teste2';
campaign.setName(newCampaignName);
Logger.log("Campaign Name Changed")
}
}
I have also included a "Logger.log" to display the output of the while loop. If that isn't triggering, then there is something wrong with your Iterator condition; maybe you dn't have a campaign with the name you've used.
If you wish to rename a campaign, you must provide the ID. This field can be selected using the value "Name". This field can be filtered on.
Related
I am trying to get the values of several input fields and then displaying those values somewhere else on the page using JS functions. I will have 10 input fields, therefore is there a way I can optimize my JS code and write a function to loop through the values of the input fields and display them afterwards? Here are two functions which I wrote for two different fields:
function gotoTask() {
var message = document.getElementById("goto").value;
goto_message.innerHTML = message;
}
function waitTask() {
var message = document.getElementById("wait").value;
wait_message.innerHTML = message;
}
You could write a curry/factory function:
function createTaskFn(el, messageElId) {
return function() {
var message = document.getElementById(messageElId).value;
el.innerHTML = message;
};
}
var gotoTask = crateTaskFn(goto_message, 'goto');
var waitTask = crateTaskFn(wait_message, 'wait');
Give same class to your all inputs , then select them by let inputArr = document.getElementsByClassName('inputsClass') , then loop through inputArr and display their values.
You could store all the ids in an array like so
const inputIds = ['goto', 'wait', ...]
Then you can iterate over that array and call your method like so
inputIds.forEach((id) => {
const message = document.getElementById(id).value;
document.getElementById(`${id}_message`).innerHTML = message;
})
Disadvantage of my implementation: Your ids of the message fields have to have the same structure [id]_message
I am trying to find a way to find the value of the id given the email.
For example, If I had email2#gmail.com, It would give me the ID 108454568498950432898.
All emails are unique and there will be no repetition of emails.
This is my user tree:
Note: In the image it says email2 instead of email2#gmail.com. Ignore this
Here's my code so far:
(Code won't run obviously but it's easier to enter code using the embed)
var users;
var givenEmail = "email2#gmail.com";
var neededID;
var dataRef = firebase.database().ref('users');
dataRef.on('value', (snapshot) => {
const data = snapshot.val();
users = data;
});
var usersArray = Object.keys(users);
for(i = 0; i < usersArray.length; i++) {
if(users[i].email == givenEmail) {
neededID = i;
break;
}
}
I recommend using a query to perform the filtering on the server, instead of downloading the entire users node and filtering in your application code as you now do.
var givenEmail = "email2#gmail.com";
var dataRef = firebase.database().ref('users');
var query = dataRef.orderByChild('email').equalTo(givenEmail);
dataRef.once('value', (snapshot) => {
snapshot.forEach((userSnapshot) => {
console.log(userSnapshot.val().id);
});
});
Well, I think you are almost there.
users[i].email
you can retrieve the email using this method, and similarly you can do it with id too
users[i].id
Please note that you wanted to find email2#gmail.com but your firebase only have email2
Maybe you would want to change that
I am trying to edit/update current data using the contenteditable attribute which I have successfully enabled onclick. My 'enter' key allows the data to be submitted. However, the console.log reads that a PUT request has been made for a particular list item but without the 'title' or 'isbn' being updated along with it.
Another prominent issue is that my console.log shows books.forEach is not a function, and I have no idea why this is the case since the code inside that function is processed.
HTML ('li' items are solely JS-Generated with a POST request)
<div id="divShowBooks">
<li id="[object HTMLParagraphElement]">
<p id="24" name="anID" placeholder="24">1</p>
<p id="TEST" name="aTitle" placeholder="TEST">TEST</p>
<p id="12345" name="anISBN" placeholder="12345" contenteditable="true">12345</p>
<button>Delete</button>
</li>
</div>
JavaScript
var book_list = document.querySelector('#divShowBooks');
book_list.innerHTML = "";
var books = JSON.parse(this.response);
books.forEach(function (book) {
// Text information to be displayed per item
var id = document.createElement('p');
id.type = 'text';
id.innerHTML = book.id;
var title = document.createElement('p');
title.type = 'text';
title.innerHTML = book.title;
var isbn = document.createElement('p');
isbn.type = 'text';
isbn.innerHTML = book.isbn;
// Defining the element that will be created as a list item
var book_item = document.createElement('li');
// Displays id, title and ISBN of the books from the database
book_item.appendChild(id);
book_item.appendChild(title);
book_item.appendChild(isbn);
// Creates an ID attribute per list item
book_item.setAttribute("id", id)
// Assigns attributes to p items within book items
id.setAttribute("id", book.id)
title.setAttribute("id", book.title)
isbn.setAttribute("id", book.isbn)
// Adding a generic name to these elements
id.setAttribute("name", "anID")
title.setAttribute("name", "aTitle")
isbn.setAttribute("name", "anISBN")
title.addEventListener('click', function (e) {
e.preventDefault();
title.contentEditable = "true";
title.setAttribute("contenteditable", true);
title.addEventListener('keypress', function (e) {
if (e.keyCode === 13) {
e.preventDefault();
xhttp.open("PUT", books_url + '/' + book.id, true);
var editTitle = new FormData() /
editTitle.append("title", document.getElementsByName("aTitle")[0].value)
xhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded')
xhttp.send(); //
}
});
});
UPDATE
I have added the following to my code. This seems to display my database items as an array in the log. But, I am now having a similar issue with Uncaught TypeError: JSON.parse(...).map is not a function:
var params = [
id = 'id',
title = 'title',
isbn = 'isbn',
createdAt = 'createdAt',
updatedAt = 'updatedAt'
];
var books = JSON.parse(this.response).map(function(obj) {
return params.map(function(key) {
return obj[key];
});
});
console.log(books);
UPDATE 2
Here is an image of what I receive in the console.log. The first part displays the original JSON content and the second is my attempt to convert each object into an array.
See Image
You have to make sure that your books variable actually contains an Array after parsing.
Alternatively, but this wouldn't make sense, just to address the "books.forEach is not a function" issue, You can use Object.assign([], this.response);. To make sure that books will contain an array, you wrap it in a try catch and make something like this:
var books = [];
try {
books = Object.assign([], this.response);
} catch (error) {
books = [];
}
books.forEach will then be expected to always work but you have to be careful because something like this could happen:
var myStringObject = "{'myProperty':'value'}";
var myArray = Object.assign([], myStringObject );
//myArray value is ["{", "'", "myProperty", "'", ":", "'", "value", "'", "}"]
Which will leave you having to check the book in your forEach callback if it is correct:
//at the topmost of your forEach callback
if(!book.id) throw BreakException; //A simple break will not work on forEach
This will leave you again with another exception to handle. Or leave you having to use the traditional for loop since you cannot short circuit Array.forEach with a break.
TLDR: make sure books always contains an Array.
You are getting books from JSON.parse(), which means books is an object and not an array.
forEach is an array method.
Try console logging books and look for an array inside of it.
Can anyone help me to get the user info from a person column using javascript? So far I have been able to read the list item and return a SP.FieldUserValue from which I can get a numeric Id (not sure what this ID is) and the display name. e.g.
var ManVal = oListItem.get_item("RecruitingManager").get_lookupValue();
var ManId = oListItem.get_item("RecruitingManager").get_lookupId();
How do I take this one step further to create a sp user object?
Ultimately what I'm trying to achieve is to retrieve the details from the list and then populate a people editor.
Ok, I've got it.
Here is my code, hope it helps somebody. I haven't included the method to retrieve the list item, just the line from that function where I'm getting the value of the person.
var _lineManager;
var lineManager = oListItem.get_item("RecruitingManager").get_lookupId();
_lineManager = oWebsite.getUserById(lineManager);
getLineManager();
function getLineManager() {
context.load(_lineManager);
context.executeQueryAsync(onGetUserNameSuccessLM, onGetUserNameFailLM);
}
function onGetUserNameSuccessLM() {
alert(lineManager.get_title());
var schema = {};
schema['PrincipalAccountType'] = 'User,DL,SecGroup,SPGroup';
schema['SearchPrincipalSource'] = 15;
schema['ResolvePrincipalSource'] = 15;
schema['AllowMultipleValues'] = false;
schema['MaximumEntitySuggestions'] = 50;
schema['Width'] = '280px';
var users = new Array(1);
var defaultUser = new Object();
defaultUser.AutoFillDisplayText = lineManager.get_title();
defaultUser.AutoFillKey = lineManager.get_loginName();
defaultUser.Description = lineManager.get_email();
defaultUser.DisplayText = lineManager.get_title();
defaultUser.EntityType = "User";
defaultUser.IsResolved = true;
defaultUser.Key = lineManager.get_loginName();
defaultUser.Resolved = true;
users[0] = defaultUser;
SPClientPeoplePicker_InitStandaloneControlWrapper('peoplePickerDivLinMan', users, schema);
}
function onGetUserNameFailLM(sender, args) {
alert('Failed to get user name. Error:' + args.get_message());
}
The person field (actually called "people picker") has a specific JavaScript function which you might find useful: GetAllUserInfo()
There is a nice article on MSDN:
How to: Use the client-side People Picker control in apps for SharePoint
The relevant code is:
// Get the people picker object from the page.
var peoplePicker = this.SPClientPeoplePicker.SPClientPeoplePickerDict.peoplePickerDiv_TopSpan;
// Get information about all users.
var users = peoplePicker.GetAllUserInfo();
var userInfo = '';
for (var i = 0; i < users.length; i++) {
var user = users[i];
for (var userProperty in user) {
userInfo += userProperty + ': ' + user[userProperty] + '<br>';
}
}
$('#resolvedUsers').html(userInfo);
// Get user keys.
var keys = peoplePicker.GetAllUserKeys();
$('#userKeys').html(keys);
So basically you have to cast your field to a SPClientPeoplePicker and can then use GetAllUserInfo to iterate over all users in the field.
I have an indexedDB and using it for a login function. I'm trying to populate a form with the users information when they log in. However the form populates with [object HTMLInputElement] instead of the users info.
This is where I take the user (db key) to access the Object (the user)
EDITThis is my site where it's running: http://www3.carleton.ca/clubs/sissa/html5/admin.html
My site editor is updating it as I save, so there may be changes to the site script as I try new things.
This is where I take the user (db key) to access the Object (the user)
function loginCheck(user,pass){ db.transaction("users").objectStore("users").get(user).onsuccess = function(event) {
var loggedUser = event.target.result;
if(!loggedUser){
alert('Sorry, Username does not exist. Please try again.');
}else if(pass !== loggedUser.pw ){
alert('Incorrect log in combination. Please try again.');
}else{loggedIn(loggedUser);}
}
}
function loggedIn(loggedUser){
var u=loggedUser;
alert('Welcome '+u.fn+' '+u.ln+' to Macroplay');
//function to populate fields
alert('get values called');
getValues(u);
//session store
var signedin = 'user';
var username = u.userName;
newLocal(signedin,username);
alert('local storage set');
}
I use this function getValues to store the various fields I want from the object.
EDIT: I declared the variable test as global and stored the users first name (fn). The alerts show the correct name but the populate still gives me undefined.
var test;
function getValues(loggedUser){
var u = loggedUser;
alert('storing first name');
test = u.fn;
alert('First name = '+test);
lName = u.ln;
users = u.userName;
pass = u.pw;
email = u.em;
dob = u.dob;
tel = u.tel;
bio = u.bio;
school = u.scl;
alert('user values stored');
if(u.gender == 'M'){
gender[0].checked= true ;
}else{gender[1].checked= true ;}
}
This is the function I use to populate the form that's giving me [object HTMLInputElement]
function populateFields(){
alert('Name of populated field: '+test);
fName.value = test;
lName.value = lName;
users.value = users;
pass.value = pass;
email.value = email;
dob.value = dob;
tel.value = tel;
bio.value = bio;
terms.disabled = true;
school.value = school;
alert('populate fields done');
save.value = 'Update';
signin.innerHTML = 'Log Out';
registerLabel.innerHTML = 'Account Information';
//open user info form
var accountInfo = document.getElementsByTagName('details');
accountInfo[1].open = open;
}
Just look at one line:
fName.value = fName
You are setting the value property of fName to fName itself.
Rather than creating numerous global variables, just use loggedUser directly in populateFields():
fName.value = loggedUser.fn;
Edit: Looking at your site, I see the important bit you left out. populateFields() is being called after the page reloads. So, populateFields() does not have access to any variable created before the page reloaded.
Since I'm helping you with homework, I don't want to just hand you the answer on a silver platter. The trick is that the user data must be retrieved from the database and made available to populateFields() before it is called, or from within the function. You can make the user object available as a global variable, but it may be better to pass it in as a parameter.
You probably want to also cancel the form submission:
document.getElementById("loginForm").onsubmit = function (e) {
e.preventDefault();
}
And then just call populateFields() directly from loggedIn() instead of getValues().