Shift Cell Range in Google Sheets - javascript

I'm trying to take a range of cells and shift them all to the right by one cell. I'd like this to occur once per weekly automatically. I'm aware in the Script editor I can create a trigger for it to schedule weekly, but I'm not sure how to code it.
If someone can help provide a code that allows me to indicate which SHEET and CELL RANGE to shift to the right by one cell, I would appreciate it.
Basically, what I'm trying to accomplish is tracking data for a number of weeks. Each week the sheet will be updated, and I would like the older data to shift right one, basically indicating that the data has gotten a week older.
In addition, I'm only trying to keep data for like 6 weeks, so the data isn't ongoing forever.
A bit of an example: Column A = current week (updated manually).
Columns B-F = previous weeks (1-5 weeks ago).
Once a week, the data in columns A-E should be shifted right 1 to preserve the data. After the shift, data is manually updated in Column A to represent the current week. This would then result in showing data for the current week and 5 additional weeks... totaling 6 weeks of data.
I'd be interested if there is a way to just shift columns while excluding the header row, instead of a range, if possible.

Could try something like this?
function myFunction() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
// This inserts 1 columns before the first column
sheet.insertColumnsBefore(1, 1);
// labels the weeks static
ss.getRange('A1').setFontWeight("bold").setValue("Week1").setBackground("#BBBBBB");
ss.getRange('B1').setFontWeight("bold").setValue("Week2").setBackground("#BBBBBB");
ss.getRange('C1').setFontWeight("bold").setValue("Week3").setBackground("#BBBBBB");
ss.getRange('D1').setFontWeight("bold").setValue("Week4").setBackground("#BBBBBB");
ss.getRange('E1').setFontWeight("bold").setValue("Week5").setBackground("#BBBBBB");
ss.getRange('F1').setFontWeight("bold").setValue("Week6").setBackground("#BBBBBB");
}

