[#31] Upgrade recipe selector to support search
* Add the jQuery-UI autocomplete component instead of a regular select control for choosing recipes
This commit is contained in:
+66
-55
@@ -1,10 +1,12 @@
|
|||||||
// Constants //////////////////////////////////////////////////////////////////////////////////////////////////////////
|
// Constants //////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
var ERROR_DISPLAY_DURATION = 10000; // ms
|
||||||
var FADE_DURATION = 250; // ms
|
var FADE_DURATION = 250; // ms
|
||||||
var ERROR_DISPLAY_DURATION = 5000; // ms
|
var SLIDE_DURATION = 600; // ms
|
||||||
|
|
||||||
// Global Variables ///////////////////////////////////////////////////////////////////////////////////////////////////
|
// Global Variables ///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
var __loadingCount = 0;
|
||||||
var __recipebooks = [];
|
var __recipebooks = [];
|
||||||
var __toolsIncluded = false;
|
var __toolsIncluded = false;
|
||||||
|
|
||||||
@@ -12,32 +14,24 @@ var __toolsIncluded = false;
|
|||||||
|
|
||||||
$(function() {
|
$(function() {
|
||||||
$("#recipebook_load_button").click(onRecipeLoadButtonClicked);
|
$("#recipebook_load_button").click(onRecipeLoadButtonClicked);
|
||||||
$("#crafting_selector").change(onCraftingSelectorChanged);
|
|
||||||
$("#crafting_count").change(onCraftingSelectorChanged);
|
$("#crafting_count").change(onCraftingSelectorChanged);
|
||||||
$("#tools_included").change(onIncludeToolsChanged);
|
$("#tools_included").change(onIncludeToolsChanged);
|
||||||
|
$("#crafting_selector").focus(onCraftingSelectorFocused);
|
||||||
|
|
||||||
loadRecipebook("data/vanilla.json", function() {
|
loadRecipebook("data/vanilla.json");
|
||||||
loadRecipebook("data/buildcraft.json", function() {
|
loadRecipebook("data/buildcraft.json");
|
||||||
loadRecipebook("data/industrial_craft.json", function() {
|
loadRecipebook("data/industrial_craft.json");
|
||||||
parseUrlParameters();
|
|
||||||
onCraftingSelectorChanged();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
function onCraftingSelectorChanged() {
|
function onCraftingSelectorChanged() {
|
||||||
var recipeName = $("#crafting_selector option:selected").val();
|
var recipeName = $("#crafting_selector").val();
|
||||||
var count = parseInt($("#crafting_count option:selected").val());
|
var count = parseInt($("#crafting_count option:selected").val());
|
||||||
if (recipeName === undefined) return;
|
|
||||||
if (count === undefined) return;
|
if (count === undefined) return;
|
||||||
|
|
||||||
updatePageState(count, recipeName);
|
|
||||||
|
|
||||||
var recipe = findRecipe(recipeName);
|
var recipe = findRecipe(recipeName);
|
||||||
if (recipe === undefined) {
|
if (recipe === undefined) {
|
||||||
$("#crafting_error").html("Cannot find recipe for " + recipeName);
|
$("#crafting_output").slideUp(SLIDE_DURATION);
|
||||||
$("#crafting_error").fadeIn(FADE_DURATION).delay(ERROR_DISPLAY_DURATION).fadeOut(FADE_DURATION);
|
|
||||||
} else {
|
} else {
|
||||||
var inventory = createManifest();
|
var inventory = createManifest();
|
||||||
var craftedItems = createManifest();
|
var craftedItems = createManifest();
|
||||||
@@ -50,7 +44,28 @@ function onCraftingSelectorChanged() {
|
|||||||
$("#missing_materials").html(missingMaterials.toHtml());
|
$("#missing_materials").html(missingMaterials.toHtml());
|
||||||
$("#crafted_items").html(craftedItems.toHtml());
|
$("#crafted_items").html(craftedItems.toHtml());
|
||||||
$("#leftover_materials").html(inventory.toHtml());
|
$("#leftover_materials").html(inventory.toHtml());
|
||||||
$("#crafting_output").fadeIn(FADE_DURATION);
|
$("#crafting_output").slideDown(SLIDE_DURATION);
|
||||||
|
}
|
||||||
|
|
||||||
|
updatePageState(count, recipeName);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onCraftingSelectorFocused() {
|
||||||
|
$("#crafting_selector").autocomplete("search");
|
||||||
|
}
|
||||||
|
|
||||||
|
function onIncludeToolsChanged() {
|
||||||
|
__toolsIncluded = $("#tools_included").is(":checked");
|
||||||
|
onCraftingSelectorChanged()
|
||||||
|
}
|
||||||
|
|
||||||
|
function onRecipeBookLoaded() {
|
||||||
|
if (__loadingCount > 0 || __recipebooks.length === 0) {
|
||||||
|
$("#crafting").fadeOut(FADE_DURATION);
|
||||||
|
} else if (__loadingCount === 0 && __recipebooks.length > 0) {
|
||||||
|
updateCraftingSelector();
|
||||||
|
parseUrlParameters();
|
||||||
|
$("#crafting").fadeIn(FADE_DURATION);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,14 +77,10 @@ function onRecipeLoadButtonClicked() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function onIncludeToolsChanged() {
|
|
||||||
__toolsIncluded = $("#tools_included").is(":checked");
|
|
||||||
onCraftingSelectorChanged()
|
|
||||||
}
|
|
||||||
|
|
||||||
// UI Helper Functions ////////////////////////////////////////////////////////////////////////////////////////////////
|
// UI Helper Functions ////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
function loadRecipebook(recipebookUrl, onSuccess) {
|
function loadRecipebook(recipebookUrl) {
|
||||||
|
__loadingCount++;
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: recipebookUrl,
|
url: recipebookUrl,
|
||||||
dataType: "text",
|
dataType: "text",
|
||||||
@@ -79,19 +90,18 @@ function loadRecipebook(recipebookUrl, onSuccess) {
|
|||||||
__recipebooks.push(recipebook);
|
__recipebooks.push(recipebook);
|
||||||
|
|
||||||
recipebook.asTableRow().insertBefore($("#recipebook_table tr").last());
|
recipebook.asTableRow().insertBefore($("#recipebook_table tr").last());
|
||||||
|
|
||||||
updateCraftingSelector();
|
|
||||||
$("#crafting").fadeIn(FADE_DURATION);
|
|
||||||
|
|
||||||
if (onSuccess !== undefined) onSuccess();
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
$("#load_error").html(e);
|
$("#load_error").html(e);
|
||||||
$("#load_error").slideDown(FADE_DURATION).delay(ERROR_DISPLAY_DURATION).slideUp(FADE_DURATION);
|
$("#load_error").slideDown(FADE_DURATION).delay(ERROR_DISPLAY_DURATION).slideUp(FADE_DURATION);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
error: function(response, status, error) {
|
error: function(response, status, error) {
|
||||||
$("#load_error").html(error);
|
$("#load_error").html(status + ": " + error);
|
||||||
$("#load_error").slideDown(FADE_DURATION).delay(ERROR_DISPLAY_DURATION).slideUp(FADE_DURATION);
|
$("#load_error").slideDown(FADE_DURATION).delay(ERROR_DISPLAY_DURATION).slideUp(FADE_DURATION);
|
||||||
|
},
|
||||||
|
complete: function() {
|
||||||
|
__loadingCount--;
|
||||||
|
onRecipeBookLoaded();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -113,7 +123,9 @@ function parseUrlParameters() {
|
|||||||
if (recipeName !== undefined) {
|
if (recipeName !== undefined) {
|
||||||
$("#crafting_selector").val(recipeName);
|
$("#crafting_selector").val(recipeName);
|
||||||
|
|
||||||
if ($("#crafting_selector option:selected").val() === undefined) {
|
if (findRecipe(recipeName) !== undefined) {
|
||||||
|
onCraftingSelectorChanged();
|
||||||
|
} else if (recipeName.length > 0) {
|
||||||
$("#crafting_error").html("Cannot find recipe for " + recipeName);
|
$("#crafting_error").html("Cannot find recipe for " + recipeName);
|
||||||
$("#crafting_error").fadeIn(FADE_DURATION).delay(ERROR_DISPLAY_DURATION).fadeOut(FADE_DURATION);
|
$("#crafting_error").fadeIn(FADE_DURATION).delay(ERROR_DISPLAY_DURATION).fadeOut(FADE_DURATION);
|
||||||
}
|
}
|
||||||
@@ -121,38 +133,37 @@ function parseUrlParameters() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function updateCraftingSelector() {
|
function updateCraftingSelector() {
|
||||||
var $selector = $("#crafting_selector");
|
var $selector = $("crafting_selector");
|
||||||
$selector.html("");
|
var names = [];
|
||||||
|
$(__recipebooks).each(function(i, recipebook) {
|
||||||
|
for (var name in recipebook.recipes) {
|
||||||
|
names.push(name);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
names.sort();
|
||||||
|
|
||||||
if (__recipebooks.length == 0) {
|
$("#crafting_selector").autocomplete({
|
||||||
$selector.attr("disabled", "disabled");
|
source: names, delay: 0, minLength: 0,
|
||||||
$selector.html("<option>No recipes</option>");
|
change: onCraftingSelectorChanged,
|
||||||
} else {
|
close: onCraftingSelectorChanged,
|
||||||
$(__recipebooks).each(function(i, recipebook) {
|
select: onCraftingSelectorChanged,
|
||||||
var $optgroup = $("<optgroup label=\"" + recipebook.name + "\">");
|
});
|
||||||
$selector.append($optgroup);
|
|
||||||
|
|
||||||
var names = [];
|
|
||||||
for (var name in recipebook.recipes) {
|
|
||||||
names.push(name);
|
|
||||||
}
|
|
||||||
names.sort();
|
|
||||||
|
|
||||||
for (var i = 0; i < names.length; i++) {
|
|
||||||
$optgroup.append("<option value=\"" + names[i] + "\">" + names[i] + "</option>");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
$selector.removeAttr("disabled");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function updatePageState(count, recipeName) {
|
function updatePageState(count, recipeName) {
|
||||||
var newTitle = "Crafting Guide: " + count + " " + recipeName;
|
var newTitle = "Crafting Guide";
|
||||||
var newLink = "?count=" + count + "&recipeName=" + encodeURIComponent(recipeName);
|
var newLink = window.location.pathname;
|
||||||
newLink = newLink.replace(/%20/g, "+");
|
var state = {}
|
||||||
|
if (recipeName !== undefined && recipeName.length > 0) {
|
||||||
|
newTitle = "Crafting Guide: " + count + " " + recipeName;
|
||||||
|
newLink = "?count=" + count + "&recipeName=" + encodeURIComponent(recipeName);
|
||||||
|
newLink = newLink.replace(/%20/g, "+");
|
||||||
|
state = {count: count, name: recipeName};
|
||||||
|
}
|
||||||
|
console.log("newTitle: " + newTitle + ", newLink: " + newLink);
|
||||||
|
|
||||||
document.title = newTitle;
|
document.title = newTitle;
|
||||||
history.pushState({count: count, name: recipeName}, newTitle, newLink);
|
history.pushState(state, newTitle, newLink);
|
||||||
ga('send', 'pageview');
|
ga('send', 'pageview');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ p { margin-left: 10px; margin-right: 10px; }
|
|||||||
#crafting_output { margin-left: 10px; width: 920px; }
|
#crafting_output { margin-left: 10px; width: 920px; }
|
||||||
#crafting_output th { background: #f8f8f8; border-left: 1px solid #bbb; font-weight: bold; padding: 10px; }
|
#crafting_output th { background: #f8f8f8; border-left: 1px solid #bbb; font-weight: bold; padding: 10px; }
|
||||||
#crafting_output td { background: #f8f8f8; border-left: 1px solid #bbb; padding: 10px; }
|
#crafting_output td { background: #f8f8f8; border-left: 1px solid #bbb; padding: 10px; }
|
||||||
|
#crafting_selector { width: 400px; }
|
||||||
#footer { background: #3E1D0A; color: white; padding-top: 10px; };
|
#footer { background: #3E1D0A; color: white; padding-top: 10px; };
|
||||||
#footer iframe { display: inline-block; }
|
#footer iframe { display: inline-block; }
|
||||||
#footer a { color: gray; }
|
#footer a { color: gray; }
|
||||||
@@ -31,3 +32,4 @@ p { margin-left: 10px; margin-right: 10px; }
|
|||||||
#recipebook_url { width: 600px; }
|
#recipebook_url { width: 600px; }
|
||||||
#recipebooks { margin-top: 32px; margin-bottom: 32px; }
|
#recipebooks { margin-top: 32px; margin-bottom: 32px; }
|
||||||
|
|
||||||
|
.ui-autocomplete { max-height: 400px; overflow-y: auto; overflow-x: hidden; }
|
||||||
|
|||||||
+7
-5
@@ -2,11 +2,12 @@
|
|||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>Crafting Guide</title>
|
<title>Crafting Guide</title>
|
||||||
<link rel='stylesheet' type='text/css' href='http://fonts.googleapis.com/css?family=Press+Start+2P'/>
|
|
||||||
<link rel="stylesheet" type="text/css" href="css/reset.css"/>
|
<link rel="stylesheet" type="text/css" href="css/reset.css"/>
|
||||||
<link rel="stylesheet" type="text/css" href="css/text.css"/>
|
<link rel="stylesheet" type="text/css" href="css/text.css"/>
|
||||||
<link rel="stylesheet" type="text/css" href="css/960.css"/>
|
<link rel="stylesheet" type="text/css" href="css/960.css"/>
|
||||||
<link rel="stylesheet" type="text/css" href="css/main.css"/>
|
<link rel="stylesheet" type="text/css" href="css/main.css"/>
|
||||||
|
<link rel="stylesheet" type="text/css" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css"/>
|
||||||
|
<link rel='stylesheet' type='text/css' href='http://fonts.googleapis.com/css?family=Press+Start+2P'/>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="container_12">
|
<body class="container_12">
|
||||||
@@ -32,7 +33,7 @@
|
|||||||
|
|
||||||
<div id="crafting" class="hidden">
|
<div id="crafting" class="hidden">
|
||||||
<h1><img src="images/workbench_top.png"> Crafting</h1>
|
<h1><img src="images/workbench_top.png"> Crafting</h1>
|
||||||
<p>Choose a recipe:
|
<p>I want to make
|
||||||
<select id="crafting_count">
|
<select id="crafting_count">
|
||||||
<option value="1">1</option>
|
<option value="1">1</option>
|
||||||
<option value="2">2</option>
|
<option value="2">2</option>
|
||||||
@@ -42,9 +43,9 @@
|
|||||||
<option value="32">32</option>
|
<option value="32">32</option>
|
||||||
<option value="64">64</option>
|
<option value="64">64</option>
|
||||||
</select>
|
</select>
|
||||||
<select id="crafting_selector" disabled></select>
|
<input id="crafting_selector"></input>
|
||||||
<input id="tools_included" name="tools_included" type="checkbox"></input>
|
<input id="tools_included" name="tools_included" type="checkbox"></input>
|
||||||
<label for="include_tools">include tools</label>
|
<label for="tools_included">include tools</label>
|
||||||
</p>
|
</p>
|
||||||
<table id="crafting_output" class="hidden" cellpadding="0" cellspacing="0">
|
<table id="crafting_output" class="hidden" cellpadding="0" cellspacing="0">
|
||||||
<tr>
|
<tr>
|
||||||
@@ -96,7 +97,8 @@
|
|||||||
<div id="border_bedrock" class="grid_12 alpha omega"> </div>
|
<div id="border_bedrock" class="grid_12 alpha omega"> </div>
|
||||||
</div> <!-- .container_12 -->
|
</div> <!-- .container_12 -->
|
||||||
|
|
||||||
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
|
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
|
||||||
|
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
|
||||||
<script src="purl.js"></script>
|
<script src="purl.js"></script>
|
||||||
<script src="crafting.js"></script>
|
<script src="crafting.js"></script>
|
||||||
<script>
|
<script>
|
||||||
|
|||||||
Reference in New Issue
Block a user