Skip to content

Instantly share code, notes, and snippets.

@rfprod
Last active July 3, 2017 14:03
Show Gist options
  • Save rfprod/302d6c665b0dcfa94c18 to your computer and use it in GitHub Desktop.
Save rfprod/302d6c665b0dcfa94c18 to your computer and use it in GitHub Desktop.
Recipe Box
<link href='https://fonts.googleapis.com/css?family=Play&effect=neon' rel='stylesheet' type='text/css'>
<div class="container-fluid nopadding">
<nav class="navbar navbar-inverse navbar-fixed-top topnav" role="navigation">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#toggle-nav" aria-expanded="false">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand font-effect-neon" target=_blank href="http://codepen.io/rfprod"><span class="glyphicon glyphicon-wrench"></span> RFProd</a>
</div>
<div class="collapse navbar-collapse" id="toggle-nav">
<div class="container-fluid">
<ul class="nav navbar-nav navbar-right font-effect-emboss">
<li class="nav-tabs"><a href="#leaderboard"><span class="glyphicon glyphicon-cutlery"></span> RECIPE BOX</a></li>
<li class="nav-tabs"><a href="https://gist.github.com/rfprod/302d6c665b0dcfa94c18" target=_blank><span class="glyphicon glyphicon-download-alt" ></span> GIST</a></li>
</ul>
</div>
</div>
</nav>
<div class="home sect">
<div class="container-fluid">
<div class="col-xs-12 col-sm-12 col-md-12 col-lg-12">
<h2><span class="glyphicon glyphicon-cutlery"></span> Recipe Box</h2>
<div id="output">
Output
</div>
<span class="credits">licence <a href="http://www.gnu.org/licenses/gpl-3.0.en.html" target=_blank>GPL 3.0</a></span>
</div>
</div>
</div>
</div>

Recipe Box

User can:

  • create recipes that have names and ingredients;
  • see an index view where the names of all the recipes are visible;
  • click into any of those recipes to view it;
  • edit these recipes;
  • delete these recipes. All new recipes User adds are saved in user's browser's local storage. If user refreshes the page, these recipes will still be there.

A Pen by V on CodePen.

License.