Copy or Cut and Paste
Based upon your last comment I decided to give you another solution. This solution will either copy or cut and paste any range of data from any sheet to a any other range with the same dimensions. The ranges can be on the same page or different pages and the ranges can overlap. Also once you copy a range the document will remember the source and destination ranges so that you can copy or cut and paste them again without having to set up the ranges. If you want to change the range just run the routine and it will give you the choice to clear the range and then you can just run it again and it will remember the new ranges.
The copy and cut selection on the menu runs the routine. The Display Properties selection displays you current setup. The clear ranges will just delete everything in DocumentProperties.
But the Copy and Cut selection will give you all of the same info.
function onOpen()
{
var ui = SpreadsheetApp.getUi();
ui.createMenu('My Tools')
.addItem('Copy or Cut', 'copyFromToSetupUi')
.addItem('Display Properties','dispProperties')
.addItem('Clear Ranges','clearCopyProperties')
.addToUi();
}
function dispProperties()
{
var copyProperties = PropertiesService.getDocumentProperties();
var srcShtNameStr = copyProperties.getProperty('SourceSheetName');
var srcShtRangeStr = copyProperties.getProperty('SourceSheetRange');
var desShtNameStr = copyProperties.getProperty('DestinationSheetName');
var desShtRangeStr = copyProperties.getProperty('DestinationSheetRange');
var title = 'Copy From To Sheets Properties';
var msg = 'Source Sheet Name = ' + srcShtNameStr + '<br />';
msg += 'Source Sheet Range = ' + srcShtRangeStr + '<br />';
msg += 'Destination Sheet Range = ' + desShtNameStr + '<br />';
msg += 'Destination Sheet Range = ' + desShtRangeStr + '<br />';
msg += '<input type="button" value="Exit" onClick="google.script.host.close();" />';
dispStatus(title,msg);
}
function copyFromToSheets()
{
var copyProperties = PropertiesService.getDocumentProperties();
var srcRange = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(copyProperties.getProperty('SourceSheetName')).getRange(copyProperties.getProperty('SourceSheetRange'));
var srcA = srcRange.getValues();
srcRange.setBackground('#ffffff');
var desRange = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(copyProperties.getProperty('DestinationSheetName')).getRange(copyProperties.getProperty('DestinationSheetRange'));
desRange.setValues(srcA);
desRange.setBackground('#ffffff');
}
function cutnpasteFromToSheets()
{
var copyProperties = PropertiesService.getDocumentProperties();
var srcRange = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(copyProperties.getProperty('SourceSheetName')).getRange(copyProperties.getProperty('SourceSheetRange'));
var srcA = srcRange.getValues();
srcRange.clearContent();
srcRange.setBackground('#ffffff');
var desRange = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(copyProperties.getProperty('DestinationSheetName')).getRange(copyProperties.getProperty('DestinationSheetRange'));
desRange.setValues(srcA);
desRange.setBackground('#ffffff');
}
function setCopySource()
{
var srcShtName = SpreadsheetApp.getActiveSheet().getName();
var srcShtRange = SpreadsheetApp.getActiveRange();
var copyProperties = PropertiesService.getDocumentProperties();
copyProperties.setProperty('SourceSheetRange', srcShtRange.getA1Notation());
copyProperties.setProperty('SourceSheetName', srcShtName);
srcShtRange.setBackground('#d9caa9');
}
function setCopyDestination()
{
var desShtName = SpreadsheetApp.getActiveSheet().getName();
var desShtRange = SpreadsheetApp.getActiveRange();
var copyProperties = PropertiesService.getDocumentProperties();
copyProperties.setProperty('DestinationSheetRange',desShtRange.getA1Notation());
copyProperties.setProperty('DestinationSheetName', desShtName);
desShtRange.setBackground('#c4df87');
}
function clearCopyProperties()
{
var copyProperties = PropertiesService.getDocumentProperties();
var srcShtNameStr = copyProperties.getProperty('SourceSheetName');
var srcShtRangeStr = copyProperties.getProperty('SourceSheetRange');
var desShtNameStr = copyProperties.getProperty('DestinationSheetName');
var desShtRangeStr = copyProperties.getProperty('DestinationSheetRange');
if(srcShtNameStr && srcShtRangeStr)
{
var srcShtRange = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(srcShtNameStr).getRange(srcShtRangeStr);
srcShtRange.setBackground('#ffffff');
}
else
{
SpreadsheetApp.getUi().alert('At least one of the Source String Properties is undefined in clearCopyProperties so background color cannot be reset.');
}
if(desShtNameStr && desShtRangeStr)
{
var desShtRange = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(desShtNameStr).getRange(desShtRangeStr);
desShtRange.setBackground('#ffffff');
}
else
{
SpreadsheetApp.getUi().alert('At least one of the Destination String Properties is undefined in clearCopyProperties so background color cannot be reset.');
}
copyProperties.setProperty('SourceSheetName', '');
copyProperties.setProperty('SourceSheetRange', '');
copyProperties.setProperty('DestinationSheetName', '');
copyProperties.setProperty('DestinationSheetRange', '');
}
function copyFromToSetupUi()
{
var copyProperties = PropertiesService.getDocumentProperties();
var srcShtNameStr = copyProperties.getProperty('SourceSheetName');
var srcShtRangeStr = copyProperties.getProperty('SourceSheetRange');
var desShtNameStr = copyProperties.getProperty('DestinationSheetName');
var desShtRangeStr = copyProperties.getProperty('DestinationSheetRange');
var title='No Title';
var msg = 'No Text';
if(!srcShtNameStr || !srcShtRangeStr ) //if !src
{
title = 'Select Source Range';
msg = '<p>Please select input range from <strong>Source Sheet.</strong> and then press "Source Range Selected" button below.</p>\
<br /><input type="button" value="Source Range Selected" onclick="google.script.run.copyFromToSetupHelper(1);google.script.host.close();" />';
msg += '<script>console.log(\'flag1\');</script>';
dispStatus(title, msg);
}
if ((srcShtNameStr && srcShtRangeStr) && (!desShtNameStr || !desShtRangeStr)) //if src and !des
{
var srcShtRange = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(srcShtNameStr).getRange(srcShtRangeStr);
title = 'Select Destination Range';
msg = '<p>Please select a destination range which is ' + srcShtRange.getNumRows() + ' rows by ' + srcShtRange.getNumColumns() + ' columns.</p>';
msg += '<br /><input type="button" value="Destination Range Selected" onclick="google.script.run.copyFromToSetupHelper(2);google.script.host.close();" />';
msg += '<br />Input Range: ' + srcShtRangeStr + '<br /><input type="button" value="Clear Ranges and Start Over" onClick="google.script.run.clearCopyProperties();google.script.host.close(); />';
dispStatus(title, msg);
}
if((srcShtNameStr && srcShtRangeStr) && (desShtNameStr && desShtRangeStr))//if src and des
{
var srcShtRange = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(srcShtNameStr).getRange(srcShtRangeStr);
var desShtRange = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(desShtNameStr).getRange(desShtRangeStr);
if((desShtRange.getWidth()===srcShtRange.getWidth()) && (desShtRange.getHeight()===srcShtRange.getHeight()))
{
title= 'Displaying Source and Destination Ranges';
msg = '<br />Source Sheet/Range: ' + srcShtNameStr + '/' + srcShtRangeStr + '<br />Destination Sheet/Range: ' + desShtNameStr + '/' + desShtRangeStr + '<br />';
msg += '<br /><input type="button" value="Perform Copy" onclick="google.script.run.copyFromToSheets();google.script.host.close();" />';
msg += '<br /><input type="button" value="Perform Cut & Paste" onclick="google.script.run.cutnpasteFromToSheets();google.script.host.close();" />';
msg += '<br /><input type="button" value="Keep both Ranges Defined" onclick="google.script.host.close();" />';
msg += '<br /><input type="button" value="Clear Ranges and Start Over" onclick="google.script.run.clearCopyProperties();google.script.host.close();" />';
dispStatus(title,msg);
}
else
{
var srcShtRange = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(srcShtNameStr).getRange(srcShtRangeStr);
var desShtRange = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(desShtNameStr).getRange(desShtRangeStr);
var newdesShtRange = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(desShtNameStr).getRange(desShtRange.getRow(), desShtRange.getColumn(), srcShtRange.getNumRows(), srcShtRange.getNumColumns());
desShtRange.setBackground('white');
newdesShtRange.setBackground('#c4df87');
copyProperties.setProperty('DestinationSheetRange', newdesShtRange.getA1Notation());
title = 'Destination Range Adjusted';
msg = 'Source Range and Destination Range Dimension did not Match. So it was assumed that the upper left corner of the Destination Range is correct';
msg += 'and that the Sheet Selections were correct. The Destination Range was modified to have the same dimensions as the Source Range. ';
msg += '<br />Source Sheet/Range: ' + srcShtNameStr + '/' + srcShtRangeStr + '<br />Destination Sheet/Range: ' + desShtNameStr + '/' + newdesShtRange.getA1Notation() + '<br />';
msg += '<br /><input type="button" value="Perform Copy" onclick="google.script.run.copyFromToSheets();google.script.host.close();" />';
msg += '<br /><input type="button" value="Perform Cut & Paste" onclick="google.script.run.cutnpasteFromToSheets();google.script.host.close();" />';
msg += '<br /><input type="button" value="Keep both Ranges Defined" onclick="google.script.host.close();" />';
msg += '<br /><input type="button" value="Clear Ranges and Start Over" onclick="google.script.run.clearCopyProperties();;google.script.host.close(); />';
dispStatus(title,msg);
}
}
}
function copyFromToSetupHelper(mode)
{
var mode = (typeof(mode) !== 'undefined')? mode : 0;
switch(mode)
{
case 1:
setCopySource();
copyFromToSetupUi();
break;
case 2:
setCopyDestination();
copyFromToSetupUi();
break;
default:
clearCopyProperties();
}
}
// Display a modeless dialog box with custom HtmlService content.
function dispStatus(title,html,width,height)
{
var title = typeof(title) !== 'undefined' ? title : 'No Title Provided';
var width = typeof(width) !== 'undefined' ? width : 400;
var height = typeof(height) !== 'undefined' ? height : 300;
var html = typeof(html) !== 'undefined' ? html : '<p>No html provided.</p>';
var htmlOutput = HtmlService
.createHtmlOutput(html)
.setWidth(width)
.setHeight(height);
SpreadsheetApp.getUi().showModelessDialog(htmlOutput, title);
}

