I have written a code that finds two strings and in return it should tell me if these two strings are existing:
function searchTwoString(data, str1, str2) {
var strX = str1 + " " + strValueX + "\r\n";
var strY = str2 + " " + strValueY;
var strValueX;
var strValueY;
for (var i = 0; i < data.length; i++) {
if (data[i] === str1) {
var strValueX = " exist";
continue;
} else if (data[i] === str2) {
var strValueY = " exist";
break;
}
}
return strX + strY;
}
Achieved result:
str1 undefined
str2 undefined
Expected result:
str1 exist
str2 exist
it tells me my strvalueX & strvalueY are undefined isn't it i have already gave the values in the if statement?
thanks to those who will help out
Here is an answer to your question with comment.
Hope you understand what I'm talking about.
function searchTwoString(data, str1, str2) {
var strX;// = str1 + " " + strValueX + "\r\n";
var strY;// = str2 + " " + strValueY;
var strValueX;
var strValueY;
for (var i = 0; i < data.length; i++) {
if (data[i] === str1) {
// var strValueX = " exist";
// do not define again
strValueX = " exist";
continue;
} else if (data[i] === str2) {
// var strValueY = " exist";
// do not define again
strValueY = " exist";
break;
}
}
// define the value here after strValueX and strValueY is set
strX = str1 + " " + strValueX + "\r\n";
strY = str2 + " " + strValueY;
return strX + strY;
}
The order of your statements is off. In lines 2 and 3, you are using strValueX and strValueY before they are defined. Lines 2 and 3 should be moved to before the return so that they will have the updated values.
I believe there is also a shadowing problem, as in the if statements you are creating new variables with the var keyword (e.g. var strValueX = " exist";). You will want to remove var from the if statements so that it updates the values of the outer variables.
I'm creating a basic .fountain editor to html parser that pretty much checks for words typed in a textarea on keyup.
Line by line parsing works below, but of course users would type in " **bold** then *italic* " in a single line but I can't seem to get it to scan each word in a line.
Below is my code:
jQuery.fn.parseAsFountain = function( window, jQuery ){
jQuery = $;
var storybox = $(this).val();
story = storybox.split('\n');
// Process The entire box
for( var i=0;i<story.length;i++ ){
var line = story[i];
SubstitutePerLine(line);
}
story_cleared = story.join('\n');
story_breaks = story_cleared.replace(/(?:\r\n|\r|\n)/g, '<br />');
return story_breaks;
function SubstitutePerLine(line){
if( line.match(/^[*].*[*]$/) ){
newval = line.slice(1, -1);
if( newval.match(/^[*].*[*]$/) ){
newval2 = newval.slice(1, -1);
if( newval2.match(/^[*].*[*]$/) ){
newval3 = newval2.slice(1, -1);
if( newval3.match(/\\/) ) {
if(newval3.match(/\\\*/)){
slash_val = newval3.replace(/\\/, '');
story[i] = '<b><i>' + slash_val + '</i></b>';
}
else {
story[i] = '<b><i>' + newval3 + '</i></b>';
}
}
else {
story[i] = '<b><i>' + newval3 + '</i></b>';
}
}
else if( newval2.match(/\\/) ) {
if(newval2.match(/\\\*/)){
slash_val = newval2.replace(/\\/, '');
story[i] = '<b>' + slash_val + '</b>';
}
else {
story[i] = '<b>' + newval2 + '</b>';
}
}
else {
story[i] = '<b>' + newval2 + '</b>';
}
}
else if( newval.match(/\\/) ) {
if(newval.match(/\\\*/)){
slash_val = newval.replace(/\\/, '');
story[i] = '<i>' + slash_val + '</i>';
}
else {
story[i] = '<i>' + newval + '</i>';
}
}
else {
story[i] = '<i>' + newval + '</i>';
}
}
if( line.match(/#/) ){
newval = line.replace(/^#/, '');
story[i] = '<p hidden>' + newval + '</p>';
}
if( line.match(/##/) ){
newval = line.replace(/^##/, '');
story[i] = '<p hidden>' + newval + '</p>';
}
if( line.match(/###/) ){
newval = line.replace(/^###/, '');
story[i] = '<p hidden>' + newval + '</p>';
}
return story;
}
}
I've tried re-splitting it by word in another split(" ") inside the loop then joining it again afterwards but to no avail.
Parsing markup is not a straightforward task. To name a few things:
If an asterisk is followed by a space, it will not be the start of a formatted piece of text;
Several parts can be formatted in one line, not only single words, but also word groups;
Formatting may even cross over a line break.
There might be an even number of slashes preceding an asterisk, in which case the asterisk is not escaped.
Here is a solution that only deals with italic, bold and italic+bold formatting, and the removal of escaping slashes. I did not deal with the hashes (#) as this was already quite broad for a Q&A:
jQuery.fn.parseAsFountain = function() {
var txt = this.val(),
re = /(\s?)(\\*)(\*+)(?=(\s?))/g,
arr,
openAsterisks = 0,
result = [],
last = 0,
start;
while ((arr = re.exec(txt)) !== null) {
var [all, prefix, escaped, asterisks, suffix] = arr;
if (escaped.length % 2) { // First asterisk is escaped
escaped += asterisks[0];
asterisks = asterisks.substr(1);
if (!asterisks.length) continue; // Nothing to do
}
var useAsterisks = 0;
if (openAsterisks && !prefix.length) {
useAsterisks = Math.min(openAsterisks, asterisks.length);
// Add HTML for bold, italic or both
result.push(
txt.substr(last, start - useAsterisks - last),
['<i>','<b>','<i><b>'][useAsterisks-1],
txt.substr(start, arr.index + escaped.length - start),
['</i>','</b>','</b></i>'][useAsterisks-1]);
last = arr.index + escaped.length + useAsterisks;
openAsterisks = 0;
}
if (!openAsterisks && asterisks.length > useAsterisks && !suffix.length) {
openAsterisks = asterisks.length - useAsterisks;
start = arr.index + prefix.length + escaped.length + asterisks.length;
}
}
// Flush remaining text
result.push(txt.substr(last));
// Remove escaping slashes (not escaped ones!):
result = result.join('').replace(/\\(.)/g, '$1');
return result;
}
$('textarea').on('input', function () {
$('pre').html($(this).parseAsFountain());
}).trigger('input');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea style="width:100%" rows=5>
This is **a** test *with several* ***formats
but*** keeping asterisks \*where* needed.
</textarea>
<h3>Rendered:</h3>
<pre>
</pre>
I am having a problem with "\n" creating a line even when it is told not to when copying. The fix is probably something simple that I am just not seeing for some reason. I would appreciate any input or coaching on this problem.
(Please only give me Javascript answers as I am not interested in jquery or other methods)
<script type="text/javascript">
if (pullDownResponseE == "")
{
}
else {
var pullDownValuesE = document.getElementById("taskOne");
var pullDownResponseE = pullDownValuesE.options[pullDownValuesE.selectedIndex].value;
stuffToCopy = stuffToCopy + "\n" + pullDownResponseE;
}
if (pullDownResponseF == "")
{
}
else{
var pullDownValuesF = document.getElementById("taskTwo");
var pullDownResponseF = pullDownValuesF.options[pullDownValuesF.selectedIndex].value;
stuffToCopy = stuffToCopy + "\n" + pullDownResponseF;
}
</script>
As you can see, pullDownResponseF and pullDownReponseE should do nothing if my dropdown value equals "" and this portion works for the most part, it doesn't execute any of the else code EXCEPT for the new line "\n" part.
Can anyone explain what is going wrong here?
EDIT: Having more code might help here. I'll only include the essential portions since it is so long.
<script type="text/javascript">
function copyNotesTemplate()
{
var stuffToCopy = document.getElementById('myForm').value;
if(stuffToCopy.length > 1)
{
var stuffToCopy = "PT meets criteria" + "\n" + document.getElementById('myForm').value;
}
if(document.getElementById('noPtCriteria').checked)
{
var stuffToCopy = document.getElementById('noPtCriteria').value;
}
if (pullDownResponsee == "")
{
}
else {
var pullDownValuese = document.getElementById("taskOne");
var pullDownResponsee = pullDownValuese.options[pullDownValuese.selectedIndex].value;
stuffToCopy = stuffToCopy + "\n" + pullDownResponsee;
}
if (pullDownResponsef == "")
{
}
else{
var pullDownValuesf = document.getElementById("taskTwo");
var pullDownResponsef = pullDownValuesf.options[pullDownValuesf.selectedIndex].value;
stuffToCopy = stuffToCopy + "\n" + pullDownResponsef;
}
if (pullDownResponseg == "")
{
}
else{
var pullDownValuesg = document.getElementById("taskThree");
var pullDownResponseg = pullDownValuesg.options[pullDownValuesg.selectedIndex].value;
stuffToCopy = stuffToCopy + "\n" + pullDownResponseg;
}
var tempValues = document.getElementById('whatUpdate').value
if(tempValues.length > 1)
{
var stuffToCopy = stuffToCopy + "Updated" + " " + document.getElementById('whatUpdate').value + " ";
}
else{
}
var tempValuess = document.getElementById('whatInfo').value
if(tempValuess.length > 1)
{
var stuffToCopy = stuffToCopy + "per" + " " + document.getElementById('whatInfo').value + "\n";
}
else{
}
var tempValue = document.getElementById('whatDSCRP').value
if(tempValue.length > 1)
{
var stuffToCopy = stuffToCopy + document.getElementById('whatDSCRP').value + " " + "dscrp on Collection tube and trf was resolved using" + " ";
}
else{
}
var tempValue = document.getElementById('resolveIT').value
if(tempValue.length > 1)
{
var stuffToCopy = stuffToCopy + document.getElementById('resolveIT').value + " ";
}
else{
}
var tempValue = document.getElementById('tubeCorrect').value
if(tempValue.length > 1)
{
var stuffToCopy = stuffToCopy + "trf was" + " " + document.getElementById('tubeCorrect').value;
}
else{
}
if(stuffToCopy.length > 1)
{
var stuffToCopy = stuffToCopy + "\n" + document.getElementById('moreNotes').value;
}
else{
}
if (pullDownResponsesu == "")
{
}
else{
var pullDownValuesu = document.getElementById("mod33Apply");
var pullDownResponsesu = pullDownValuesu.options[pullDownValuesu.selectedIndex].value;
stuffToCopy = stuffToCopy + "\n" + pullDownResponsesu;
}
if (pullDownResponsesb == "")
{
}
else{
var pullDownValuesb = document.getElementById("resultICR");
var pullDownResponsesb = pullDownValuesb.options[pullDownValuesb.selectedIndex].value;
stuffToCopy = stuffToCopy + "\n" + pullDownResponsesb + "," + " ";
}
if (pullDownResponsesc == "")
{
}
else{
var pullDownValuesc = document.getElementById("moneyNCIS");
var pullDownResponsesc = pullDownValuesc.options[pullDownValuesc.selectedIndex].value;
stuffToCopy = stuffToCopy + pullDownResponsesc + " ";
}
if (pullDownResponsesd == "")
{
}
else{
var pullDownValuesd = document.getElementById("resultMMT");
var pullDownResponsesd = pullDownValuesd.options[pullDownValuesd.selectedIndex].value;
stuffToCopy = stuffToCopy + pullDownResponsesd;
}
if(stuffToCopy.length > 1)
{
var stuffToCopy = stuffToCopy + " " + "Reason:" + " " + document.getElementById('whyNotEligible').value;
}
else{
}
if (pullDownResponsesa == "")
{
}
else{
var pullDownValuesa = document.getElementById("testReleased");
var pullDownResponsesa = pullDownValuesa.options[pullDownValuesa.selectedIndex].value;
stuffToCopy = stuffToCopy + "\n" + pullDownResponsesa;
}
window.clipboardData.setData('text', stuffToCopy);
}
</script>
If somebody skips filling out a note field or skips a dropdown in this example then it will not execute the code like I intended but it does create a new line when copied like this:
taskOne selected
(extra line here since task two wasn't selected)
taskThree selected
I would like there not to be an extra line between Task one and three if task two is skipped. Like this:
taskOne selected
taskThree selected
Note: I know that having else {} is pointless but it helps me visually.
I created snips of exactly what it looks like when copy/pasted from my tool that you can view here if you would like:
Example 1: http://imgur.com/wGO5vnT
Example 2: http://imgur.com/UX1tG5S
Here is an example of my html as well:
<html lang="en">
What tasks are needed for the case?
<br />
<select class="style3" id="taskOne">
<option value=""></option>
<option value="ABN needed">ABN needed</option>
<option value="Auth needed">Auth needed</option>
</select>
</html>
No, it doesn't add a new line, see:
stuffToCopy = "";
controlGroup = "a\nb";
pullDownResponseE = "";
if (pullDownResponseE == "")
{
}
else {
var pullDownValuesE = "taskOne";
var pullDownResponseE = "value";
stuffToCopy = stuffToCopy + "\n" + pullDownResponseE;
}
alert("stuffToCopy:"+stuffToCopy+";(no new-line here)\ncontrolGroup:"+controlGroup);
My guess is that your html is printed in such away that the values you get from the inputs contain an extra new-line at the end. Try changing your html to be 1 line, without new-lines, and test again.
Instead of:
<option value="a
">b
</option>
try:
<option value="a">b</option>
Alright so I fixed it, should have used the almighty document.getElementById instead of attempting to use pullDownReponse for my if statements..
I simply changed the if statements like this:
if (pullDownResponseg == "")
{
}
To this:
if (document.getElementById("taskThree").value == "")
{
}
Thanks for the help from the sincere. (and ridiculous non-answers from the others)
I am trying to bring in the JSON feeds from multiple Google calendars so that I can sort the upcoming events and display the next X number in an "Upcoming Events" list.
I have this working with Yahoo! pipes but I want to get away from using a 3rd party to aggregate. I think I am close, but I cannot get the JSON objects created correctly. I am getting the data into the array but not in JSON format, so I can't manipulate it.
I have tried var myJsonString = JSON.stringify(JSONData); using https://github.com/douglascrockford/JSON-js but that just threw errors. I suspect because my variable is in the wrong starting format. I have tried just calling the feed like: $.getJSON(url); and creating a function concant1() to do the JSONData=JSONData.concat(data);, but it doesn't fire and I think it would produce the same end result anyway. I have also tried several other methods of getting the end result I want with varying degrees of doom. Here is the closest I have come so far:
var JSONData = new Array();
var urllist = ["https://www.google.com/calendar/feeds/dg61asqgqg4pust2l20obgdl64%40group.calendar.google.com/public/full?orderby=starttime&max-results=3&sortorder=ascending&futureevents=true&ctz=America/New_York&singleevents=true&alt=json&callback=concant1","https://www.google.com/calendar/feeds/5oc3kvp7lnu5rd4krg2skcu2ng%40group.calendar.google.com/public/full?orderby=starttime&max-results=3&sortorder=ascending&futureevents=true&ctz=America/New_York&singleevents=true&alt=json&callback=concant1","http://www.google.com/calendar/feeds/rine4umu96kl6t46v4fartnho8%40group.calendar.google.com/public/full?orderby=starttime&max-results=3&sortorder=ascending&futureevents=true&ctz=America/New_York&singleevents=true&alt=json&callback=concant1"];
urllist.forEach(function addFeed(url){
alert("The URL being used: "+ url);
if (void 0 != JSONData){JSONData=JSONData.concat($.getJSON(url));}
else{JSONData = $.getJSON(url);}
alert("The count from concantonated JSONData: "+JSONData.length);
});
document.write("The final count from JSONData: "+JSONData.length+"<p>");
console.log(JSONData)
UPDATE:
Now with full working source!! :) If anyone would like to make suggestions on how to improve the code's efficiency it would be gratefully accepted. I hope others find this useful.:
// GCal MFA - Google Calendar Multiple Feed Aggregator
// Useage: GCalMFA(CIDs,n);
// Where 'CIDs' is a list of comma seperated Google calendar IDs in the format: id#group.calendar.google.com, and 'n' is the number of results to display.
// While the contained console.log(); outputs are really handy for testing, you will probably want to remove them for regular usage
// Author: Jeramy Kruser - http://jeramy.kruser.me
// This is error-checking code for IE and can be removed
// onerror=function (d, f, g){alert (d+ "\n"+ f+ "\n");}
// This keeps IE from complaining about console.log and can be removed if all the console.log testing statements are removed
// if (!window.console) {console = {log: function() {}};}
// Add a tag to your page to identify it as js-enabled for CSS purposes
document.body.className += ' js-enabled';
// Global variables
var urllist = [];
var maxResults = 3; // The default is 3 results unless a value is sent
var JSONData = {};
var eventCount = 0;
var errorLog = "";
JSONData = { count: 0,
value : {
description: "Aggregates multiple Google calendar feeds into a single sorted list",
generator: "StackOverflow communal coding - Thanks for the assist Patrick M",
website: "http://jeramy.kruser.me",
author: "Jeramy & Kasey Kruser",
items: []
}};
// Prototype forEach required for IE
if ( !Array.prototype.forEach ) {
Array.prototype.forEach = function(fn, scope) {
for(var i = 0, len = this.length; i < len; ++i) {
fn.call(scope, this[i], i, this);
}
}
}
// For putting dates from feed into a format that can be read by the Date function for calculating event length.
function parse (str) {
// validate year as 4 digits, month as 01-12, and day as 01-31
str = str.match (/^(\d{4})(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])$/);
if (str) {
// make a date
str[0] = new Date ( + str[1], + str[2] - 1, + str[3]);
// check if month stayed the same (ie that day number is valid)
if (str[0].getMonth () === + str[2] - 1) {
return str[0];
}
}
return undefined;
}
//For outputting to HTML
function output() {
var months, day_in_ms, summary, i, item, eventlink, title, calendar, where,dtstart, dtend, endyear, endmonth, endday, startyear, startmonth, startday, endmonthdayyear, eventlinktitle, startmonthday, length, curtextval, k;
// Array of month names from numbers for page display.
months = {'0':'January', '1':'February', '2':'March', '3':'April', '4':'May', '5':'June', '6':'July', '7':'August', '8':'September', '9':'October', '10':'November', '11':'December'};
// For use in calculating event length.
day_in_ms = 24 * 60 * 60 * 1000;
// Instantiate HTML Arrays.
summary = [];
for (i = 0; i < maxResults; i+=1 ) {
// console.log("i: "+i+" < "+"maxResults: "+ maxResults);
if (!(JSONData.value.items[i] === undefined)) {
item = JSONData.value.items[i];
// Grabbing data for each event in the feed.
eventlink = (item.link[0].href);
title = item.title.$t;
// Only display the calendar title if there is more than one
calendar = "";
if (urllist.length > 1) {
calendar = '<br />Calendar: <a href="https://www.google.com/calendar/embed?src=' + item.gd$who[0].email + '&ctz=America/New_York">' + item.gd$who[0].valueString + '<\/a> (<a href="https://www.google.com/calendar/ical/' + item.gd$who[0].email + '/public/basic.ics">iCal<\/a>)';
}
// Grabbing event location, if entered.
if ( item.gd$where[0].valueString !== "" ) {
where = '<br />' + (item.gd$where[0].valueString);
}
else {
where = ("");
}
// Grabbing start date and putting in form YYYYmmdd. Subtracting one day from dtend without a specified end time (which contains colons) to fix Google's habit of ending an all-day event at midnight on the following day.
dtstart = new Date(parse(((item.gd$when[0].startTime).substring(0,10)).replace(/-/g,"")));
if((item.gd$when[0].endTime).indexOf(':') === -1) {
dtend = new Date(parse(((item.gd$when[0].endTime).substring(0,10)).replace(/-/g,"")) - day_in_ms);
}
else {
dtend = new Date(parse(((item.gd$when[0].endTime).substring(0,10)).replace(/-/g,"")));
}
// Put dates in pretty form for display.
endyear = dtend.getFullYear();
endmonth = months[dtend.getMonth()];
endday = dtend.getDate();
startyear = dtstart.getFullYear();
startmonth = months[dtstart.getMonth()];
startday = dtstart.getDate();
//consolidate some much-used variables for HTML output.
endmonthdayyear = endmonth + ' ' + endday + ', ' + endyear;
eventlinktitle = '<a href="' + eventlink + '">' + title + '<\/a>';
startmonthday = startmonth + ' ' + startday;
// Calculates the number of days between each event's start and end dates.
length = ((dtend - dtstart) / day_in_ms);
// HTML for each event, depending on which div is available on the page (different HTML applies). Only one div can exist on any one page.
if (document.getElementById("homeCalendar") !== null ) {
// If the length of the event is greater than 0 days, show start and end dates.
if ( length > 0 && startmonth !== endmonth && startday === endday ) {
summary[i] = ('<h3>' + eventlink + '">' + startmonthday + ', ' + startyear + ' - ' + endmonthdayyear + '<\/a><\/h3><p>' + title + '<\/p>'); }
// If the length of the event is greater than 0 and begins and ends within the same month, shorten the date display.
else if ( length > 0 && startmonth === endmonth && startyear === endyear ) {
summary[i] = ('<h3><a href="' + eventlink + '">' + startmonthday + '-' + endday + ', ' + endyear + '<\/a><\/h3><p>' + title + '<\/p>'); }
// If the length of the event is greater than 0 and begins and ends within different months of the same year, shorten the date display.
else if ( length > 0 && startmonth !== endmonth && startyear === endyear ) {
summary[i] = ('<h3><a href="' + eventlink + '">' + startmonthday + ' - ' + endmonthdayyear + '<\/a><\/h3><p>' + title + '<\/p>'); }
// If the length of the event is less than one day (length < = 0), show only the start date.
else {
summary[i] = ('<h3><a href="' + eventlink + '">' + startmonthday + ', ' + startyear + '<\/a><\/h3><p>' + title + '<\/p>'); }
}
else if (document.getElementById("allCalendar") !== null ) {
// If the length of the event is greater than 0 days, show start and end dates.
if ( length > 0 && startmonth !== endmonth && startday === endday ) {
summary[i] = ('<li>' + eventlinktitle + '<br />' + startmonthday + ', ' + startyear + ' - ' + endmonthdayyear + where + calendar + '<\/li>'); }
// If the length of the event is greater than 0 and begins and ends within the same month, shorten the date display.
else if ( length > 0 && startmonth === endmonth && startyear === endyear ) {
summary[i] = ('<li>' + eventlinktitle + '<br />' + startmonthday + '-' + endday + ', ' + endyear + where + calendar + '<\/li>'); }
// If the length of the event is greater than 0 and begins and ends within different months of the same year, shorten the date display.
else if ( length > 0 && startmonth !== endmonth && startyear === endyear ) {
summary[i] = ('<li>' + eventlinktitle + '<br />' + startmonthday + ' - ' + endmonthdayyear + where + calendar + '<\/li>'); }
// If the length of the event is less than one day (length < = 0), show only the start date.
else {
summary[i] = ('<li>' + eventlinktitle + '<br />' + startmonthday + ', ' + startyear + where + calendar + '<\/li>'); }
}
}
if (summary[i] === undefined) { summary[i] = "";}
// console.log(summary[i]);
}
// console.log(JSONData);
// Puts the HTML into the div with the appropriate id. Each page can have only one.
if (document.getElementById("homeCalendar") !== null ) {
curtextval = document.getElementById("homeCalendar");
// console.log("homeCalendar: "+curtextval);
}
else if (document.getElementById("oneCalendar") !== null ) {
curtextval = document.getElementById("oneCalendar");
// console.log("oneCalendar: "+curtextval);
}
else if (document.getElementById("allCalendar") !== null ) {
curtextval = document.getElementById("allCalendar");
// console.log("allCalendar: "+curtextval.innerHTML);
}
for (k = 0; k<maxResults; k+=1 ) { curtextval.innerHTML = curtextval.innerHTML + summary[k]; }
if (JSONData.count === 0) {
errorLog += '<div id="noEvents">No events found.</div>';
}
if (document.getElementById("homeCalendar") === null ) {
curtextval.innerHTML = '<ul>' + curtextval.innerHTML + '<\/ul>';
}
if (errorLog !== "") {
curtextval.innerHTML += errorLog;
}
}
// For taking in each feed, breaking out the events and sorting them into the object by date
function sortFeed(event) {
var tempEntry, i;
tempEntry = event;
i = 0;
// console.log("*** New incoming event object #"+eventCount+" ***");
// console.log(event.title.$t);
// console.log(event);
// console.log("i = " + i + " and maxResults " + maxResults);
while(i<maxResults) {
// console.log("i = " + i + " < maxResults " + maxResults);
// console.log("Sorting event = " + event.title.$t + " by date of " + event.gd$when[0].startTime.substring(0,10).replace(/-/g,""));
if (JSONData.value.items[i]) {
// console.log("JSONData.value.items[" + i + "] exists and has a startTime of " + JSONData.value.items[i].gd$when[0].startTime.substring(0,10).replace(/-/g,""));
if (event.gd$when[0].startTime.substring(0,10).replace(/-/g,"")<JSONData.value.items[i].gd$when[0].startTime.substring(0,10).replace(/-/g,"")) {
// console.log("The incoming event value of " + event.gd$when[0].startTime.substring(0,10).replace(/-/g,"") + " is < " + JSONData.value.items[i].gd$when[0].startTime.substring(0,10).replace(/-/g,""));
tempEntry = JSONData.value.items[i];
// console.log("Existing JSONData.value.items[" + i + "] value " + JSONData.value.items[i].gd$when[0].startTime.substring(0,10).replace(/-/g,"") + " stored in tempEntry");
JSONData.value.items[i] = event;
// console.log("Position JSONData.value.items[" + i + "] set to new value: " + event.gd$when[0].startTime.substring(0,10).replace(/-/g,""));
event = tempEntry;
// console.log("Now sorting event = " + event.title.$t + " by date of " + event.gd$when[0].startTime.substring(0,10).replace(/-/g,""));
}
else {
// console.log("The incoming event value of " + event.gd$when[0].startTime.substring(0,10).replace(/-/g,"") + " is > " + JSONData.value.items[i].gd$when[0].startTime.substring(0,10).replace(/-/g,"") + " moving on...");
}
}
else {
JSONData.value.items[i] = event;
// console.log("JSONData.value.items[" + i + "] does not exist so it was set to the Incoming value of " + event.gd$when[0].startTime.substring(0,10).replace(/-/g,""));
i = maxResults;
}
i += 1;
}
}
// For completing the aggregation
function complete(result) {
// Track the number of calls completed back, we're not done until all URLs have processed
if( complete.count === undefined ){
complete.count = urllist.length;
}
// console.log("complete.count = "+complete.count);
// console.log(result.feed);
if(result.feed.entry){
JSONData.count = maxResults;
// Check each incoming item against JSONData.value.items
// console.log("*** Begin Sorting " + result.feed.entry.length + " Events ***");
// console.log(result.feed.entry);
result.feed.entry.forEach(
function(event){
eventCount += 1;
sortFeed(event);
}
);
}
if( (complete.count-=1)<1 ) {
// console.log("*** Done Sorting ***");
output();
}
}
// This is the main function. It takes in the list of Calendar IDs and the number of results to display
function GCalMFA(list,results){
var i, calPreProperties, calPostProperties1, calPostProperties2;
calPreProperties = "https://www.google.com/calendar/feeds/";
calPostProperties1 = "/public/full?max-results=";
calPostProperties2 = "&orderby=starttime&sortorder=ascending&futureevents=true&ctz=America/New_York&singleevents=true&alt=json&callback=?";
if (list) {
if (results) {
maxResults = results;
}
urllist = list.split(',');
for (i = 0; i < urllist.length; i+=1 ){
// console.log(urllist[i]);
if (urllist[i] === ""){ urllist.splice(i,1);}
else{
urllist[i] = calPreProperties + urllist[i] + calPostProperties1+maxResults+calPostProperties2;}
}
// console.log("There are " + urllist.length + " URLs");
urllist.forEach(function addFeed(url){
$.getJSON(url, complete);
});
}
else {
errorLog += '<div id="noURLs">No calendars have been selected.</div>';
output();
}
}
All right, here's the gist of what needs to change.
Updated fiddle: http://jsfiddle.net/ynuQ5/2/
Don't concat on the return value of $.getJSON. As I mentioned above, that gets you the XMLHttpRequest object, which is a lot more than the data you're interested in. Critically, however, at that point the request hasn't been made and the data isn't available yet.
Instead, handle it in callback for the AJAX request. I updated your URL list to use &callback=?, initialize the JSONData var to look more like the structure in your 2nd screenshot and then changed the javascript for the AJAX requests to this:
var JSONData = { count: 0,
value : {
description: "Calendars from the Unitarian Universalist Association (UUA.org)",
generator: "StackOverflow communal coding",
items: []
}};
// url list declaration goes here
urllist.forEach(function addFeed(url){
$.getJSON(url, function(result) {
if(!result.feed.entry) {
console.log("No entries from " + url);
return;
}
JSONData.count += result.feed.entry.length;
JSONData.value.items = JSONData.value.items.concat(result.feed.entry);
console.log(JSONData);
});
});
Right away you'll notice there are still some discrepancies between the raw data you get back from google and the data provided by the Yahoo pipe transform. Noticeably, a lot of their provided values have been transformed from objects to texts. For example, google gives us this:
id: Object
$t: "http://www.google.com/calendar/feeds/5oc3kvp7lnu5rd4krg2skcu2ng%40group.calendar.google.com/public/full/bbidp5qb4vh5vk9apok1cpnino_20130119"
link: Array[2]
0: Object
href: "https://www.google.com/calendar/event?eid=YmJpZHA1cWI0dmg1dms5YXBvazFjcG5pbm9fMjAxMzAxMTkgNW9jM2t2cDdsbnU1cmQ0a3JnMnNrY3UybmdAZw"
rel: "alternate"
title: "alternate"
type: "text/html"
1: Object
length: 2
published: Object
$t: "2012-11-13T15:59:31.000-05:00"
title: Object
$t: "30 Days of Love"
type: "text"
updated: Object
$t: "2012-11-13T15:59:31.000-05:00"
Where as your yahoo transform returns data more like this:
id: "http://www.google.com/calendar/feeds/5oc3kvp7lnu5rd4krg2skcu2ng%40group.calendar.google.com/public/full/bbidp5qb4vh5vk9apok1cpnino_20130119"
link: "href: "https://www.google.com/calendar/event?eid=YmJpZHA1cWI0dmg1dms5YXBvazFjcG5pbm9fMjAxMzAxMTkgNW9jM2t2cDdsbnU1cmQ0a3JnMnNrY3UybmdAZw"
published: "2012-11-13T15:59:31.000-05:00"
title: "30 Days of Love"
updated: "2012-11-13T15:59:31.000-05:00"
You can transform the data more when you receive it. Or you can modify your display code to use the more convoluted, raw values.
Let me know if I can clear anything up in my code or response.
Edit: Updated fiddle showing how to access author (aka feed name, apparently), start time and title: http://jsfiddle.net/ynuQ5/8/
Let me know if there's more specific stuff you want out of it :-)
Below is the code, the program is split into two main segments.
One that performs operation on each Select element and the other
on all the option elements within this\each select and this one
does not work as it should append a price "[+$00]" to each select option text value,
bar the currently selected one. The piece of code that does not work is tagged.
Worked fine with 1.5.1, 1.5.2 and does not work with all starting from 1.6
// ===== CODE DOES NOT WORK FROM HERE WITH 1.6.4============
$(this).find('option').each(function () {
//$(this).append('<span></span>');
var uov = parseInt($(this).attr('value')) || 0; //Unselected option value
var uop; //Unselected Option Price
for (d = 0; d <= data.length; d++) {
if (data[d].partid == uov) {
uop = data[d].price;
break;
}
}
//debugger;
var pricediff = Math.abs(uop - sop);
var xtext = $(this).text();
if (xtext.match(/\✔/) != null) {
var temp = xtext.replace(/✔/g, '');
xtext = temp;
}
if (xtext.match(/\[.*\]/) != null) {
var temp = xtext.split('[')[0];
var temp2 = xtext.split(']')[1];
xtext = temp2;
}
if (uov != 0) {
if (pricediff != 0) {
var diff = '[' + (sop > uop ? '-' : '+') + '$' + pricediff + ']';
$(this).attr("text", diff + " " + xtext);
}
else {
$(this).attr("text", " ✔ " + " " + xtext);
}
}
//=============== TO HERE ========================
Don't use:
$(this).attr('value')
to get the value of a form field. Use:
$(this).val()
This has caused many headaches with our client developers when we changed our framework's jQuery version.
--- Edit ---
You most certainly should not be trying to edit the text of an element with the attr() function as you have here:
$(this).attr("text", diff + " " + xtext);
You should use:
$(this).text(diff + " " + xtext);