I am not very good at scripts, but I have created a PDF fillable form to calculate hours worked. When there is no data entered, the result fields show NaN:NaN, is there a way to hide this if the fields are blank?
The script formula I have used is.....
var hrsStart = parseInt(this.getField("hrsstart1").value.split(":")[0]);
var minStart = parseInt(this.getField("hrsstart1").value.split(":")[1]);
var hrsEnd = parseInt(this.getField("hrsend1").value.split(":")[0]);
var minEnd = parseInt(this.getField("hrsend1").value.split(":")[1]);
if (minStart > minEnd) {
var minRez = 60 + minEnd - minStart;
var hrsRez = hrsEnd - 1 - hrsStart;
} else {
var minRez = minEnd - minStart;
var hrsRez = hrsEnd - hrsStart;
}
this.getField("Totalhrs1").value = hrsRez + ":" + minRez;
When there is no data entered, the result fields show NaN:NaN, is there a way to hide this if the fields are blank?
Use NaN checker function isNaN() like below:
if(!(isNaN(hrsRez)) && !(isNaN(minRez)) {
this.getField("Totalhrs1").value = hrsRez + ":" + minRez;
}
Try this:
var startValue = this.getField("hrsstart1").value;
var endValue = this.getField("hrsend1").value;
var timeValue = '';
if(startValue && endValue)
{
var startArr = startValue.split(":");
var endArr = endValue.split(":");
var hrsStart = parseInt(startArr[0]);
var minStart = parseInt(startArr[1]);
var hrsEnd = parseInt(endArr[0]);
var minEnd = parseInt(endArr[1]);
if(!isNaN(hrsStart) && !isNaN(minStart) && !isNaN(hrsEnd) && !isNaN(minEnd))
{
var minRez, hrsRez;
if (minStart > minEnd) {
minRez = 60 + minEnd - minStart;
hrsRez = hrsEnd - 1 - hrsStart;
} else {
minRez = minEnd - minStart;
hrsRez = hrsEnd - hrsStart;
}
timeValue = hrsRez + ":" + minRez;
}
}
this.getField("Totalhrs1").value = timeValue;
Related
I am trying to create a cash flow with dates.
I have 2 dates: Start and End
If payments are monthly and suppose the rent payment day is on 15th. Then the cashflow would :
10/15/2018
11/15/2018
12/15/2018
1/15/2019..... and so forth until the end date.
Similarly if rent is paid every 3 months then cashflow would look like:
10/15/2018 1/15/2018 4/15/2018... and so forth.
I have the following code which works every time except when the rent is on 1st day of the month or last day of the month.
function createLedger(stDate, etDate){
if (stDate && etDate) {
var d2 = new Date(etDate);
var sDay = d2.getUTCDate();
var sMonth = d2.getUTCMonth() + 1;
var sYear = d2.getUTCFullYear();
var endOfLeaseDate = sYear + "-" + sMonth + "-" + sDay;
var d3 = new Date(stDate);
var s1Day = d3.getUTCDate();
var s1Month = d3.getUTCMonth() + 1;
var s1Year = d3.getUTCFullYear();
var startOfLeaseDate = s1Year + "-" + s1Month + "-" + s1Day;
var ddlFrequency = document.getElementById("ddFrequency");
var selectedFrequency = ddlFrequency.options[ddlFrequency.selectedIndex].value;
if (selectedFrequency) {
if (selectedFrequency == "D") {
dates = dateRange(startOfLeaseDate, endOfLeaseDate);
}
Here is where the issue is:
else if (selectedFrequency == "Q") {
dates = getQuartersDateRange(d3, d2)
dates = SortedQuarter(d3,dates);
}
else {
dates = [];
}
}
else {
dates = [];
}
createFormElement();
}
}
And i have the following codes to get the date range and quarter range.
function getQuartersDateRange(startOfLeaseDate, endOfLeaseDate) {
var dates = [];
var qlist = listQuarters(startOfLeaseDate, endOfLeaseDate);
for (var i = 0; i < qlist.length; i++) {
var yearquarter = qlist[i].split('-');
var dateQ = new Date(yearquarter[0], (yearquarter[1] * 3 - 3) + 1, startOfLeaseDate.getUTCDate());
qDay = dateQ.getUTCDate();
qMonth = dateQ.getUTCMonth();
qYear = dateQ.getUTCFullYear();
var qDate = qYear + "-" + qMonth + "-" + qDay;
dates.push(qDate);
}
return dates;
}
function SortedQuarter(startOfLeaseDate, dates) {
var qdatesSorted = [];
for (var j = 0; j < dates.length; j++) {
var month;
var splitDate = dates[j].split('-');
if (j == 0)
month = startOfLeaseDate.getUTCMonth() + 1;
else {
startOfLeaseDate.setMonth(startOfLeaseDate.getUTCMonth() + 3)
month = startOfLeaseDate.getUTCMonth() + 1;
}
var qDate = splitDate[0] + "-" + month + "-" + splitDate[2];
qdatesSorted.push(qDate);
}
return qdatesSorted;
}
function listQuarters(sDate, eDate) {
if (sDate > eDate) {
var t = eDate;
eDate = sDate;
sDate = t;
}
sDate = new Date(sDate);
sDate.setDate(2);
var startQ = getQuarter(sDate);
var endQ = getQuarter(eDate);
var result = [startQ];
while (startQ != endQ) {
sDate.setMonth(sDate.getUTCMonth() + 3);
startQ = getQuarter(sDate);
result.push(startQ);
}
return result;
}
The issue here is that when the start date = 11/1/2018 and end date = 01/31/2020
the cashflow prints as follows
11/1/2018 3/1/2019 6/1/2019 9/1/2019 12/1/2019...and so forth. So instead of going from 11/1/2018 to 2/1/2018, it skips the month and goes to the next one. I am not sure why it does that only towards the end of the month or the beginning of the month.
Any help is appreciated. Thank you.
Using moment library worked for me. aLSO, I rewrote the date range as follows:
function createLedger(stDate, etDate) {
if (stDate && etDate) {
var endOfLeaseDate = moment(etDate, "MM/DD/YYYY");
var startOfLeaseDate = moment(stDate, "MM/DD/YYYY");
dateRange(startOfLeaseDate, endOfLeaseDate);
}
}
function dateRange(stDate, etDate) {
var dates = [];
var now = etDate.clone();
var day = etDate.date();
while(now.isAfter(stDate)) {
var month = now.clone().endOf("month");
if (now.date() < day && day <= month.date()) {
now.date(day);
}
dates.push(now.format("MM/DD/YYYY"));
//dates._reverse();
now = now.clone().subtract({"months": 1});
}
console.log(dates);
}
function RunLedgerAndPV() {
var stDate = "11/26/2018";
var etDate = "09/25/2019";
createLedger(stDate, etDate);
}
RunLedgerAndPV();
This is an extension of the following question. I can't use it because PropertiesService and ScriptApp is not supported in Adwords and I didn't find anything relevant so far on the question adapted to Adwords.
I have an Adwords script that constantly gets the error Exceeded maximum execution time. For an MCC accounts, I think the maximum time execution is 30 minutes. Does anyone know if there is a way to extend this time limit? Or perhaps is there a way to call the Adwords script again and it picks up from where it left off? Queuing? Could I use an MCCScript with Google-Apps-Script?
Here is what I have done so far ...
function timeDrivenTrigger(myFunct) {
var REASONABLE_TIME_TO_WAIT = 4*6000;
var MAX_RUNNING_TIME = 1*6000;
var ss = SpreadsheetApp.openByUrl('https://docs.google.com/spreadsheets/d/1sYQ__CM33oL2OLzbScQEdcQ6LvDxJCohP024vdSGfSI/edit#gid=0');
var sheet = ss.getSheets()[0];
var cell = sheet.getRange('A1');
var startTime= (new Date()).getTime();
myFunct;
var startRow= cell.getValue() || 1;
for(var ii = startRow; ii <= 10000; ii++) {
var currTime = (new Date()).getTime();
if(currTime - startTime >= MAX_RUNNING_TIME) {
cell.setValue(ii);
ScriptApp.newTrigger("runMe")
.timeBased()
.at(new Date(currTime+REASONABLE_TIME_TO_WAIT))
.create();
break;
}
}
}
UPDATE WITH PARALLEL EXECUTION
Here is my whole code ...
//Your build Google-Spreadsheet
var SPREADSHEET_URL = "https://docs.google.com/spreadsheets/d/1k4o_8O_11OvhZRergefWKgXQ8_XxIs7D31-NV9Ove-o/edit#gid=749396300";
//Fetch and convert data in a JSON structure
var spreadsheet = SpreadsheetApp.openByUrl(SPREADSHEET_URL);
var sheet = spreadsheet.getSheetByName('Campaigns');
var data = sheet.getRange("A:C").getValues();
var accountList = accountsListing(data);
accountList= accountList.map(function (el) {
return el.trim();
});
function main() {
accountIdList = [];
accountItr = MccApp.accounts().get();
while(accountItr.hasNext()) {
account = accountItr.next();
if (accountList.indexOf(account.getName()) > -1) {
accountIdList.push(account.getCustomerId())
}
}
if(accountList.length > 0) {
var accountSelector = MccApp.accounts()
.withIds(accountIdList)
.withLimit(40);
accountSelector.executeInParallel('adjustCPCmax');
}
}
String.prototype.format = function () {
var i = 0, args = arguments;
return this.replace(/{}/g, function () {
return typeof args[i] != 'undefined' ? args[i++] : '';
});
};
function isBlank(line) {
return line[0].trim() === '' && line[1].trim() === '';
}
function parseData(data) {
const output = {};
var currentGroupName = '';
data.forEach(function(line, index){
if (isBlank(line) || index === 0){
return;
}
if (line[0].trim().length > 1) {
currentGroupName = line[0].trim();
}
output[currentGroupName] = output[currentGroupName] || {};
output[currentGroupName][line[1]] = line[2];
});
return output;
}
function accountsListing(data) {
function isBlank(line){
return line[0].trim() === '';
}
const output = [];
data.forEach(function(line, index) {
if (isBlank(line) || index === 0) {
return;
}
output.push(line[0])
});
return output
}
function parseKeyword(keyword, keywordId, maxCPC) {
Logger.log('THE NAME OF THE KEYWORDID IS ' + keywordId + '\n')
var report = AdWordsApp.report(
'SELECT Id, Criteria, CampaignName, CpcBid, FirstPageCpc, FirstPositionCpc, TopOfPageCpc, Criteria ' +
'FROM KEYWORDS_PERFORMANCE_REPORT ' +
'WHERE ' +
'Id = ' + keywordId);
var rows = report.rows();
while(rows.hasNext()) {
var row = rows.next();
var keywordIdReport = row['Id'];
var keywordNameReport = row['Criteria'];
var campaignName = row['CampaignName'];
var cpcBid = row['CpcBid'];
var firstPageCpc = row['FirstPageCpc'];
var firstPositionCpc = row['FirstPositionCpc'];
var topOfPageCpc = row['TopOfPageCpc'];
Logger.log('INFO')
Logger.log(keyword.getText())
Logger.log(keywordId)
Logger.log(keywordNameReport)
Logger.log(keywordIdReport + '\n')
if (keywordId === keywordIdReport) {
if (firstPositionCpc && (firstPositionCpc > 0 && firstPositionCpc <= maxCPC)) {
var newCPC = firstPositionCpc;
} else if (topOfPageCpc && (topOfPageCpc > 0 && topOfPageCpc <= maxCPC)) {
var newCPC = topOfPageCpc;
} else if (firstPageCpc && (firstPageCpc > 0 && firstPageCpc <= maxCPC )) {
var newCPC = firstPageCpc;
} else {
var newCPC = minCPC;
}
Logger.log('KeywordIdReport :' + keywordIdReport)
Logger.log('campaignName :' + campaignName)
Logger.log('CPCbid :' + cpcBid)
Logger.log('firstPositionCpc : ' + firstPositionCpc)
Logger.log('topOfPageCpc : ' + topOfPageCpc)
Logger.log('firstPageCpc : ' + firstPageCpc)
Logger.log('NewCPC : ' + newCPC + '\n')
keyword.bidding().setCpc(newCPC)
break;
}
}
}
function getMaxCPC(account, campaign) {
var cleanData= parseData(data);
//Formatting account and campaign
var account = '{}'.format(account.getName())
var campaign = '{}'.format(campaign.getName())
Logger.log('Account :' + account)
Logger.log('Campaign :' + campaign + '\n')
return cleanData[account][campaign];
}
function adjustCPCmax() {
//min CPC
var minCPC = 0.50;
var account = AdWordsApp.currentAccount();
Logger.log('=================================' + account.getName() + "=======================================")
var campaignIterator = AdWordsApp.campaigns().get();
while (campaignIterator.hasNext()) {
var campaign = campaignIterator.next();
try {
var maxCPC = getMaxCPC(account, campaign)
}
catch(e) {
}
if (maxCPC) {
Logger.log('The entrence worked with max CPC : ' + maxCPC + '\n')
keywordIterator = campaign.keywords().get();
var startTime= (new Date()).getTime();
while (keywordIterator.hasNext()) {
var keyword= keywordIterator.next()
var keywordId = Number(keyword.getId()).toPrecision()
parseKeyword(keyword, keywordId, maxCPC);
}
}
}
}
Be aware that this code will work in the MCC script environment. It could work for any account from a Google spreadsheet.
P.S. This following question gave me a good idea how to process, but I want to know your suggestions.
I have a bid-to-position script that targets keywords that have a label associated with them. The label contains the desired position and the script adjusts the keyword's bid in order to reach that position. Right now the script targets any keyword with the label. I'm trying to edit the script so it will look for labeled keywords in campaigns that I choose. I tried adding .withCondition(CampaignName = ' My Campaign Name'") to the labelIterator variable but had no luck. Can anyone point me in the right direction?
/**
*
* Average Position Bidding Tool
*
* This script changes keyword bids so that they target specified positions,
* based on recent performance.
*
* Version: 1.2
* Updated 2015-09-28 to correct for report column name changes
* Updated 2016-02-05 to correct label reading, add extra checks and
* be able to adjust maximum bid increases and decreases separately
* Google AdWords Script maintained on brainlabsdigital.com
*
**/
// Options
var maxBid = 5.00;
// Bids will not be increased past this maximum.
var minBid = 0.10;
// Bids will not be decreased below this minimum.
var firstPageMaxBid = 1.00;
// The script avoids reducing a keyword's bid below its first page bid estimate. If you think
// Google's first page bid estimates are too high then use this to overrule them.
var dataFile = "AveragePositionData.txt";
// This name is used to create a file in your Google Drive to store today's performance so far,
// for reference the next time the script is run.
var useFirstPageBidsOnKeywordsWithNoImpressions = false;
// If this is true, then if a keyword has had no impressions since the last time the script was run
// its bid will be increased to the first page bid estimate (or the firsPageMaxBid if that is smaller).
// If this is false, keywords with no recent impressions will be left alone.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
// Advanced Options
var bidIncreaseProportion = 0.2;
var bidDecreaseProportion = 0.4;
var targetPositionTolerance = 0.2;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
function main() {
var fieldJoin = ",";
var lineJoin = "$";
var idJoin = "#";
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
var files = DriveApp.getFilesByName(dataFile);
if (!files.hasNext()) {
var file = DriveApp.createFile(dataFile,"");
Logger.log("File '" + dataFile + "' has been created.");
} else {
var file = files.next();
if (files.hasNext()) {
Logger.log("Error - more than one file named '" + dataFile + "'");
return;
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
var labelIds = [];
var labelIterator = AdWordsApp.labels()
.withCondition("CampaignName CONTAINS_IGNORE_CASE 'MY CAMPAIGN NAME' ")
.withCondition("KeywordsCount > 0")
.withCondition("LabelName CONTAINS_IGNORE_CASE 'Position '")
.get();
while (labelIterator.hasNext()) {
var label = labelIterator.next();
if (label.getName().substr(0,"position ".length).toLowerCase() == "position ") {
labelIds.push(label.getId());
}
}
if (labelIds.length == 0) {
Logger.log("No position labels found.");
return;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
var keywordData = {
//UniqueId1: {LastHour: {Impressions: , AveragePosition: }, ThisHour: {Impressions: , AveragePosition: },
//CpcBid: , FirstPageCpc: , MaxBid, MinBid, FirstPageMaxBid, PositionTarget: , CurrentAveragePosition:,
//Criteria: }
}
var ids = [];
var uniqueIds = [];
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
var report = AdWordsApp.report(
'SELECT Id, Criteria, AdGroupId, AdGroupName, CampaignName, Impressions, AveragePosition, CpcBid, FirstPageCpc, Labels, BiddingStrategyType ' +
'FROM KEYWORDS_PERFORMANCE_REPORT ' +
'WHERE Status = ENABLED AND AdGroupStatus = ENABLED AND CampaignStatus = ENABLED ' +
'AND LabelIds CONTAINS_ANY [' + labelIds.join(",") + '] ' +
'AND AdNetworkType2 = SEARCH ' +
'AND Device NOT_IN ["HIGH_END_MOBILE"] ' +
'DURING TODAY'
);
var rows = report.rows();
while(rows.hasNext()){
var row = rows.next();
if (row["BiddingStrategyType"] != "cpc") {
if (row["BiddingStrategyType"] == "Enhanced CPC"
|| row["BiddingStrategyType"] == "Target search page location"
|| row["BiddingStrategyType"] == "Target Outranking Share"
|| row["BiddingStrategyType"] == "None"
|| row["BiddingStrategyType"] == "unknown") {
Logger.log("Warning: keyword " + row["Criteria"] + "' in campaign '" + row["CampaignName"] +
"' uses '" + row["BiddingStrategyType"] + "' rather than manual CPC. This may overrule keyword bids and interfere with the script working.");
} else {
Logger.log("Warning: keyword " + row["Criteria"] + "' in campaign '" + row["CampaignName"] +
"' uses the bidding strategy '" + row["BiddingStrategyType"] + "' rather than manual CPC. This keyword will be skipped.");
continue;
}
}
var positionTarget = "";
var labels = row["Labels"].toLowerCase().split("; ")
for (var i=0; i<labels.length; i++) {
if (labels[i].substr(0,"position ".length) == "position ") {
var positionTarget = parseFloat(labels[i].substr("position ".length-1).replace(/,/g,"."),10);
break;
}
}
if (positionTarget == "") {
continue;
}
if (integrityCheck(positionTarget) == -1) {
Logger.log("Invalid position target '" + positionTarget + "' for keyword '" + row["Criteria"] + "' in campaign '" + row["CampaignName"] + "'");
continue;
}
ids.push(parseFloat(row['Id'],10));
var uniqueId = row['AdGroupId'] + idJoin + row['Id'];
uniqueIds.push(uniqueId);
keywordData[uniqueId] = {};
keywordData[uniqueId]['Criteria'] = row['Criteria'];
keywordData[uniqueId]['ThisHour'] = {};
keywordData[uniqueId]['ThisHour']['Impressions'] = parseFloat(row['Impressions'].replace(/,/g,""),10);
keywordData[uniqueId]['ThisHour']['AveragePosition'] = parseFloat(row['AveragePosition'].replace(/,/g,""),10);
keywordData[uniqueId]['CpcBid'] = parseFloat(row['CpcBid'].replace(/,/g,""),10);
keywordData[uniqueId]['FirstPageCpc'] = parseFloat(row['FirstPageCpc'].replace(/,/g,""),10);
setPositionTargets(uniqueId, positionTarget);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
setBidChange();
setMinMaxBids();
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
var currentHour = parseInt(Utilities.formatDate(new Date(), AdWordsApp.currentAccount().getTimeZone(), "HH"), 10);
if (currentHour != 0) {
var data = file.getBlob().getDataAsString();
var data = data.split(lineJoin);
for(var i = 0; i < data.length; i++){
data[i] = data[i].split(fieldJoin);
var uniqueId = data[i][0];
if(keywordData.hasOwnProperty(uniqueId)){
keywordData[uniqueId]['LastHour'] = {};
keywordData[uniqueId]['LastHour']['Impressions'] = parseFloat(data[i][1],10);
keywordData[uniqueId]['LastHour']['AveragePosition'] = parseFloat(data[i][2],10);
}
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
findCurrentAveragePosition();
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
try {
updateKeywords();
} catch (e) {
Logger.log("Error updating keywords: " + e);
Logger.log("Retrying after one minute.");
Utilities.sleep(60000);
updateKeywords();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
var content = resultsString();
file.setContent(content);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
// Functions
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
function integrityCheck(target){
var n = parseFloat(target, 10);
if(!isNaN(n) && n >= 1){
return n;
}
else{
return -1;
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
function setPositionTargets(uniqueId, target){
if(target !== -1){
keywordData[uniqueId]['HigherPositionTarget'] = Math.max(target-targetPositionTolerance, 1);
keywordData[uniqueId]['LowerPositionTarget'] = target+targetPositionTolerance;
}
else{
keywordData[uniqueId]['HigherPositionTarget'] = -1;
keywordData[uniqueId]['LowerPositionTarget'] = -1;
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
function bidChange(uniqueId){
var newBid = -1;
if(keywordData[uniqueId]['HigherPositionTarget'] === -1){
return newBid;
}
var cpcBid = keywordData[uniqueId]['CpcBid'];
var minBid = keywordData[uniqueId]['MinBid'];
var maxBid = keywordData[uniqueId]['MaxBid'];
if (isNaN(keywordData[uniqueId]['FirstPageCpc'])) {
Logger.log("Warning: first page CPC estimate is not a number for keyword '" + keywordData[uniqueId]['Criteria'] + "'. This keyword will be skipped");
return -1;
}
var firstPageBid = Math.min(keywordData[uniqueId]['FirstPageCpc'], keywordData[uniqueId]['FirstPageMaxBid'], maxBid);
var currentPosition = keywordData[uniqueId]['CurrentAveragePosition'];
var higherPositionTarget = keywordData[uniqueId]['HigherPositionTarget'];
var lowerPositionTarget = keywordData[uniqueId]['LowerPositionTarget'];
var bidIncrease = keywordData[uniqueId]['BidIncrease'];
var bidDecrease = keywordData[uniqueId]['BidDecrease'];
if((currentPosition > lowerPositionTarget) && (currentPosition !== 0)){
var linearBidModel = Math.min(2*bidIncrease,(2*bidIncrease/lowerPositionTarget)*(currentPosition-lowerPositionTarget));
var newBid = Math.min((cpcBid + linearBidModel), maxBid);
}
if((currentPosition < higherPositionTarget) && (currentPosition !== 0)) {
var linearBidModel = Math.min(2*bidDecrease,((-4)*bidDecrease/higherPositionTarget)*(currentPosition-higherPositionTarget));
var newBid = Math.max((cpcBid-linearBidModel),minBid);
if (cpcBid > firstPageBid) {
var newBid = Math.max(firstPageBid,newBid);
}
}
if((currentPosition === 0) && useFirstPageBidsOnKeywordsWithNoImpressions && (cpcBid < firstPageBid)){
var newBid = firstPageBid;
}
if (isNaN(newBid)) {
Logger.log("Warning: new bid is not a number for keyword '" + keywordData[uniqueId]['Criteria'] + "'. This keyword will be skipped");
return -1;
}
return newBid;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
function findCurrentAveragePosition(){
for(var x in keywordData){
if(keywordData[x].hasOwnProperty('LastHour')){
keywordData[x]['CurrentAveragePosition'] = calculateAveragePosition(keywordData[x]);
} else {
keywordData[x]['CurrentAveragePosition'] = keywordData[x]['ThisHour']['AveragePosition'];
}
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
function calculateAveragePosition(keywordDataElement){
var lastHourImpressions = keywordDataElement['LastHour']['Impressions'];
var lastHourAveragePosition = keywordDataElement['LastHour']['AveragePosition'];
var thisHourImpressions = keywordDataElement['ThisHour']['Impressions'];
var thisHourAveragePosition = keywordDataElement['ThisHour']['AveragePosition'];
if(thisHourImpressions == lastHourImpressions){
return 0;
}
else{
var currentPosition = (thisHourImpressions*thisHourAveragePosition-lastHourImpressions*lastHourAveragePosition)/(thisHourImpressions-lastHourImpressions);
if (currentPosition < 1) {
return 0;
} else {
return currentPosition;
}
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
function keywordUniqueId(keyword){
var id = keyword.getId();
var idsIndex = ids.indexOf(id);
if(idsIndex === ids.lastIndexOf(id)){
return uniqueIds[idsIndex];
}
else{
var adGroupId = keyword.getAdGroup().getId();
return adGroupId + idJoin + id;
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
function setMinMaxBids(){
for(var x in keywordData){
keywordData[x]['MinBid'] = minBid;
keywordData[x]['MaxBid'] = maxBid;
keywordData[x]['FirstPageMaxBid'] = firstPageMaxBid;
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
function setBidChange(){
for(var x in keywordData){
keywordData[x]['BidIncrease'] = keywordData[x]['CpcBid'] * bidIncreaseProportion/2;
keywordData[x]['BidDecrease'] = keywordData[x]['CpcBid'] * bidDecreaseProportion/2;
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
function updateKeywords() {
var keywordIterator = AdWordsApp.keywords()
.withIds(uniqueIds.map(function(str){return str.split(idJoin);}))
.get();
while(keywordIterator.hasNext()){
var keyword = keywordIterator.next();
var uniqueId = keywordUniqueId(keyword);
var newBid = bidChange(uniqueId);
if(newBid !== -1){
keyword.setMaxCpc(newBid);
}
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
function resultsString(){
var results = [];
for(var uniqueId in keywordData){
var resultsRow = [uniqueId, keywordData[uniqueId]['ThisHour']['Impressions'], keywordData[uniqueId]['ThisHour']['AveragePosition']];
results.push(resultsRow.join(fieldJoin));
}
return results.join(lineJoin);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
}
so CampaignName isn't a valid with condition for the label selector. What you need to do instead is have a Campaign Selector in a while look before you come to your Label selector, which then feeds from the campaign iteration. I've done a quick and dirty example below, but of course, you'd have to take a look to see if doing this will require other changes later on (or earlier on) in your code.
var labelIds = [];
var campaignIterator = AdWordsApp.campaigns()
.withCondition("CampaignName CONTAINS_IGNORE_CASE 'MY CAMPAIGN NAME' ")
.get()
while (campaignIterator.hasNext())
{
var campaign = campaignIterator.next()
var labelIterator = campaign.labels()
.withCondition("CampaignName CONTAINS_IGNORE_CASE 'MY CAMPAIGN NAME' ")
.withCondition("KeywordsCount > 0")
.withCondition("LabelName CONTAINS_IGNORE_CASE 'Position '")
.get();
while (labelIterator.hasNext()) {
var label = labelIterator.next();
if (label.getName().substr(0,"position ".length).toLowerCase() == "position ") {
labelIds.push(label.getId());
}
}
if (labelIds.length == 0) {
Logger.log("No position labels found.");
return;
}
}
var labelIterator = AdWordsApp.labels()
I have this e-calendar JavaScript code that is displaying 24hour clock format. How do you get it to change to 12 hour clock? Forgive the chopped up code, I had to delete some of it to create the post.
I have posted the code below:
(function ($) {
var eCalendar = function (options, object) {
// Initializing global variables
var adDay = new Date().getDate();
var adMonth = new Date().getMonth();
var adYear = new Date().getFullYear();
var dDay = adDay;
var dMonth = adMonth;
var dYear = adYear;
var instance = object;
var settings = $.extend({}, $.fn.eCalendar.defaults, options);
function print() {
loadEvents();
var dWeekDayOfMonthStart = new Date(dYear, dMonth, 1).getDay();
var dLastDayOfMonth = new Date(dYear, dMonth + 1, 0).getDate();
var dLastDayOfPreviousMonth = new Date(dYear, dMonth + 1, 0).getDate() - dWeekDayOfMonthStart + 1;
var cBody = $('<div/>').addClass('c-grid');
var cEvents = $('<div/>').addClass('c-event-grid');
var cEventsBody = $('<div/>').addClass('c-event-body');
cEvents.append($('<div/>').addClass('c-event-title c-pad-top').html(settings.eventTitle));
cEvents.append(cEventsBody);
var cNext = $('<div/>').addClass('c-next c-grid-title c-pad-top');
var cMonth = $('<div/>').addClass('c-month c-grid-title c-pad-top');
var cPrevious = $('<div/>').addClass('c-previous c-grid-title c-pad-top');
cPrevious.html(settings.textArrows.previous);
cMonth.html(settings.months[dMonth] + ' ' + dYear);
cNext.html(settings.textArrows.next);
cPrevious.on('mouseover', mouseOver).on('mouseleave', mouseLeave).on('click', previousMonth);
cNext.on('mouseover', mouseOver).on('mouseleave', mouseLeave).on('click', nextMonth);
cBody.append(cPrevious);
cBody.append(cMonth);
cBody.append(cNext);
for (var i = 0; i < settings.weekDays.length; i++) {
var cWeekDay = $('<div/>').addClass('c-week-day c-pad-top');
cWeekDay.html(settings.weekDays[i]);
cBody.append(cWeekDay);
}
var day = 1;
var dayOfNextMonth = 1;
for (var i = 0; i < 42; i++) {
var cDay = $('<div/>');
if (i < dWeekDayOfMonthStart) {
cDay.addClass('c-day-previous-month c-pad-top');
cDay.html(dLastDayOfPreviousMonth++);
} else if (day <= dLastDayOfMonth) {
cDay.addClass('c-day c-pad-top');
if (day == dDay && adMonth == dMonth && adYear == dYear) {
cDay.addClass('c-today');
}
for (var j = 0; j < settings.events.length; j++) {
var d = settings.events[j].datetime;
if (d.getDate() == day && (d.getMonth() - 1) == dMonth && d.getFullYear() == dYear) {
cDay.addClass('c-event').attr('data-event-day', d.getDate());
cDay.on('mouseover', mouseOverEvent).on('mouseleave', mouseLeaveEvent);
}
}
cDay.html(day++);
} else {
cDay.addClass('c-day-next-month c-pad-top');
cDay.html(dayOfNextMonth++);
}
cBody.append(cDay);
}
var eventList = $('<div/>').addClass('c-event-list');
for (var i = 0; i < settings.events.length; i++) {
var d = settings.events[i].datetime;
if ((d.getMonth() - 1) == dMonth && d.getFullYear() == dYear) {
var date = lpad(d.getDate(), 2) + '/' + lpad(d.getMonth(), 2) + ' ' + lpad(d.getHours(), 2) + ':' + lpad(d.getMinutes(), 2);
var item = $('<div/>').addClass('c-event-item');
var title = $('<div/>').addClass('title').html(date + ' ' + settings.events[i].title + '<br />');
var description = $('<div/>').addClass('description').html(settings.events[i].description + '<br />');
item.attr('data-event-day', d.getDate());
item.on('mouseover', mouseOverItem).on('mouseleave', mouseLeaveItem);
item.append(title).append(description);
eventList.append(item);
}
}
$(instance).addClass('calendar');
cEventsBody.append(eventList);
$(instance).html(cBody).append(cEvents);
}
return print();
}
$.fn.eCalendar = function (oInit) {
return this.each(function () {
return eCalendar(oInit, $(this));
});
};
}(jQuery));
getHours returns the range 0-23, so if it's greater than 11, subtract 12.
You could even get fancy and do like
(getHours() + 24) % 12 || 12
I meet a trouble with a function. actually I need to make this function to perform a calculation on some text fields. When I worked on a single line no problems. But recently, someone asked to make a table with multiple lines (one line can be added dynamically) so, I do the following function so that it can not only duplicate line but id change all the fields concerned, so I add class to these fields. therefore I proceed as follows:
function clone(line) {
newLine = line.cloneNode(true);
line.parentNode.appendChild(newLine);
var tab = document.getElementsByClassName('libelle_debours')
var i = -1;
while (tab[++i]) {
tab[i].setAttribute("id", "_" + i);
};
var cab = document.getElementsByClassName('ht_no_tva')
var j = -1;
while (cab[++j]) {
cab[j].setAttribute("id", "_" + j);
};
var dab = document.getElementsByClassName('ht_tva')
var k = -1;
while (dab[++k]) {
dab[k].setAttribute("id", "_" + k);
};
var eab = document.getElementsByClassName('taux')
var l = -1;
while (eab[++l]) {
eab[l].setAttribute("id", "_" + l);
};
var fab = document.getElementsByClassName('tva')
var m = -1;
while (fab[++m]) {
fab[m].setAttribute("id", "_" + m);
};
}
function delRow() {
var current = window.event.srcElement;
//here we will delete the line
while ((current = current.parentElement) && current.tagName != "TR");
current.parentElement.removeChild(current);
}
The problem in fact is the second function that is used to make the calculation:
function calcdebours() {
var taux = document.getElementById('debours_taux_tva').value;
var ht_no_tva = document.getElementById('debours_montant_ht_no_tva').value;
var ht_tva = document.getElementById('debours_montant_ht_tva').value;
var tva = Math.round((((ht_tva) * (taux)) / 100) * 100) / 100;;
if (taux == '') {
taux = 0;
}
if (ht_no_tva == '') {
ht_no_tva = 0;
}
if (ht_tva == '') {
ht_tva = 0;
}
document.getElementById('debours_montant_tva').value = tva;
document.getElementById('debours_montant_ttc').value = (tva) + parseFloat(ht_tva) + parseFloat(ht_no_tva)
}
function
montant_debours() {
var ttc = document.getElementById('debours_montant_ttc').value;
var ttc2 = document.getElementById('debours_montant_ttc2').value;
if (ttc == '') {
var ttc = 0;
} else {
var ttc = document.getElementById('debours_montant_ttc').value;
}
if (ttc2 == '') {
var ttc2 = 0;
} else {
var ttc2 = document.getElementById('debours_montant_ttc2').value;
}
tx = parseFloat(ttc) + parseFloat(ttc2);
document.getElementById('ttc_cheque').value = Math.round(tx * 100) / 100;
}
As Id are not the same, do I have to create as many functions
there are lines?
Is it possible to fit a single function to process each line?
If so can you tell me how?
If I'm not mistaken you can use for loop and append increment to the end of element's id. Like this:
trs = document.getElementById('container Id').getElementsByTagName('tr');
For (var i = 1, i <= trs.length; i++)
{
var el = document.getElementById('debours_montant_ttc' + i);
}