Google Script: Moves active selection range any direction
This will shift any selected range any direction you wish and it can select the destination range as the active selection. I've only tried it for one cell step moves so far.
function rangeJog(hoffset,voffset,moveselection)
{
var hoffset = (typeof(hoffset) !== 'undefined')? hoffset : 1;
var voffset = (typeof(voffset) !== 'undefined')? voffset : 0;
var moveselection = (typeof(moveselection) != 'undefined')? moveselection : true;
var src = SpreadsheetApp.getActiveRange();
var srcA1 = src.getA1Notation();
var row = src.getRow() + voffset;
var col = src.getColumn() + hoffset;
var rows = src.getLastRow() - src.getRow() + 1;
var cols = src.getLastColumn() - src.getColumn() +1;
if((row<1) || (col<1))
{
//dispStatus('No More Room to Move','<p>Either the first row or the first column or both will be less than one. <input type="button" value="exit" onClick="google.script.host.close();" /></p>', 400, 200);
SpreadsheetApp.getUi().alert('No more room to move.');
}
else
{
var des = SpreadsheetApp.getActiveSheet().getRange(src.getRow() + voffset, src.getColumn() + hoffset, src.getLastRow() - src.getRow() + 1, src.getLastColumn() - src.getColumn() +1);
var srcA = src.getValues();
src.clearContent();
des.setValues(srcA);
if(moveselection)
{
SpreadsheetApp.getActiveSheet().setActiveSelection(des);
}
}
var end = "is near";
}
It works on the selected range for now but any range could work because all calculations are relative to the src range. I also modified it to move the selection if moveselection is true.
But the idea of inserting a new column to the left is perhaps a simpler way to go. Although I don't see any insert cells command so inserting a column will move your headers around as well.

Related

Using variable for an identifier name (using jquery selectors)

