The Recipe Engine

Developer
Size
9,316 Kb
Views
28,336

How do I make an the recipe engine?

What is a the recipe engine? How do you make a the recipe engine? This script and codes were developed by Bob Sutton on 11 September 2022, Sunday.

The Recipe Engine Previews

The Recipe Engine - Script Codes HTML Codes

<!DOCTYPE html>
<html >
<head> <meta charset="UTF-8"> <title>The Recipe Engine</title> <link rel='stylesheet prefetch' href='https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css'>
<link rel='stylesheet prefetch' href='https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css'> <link rel="stylesheet" href="css/style.css">
</head>
<body> <div class="container">
<h1 class="text-center">The Recipe Engine</h1> <div class="row"> <div class="col-sm-1"> </div> <div class="col-sm-4"> <div id="recipe-list"></div> </div> <div class="col-sm-6"> <div id="recipe-text"></div> </div> <div class="col-sm-1"></div> </div> <div id="buttons-box" class="row"> <div class="col-sm-2"></div> <div id="new-recipe-button" class="col-sm-1"></div> <div id="edit-recipe-button" class="col-sm-1"></div> <div class="col-sm-5"></div> <div id="delete-recipe-button" class="col-sm-1"></div> <div class="col-sm-2"></div> </div> </div>
</div>
<div id="new-recipe-dialog"> <div id="new-recipe-text-field"></div> <div id="new-recipe-text-area"></div> <div id="create-new-recipe-button"></div>
</div>
<div id="edit-recipe-dialog"> <div id="edit-recipe-text-field"></div> <div id="edit-recipe-text-area"></div> <div id="update-recipe-button"></div>
</div> <script src='https://cdnjs.cloudflare.com/ajax/libs/react/15.3.1/react.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/react/15.3.1/react-dom.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.0/jquery-ui.min.js'></script> <script src="js/index.js"></script>
</body>
</html>

The Recipe Engine - Script Codes CSS Codes

body { background-color: #DCDCCA;
}
h1 { margin-top: 30px; height: 40px;
}
#recipe-list { margin-top: 30px;
}
#recipe-list li { background: #ffcc66;
}
#recipe-text { margin-top: 30px; height: 500px;
}
#recipe-text textarea { background: #ccffff;
}
textarea { padding: 5px; width: 100%; height: 100%; resize: none; border: 1px solid #cfdfdf; border-radius: 4px;
}
#buttons-box { margin-top: 20px;
}
#new-recipe-dialog { display: none;
}
#new-recipe-dialog input { width: 100%; height: 10%;
}
#new-recipe-dialog textarea { width: 100%; height: 255px; margin-top: 10px; margin-bottom: 10px;
}
#edit-recipe-dialog { display: none;
}
#edit-recipe-dialog input { width: 100%; height: 10%;
}
#edit-recipe-dialog textarea { width: 100%; height: 255px; margin-top: 10px; margin-bottom: 10px;
}

The Recipe Engine - Script Codes JS Codes

