Help on Return to Office template

Hello im using the Return to Office Template, to create a CHeking and chekout app for homwoffice.
I have created a new database called Return to Office - Turns, so i can associate with the spaces, in my case spaces will be used as working places for my office.
So in the edit space form i need to load the right turn for it, and also the geolocalization for it as well, but my skiil on Javascript are very low.
Here is the code that i have created to first populate my dropdown with the right information.

//In edit mode load the right office name into select office form

Fliplet.FormBuilder.get().then(function(form) {
Fliplet.DataSources.connectByName(‘Return to Office - Offices’)
.then(function(connection) {
return connection.find({
attributes: [‘Name’]
});
})
.then(function(records) {
var offices = [];
_.forEach(records, function(record) {
offices.push(record.data.Name);
});

  form.field('Office Name').options(offices);
//inicio
Fliplet.DataSources.connectByName('Return to Office - Turns')
.then(function(connection) {
  return connection.find({
    attributes: ['Nome']
  });
})
.then(function(records) {
  var turns = [];
  _.forEach(records, function(record) {
    turns.push(record.data.Nome);
    alert(turns)
  });

  form.field('turno').options(turns);}
//fim
	if(!Fliplet.Navigate.query.dataSourceEntryId){
    return Fliplet.App.Storage.get('officeName').then(function (value) {
      console.log(value);
      form.field('Office Name').set(value);
    });
  }
  return Fliplet.DataSources.connectByName('Return to Office - OfficeSpaces').then(function(
    connection
  ) {
    return connection.findById(Fliplet.Navigate.query.dataSourceEntryId).then(function(record) {
      return Fliplet.FormBuilder.get().then(function(form) {
        form.field('Office Name').set(record.data['Office Name']);
      });
    });
  });
});

});

Nothing is loading, i need help with this project

Hi Ignacio,

Thank you for sending this question. We will soon release a new low code screen template that will show how to populate a dropdown field from a data source.

For now, I will share an example with you that I believe will be helpful.

Imagine you have a form with two fields ‘Country’ and ‘Region’:

Form

Based on a data source named ‘Countries and regions’ containing two columns also called ‘Country’ and ‘Region’ you want to populate the first field of the form with the countries that are in the first column and, according to the country the user selects, you want the second dropdown to display the regions associated with that country.

Imagine you also have a second data source named ‘Submissions’ in which you want to save the form submissions.

One way you could implement this would be using the code below.
Although the context you are applying is a little bit different, Ignacio, the code can be adapted to your application. I left instructions commented in the code, specifying the variables you would need to change.
If I understood correctly what you are trying to achieve, your ‘Return to Office - Turns’ data source would be the equivalent of the ‘Countries and regions’, ‘Space’ would be the equivalent of ‘Countries’ and ‘Turns’ the equivalent of ‘Regions’ in my example. Does that make sense?
If you have any questions, please let us know.

/* CHANGES REQUIRED */
// Change 'Countries and regions' for the name of the data source containing the data you want to use to populate the dropdown fields 
var recordsDS = 'Countries and regions';

// Change 'Submissions' for the name of the data source in which you want to save the data when a user submits the form 
var dsToSaveFormSubmission = 'Submissions';

// Change 'Country' for the name of the first dropdown field you want to populate. Make sure both data sources - the one that has the data you want to use to populate the data source and the one in which you want to save the form submission - use the same column name for the field you are populating.
var fieldToBePopulated = 'Country';

// Change 'Region' for the name of the second field that will be shown after the first value is selected. Make sure both data sources - the one that has the data you want to use to populate the data source and the one in which you want to save the form submission - use the same column name for the field you are populating.
var secondField = 'Region';

/* END OF CHANGES REQUIRED */

var query = Fliplet.Navigate.query;

Fliplet.FormBuilder.get().then(function(form) {
  //Populates the first field from the datasource
  Fliplet.DataSources.connectByName(recordsDS)
    .then(function(connection) {
      return connection.find({
        attributes: [fieldToBePopulated]
      });
    })
    .then(function(records) {
      var listOfRecords = [];
      _.forEach(records, function(record) {
        if (listOfRecords.includes(record.data[fieldToBePopulated]) == false) {
        	listOfRecords.push(record.data[fieldToBePopulated]);
      	}
      });

      form.field(fieldToBePopulated).options(listOfRecords);
  	})
    .then(function() {
    console.log(query.dataSourceEntryId)
      if (query.dataSourceEntryId) {
        Fliplet.DataSources.connectByName(dsToSaveFormSubmission).then(function(connection) {
          connection.findById(query.dataSourceEntryId).then(function(record) {
            Fliplet.FormBuilder.get().then(function(form) {
              form.field(fieldToBePopulated).set(record.data[fieldToBePopulated]);
            });
          });
        });
      }
    });
  
  	//Populates the second field from the datasource, according to the first field selected
    form.field(fieldToBePopulated).change(function (val) {
      Fliplet.DataSources.connectByName(recordsDS)
    		.then(function(connection) {
     			return connection.find({
        		attributes: [secondField, fieldToBePopulated]
      		});
    		})
    		.then(function(records) {
      		var listOfRecordsSecond = [];
      		_.forEach(records, function(record) {
        		if (listOfRecordsSecond.includes(record.data[secondField]) == false) {
          		if (record.data[fieldToBePopulated] == val) {
        				listOfRecordsSecond.push(record.data[secondField]);
        			}
      			}
      		});

      		form.field(secondField).options(listOfRecordsSecond);
        })
    		.then(function() {
      		if (query.dataSourceEntryId) {
        		Fliplet.DataSources.connectByName(dsToSaveFormSubmission).then(function(connection) {
          		connection.findById(query.dataSourceEntryId).then(function(record) {
            		Fliplet.FormBuilder.get().then(function(form) {
              		form.field(secondField).set(record.data[secondField]);
            		});
          		});
        		});
      		}
    		});
   	 	});
    });

Great i will implement, and get back to you

Ok now i have the folowing situations:
In the form i will add latitude and longitude and also a distance in metters to get the radios of the place.
With that information when the user does the chekin i need to chek not if he answered correctly the covid form but if he is on the right spot of the place associated with his account, as well the correct time added in the Turns database.
And for last but not least i need to add a function that he can chekout for lunch and comebask in the right time also specified in the Turn database associated with the place.
SO i wont need the seats taken and everything else.
The code now for the chekin process is as follows.
var checkinRequiresBooking = false;
dynamicOfficeandSpace();

logUserEmailInForm(‘Email’);
//Show loading icon for barcode scanning
function userFeedBack(status) {
if (status === true) {
if ($(’.circle-loader’).hasClass(‘failmark’)) {
$(’.circle-loader’).toggleClass(‘failmark’);
$(’.circle-loader’).toggleClass(‘checkmark’);
$(’.loader-message’).hide();
} else {
$(’.circle-loader’).toggleClass(‘checkmark load-complete’);
$(’.circle-loder > div’).toggle();
$(’.loader-message’).fadeOut();
$(’.success, .retry’).fadeIn();
}
} else {
if ($(’.circle-loader’).hasClass(‘checkmark’)) {
$(’.circle-loader’).toggleClass(‘checkmark’);
$(’.circle-loader’).toggleClass(‘failmark’);
$(’.loader-message’).hide();
} else {
$(’.circle-loader’).toggleClass(‘failmark load-complete’);
$(’.circle-loder > div’).toggle();
$(’.loader-message’).fadeOut();
$(’.success, .retry’).faceIn();
}
}
}

function getUrlParameter(name, url) {
name = name.replace(/[[]/, ‘\[’).replace(/[]]/, ‘\]’);
var regex = new RegExp(’[\?&]’ + name + ‘=([^&#]*)’);
var results = regex.exec(url);
return results === null ? ‘’ : decodeURIComponent(results[1].replace(/+/g, ’ '));
}

/display check/
function success() {
userFeedBack(true);
}

/display cross/
function failure() {
userFeedBack(false);
}

//get current capacity
function getCurrentCapacity(officeName, spaceName, requestedNumber, date) {
var checkInsQuery = {};
var checkedInTotal = 0;
var tommorowDate = moment(date)
.add(1, ‘days’)
.format(‘YYYY-MM-DD’);
checkInsQuery[‘OfficeSpaceName’] = spaceName;
checkInsQuery[‘OfficeName’] = officeName;
checkInsQuery[‘CheckedIn’] = { $and: [{ $gte: date }, { $lt: tommorowDate }] };
return Fliplet.DataSources.connectByName(‘Return to Office - Checkins’)
.then(function(connection) {
return connection.find({
where: checkInsQuery
});
})
.then(function(records) {
_.forEach(records, function(record) {
if (!record.data.CheckedOut) {
checkedInTotal = checkedInTotal + 1;
}
})
var spacesQuery = {};
spacesQuery[‘Name’] = spaceName;
return Fliplet.DataSources.connectByName(‘Return to Office - OfficeSpaces’)
.then(function(connection) {
return connection.find({
where: spacesQuery
});
})
.then(function(records) {
if (parseInt(records[0].data.Capacity) - parseInt(checkedInTotal) > 0) {
return ‘Capacity available’;
} else {
return ‘No Capacity’;
}
});
});
}

function sendOMEmail(officeName, officeSpace, email) {
Fliplet.DataSources.connectByName(‘Return to Office - Offices’).then(function(connection) {
connection
.find({
attributes: [‘ManagerEmail’],
where: {
Name: { $eq: officeName }
}
})
.then(function(records) {
var emailsArr = records[0].data[‘ManagerEmail’].split(’,’);
var emailToObj = {};
var emailToArr = [];

    _.forEach(emailsArr, function(user) {
      emailToObj['email'] = user;
      emailToArr.push(emailToObj);
    });

    var body =
      '<p>A check in occured at a full capacity space</p>' +
      '<ul>' +
      '<li>Checked in user: ' +
      email +
      '</li>' +
      '<li>Office: ' +
      officeName +
      '</li>' +
      '<li>Space: ' +
      officeSpace +
      ' </li>' +
      '</ul>' +
      '<p>To view this check in visit ' +
      Fliplet.Env.get('appName') +
      '</p>' +
      '<p>Reply to this email if you want to contact the person directly.</p>';

    var options = {
      to: emailToArr,
      html: body,
      subject: 'Check In for ' + officeName + ' : ' + officeSpace,
      headers: {
        'Reply-To': email
      }
    };
    // Returns a promise
    Fliplet.Communicate.sendEmail(options);
  });

});
}

//get location name from query paramter in QR code
var insertID;
function checkIn(officeName, spaceName, userEmail) {
//$(’.test’).text(officeName, spaceName);
return Fliplet.DataSources.connectByName(‘Return to Office - Checkins’, {
offline: false // disable querying offline on mobile devices
})
.then(function(connection) {
return connection.insert({
Email: userEmail,
OfficeName: officeName,
OfficeSpaceName: spaceName,
CheckedIn: moment().toISOString()
});
})
.then(function(records) {
insertID = records.id;
success();
$(’.success-message’).text('You have been sucessfully checked into ’ + officeName + ’ office, ’ + spaceName);
});
}

function checkoutOfCurrentCheckin(email) {
return Fliplet.DataSources.connectByName(‘Return to Office - Checkins’).then(function(
connection
) {
return connection
.find({
where: {
Email: email
}
})
.then(function(records) {
var records = _.remove(records, function(n) {
if (!n.data.CheckedOut) {
return n;
}
});
console.log(records);
if (records.length > 0) {
return Fliplet.DataSources.connectByName(‘Return to Office - Checkins’).then(function(
connection
) {
return connection.update(records[0].id, {
CheckedOut: moment().toISOString()
});
});
}
});
});
}

function checkIfBookingExists(email, office, space) {
return Fliplet.DataSources.connectByName(‘Return to Office - OfficeBookings’).then(function(
connection
) {
return connection
.find({
where: {
Email: email,
Date: moment().format(‘YYYY-MM-DD’),
Office: office,
Space: space
}
})
.then(function(records) {
if (records.length > 0) {
return true;
} else {
return false;
}
});
});
}

//open barcode scanner

function openScanner(userEmail) {
var options = {
preferFrontCamera: false, // iOS and Android
showFlipCameraButton: true, // iOS and Android
showTorchButton: true, // iOS and Android
torchOn: false, // Android, launch with the torch switched on (if available)
saveHistory: true, // Android, save scan history (default false)
prompt: ‘Place a barcode inside the scan area’ // Android
};

return Fliplet.Barcode.scan(options)
.then(function(result) {
//$(’.test’).text(JSON.stringify(result));
var officeName = getUrlParameter(‘officeName’, result.text);
var spaceName = getUrlParameter(‘officespaceName’, result.text);
if (getUrlParameter(‘action’, result.text) === ‘checkin’) {
var bookingPromise;
if (checkinRequiresBooking) {
bookingPromise = checkIfBookingExists(userEmail, officeName, spaceName);
} else {
bookingPromise = Promise.resolve(true);
}
bookingPromise.then(function(bookingstatus) {
if (!bookingstatus) {
var options = {
type: ‘regular’,
tapToDismiss: true,
duration: false,
message: ‘Please make a booking for this space before checking in’
};
Fliplet.UI.Toast(options);
failure();
return;
}
$(’.test’).text(JSON.stringify(bookingstatus));
checkoutOfCurrentCheckin(userEmail).then(function() {
getCurrentCapacity(officeName, spaceName, 1, moment().format(‘YYYY-MM-DD’)).then(
function(status) {
// $(’.test’).text(status);
if (status === ‘Capacity available’) {
checkIn(officeName, spaceName, userEmail);
} else {
var options = {
title: ‘Space Full’,
message: ‘This Space is full. Are you sure you want to check in?’,
labels: [‘Agree’, ‘No’] // Native only (defaults to [OK,Cancel])
};

              Fliplet.Navigate.confirm(options).then(function(result) {
                if (!result) {
                  return console.log('Not confirmed!');
                }
                checkIn(officeName, spaceName, userEmail);
                sendOMEmail(officeName, spaceName, userEmail);
              });
            }
          }
        );
      });
    });
  } else if (getUrlParameter('action', result.text) === 'checkout') {
    return Fliplet.DataSources.connectByName('Return to Office - Checkins').then(function(
      connection
    ) {
      return connection
        .find({
          where: {
            Email: userEmail,
            OfficeName: getUrlParameter('officeName', result.text),
            OfficeSpaceName: getUrlParameter('officespaceName', result.text),
            CheckedIn: { $gte: moment().format('YYYY-MM-DD') }
          }
        })
        .then(function(records) {
        $('.test').text(JSON.stringify(result.text));
          var records = _.remove(records, function(n) {
            if (!n.data.CheckedOut) {
              return n;
            }
          });
        
          return Fliplet.DataSources.connectByName('Return to Office - Checkins')
            .then(function(connection) {
              connection.update(records[0].id, {
                CheckedOut: moment().toISOString()
              });
            })
            .then(function() {
              success();
              $('.success-message').text(
                'You have been successfully checked out of ' + officeName + ' , ' + spaceName
              );
              $('.optional-form').hide();
            });
        });
    });
  }
})
.catch(function(error) {
  failure();
});

}

var loggedInEmail;
$(’.scanAgain’).click(function() {
openScanner(loggedInEmail);
});

Fliplet.User.getCachedSession().then(function(session) {
var user;
if (session.entries.dataSource) {
user = _.get(session, ‘entries.dataSource.data’);
if (!user) {
return; // user is not logged in
}
loggedInEmail = user.Email;
}

// contains all columns found on the connected dataSource entry

if (Fliplet.Env.get(‘platform’) === ‘web’) {
$(’.circle-loader’).hide();
$(’.loader-message’).hide();
} else {
var isOnline = Fliplet.Navigator.isOnline();

if (isOnline) {
  // device is online
  openScanner(loggedInEmail);
} else {
  // device is offline
  $('.loader-message').text('Device Offline');
  setTimeout(function() {
    failure();
  }, 3000);
  //failure();
}

}
});

//change to datasource Name with the checkin/checkout data will be stored.
var datasourceName = ‘Return to Office - Checkins’;
//Change to the column where the name of the office will be stored in the above datasource
var officeNameColumn = ‘OfficeName’;
//Change to the column where the name of the space will be stored in the above datasource
var spaceNameColumn = ‘OfficeSpaceName’;

function getData(userEmail, officeName, spaceName) {
var insert = {};
insert[‘Email’] = userEmail;
insert[officeNameColumn] = officeName;
insert[spaceNameColumn] = spaceName;
insert[‘CheckedIn’] = moment().toISOString();
return Fliplet.DataSources.connectByName(datasourceName).then(function(connection) {
return connection.insert(insert);
});
}

Fliplet.Hooks.on(‘beforeFormSubmit’, function(data) {
if (data.Office) {
getData(data.Email, data.Office, data.Space);
}

if (data[‘Number of guests with you (optional)’]) {
return Fliplet.DataSources.connectByName(‘Return to Office - Checkins’).then(function(
connection
) {
connection.update(insertID, {
Guests: data[‘Number of guests with you (optional)’]
});
});
}
});

Hi Ignacio,
I am not sure I understand what you are trying to achieve. Do you want to get GPS coordinates? If that is the case, you can check how it can be done here:

No the gps location i already getting… what i need is to check when the uses chekin if he is in the right location.

Ok i will use the manage Booking for do what i need to do, so instead of having a booking, i will need to associate a user with a space, and he will always be booked, also i need to alert the office manager when he arrives 15 minutes or more late, so i will have the user associated with the booking.
Any help?