Believe me, I've been looking for examples online for hours. None of them seem to help.
I'm working on making a table. There are some columns with dropdown menu and I've assigned ID to each menu. Inside a loop, I'm trying to assign selected value for each dropdown menu.
var row$ = $('<tr/>');
function updateDataBodyGenerator(myList) {
for (var i = 0 ; i < myList.length ; i++) {
var row$ = $('<tr/>');
var colIndex = 0;
for (var key in myList[i]) {
var cellValue = myList[i][columns[colIndex]];
if (cellValue == null) { cellValue = ""; }
var severityDropDownMenu = "severityDropDownMenu" + i;
colIndex++;
switch (key) {
case "Test Case":
...
break;
case "Test Result":
...
break;
case "Severity":
var severitySting = '<td><select id="' + severityDropDownMenu + '" class="dropDownMenu">' +
'<option value="Red">Red</option>' +
'<option value="Green">Green</option>'+
'<option value="Yellow">Yellow</option>';
row$.append($(severitySting));
//failed
//$("#severityDropDownMenu" + i).val(cellValue);
//failed
//var selectorString = "#" + severityDropDownMenu.toString();
//$(selectorString).val("Green");
//failed
//$("#" + severityDropDownMenu).val(cellValue);
//failed
//var selectorString = '#' + severityDropDownMenu;
//$(selectorString).val(cellValue);
//works
//$('#severityDropDownMenu0').val(cellValue);
...
As you can see in the comments, I've tried several approaches and only 1 worked which was $('#severityDropDownMenu0').val(cellValue); but that will only change 1 dropdown menu.
I appreciate your time and assistance.
Currently you're trying to use the # selector to target the dropdown by ID.
The issue here (as mentioned in the comments) is that this selector will search the DOM for the element, however because you've never added this element to the DOM, it doesn't exist on the page; the selector will return nothing.
What you can do instead is actually turn your severitySting into a jQuery element to set its value. Whenever you do append it, the value will be properly set. Like so:
var $severity = $(severitySting); //This is the <td>
var $dropdown = $severity.find("select") //This is the <select>
$dropdown.val(cellValue); //Set dropdown value
Demo:
var severityDropDownMenu = "mytest";
var cellValue = "Yellow";
var severitySting = '<td><select id="' + severityDropDownMenu + '" class="dropDownMenu">' +
'<option value="Red">Red</option>' +
'<option value="Green">Green</option>' +
'<option value="Yellow">Yellow</option>';
var $severity = $(severitySting);
var $dropdown = $severity.find("select");
$dropdown.val(cellValue);
$("tr").append($severity);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr></tr>
</table>

.replacewith not working when called a second time

I have the following markup:
<fieldset>
<legend>Headline Events...</legend>
<div style="width:100%; margin-top:10px;">
<div style="width:100%; float:none;" class="clear-fix">
<div style="width:400px; float:left; margin-bottom:8px;">
<div style="width:150px; float:left; text-align:right; padding-top:7px;">
Team Filter:
</div>
<div style="width:250px; float:left;">
<input id="teamFilter" style="width: 100%" />
</div>
</div>
<div style="width:400px; float:left; margin-bottom:8px;">
<div style="width:150px; float:left; text-align:right; padding-top:7px;">
Type Filter:
</div>
<div style="width:250px; float:left;">
<input id="typeFilter" style="width: 100%" />
</div>
</div>
</div>
</div>
<div id="diaryTable" name="diaryTable" class="clear-fix">
Getting latest Headlines...
</div>
</fieldset>
I also have the following scripts
<script>
function teamFilterChange(e) {
//alert(this.value());
setCookie('c_team', this.value(), 90);
$c1 = getCookie('c_team');
$c2 = getCookie('c_type');
var param = "true|" + $c1 + "|" + $c2;
outputHLDiaryEntries(param);
}
function typeFilterChange(e) {
//alert(this.value());
setCookie('c_type', this.value(), 90);
$c1 = getCookie('c_team');
$c2 = getCookie('c_type');
var param = "true|" + $c1 + "|" + $c2;
outputHLDiaryEntries(param);
}
// This optional function html-encodes messages for display in the page.
function htmlEncode(value) {
var encodedValue = $('<div />').text(value).html();
return encodedValue;
}
function outputHLDiaryEntries(param) {
var url = "Home/DiaryEntries/";
var data = "id=" + param;
$.post(url, data, function (json) {
var n = json.length;
alert(n + ' ' + json);
if(n == 0){
//json is 0 length this happens when there were no errors and there were no results
$('#diaryTable').replaceWith("<span style='color:#e00;'><strong>Sorry: </strong> There are no headline events found. Check your filters.</span>");
} else {
//json has a length so it may be results or an error message
//if jsom[0].dID is undefined then this mean that json contains the error message from an exception
if (typeof json[0].dID != 'undefined') {
//json[0].dDI has a value so we
//output the json formatted results
var out = "";
var i;
var a = "N" //used to change the class for Normal and Alternate rows
for (i = 0; i < json.length; i++) {
out += '<div class="dOuter' + a + '">';
out += '<div class="dInner">' + json[i].dDate + '</div>';
out += '<div class="dInner">' + json[i].dRef + '</div>';
out += '<div class="dInner">' + json[i].dTeam + '</div>';
out += '<div class="dInner">' + json[i].dCreatedBy + '</div>';
out += '<div class="dType ' + json[i].dType + '">' + json[i].dType + '</div>';
out += '<div class="dServer">' + json[i].dServer + '</div>';
out += '<div class="dComment">' + htmlEncode(json[i].dComment) + '</div></div>';
//toggle for normal - alternate rows
if (a == "N") {
a = "A";
} else {
a = "N";
}
}
//output our formated data to the diaryTable div
$('#diaryTable').replaceWith(out);
} else {
//error so output json string
$('#diaryTable').replaceWith(json);
}
}
}, 'json');
}
$(document).ready(function () {
//Set User Preferences
//First check cookies and if null or empty set to default values
var $c1 = getCookie('c_team');
if ($c1 == "") {
//team cookie does not exists or has expired
setCookie('c_team', 'ALL', 90);
$c1 = "ALL";
}
var $c2 = getCookie('c_type');
if ($c2 == "") {
//type cookie does not exists or has expired
setCookie('c_type', "ALL", 90);
$c2 = "ALL";
}
// create DropDownList from input HTML element
//teamFilter
$("#teamFilter").kendoDropDownList({
dataTextField: "SupportTeamText",
dataValueField: "SupportTeamValue",
dataSource: {
transport: {
read: {
dataType: "json",
url: "Home/SupportTeams?i=1",
}
}
}
});
var teamFilter = $("#teamFilter").data("kendoDropDownList");
teamFilter.bind("change", teamFilterChange);
teamFilter.value($c1);
//typeFilter
$("#typeFilter").kendoDropDownList({
dataTextField: "dTypeText",
dataValueField: "dTypeValue",
dataSource: {
transport: {
read: {
dataType: "json",
url: "Home/DiaryTypes?i=1",
}
}
}
});
var typeFilter = $("#typeFilter").data("kendoDropDownList");
typeFilter.bind("change", typeFilterChange);
typeFilter.value($c2);
// Save the reference to the SignalR hub
var dHub = $.connection.DiaryHub;
// Invoke the function to be called back from the server
// when changes are detected
// Create a function that the hub can call back to display new diary HiLights.
dHub.client.addNewDiaryHiLiteToPage = function (name, message) {
// Add the message to the page.
$('#discussion').append('<li><strong>' + htmlEncode(name)
+ '</strong>: ' + htmlEncode(message) + '</li>');
};
// Start the SignalR client-side listener
$.connection.hub.start().done(function () {
// Do here any initialization work you may need
var param = "true|" + $c1 + "|" + $c2;
outputHLDiaryEntries(param)
});
});
</script>
On initial page load the outputHLDiaryEntries function is called when the signalR hub is started. If I then change any of the dropdownlists this calls the outputHLDiaryEntries but the $('#diaryTable').replaceWith(); does not work. If I refresh the page the correct data is displayed.
UPDATE!
Based on A.Wolff's comments I fixed the issue by wrapping the content I needed with the same element I was replacing... by adding the following line at the beginning of the outputHLDiartEntries function...
var outStart = '<div id="diaryTable" name="diaryTable" class="clear-fix">';
var outEnd = '</div>';
and then changing each of the replaceWith so that they included the wrappers e.g.
$('#diaryTable').replaceWith(outStart + out + outEnd);
replaceWith() replaces element itself, so then on any next call to $('#diaryTable') will return empty matched set.
You best bet is to replace element's content instead, e.g:
$('#diaryTable').html("<span>New content</span>");
I had the same problem with replaceWith() not working when called a second time.
This answer helped me figure out what I was doing wrong.
The change I made was assigning the same id to the new table I was creating.
Then when I would call my update function again, it would create a new table, assign it the same id, grab the previous table by the id, and replace it.
let newTable = document.createElement('table');
newTable.id = "sameId";
//do the work to create the table here
let oldTable = document.getElementById('sameId');
oldTable.replaceWith(newTable);

Event listener code won't execute function as expected

I am trying to write a small javascript function which takes data from OpenSignal and then displays it in an html table.
This worked fine up until the point where I tried to make it user friendly by adding in an html form to accept the postcodes input. I tried to avoid using PHP to do this as my client won't have this installed.
I am adding an event listener to the submit button to detect when the form data has been submitted. I am then taking this and validating the string contains valid postcode(s). If they're invalid the program spits out an alert which says "Sorry but you seem to have entered an incorrect postcode.".
If not then I am taking the postcodes and passing them into my function processPostcodesOnServer(). The thing is that this doesn't work inside the event listener. When I pass postcodes in manually using javascript arrays and call the function outside of the event listener everything works fine. When I put it in the event listener it simply doesn't work. I have checked all the inputs to the function are correct and have stepped through the whole program numerous times and cannot find out what is causing the problem. It seems to me this is just another case of Javascripts random behaviour.
Can anyone help?? This is my HTML and Javascript files (I am using some JQuery so you will have to link with the latest version if you want to run this).
<!DOCTYPE html>
<html>
<head>
<title>Mobile Signals</title>
<script src="jquery-1.11.3.min.js"></script>
<script src="NetworkStats.js"></script>
</head>
<body>
<form id="postcodeForm">
Enter postcodes separated by commas<br>
<input type="text" id="postcodes" name="postcodes">
</br></br>
<input type="submit" value="Submit" id="submitButton">
</form>
<div id="theDiv">
</div>
<div id ="secondDiv"> </div>
<table id="theTable" border="1">
</table>
And Javascript
$( document ).ready(function() {
document.getElementById('submitButton').addEventListener('click', function() {
var input = $('#postcodeForm').serializeArray();
var postcodeString = input[0]["value"];
var output = postcodeString.split(",");
var postcodeString = "";
// check each postcode to see if there is any false postcodes
for (var postcode in output) {
var newPostcode = checkPostCode(output[postcode]);
if (newPostcode) {
postcodeString += " true ";
} else {
postcodeString += " false ";
}
}
if (postcodeString.indexOf("false") >= 0) {
// string contains a false so output an error message
window.alert("Sorry but you seem to have entered an incorrect postcode.")
} else {
// all the postcodes are correct, proceed to perform operations on them
processPostcodesOnServer(output);
}
}, false);
function processPostcodesOnServer(output) {
var apiKey = "c590c63f5b3818271a87a3e89fa215ae";
var distance = 10;
var tableNumber = 0;
//var output = ["WR141NE"];
for (var postcode in output) {
strippedPostcode = output[postcode].replace(/ /g,'');
getLatAndLong(strippedPostcode);
}
function googleCallback(latitude, longitude, postcode) {
contactServer(latitude, longitude, postcode);
}
/* Function to contact google and convert the postcode to lat long */
function getLatAndLong(postcode) {
var latitude;
var longitude;
var googleXmlHttp = new XMLHttpRequest();
var googleUrl = "http://maps.googleapis.com/maps/api/geocode/json?address="+ postcode + "&sensor=false";
googleXmlHttp.onreadystatechange = function() {
if (googleXmlHttp.readyState == 4 && googleXmlHttp.status == 200) {
var latLong = JSON.parse(googleXmlHttp.responseText);
latitude = latLong.results[0].geometry.location.lat;
longitude = latLong.results[0].geometry.location.lng;
googleCallback(latitude, longitude, postcode);
}
}
googleXmlHttp.open("GET", googleUrl, true);
googleXmlHttp.send();
}
function contactServer(latitude, longitude, postcode) {
var xmlhttp = new XMLHttpRequest();
var networkStatsUrl = "http://api.opensignal.com/v2/networkstats.json?lat="+latitude+"&lng="+longitude+"&distance=" + distance + "&apikey=" + apiKey;
/*
Functions to contact server and read JSON response back for NetworkStats
*/
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
var myArr = JSON.parse(xmlhttp.responseText);
sortTableData(myArr, postcode);
//displayData(myArr);
}
}
xmlhttp.open("GET", networkStatsUrl, true);
xmlhttp.send();
var functionCount = -1;
function sortTableData(arr, postcode) {
tableNumber++;
$("body").append("</br>" + postcode + "</br>");
theTable = "<table id='table"+ tableNumber + "' border='1'> </table>"
$("body").append(theTable);
var column1 = new Array();
var column2 = new Array();
var column3 = new Array();
var column4 = new Array();
var column5 = new Array();
var column6 = new Array();
var column7 = new Array();
//var output = '<table border="1">';
//var output = "";
for (var obj in arr) {
// find all the networks
if ((typeof arr[obj] === 'object') && (obj == "networkRank")) {
var networks = new Object();
networks = arr[obj];
var allNetworkKeys = Object.keys(networks);
//console.log(allNetworkKeys);
var networksArray = new Array();
$.each(networks, function(networkKey, networkValue){
//Do something with your key and value.
column1.push(networkKey);
if (networkKey.substring(0, 7) == "network") {
$.each(networkValue, function(networkTypeKey, networkTypeValue){
if (networkTypeKey == "type2G") {
column2.push('');
column3.push(networkTypeKey);
for (var variable in networkTypeValue) {
column2.push(variable);
column3.push(networkTypeValue[variable]);
}
} else if (networkTypeKey == "type3G") {
column4.push('');
column5.push(networkTypeKey);
for (var variable in networkTypeValue) {
column4.push(variable);
column5.push(networkTypeValue[variable]);
}
} else if (networkTypeKey == "type4G") {
column6.push('');
column7.push(networkTypeKey);
for (var variable in networkTypeValue) {
column6.push(variable);
column7.push(networkTypeValue[variable]);
}
}
});
//console.log(column1);
}
//console.log(column1, column2, column3, column4);
displayTable(column1, column2, column3, column4, column5, column6, column7);
column1 = []; column2 = []; column3 = []; column4 = []; column5 = []; column6 = []; column7 = [];
});
}
}
}
var counter = 0;
function displayTable(column1, column2, column3, column4, column5, column6, column7) {
var output = ""
//console.log(counter);
counter++;
var column1Length = column1.length;
var column2Length = column2.length;
var column3Length = column3.length;
var column4Length = column4.length;
var column5Length = column5.length;
var column6Length = column6.length;
var column7Length = column7.length;
var highestNumber = Math.max(column1Length, column2Length, column3Length, column4Length, column5Length, column6Length, column7Length);
for (var i=0; i<highestNumber; i++) {
var column1Reference = column1[i];
var column2Reference = column2[i];
var column3Reference = column3[i];
var column4Reference = column4[i];
var column5Reference = column5[i];
var column6Reference = column6[i];
var column7Reference = column7[i];
if (column1Reference === void 0) {
column1Reference = " "
}
if (column2Reference === void 0) {
column2Reference = " "
}
if (column3Reference === void 0) {
column3Reference = " "
}
if (column4Reference === void 0) {
column4Reference = " "
}
if (column5Reference === void 0) {
column5Reference = " "
}
if (column6Reference === void 0) {
column6Reference = " "
}
if (column7Reference === void 0) {
column7Reference = " "
}
output += "<tr>";
output += "<td>" + column1Reference + "</td>";
output += "<td>" + column2Reference + "</td>";
output += "<td>" + column3Reference + "</td>";
output += "<td>" + column4Reference + "</td>";
output += "<td>" + column5Reference + "</td>";
output += "<td>" + column6Reference + "</td>";
output += "<td>" + column7Reference + "</td>";
output += "</tr>";
}
//output += "</table>";
//var table = document.getElementById('theTable');
//console.log(output);
//oldOutput = table.innerHTML;
//table.innerHTML = oldOutput + output;
$("#table" +tableNumber).append(output);
console.log(output);
}
}
}
});
Alright, I got it working.
The table would actually be displayed, if only submitting the form wouldn't reload the page.
There are two ways around this:
Change your click handler to a submit handler and cancel the event!
Replace
document.getElementById('submitButton').addEventListener('click', function() {
// ...
}, false);
by
document.getElementById('postcodeForm').addEventListener('submit', function(event) {
event.preventDefault();
// ...
}, false);
Remove the form:
That would be as simple as removing <form id="postcodeForm"> and </form> from your HTML code, but since you use $('#postcodeForm') in JS, you're gonna have to change
var input = $('#postcodeForm').serializeArray();
var postcodeString = input[0]["value"];
var output = postcodeString.split(",");
into
var output = document.getElementById('postcodes').value.split(",");
to make it work.
(Inlining postcodeString is not actually necessary, but I suggest it, see below.)
If you go with this option, I suggest also removing the name attribute from #postcodes, simply because it serves no purpose.
But regardless of which option you choose, you should fix all those </br>s: It's <br> in HTML 5 (and it was <br/> in HTML 4, but never </br>).
(And don't forget those in your JS!)
And what is the googleCallback function good for, if it only passes its arguments to a function with the exact same list of parameters? Why not use contactServer directly?
And this code is really inefficient:
var postcodeString = "";
// check each postcode to see if there is any false postcodes
for(var postcode in output)
{
var newPostcode = checkPostCode(output[postcode]);
if(newPostcode)
{
postcodeString += " true ";
}
else
{
postcodeString += " false ";
}
}
if(postcodeString.indexOf("false") >= 0)
{
// string contains a false so output an error message
window.alert("Sorry but you seem to have entered an incorrect postcode.")
}
else
{
// all the postcodes are correct, proceed to perform operations on them
processPostcodesOnServer(output);
}
I mean, strings, really? Consider:
// check each postcode to see if there is any invalid postcodes
for(var postcode in output)
{
if(checkPostCode(output[postcode]) === false)
{
// current postcode is invalid so output an error message and return
window.alert("Sorry but you seem to have entered an incorrect postcode.");
return;
}
// at this point, all the postcodes are valid, proceed to perform operations on them
processPostcodesOnServer(output);
Also, you use a lot of variables only exactly once, resulting in quite an overhead.
For example, this:
var column1Length = column1.length;
var column2Length = column2.length;
var column3Length = column3.length;
var column4Length = column4.length;
var column5Length = column5.length;
var column6Length = column6.length;
var column7Length = column7.length;
var highestNumber = Math.max(column1Length, column2Length, column3Length, column4Length, column5Length, column6Length, column7Length);
Which could be shortened to this:
var highestNumber = Math.max(column1.length, column2.length, column3.length, column4.length, column5.length, column6.length, column7.length);
Sure this makes the line a little longer, but for 7 additional characters you can save 7 entire lines!
Or, your displayTable function could really be shortened to this:
function displayTable()
{
var output = '';
var highestNumber = Math.max(arguments[0].length, arguments[1].length, arguments[2].length, arguments[3].length, arguments[4].length, arguments[5].length, arguments[6].length);
for(var i = 0; i < highestNumber; i++)
{
output += '<tr>';
for(var j = 0; j < 7; j++)
{
output += '<td>' + arguments[j][i] + '</td>';
}
output += '</tr>';
}
$('#table' + tableNumber).append(output);
}
Then, you have a lot of {1} in your RegEx - why? [0-9]{1} is equal to [0-9] (or \d, but with that be careful to escape \ if using it in strings).
And finally, I suggest you run your code through JSHint or something similar to get rid of inconsistencies (be careful with JSLint though, that one has really aggressive and unreasonable conventions).
You have var postcodeString twice.
var keyword should only be used once per scope.

How to make list in jQuery mobile nested list?

Can you please tell me how to make list in jQuery mobile? I am trying to make this type list as given in fiddle on pop up screen dynamically .
Here is the fiddle
In this fiddle I make two rows.In first row there is only p tag. But in second row there is nested collapsible rows. I need to make same thing in pop up screen. I am able to make first row. But In my second row contend is null why? Can you suggest where I am wrong?
fiddle
$(function () {
$('#test').click(function(){
alert('d');
createCommandPopUpTabs();
$("#tabbedPopup").popup("open");
});
});
var tabsHeader = [ "InputParameter", "basic"];
var tabsHeader_basic = [ "XYZ", "Third Level",
];
function createCommandPopUpTabs(){
var header = "<h3 >dd</h3>";
var commmand = 'dd';
var button = '<button onclick="return submitCommand("'+
'")" style="" class="donebtn common-button1">Save</button>';
$("#commandInfo").append(button);
$("#commandInfoheader").html(header);
for ( var i = 0; i < tabsHeader.length; i++) {
var headerId = tabsHeader[i] + "_tab" + commmand;
var header = "<div data-role='collapsible' data-collapsed='false' id='"
+ headerId + "'><h3>InputParameter</h3></div>";
var content ;
if(tabsHeader[i]=="InputParameter"){
content = "<p>yes</p>";
}else if(tabsHeader[i]=="basic"){
for ( var i = 0; i < tabsHeader_basic.length; i++) {
headerId = tabsHeader_basic[i] + "_tab" + commmand;
header = "<div data-role='collapsible' data-collapsed='false' id='"
+ headerId + "'><h3>basic</h3></div>";
content += getcontend(tabsHeader_basic[i]);
}
}
$("#tabbedSet").append(header);
$("#tabbedSet").find("#" + headerId).append(content);
$("#tabbedSet").collapsibleset("refresh");
}
}
function getcontend(name){
if(name=="Third Level"){
return"<p>Third Level></p>";
} if(name=="XYZ"){
return"<p> second Level></p>";
}
}
There are errors in your code and logic. I will only go over a couple of them to hopefully get you on the right path:
In tabsHeader_basic array the Third Level has a space in it which you later use as an ID which makes it an invalid ID because you cannot have spaces in an ID.
From the HTML 5 Draft:
The value must not contain any space characters.
Also, the "basic" collapsible div needs to exist before you start adding the nested collapsible div.
So this line needs to come out of the for loop
header = "<div data-role='collapsible' data-collapsed='false' id='"+ headerId + "'><h3>basic</h3></div>";
Go through the JSFiddle and compare your code agaisnt my changes.
Hopefully that helps! Let me know if you have any other questions.
I have updated createCommandPopUpTabs() function.
Also removed space in Third Level on var tabsHeader_basic = ["XYZ", "ThirdLevel"];
Check the Updated Fiddle
function createCommandPopUpTabs() {
var header = "<h3 >dd</h3>";
var commmand = 'dd';
var button = '<button onclick="return submitCommand("' +
'")" style="" class="donebtn common-button1">Save</button>';
$("#commandInfo").html(button);
$("#commandInfoheader").html(header);
$("#tabbedSet").html('');
for (var i = 0; i < tabsHeader.length; i++) {
var headerId = tabsHeader[i] + "_tab" + commmand;
var header = "<div data-role='collapsible' data-collapsed='true' id='" + headerId + "'><h3>" + tabsHeader[i] + "</h3></div>";
$("#tabbedSet").append(header);
var content;
if (tabsHeader[i] == "InputParameter") {
content = "<p>yes</p>";
$("#tabbedSet").find("#" + headerId).append(content);
} else if (tabsHeader[i] == "basic") {
for (var j = 0; j < tabsHeader_basic.length; j++) {
var headerId1 = tabsHeader_basic[j] + "_tab" + commmand;
var header1 = "<div data-role='collapsible' data-collapsed='true' id='" + headerId1 + "'><h3>" + tabsHeader_basic[j] + "</h3></div>";
var content1 = getcontend(tabsHeader_basic[j]);
$("#tabbedSet").find("#" + headerId).append(header1);
$("#tabbedSet").find("#" + headerId1).append(content1);
}
}
$("#tabbedSet").collapsibleset("refresh");
}
}

Splitting an array

I have two javascript functions, the first one is working, teh second is working but not echoing the correct value in the hidden inputs.
Ive manage to get the last hidden input value correct but I'm not sure how
var customTicketsArr = Array();
function EditEventAddTicket(){
alertWrongTime = false;
var TicketName = jQuery("#ticketname").val();
var TicketPrice = jQuery("#ticketprice").val();
var ticketquantity = jQuery("#ticketquantity").val();
var storeString = "TicketName" + TicketName + "TicketPrice" + TicketPrice + "Quantity" + ticketquantity + '';
customTicketsArr.push(storeString);
EditEventUpdateTickets(true);
}
function EditEventUpdateTickets(fade){
jQuery("#custom_tickets_string").val(customTicketsArr);
var output = "";
var style = "";
for (i = customTicketsArr.length-1; i >= 0; i--){
ticketname = customTicketsArr[i].split("TicketName");
ticketprice = customTicketsArr[i].split("TicketPrice");
ticketquantity = customTicketsArr[i].split("Quantity");
if(fade){
if (customTicketsArr.length - 1 == i){
style = "display: none; ";
var fadeInDiv = i;
} else {
style = "";
}
}
if (i % 2 == 1) { style += "background-color: #660000; "}
html = "<div id='customticket" + i + "' class='customeventbase' style='" + style + "'>";
html += '<input type="hidden" name="customTicketid[' + i + '][Name]" id="customticketName' + i + '" value="'+ ticketname + '" />';
html += '<input type="hidden" name="customTicketid[' + i + '][Price]" id="customticketPrice' + i + '" value="' +ticketprice[1] +'" />';
html += '<input type="hidden" name="customTicketid[' + i + '][Quantity]" id="customticketQuantity' + i + '" value="'+ ticketquantity[1] +'" />';
html += '<button class="customeventdel" type="button" onClick="EditEventRemoveDate(' + i + ')"></button>';
html += '<div class="clear"></div>';
html += '</div>\n';
output += html;
}
output += "<input type='hidden' id='custom_ticket_info' name='custom_ticket_info' value='" + customTicketsArr + "' />";
jQuery("#custom_ticket_container").html(output);
if(fade){
setTimeout("EditEventfadeInDiv(" + fadeInDiv +")", 10);
}
}
this outputs:
<div style="background-color: #660000; " class="customeventbase" id="customticket1">
<input type="hidden" value=",testTicketPrice50Quantity44" id="customticketName1" name="customTicketid[1][Name]">
<input type="hidden" value="undefined" id="customticketPrice1" name="customTicketid[1][Price]">
<input type="hidden" value="44" id="customticketQuantity1" name="customTicketid[1][Quantity]">
<button onclick="EditEventRemoveDate(1)" type="button" class="customeventdel"></button>
<div class="clear"></div></div>
the values for the first two hidden fields are incorrect
They're not incorrect values - split() is doing exactly what it is supposed to - returning an array of substrings after removing the separator.
With your string structure, splitting on TicketName will give you two strings - the substring before the separator and the substring after - TicketName itself is not included.
Thus, for the string "TicketNametestTicketPrice50Quantity44", you will get "" and "testTicketPrice50Quantity44" when you split on "TicketName" . Splitting the same string on TicketPrice will give you "TicketNametest" and "50Quantity44".
I'd suggest putting objects into your array instead -
var storeObject = {
"TicketName" : TicketName,
"TicketPrice" : TicketPrice,
"Quantity" : ticketquantity
};
customTicketsArr.push(storeObject);
You can then get back the data as:
for (i = customTicketsArr.length-1; i >= 0; i--){
var currentObject = customTicketsArr[i];
var ticketname = currentObject.TicketName;
var ticketprice = currentObject.TicketPrice;
var ticketquantity = currentObject.Quantity;
//do other stuff here
}
why do you save it as a string? I would recommend storing it in an object:
function EditEventAddTicket(){
alertWrongTime = false;
var TicketName = jQuery("#ticketname").val();
var TicketPrice = jQuery("#ticketprice").val();
var ticketquantity = jQuery("#ticketquantity").val();
var ticket = {"TicketName": TicketName, "TicketPrice": TicketPrice, "Quantity": ticketquantity};
customTicketsArr.push(ticket);
EditEventUpdateTickets(true);
}
and then you can simply load the data:
for (i = customTicketsArr.length-1; i >= 0; i--){
ticketname = customTicketsArr[i].TicketName;
ticketprice = customTicketsArr[i].TicketPrice;
ticketquantity = customTicketsArr[i].Quantity;
// ...
}
Why not just make a two dimensional array?
var customTicketsArr = Array();
function EditEventAddTicket() {
customTicketsArr.push({
'name' : jQuery("#ticketname").val(),
'price' : jQuery("#ticketprice").val(),
'qty' : jQuery("#ticketquantity").val()
});
}

Categories

Resources