"use strict";
/***** * * bshrcl.js -- Bob Sutton's Homespun React Class Library * *****/
/* * Button class */
function Button(text, domAttachId, className, onClick) { this.text = text; this.domAttachId = domAttachId; this.className = className; this.onClick = onClick; var button = React.createClass({ displayName: "button", getDefaultProps: function getDefaultProps() { return { text: "", className: "", onClick: function onClick() {} }; }, getInitialState: function getInitialState() { return { text: this.props.text, disabled: false }; }, render: function render() { return React.createElement( "button", { onClick: this.props.onClick, className: this.props.className ? this.props.className : "", disabled: this.state.disabled }, this.state.text ); } }); this.component = ReactDOM.render(React.createElement(button, { text: this.text, className: this.className, onClick: this.onClick }), document.getElementById(this.domAttachId));
}
Button.prototype.disabled = function (disabled) { this.component.setState({ disabled: disabled });
};
Button.prototype.isDisabled = function () { return this.component.state.disabled;
};
Button.prototype.setText = function (text) { this.component.setState({ text: text });
};
Button.prototype.getText = function () { if (!this.component) return undefined; return this.component.state.text;
};
Button.prototype.getComponent = function () { return this.component;
};
/* * Text field component */
function TextField(text, domAttachId, className, readOnly, placeholder, onChange) { this.text = text; this.domAttachId = domAttachId; this.className = className; this.readOnly = readOnly; this.placeholder = placeholder; this.onChange = onChange; var textField = React.createClass({ displayName: "textField", getDefaultProps: function getDefaultProps() { return { text: "", className: "", readOnly: false, placeholder: "" }; }, getInitialState: function getInitialState() { return { text: this.props.text, className: this.props.className, readOnly: this.props.readOnly, placeholder: this.props.placeholder, onChange: this.props.onChange }; }, render: function render() { return React.createElement("input", { type: "text", defaultValue: this.props.text, value: this.state.text, readOnly: this.state.readOnly, placeholder: this.props.placeholder, onChange: this._onChange }); }, _onChange: function _onChange(event) { if (this.props.onChange) this.props.onChange(event);else this.setState({ text: event.target.value }); } }); this.component = ReactDOM.render(React.createElement(textField, { text: this.text, className: this.className, readOnly: this.readOnly, placeholder: this.placeholder, onChange: this.onChange }), document.getElementById(this.domAttachId));
}
TextField.prototype.setText = function (text) { this.component.setState({ "text": text });
};
TextField.prototype.getText = function () { return this.component.state.text;
};
TextField.prototype.setReadOnly = function (readOnly) { this.component.setState({ readOnly: readOnly });
};
TextField.prototype.isReadOnly = function () { return this.component.state.readOnly;
};
TextField.prototype.getComponent = function () { return this.component;
};
/* * TextArea class */
function TextArea(text, domAttachId, className, readOnly, placeholder, onChange) { this.text = text; this.domAttachId = domAttachId; this.className = className; this.readOnly = readOnly; this.placeholder = placeholder; this.onChange = onChange; var textArea = React.createClass({ displayName: "textArea", getDefaultProps: function getDefaultProps() { return { text: "", className: "", readOnly: false, placeholder: "" }; }, getInitialState: function getInitialState() { return { text: this.props.text, className: this.props.className, readOnly: this.props.readOnly, onChange: this.props.onChange }; }, render: function render() { return React.createElement("textarea", { defaultValue: this.props.text, value: this.state.text, className: this.state.className, readOnly: this.state.readOnly, placeholder: this.props.placeholder, onChange: this._onChange }); }, _onChange: function _onChange(event) { if (this.props.onChange) this.props.onChange(event);else this.setState({ text: event.target.value }); } }); this.component = ReactDOM.render(React.createElement(textArea, { text: this.text, className: this.className, readOnly: this.readOnly, placeholder: this.placeholder, onChange: this.onChange }), document.getElementById(this.domAttachId));
}
TextArea.prototype.setText = function (text) { this.component.setState({ "text": text });
};
TextArea.prototype.getText = function () { return this.component.state.text;
};
TextArea.prototype.getComponent = function () { return this.component;
};
/* * SelectableList class */
function SelectableList(itemsList, domAttachId, className, onSelection) { this.itemsList = itemsList; this.domAttachId = domAttachId; this.className = className; this.onSelection = onSelection; var ul = React.createClass({ displayName: "ul", getDefaultProps: function getDefaultProps() { return { itemsList: [], className: "", onSelection: function onSelection() {} }; }, getInitialState: function getInitialState() { return { itemsList: this.props.itemsList, className: this.props.className, selectedId: undefined }; }, render: function render() { var liList = []; for (var i = 0; i < this.state.itemsList.length; i++) { var classNames = "list-group-item"; var className = this.state.itemsList[i].className; if (className) classNames += " " + className; if (this.state.selectedId === this.state.itemsList[i].id) classNames += " active"; liList.push(React.createElement( "li", { id: this.state.itemsList[i].id, key: this.state.itemsList[i].id, className: classNames }, this.state.itemsList[i].text )); } return React.createElement( "ul", { className: "list-group " + this.state.className, onClick: this._onClick }, liList ); }, _onClick: function _onClick(event) { // Get id of selected item var selectedId = event.target.id; this.setState({ selectedId: selectedId }); this.props.onSelection(selectedId); } }); this.component = ReactDOM.render(React.createElement(ul, { itemsList: this.itemsList, className: this.className, onSelection: this.onSelection }), document.getElementById(this.domAttachId));
}
SelectableList.prototype.clearSelection = function () { this.component.setState({ selectedId: undefined });
};
SelectableList.prototype.getSelectedId = function () { return this.component.state.selectedId;
};
SelectableList.prototype.update = function (itemsList) { this.component.setState({ itemsList: itemsList, selectedId: undefined });
};
SelectableList.prototype.addItem = function (id, name) { var itemsList = this.component.state.itemsList.map(function (it) { return it; }); itemsList.push({ id: id, text: name }); this.component.setState({ itemsList: itemsList });
};
SelectableList.prototype.removeItem = function (id) { var itemsList = this.component.state.itemsList.map(function (it) { return it; }); var selectedId = this.component.state.selectedId; if (this.component.state.selectedId === id) selectedId = undefined; for (var i = 0; i < itemsList.length; i++) { if (itemsList[i].id === id) { itemsList.splice(i, 1); break; } } this.component.setState({ itemsList: itemsList, selectedId: selectedId });
};
SelectableList.prototype.getComponent = function () { return this.component;
};
/****** * * End of bshrcl.js * *****/
function onNewButton() { // Clear fields newRecipeTextField.setText(""); newRecipeTextArea.setText(""); // Display dialog $("#new-recipe-dialog").dialog({ title: "Enter new recipe", modal: true, width: 500, height: 400 });
}
function onEditButton() { var selectedId = recipeList.getSelectedId(); if (!selectedId) return; var recipes = JSON.parse(localStorage.recipes); var recipe; for (var i = 0; i < recipes.length; i++) { if (recipes[i].id === selectedId) { recipe = recipes[i]; break; } } if (!recipe) return; editRecipeTextField.setText(recipe.name); editRecipeTextArea.setText(recipe.ingredients.reduce(function (a, it) { return a + "\n" + it; })); $("#edit-recipe-dialog").dialog({ title: "Edit recipe", modal: true, width: 500, height: 400 });
}
function deleteRecipe(id) { // Get list of recipes from local storage var recipes = JSON.parse(localStorage.recipes); // Delete matching recipe for (var i = 0; i < recipes.length; i++) { if (recipes[i].id === id) { recipes.splice(i, 1); break; } } // Update recipe list in local storage localStorage.recipes = JSON.stringify(recipes); // Update GUI recipeList.removeItem(id); recipeTextArea.setText(""); editButton.disabled(true); deleteButton.disabled(true);
}
function onDeleteButton() { var id = recipeList.getSelectedId(); var recipes = JSON.parse(localStorage.recipes); var recipe; for (var i = 0; i < recipes.length; i++) { if (recipes[i].id === id) { recipe = recipes[i]; break; } } if (!recipe) return; $("<div><p>Are you sure you want to delete the recipe named " + recipe.name + "?</p></div>").dialog({ title: "Recipe deletion confirmation", resizable: false, height: "auto", width: 300, modal: true, buttons: { "Delete selected recipe": function DeleteSelectedRecipe() { deleteRecipe(id); $(this).dialog("close"); } } });
}
function onListSelection(selectedId) { // Enable edit and delete buttons editButton.disabled(false); deleteButton.disabled(false); // Put text in recipe text area var recipes = JSON.parse(localStorage.recipes); for (var i = 0; i < recipes.length; i++) { if (recipes[i].id === selectedId) { recipeTextArea.setText(recipes[i].ingredients.reduce(function (a, it) { return a + "\n" + it; })); break; } }
}
function recipesListToListItems() { var recipes = JSON.parse(localStorage.recipes); return recipes.map(function (recipe) { return { id: recipe.name.replace(/[ \-]/g, "_"), text: recipe.name }; });
}
function newRecipeTextFieldValidator(event) { newRecipeTextField.setText(event.target.value); createNewRecipeButton.disabled(event.target.value.trim().length === 0 || newRecipeTextArea.getText().trim().length === 0);
}
function newRecipeTextAreaValidator(event) { newRecipeTextArea.setText(event.target.value); createNewRecipeButton.disabled(newRecipeTextField.getText().trim().length === 0 || event.target.value.trim().length === 0);
}
function editRecipeTextAreaValidator(event) { editRecipeTextArea.setText(event.target.value); updateRecipeButton.disabled(editRecipeTextField.getText().trim().length === 0 || event.target.value.trim().length === 0);
}
function updateRecipe(id, name, ingredients) { // Parse ingredients into string array ingredients = ingredients.split("\n"); for (var i = 0; i < ingredients.length; i++) { ingredients[i] = ingredients[i].trim(); }for (var i = ingredients.length - 1; i >= 0; i--) { if (ingredients[i].length === 0) ingredients.splice(i, 1); } // Update database var recipes = JSON.parse(localStorage.recipes); recipes.push({ id: id, name: name, ingredients: ingredients }); localStorage.recipes = JSON.stringify(recipes); // Update list of recipes recipeList.addItem(id, name);
}
function onCreateNewRecipeButton() { var recipes = JSON.parse(localStorage.recipes); var name = newRecipeTextField.getText(); var ingredients = newRecipeTextArea.getText(); var id = name.replace(/[ \-]/g, "_"); var found = false; for (var i = 0; i < recipes.length; i++) { if (recipes[i].id === id) { found = true; break; } } if (!found) { updateRecipe(id, name, ingredients); $("#new-recipe-dialog").dialog("close"); return; } $("<div><p>This recipe already exists. Are you sure you want to replace it?</p></div>").dialog({ title: "Recipe replacement confirmation", resizable: false, height: "auto", width: 300, modal: true, buttons: { "Replace it": function ReplaceIt() { $(this).dialog("close"); recipes.splice(i, 1); localStorage.recipes = JSON.stringify(recipes); updateRecipe(id, name, ingredients); $("#new-recipe-dialog").dialog("close"); } } });
}
function onUpdateRecipeButton() { // Close dialog $("#edit-recipe-dialog").dialog("close"); // Get select recipe id var selectedId = recipeList.getSelectedId(); // Get field contents var name = editRecipeTextField.getText(); var ingredients = editRecipeTextArea.getText().split("\n"); for (var i = ingredients.length - 1; i >= ingredients; i++) { if (ingredients[i].trim().length === 0) ingredients.splice(i, 1); } // Update recipes list var recipes = JSON.parse(localStorage.recipes); for (var i = 0; i < recipes.length; i++) { if (recipes[i].id === selectedId) { recipes[i].name = name; recipes[i].ingredients = ingredients; break; } } localStorage.recipes = JSON.stringify(recipes); // Update displayed recipe ingredients recipeTextArea.setText(ingredients.reduce(function (a, it) { return a + "\n" + it; }));
}
function mergeRecipesIntoStoredRecipes(recipes) { var storedRecipes = localStorage.recipes; if (!storedRecipes) { localStorage.recipes = JSON.stringify(recipes); return; } storedRecipes = JSON.parse(storedRecipes); for (var i = 0; i < recipes.length; i++) { var found = false; for (var j = 0; j < storedRecipes.length; j++) { if (recipes[i].id === storedRecipes[j].id) { found = true; break; } } if (!found) storedRecipes.push(recipes[i]); } localStorage.recipes = JSON.stringify(storedRecipes);
}
// Load recipes into local storage if they aren't already there
var recipes = [];
recipes.push({ id: "Country_Style_Chicken_Kiev", name: "Country-Style Chicken Kiev", ingredients: ["Boneless, skinless chicken breasts", "Oregano", "Basil", "Garlic clove", "Salt", "Chopped green onions", "Butter", "Chopped parsley", "Bread crumbs", "Ground Parmasean cheese"]
});
recipes.push({ id: "Chicken_Paprikash", name: "Chicken Paprikash", ingredients: ["Dark-meat chicken quarters", "Paprika", "Yellow Onion", "Anaheim pepper", "Sour cream", "Salt", "Butter", "Chicken stock", "Flour", "Black pepper"]
});
recipes.push({ id: "Kentucky_Fried_Chicken", name: "Kentucky Fried Chicken", ingredients: ["Chicken pieces", "Flour", "Salt", "Thyme", "Basil", "Oregano", "Celery salt", "Black pepper", "Dried mustard", "Paprika", "Garlic salt", "Ground ginger", "White pepper"]
});
mergeRecipesIntoStoredRecipes(recipes);
// Create main GUI components
var recipeList = new SelectableList(recipesListToListItems(), "recipe-list", "", onListSelection);
var recipeTextArea = new TextArea("", "recipe-text", "", true, "Recipe ingredients will appear here");
var newButton = new Button("New", "new-recipe-button", "button", onNewButton);
var editButton = new Button("Edit", "edit-recipe-button", "button", onEditButton);
editButton.disabled(true);
var deleteButton = new Button("Delete", "delete-recipe-button", "button", onDeleteButton);
deleteButton.disabled(true);
// Create new recipe dialog components
var newRecipeTextField = new TextField("", "new-recipe-text-field", "", false, "Recipe Name", newRecipeTextFieldValidator);
var newRecipeTextArea = new TextArea("", "new-recipe-text-area", "", false, "Recipe Ingredients", newRecipeTextAreaValidator);
var createNewRecipeButton = new Button("Create New Recipe", "create-new-recipe-button", "button", onCreateNewRecipeButton);
createNewRecipeButton.disabled(true);
// Create edit recipe dialog components
var editRecipeTextField = new TextField("", "edit-recipe-text-field", "", false, "Recipe Name");
editRecipeTextField.setReadOnly(true);
var editRecipeTextArea = new TextArea("", "edit-recipe-text-area", "", false, "Recipe Ingredients", editRecipeTextAreaValidator);
var updateRecipeButton = new Button("Update Recipe", "update-recipe-button", "button", onUpdateRecipeButton);
updateRecipeButton.disabled(true);
The Recipe Engine - Script Codes
The Recipe Engine - Script Codes
Home Page Home
Developer Bob Sutton
Username anischyros
Uploaded September 11, 2022
Rating 3
Size 9,316 Kb
Views 28,336
Do you need developer help for The Recipe Engine?

Find the perfect freelance services for your business! Fiverr's mission is to change how the world works together. Fiverr connects businesses with freelancers offering digital services in 500+ categories. Find Developer!

Bob Sutton (anischyros) Script Codes
Create amazing SEO content with AI!

Jasper is the AI Content Generator that helps you and your team break through creative blocks to create amazing, original content 10X faster. Discover all the ways the Jasper AI Content Platform can help streamline your creative workflows. Start For Free!