var recipeNames = ["First","Second","Third"];
var recipeIngredients = [["ingr1","ingr2","ingr3"],["ingr1","ingr2"],["ingr1"]];
$(document).on('ready',function(){
(function refresh(){
if(typeof(Storage) !== "undefined") {
console.log('local storage available, getting params');
if (typeof localStorage.recipeBook === 'undefined' || JSON.parse(localStorage.recipeBook).length === 0){
var contents = [];
for (var l=0;l<recipeNames.length;l++){
contents.push({"name":recipeNames[l],"ingredients":recipeIngredients[l]});
}
console.log(JSON.stringify(contents));
localStorage.setItem('recipeBook', JSON.stringify(contents));
}
console.log('recipeBook length: '+JSON.parse(localStorage.recipeBook).length+' | contents: '+JSON.stringify(localStorage.recipeBook));
}else console.log('local storage not available');
var PanelsContainer = React.createClass({
render: function() {
return (
<span>
<div className="panel panel-primary">
<div className="panel-heading primary" type="button">
<h4 className="panel-title">
<a aria-expanded="false" className="cllps-toggler collapsed" data-toggle="collapse" data-parent="#accordion" href="#collapse-add">Add New Recipe</a>
</h4>
</div>
<div aria-expanded="false" id="collapse-add" className="panel-collapse collapse">
<div className="panel-body">
<form role="form" action="#" className="form-vertical">
<fieldset>
<div class="form-group">
<input type="text" className="form-control" name="editname" id="edit-name" placeholder="Recipe display name"/>
</div>
<div class="form-group">
<input type="text" className="form-control" name="editingr" id="edit-ingr" placeholder="Ingredients separated by commas: ingr 1, ingr 2 " />
</div>
<div className="btn-group btn-group-justified">
<a href="#" className="btn btn-success" id="add-recipe">Add Recipe</a>
</div>
</fieldset>
</form>
</div>
</div>
</div>
<div id="panels"></div>
</span>
);
}
});
var markup = [];
var Panel = React.createClass({
render: function() {
for (var i=0;i<JSON.parse(localStorage.recipeBook).length;i++){
var Name = JSON.parse(localStorage.recipeBook)[i].name;
var IngrContainerId = "ingredients-"+i;
var collapseId = "collapse-"+i;
var collapseHREF = "#collapse-"+i;
var editRecipeId = "edit-recipe-"+i;
var deleteRecipeId = "delete-recipe-"+i;
var collapseEditId = "collapse-edit-"+i;
var collapseEditHREF = "#collapse-edit-"+i;
var updateRecipe = "update-recipe-"+i;
markup.push(<div className="panel panel-default">
<div className="panel-heading" type="button">
<h4 className="panel-title">
<a aria-expanded="false" className="cllps-toggler collapsed" data-toggle="collapse" data-parent="#accordion" href={collapseHREF}>{Name}</a>
</h4>
</div>
<div aria-expanded="false" id={collapseId} className="panel-collapse collapse">
<div className="panel-body">
<span id={IngrContainerId}></span>
<div className="btn-group btn-group-justified">
<a href={collapseEditHREF} data-toggle="collapse" className="btn btn-warning edit-rec" id={editRecipeId}>Edit Recipe</a>
<a href="#" className="btn btn-danger del-rec" id={deleteRecipeId}>Delete Recipe</a>
</div>
<div aria-expanded="false" id={collapseEditId} className="panel-collapse collapse">
<div className="panel-body">
<form role="form" action="#" className="form-vertical">
<fieldset>
<div class="form-group">
<input type="text" className="form-control" name="editname" id="edit-name" placeholder="Recipe display name"/>
</div>
<div class="form-group">
<input type="text" className="form-control" name="editingr" id="edit-ingr" placeholder="Ingredients separated by commas: ingr 1, ingr 2 " />
</div>
<div className="btn-group btn-group-justified">
<a href="#" className="btn btn-success upd-rec" id={updateRecipe}>Update Values</a>
</div>
</fieldset>
</form>
</div>
</div>
</div>
</div>
</div>);
}
return (
<div className="panel-group" id="accordion">{markup}</div>
);
}
});
ReactDOM.render(<PanelsContainer />,document.getElementById('output'));
ReactDOM.render(<Panel />,document.getElementById('panels'));
for (var i=0;i<JSON.parse(localStorage.recipeBook).length;i++){
var Ingredients = React.createClass({
render: function() {
var ingrMarkup = [];
for (var k=0;k<JSON.parse(localStorage.recipeBook)[i].ingredients.length;k++){
var CurIngr = JSON.parse(localStorage.recipeBook)[i].ingredients[k];
ingrMarkup.push(<li className="list-group-item">{CurIngr}</li>);
}
return(
<ul className="list-group">{ingrMarkup}</ul>
);
}
});
ReactDOM.render(<Ingredients />,document.getElementById('ingredients-'+i));
}
document.getElementById('add-recipe').addEventListener('click', function(){
console.log($(this).attr('id'));
console.log($(this).parent().parent().find("#edit-name").val());
console.log($(this).parent().parent().find("#edit-ingr").val());
var name = $(this).parent().parent().find("#edit-name").val();
var ingredients = $(this).parent().parent().find("#edit-ingr").val().split(',');
var updatedLocalStorage = JSON.parse(localStorage.recipeBook);
updatedLocalStorage.push({"name":name,"ingredients":ingredients});
localStorage.setItem('recipeBook', JSON.stringify(updatedLocalStorage));
refresh();
});
var delButtons = document.getElementsByClassName('del-rec');
for (var k=0;k<delButtons.length;k++){
delButtons[k].addEventListener('click', function(){
var id = $(this).attr('id');
id = id.substring(id.lastIndexOf('-')+1,id.length);
var updatedLocalStorage = JSON.parse(localStorage.recipeBook);
updatedLocalStorage.splice(id,1);
localStorage.setItem('recipeBook', JSON.stringify(updatedLocalStorage));
refresh();
});
}
var editButtons = document.getElementsByClassName('edit-rec');
for (var k=0;k<editButtons.length;k++){
editButtons[k].addEventListener('click', function(){
var id = $(this).attr('id');
id = id.substring(id.lastIndexOf('-')+1,id.length);
var recipe = JSON.parse(localStorage.recipeBook)[id];
$(this).parent().parent().find("#edit-name").val(recipe.name);
$(this).parent().parent().find("#edit-ingr").val(recipe.ingredients);
});
}
var updateButtons = document.getElementsByClassName('upd-rec');
for (var k=0;k<updateButtons.length;k++){
updateButtons[k].addEventListener('click', function(){
var id = $(this).attr('id');
id = id.substring(id.lastIndexOf('-')+1,id.length);
var name = $(this).parent().parent().find("#edit-name").val();
var ingredients = $(this).parent().parent().find("#edit-ingr").val().split(',');
var updatedLocalStorage = JSON.parse(localStorage.recipeBook);
updatedLocalStorage.splice(id,1,{"name":name,"ingredients":ingredients});
localStorage.setItem('recipeBook', JSON.stringify(updatedLocalStorage));
refresh();
});
}
})();
});
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/react/0.14.7/react.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/react/0.14.7/react-dom.js"></script>
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
$black: #000000
$red: #ff0000
body
color: $black
font-family: 'Play', sans-serif
font-size: 2.2em
overflow-x:hidden
.nopadding
padding: 0
.navbar-brand
font-size: 1em
.home
min-height: 100vh
height: auto !important
.sect
padding-top: 8vh
.githublogo
height: 1em
h2
text-align: center
font-weight: bold
#output
text-align: center
width: 100%
height: auto !important
p
color: $red
.cllps-toggler
display: block
a
text-decoration: none
.credits
display: block
text-align: center
font-size: 0.75em
a:hover
text-decoration: none
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet" />
<link href="//cdnjs.cloudflare.com/ajax/libs/animate.css/3.2.3/animate.min.css" rel="stylesheet" />
<link href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.3/themes/smoothness/jquery-ui.css" rel="stylesheet" />
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment