-
-
Save langalex/5b93cb76081790d59101cf27a37bab40 to your computer and use it in GitHub Desktop.
Cobot RFID token registration app
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var cobot = Cobot.Api(window.cobot.access_token), | |
$app = $('#app'), | |
$spaceSelect = $('#space'), | |
$tokens = $('#tokens'), | |
$tokenCount = $('#token_count'); | |
$addToken = $app.find('a[rel=add-token]'), | |
$members = $('#membership_id'), | |
$loading = $('#loading'); | |
initTokenList(); | |
initSpaceSelect(); | |
initAddToken(); | |
initRemoveToken(); | |
initScannerStatus(); | |
initMemberList(); | |
function initScannerStatus() { | |
var $ready = $('[rel=scanning-ready]'), | |
$notReady = $('[rel=scanning-not-ready]'), | |
$tokenField = $('form[rel=new-token] input[name=token]'); | |
$ready.hide(); | |
$notReady.show(); | |
$tokenField.on('focus', function() { | |
$ready.show(); | |
$notReady.hide(); | |
}); | |
$tokenField.on('blur', function() { | |
$ready.hide(); | |
$notReady.show(); | |
}); | |
$tokenField.on('keypress', function(e) { | |
if(e.keyCode == 13) { | |
e.preventDefault(); | |
$tokenField.blur(); | |
} | |
}); | |
$notReady.css('cursor', 'pointer'); | |
$notReady.on('click', function() { | |
$tokenField.val('').focus(); | |
}); | |
} | |
function initRemoveToken() { | |
$app.on('click', '[rel=remove-token]', function(e) { | |
e.preventDefault(); | |
if(confirm("Are you sure you want to remove that token?")) { | |
$(this).closest('[rel=token]').remove(); | |
cobot._delete(currentSubdomain(), '/check_in_tokens/' + $(this).data('token')); | |
} | |
}); | |
} | |
function initAddToken() { | |
var $form = $('#new-token-form'), $errors = $form.find('[rel=form-errors]'); | |
$addToken.click(function(e) { | |
e.preventDefault(); | |
emptyForm(); | |
$errors.text('').hide(); | |
$form.show(); | |
}); | |
$form.on('submit', function(e) { | |
e.preventDefault(); | |
cobot.post(currentSubdomain(), '/check_in_tokens', { | |
membership_id: $form.find('[name=membership_id]').val(), | |
token: $form.find('[name=token]').val()}).then(tokenAddedCallback, tokenErrorCallback) | |
}); | |
function tokenAddedCallback(token) { | |
alert('Token registered.'); | |
emptyForm(); | |
$form.hide(); | |
$app.trigger('reload-tokens'); | |
} | |
function tokenErrorCallback(response) { | |
var errors = JSON.parse(response.responseText).errors, | |
error = []; | |
for(var i in errors) { | |
error.push(errors[i]); | |
} | |
$errors.text(error.join(', ')).show(); | |
$errors.text(response.responseText).show(); | |
} | |
function emptyForm() { | |
$form.find('input:not(:submit)').val(''); | |
} | |
} | |
function initTokenList() { | |
$app.bind('reload-tokens', function() { | |
$tokens.find('tr[rel=token]').remove(); | |
$tokenCount.text('...'); | |
cobot.get(currentSubdomain(), '/check_in_tokens').done(showTokens); | |
}); | |
} | |
function initMemberList() { | |
$app.bind('reload-members', function() { | |
$members.find('option').remove(); | |
cobot.get(currentSubdomain(), '/memberships', {attributes: 'id,name'}).done(showMembers); | |
}); | |
} | |
function showMembers(members) { | |
$loading.remove(); | |
members.sort(function(a, b) { | |
if(a.name < b.name) { | |
return -1 | |
}; | |
if(a.name > b.name) { | |
return 1 | |
}; | |
return 0; | |
}); | |
for(var i in members) { | |
var m = members[i]; | |
$members.append('<option value="' + m.id + '">' + m.name + '</option>'); | |
} | |
} | |
function showTokens(tokens) { | |
tokens = tokens.sort(function(x,y) { | |
return tokenName(x).toLowerCase() < tokenName(y).toLowerCase() ? -1 : 1; | |
}) | |
$tokenCount.text(tokens.length); | |
for(var i in tokens) { | |
token = tokens[i]; | |
$tokens.append('<tr rel="token"><td>' + tokenName(token) + '</td><td>' + | |
token.token + '</td><td><a href="#" rel="remove-token" data-token="' + encodeURIComponent(token.token) + '">remove</a></td></tr>'); | |
} | |
function tokenName(token) { | |
return token.membership ? token.membership.name : token.admin.name; | |
} | |
} | |
function currentSubdomain() { | |
return $spaceSelect.val(); | |
} | |
function initSpaceSelect() { | |
cobot.get('www', '/user').done(function(user) { | |
for(var i in user.admin_of) { | |
$spaceSelect.append('<option value="' + user.admin_of[i].space_subdomain + '">' + user.admin_of[i].space_name + '</option>'); | |
if($spaceSelect.find('option').length === 1) { | |
$spaceSelect.find('option:first').click() | |
$spaceSelect.trigger('change'); | |
} | |
}; | |
}); | |
$spaceSelect.change(function(e) { | |
$app.trigger('reload-tokens'); | |
$app.trigger('reload-members'); | |
}); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!doctype html> | |
<html> | |
<head> | |
<meta charset="utf-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>Check-in Tokens</title> | |
<meta name="description" content="Allows space managers to add/remove tokens to check into the space, e.g. for RFID fobs."> | |
<link href="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.0/css/bootstrap-combined.min.css" rel="stylesheet"/> | |
</head> | |
<body> | |
<div id="app" class="container-fluid"> | |
<h1>Manage Check-in Tokens</h1> | |
<p class="lead">This app lets you add and remove tokens for checking in members of your space.<br/>Tokens can be swipe/RFID cards, computer's MAC addresses, passwords etc.</p> | |
<form class="form-inline"><label>Select a space: <select id="space"></select></label></form> | |
<p> | |
You have <span id="token_count">[loading...]</span> tokens registered. | |
<a href="#" rel="add-token">Register a token</a> | |
</p> | |
<div id="interactions"> | |
<div id="new-token-form" style="display:none"> | |
<p>Please select a member and enter the token you want to register.</p> | |
<p class="alert alert-error" rel="form-errors"></p> | |
<form rel="new-token" class="form-horizontal"> | |
<div class="control-group"> | |
<label class="control-label">Member</label> | |
<div class="controls"> | |
<select id="membership_id" name="membership_id"></select> | |
</div> | |
</div> | |
<div class="control-group"> | |
<label class="control-label">Token</label> | |
<div class="controls"> | |
<input type="text" name="token"/> | |
<span class="help-inline"> | |
<span class="label label-success" rel="scanning-ready">Ready for scanner</span> | |
<span class="label label-warning" rel="scanning-not-ready">Click before scanning card</span> | |
</span> | |
</div> | |
</div> | |
<div class="form-actions"> | |
<input type="submit" value="Add Token" class="btn btn-primary"/> | |
</div> | |
</form> | |
</div> | |
</div> | |
<table id="tokens" class="table table-striped"> | |
<tr> | |
<th>Name</th> | |
<th>Token</th> | |
<th></th> | |
</tr> | |
<tr id="loading"> | |
<td colspan="3">Loading...</td> | |
</tr> | |
</table> | |
</div> | |
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> | |
<script src="https://bots.apps.cobot.me/javascripts/cobot_api.js"></script> | |
<script src="app.js"></script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment