Add support for separate cook/prep time and better validation

This commit is contained in:
Chris 2018-10-01 22:10:13 +01:00
parent 974cf8cbb1
commit 601fe5e3fb
16 changed files with 350 additions and 97 deletions

View File

@ -73,6 +73,8 @@ sub _build_recipe {
});
}
my $time = ($recipe -> {"preptime"} + $recipe -> {"cooktime"}) * 60;
return $self -> {"template"} -> load_template("list/recipe.tem",
{ "%(id)s" => $recipe -> {"id"},
"%(url-view)s" => $self -> build_url(block => "view",
@ -80,7 +82,7 @@ sub _build_recipe {
"%(name)s" => $recipe -> {"name"},
"%(type)s" => $recipe -> {"type"},
"%(status)s" => $recipe -> {"status"},
"%(time)s" => $self -> {"template"} -> humanise_seconds($recipe -> {"timemins"} * 60, 1),
"%(time)s" => $self -> {"template"} -> humanise_seconds($time, 1),
"%(temp)s" => $temp,
"%(tags)s" => join("", map { $self -> _build_tag($_) } @{$recipe -> {"tags"}}),
"%(controls)s" => $controls,

View File

@ -85,17 +85,23 @@ sub _generate_new {
my $ingredients = $self -> _build_ingredients($args);
# Build up the type and status data
my $typeopts = $self -> {"template"} -> build_optionlist($self -> {"system"} -> {"entities"} -> {"types"} -> as_options(),
my $typeopts = $self -> {"template"} -> build_optionlist($self -> {"system"} -> {"entities"} -> {"types"} -> as_options(1),
$args -> {"type"});
my $statusopts = $self -> {"template"} -> build_optionlist($self -> {"system"} -> {"entities"} -> {"states"} -> as_options(0, visible => {value => 1}),
my $statusopts = $self -> {"template"} -> build_optionlist($self -> {"system"} -> {"entities"} -> {"states"} -> as_options(1, visible => {value => 1}),
$args -> {"status"});
# Convert the time fields
my ($timemins, $timesecs) = ("", 0);
if($args -> {"timemins"}) {
$timesecs = $args -> {"timemins"} * 60;
$timemins = $self -> _build_timereq($timesecs);
my ($preptime, $prepsecs) = ("", 0);
if($args -> {"preptime"}) {
$prepsecs = $args -> {"preptime"} * 60;
$preptime = $self -> _build_timereq($prepsecs);
}
my ($cooktime, $cooksecs) = ("", 0);
if($args -> {"cooktime"}) {
$cooksecs = $args -> {"cooktime"} * 60;
$cooktime = $self -> _build_timereq($cooksecs);
}
# Convert tags - can't use build_optionlist because all of them need to be selected.
@ -115,9 +121,11 @@ sub _generate_new {
"%(name)s" => $args -> {"name"} // "",
"%(source)s" => $args -> {"source"} // "",
"%(yield)s" => $args -> {"yield"} // "",
"%(timereq)s" => $args -> {"timereq"} // "",
"%(timemins)s" => $timemins,
"%(timesecs)s" => $timesecs,
"%(prepinfo)s" => $args -> {"prepinfo"} // "",
"%(preptime)s" => $preptime,
"%(prepsecs)s" => $prepsecs,
"%(cooktime)s" => $cooktime,
"%(cooksecs)s" => $cooksecs,
"%(temp)s" => $args -> {"temp"} // "",
"%(temptypes)s" => $self -> {"template"} -> build_optionlist($temptypes, $args -> {"temptype"}),
"%(types)s" => $typeopts,

View File

@ -80,6 +80,44 @@
}
}
},
"/recipes": {
"get": {
"tags": [
"recipe"
],
"summary": "Fetch a list of recipes defined in the system",
"description": "Retrieve the list of recipes defined in the system.\n",
"parameters": [
{
"name": "name",
"description": "A name to search for recipes with",
"in": "query",
"type": "string",
"required": false
}
],
"responses": {
"200": {
"description": "A list of recipes",
"schema": {
"$ref": "#/definitions/Recipes"
}
},
"403": {
"description": "Permission error",
"schema": {
"$ref": "#/definitions/Error"
}
},
"default": {
"description": "Unexpected error",
"schema": {
"$ref": "#/definitions/Error"
}
}
}
}
},
"/tags": {
"get": {
"tags": [
@ -139,6 +177,15 @@
"$ref": "#/definitions/Ingredient"
}
},
"Recipe": {
"type": "object"
},
"Recipes": {
"type": "array",
"items": {
"$ref": "#/definitions/Recipe"
}
},
"Tag": {
"type": "object",
"properties": {

View File

@ -62,6 +62,32 @@ paths:
description: Unexpected error
schema:
$ref: '#/definitions/Error'
/recipes:
get:
tags:
- recipe
summary: Fetch a list of recipes defined in the system
description: |
Retrieve the list of recipes defined in the system.
parameters:
- name: name
description: A name to search for recipes with
in: query
type: string
required: false
responses:
'200':
description: A list of recipes
schema:
$ref: '#/definitions/Recipes'
'403':
description: Permission error
schema:
$ref: '#/definitions/Error'
default:
description: Unexpected error
schema:
$ref: '#/definitions/Error'
/tags:
get:
tags:
@ -102,6 +128,12 @@ definitions:
type: array
items:
$ref: '#/definitions/Ingredient'
Recipe:
type: object
Recipes:
type: array
items:
$ref: '#/definitions/Recipe'
Tag:
type: object
properties:

View File

@ -18,9 +18,13 @@ RECIPE_PREPINFO = Prep info
RECIPE_PREPINFO_DOC = How much time each step of the recipe take?
RECIPE_PREPINFO_PH = 10 min prep + 20 min cook
RECIPE_TIMEREQ = Time required
RECIPE_TIMEREQ_DOC = How long does this recipe take in total?
RECIPE_TIMEREQ_PH = 1 hour 10 minutes
RECIPE_PREPTIME = Preparation time required
RECIPE_PREPTIME_DOC = How long does this recipe take to prepare?
RECIPE_PREPTIME_PH = 30 minutes
RECIPE_COOKTIME = Cooking time required
RECIPE_COOKTIME_DOC = How long does this recipe take to cook?
RECIPE_COOKTIME_PH = 30 minutes
RECIPE_OVENTEMP = Oven preheat
RECIPE_OVENTEMP_DOC = Initial oven temperature (show changes in method)

View File

@ -71,6 +71,16 @@ sub new {
@_)
or return undef;
# Formats of accepted types
$self -> {"formats"} = {
"recipename" => '^[-\w,. ]+$',
"tags" => '^[-\w ]+$',
"quantity" => '^[\d\w./]+$',
"sepname" => '^[-\w,. ]{1,255}$',
"ingredient" => '^[-\w,. ]{1,255}$',
"notes" => '^[-()\w,. ]{1,255}$',
};
return $self;
}

View File

@ -273,6 +273,8 @@ sub find_ids {
# is no maximum and all possible matched are returned.
# - `as`: can be set to `name`, `value`, or `text`. This determines the key
# name used for the `name` field of the entities in the results.
# - `id`: can be set to `name` or `id`. This determines whether the entity name
# or id is used as the id in the data.
#
# @param args A hash or reference to a hash of search settings.
# @return A reference to an array of hashes containing the results, ordered
@ -297,7 +299,13 @@ sub find {
default { $as = "name"; }
}
my $search = $self -> {"dbh"} -> prepare("SELECT `id`, `refcount`, `name` AS `$as`
my $id;
given($args -> {"id"}) {
when("name") { $id = "name"; }
default { $id = "id"; }
}
my $search = $self -> {"dbh"} -> prepare("SELECT `$id` AS `id`, `refcount`, `name` AS `$as`
FROM `".$self -> {"settings"} -> {"database"} -> {$self -> {"entity_table"}}."`
WHERE `name` LIKE ?
ORDER BY `name`,`id`

View File

@ -17,40 +17,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
## @class Recipe
# +-------------+--------------------------------+------+-----+----------------+
# | Field | Type | Null | Key | Extra |
# +-------------+--------------------------------+------+-----+----------------+
# | id | int(10) unsigned | NO | PRI | auto_increment |
# | prev_id | int(11) | YES | | |
# | metadata_id | int(11) | NO | | |
# | name | varchar(80) | NO | UNI | |
# | method | text | NO | | |
# | notes | text | YES | | |
# | source | varchar(255) | YES | | |
# | yield | varchar(80) | NO | | |
# | timereq | varchar(255) | NO | | |
# | timemins | int(10) unsigned | NO | MUL | |
# | temptype | enum('C','F','Gas mark','N/A') | NO | | |
# | temp | smallint(5) unsigned | YES | | |
# | type_id | int(10) unsigned | NO | MUL | |
# | status_id | int(10) unsigned | NO | MUL | |
# | creator_id | int(10) unsigned | NO | | |
# | created | int(10) unsigned | NO | MUL | |
# | viewed | int(10) unsigned | NO | | |
# +-------------+--------------------------------+------+-----+----------------+
# +-----------+------------------+------+-----+----------------+
# | Field | Type | Null | Key | Extra |
# +-----------+------------------+------+-----+----------------+
# | id | int(10) unsigned | NO | PRI | auto_increment |
# | recipe_id | int(10) unsigned | NO | MUL | |
# | unit_id | int(10) unsigned | YES | | |
# | prep_id | int(10) unsigned | YES | | |
# | ingred_id | int(10) unsigned | YES | | |
# | quantity | varchar(8) | YES | | |
# | notes | varchar(255) | YES | | |
# | separator | varchar(255) | YES | | |
# +-----------+------------------+------+-----+----------------+
# FIXME: corrected table schema here
#
#
@ -107,16 +74,14 @@ sub clear {
#
# - `id`: (optional, avoid) Set the ID to create the recipe with.
# This should generally not be specified unless doing edits.
# - `previd`: (optional) ID of the recipe this is an edit of. If specified,
# the old recipe has its state set to 'edited', and the
# metadata context of the new recipe is created as a child of
# the old recipe to ensure editing works as expected. Generally
# - `origid`: (optional) ID of the recipe this is an edit of. Generally
# this will not be specified directly; if editing a recipe,
# call edit() to have renumbering handled for you.
# - `name`: The name of the recipe
# - `source`: (optional) Where did the recipe come from originally?
# - `timereq`: (optional) A string describing the time required for the recipe
# - `timemins`: How long does the recipe take in minutes, in total?
# - `prepinfo`: (optional) A string describing the time required for the recipe
# - `preptime`: How long does the recipe take to prepare in minutes?
# - `cooktime`: How long does the recipe take to cook in minutes?
# - `yield`: A string describing how much stuff the recipe creates
# - `temp`: (optional) Oven preheat temperature
# - `temptype`: The type of units used: 'C', 'F', 'Gas mark', or 'N/A'
@ -170,19 +135,20 @@ sub create {
unless($args -> {"created"});
# We need a metadata context for the recipe
my $metadataid = $self -> _create_recipe_metadata($args -> {"previd"});
my $metadataid = $self -> _create_recipe_metadata($args -> {"origid"});
# Do the insert, and fetch the ID of the new row
my $newh = $self -> {"dbh"} -> prepare("INSERT INTO `".$self -> {"settings"} -> {"database"} -> {"recipes"}."`
(`id`, `metadata_id`, `prev_id`, `name`, `source`, `timereq`, `timemins`, `yield`, `temp`, `temptype`, `method`, `notes`, `type_id`, `status_id`, `creator_id`, `created`, `updater_id`, `updated`)
VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? ,?)");
(`id`, `metadata_id`, `original_id`, `name`, `source`, `prepinfo`, `preptime`, `cooktime`, `yield`, `temp`, `temptype`, `method`, `notes`, `type_id`, `status_id`, `creator_id`, `created`, `updater_id`, `updated`)
VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? ,?)");
my $result = $newh -> execute($args -> {"id"},
$metadataid,
$args -> {"previd"},
$args -> {"origid"},
$args -> {"name"},
$args -> {"source"},
$args -> {"timereq"},
$args -> {"timemins"},
$args -> {"prepinfo"},
$args -> {"preptime"},
$args -> {"cooktime"},
$args -> {"yield"},
$args -> {"temp"},
$args -> {"temptype"},
@ -200,7 +166,8 @@ sub create {
return $self -> self_error("No rows added when inserting recipe.")
if($result eq "0E0");
my $newid = $self -> {"dbh"} -> {"mysql_insertid"};
# If we explicitly set an ID above, use it here rather than looking it up
my $newid = $args -> {"id"} // $self -> {"dbh"} -> {"mysql_insertid"};
return $self -> self_error("Unable to obtain id for new recipe")
if(!$newid);
@ -228,7 +195,7 @@ sub create {
# updated recipe overwrites the data at the old ID).
#
# @param args This should be a reference to a hash containing the same
# elements as the args hash for create(), except previd is
# elements as the args hash for create(), except origid is
# required here. This should also contain the field
# `updaterid` containing the ID of the user doing the edit.
# @return The recipe Id on success, undef on error.
@ -238,15 +205,16 @@ sub edit {
$self -> clear_error();
return $self -> self_error("edit called without previous recipe ID")
unless($args -> {"previd"});
return $self -> self_error("edit called without master recipe ID")
unless($args -> {"origid"});
# Move the old recipe to the end of the table, but keep a record
# of its current ID
$args -> {"id"} = $args -> {"previd"};
my $renumbered = $self -> _renumber_recipe($args -> {"id"});
# We want the new recipe to get the same ID as the old one, so record it
$args -> {"id"} = $args -> {"origid"};
# Create a new one at the old ID
# Now move the old recipe out of the way so the new one can use its ID
my $renumbered = $self -> _renumber_recipe($args -> {"id"});
# Create the new recipe at the old ID
$self -> create($args)
or return undef;
@ -256,6 +224,8 @@ sub edit {
$args -> {"updaterid"})
or return undef;
return $args -> {"id"};
}
@ -296,6 +266,31 @@ sub set_status {
}
## @method $ set_viewed($recipeid, $viewerid)
# Update the 'viewed' timestamp for a recipe to show that a user has
# viewed it.
#
# @param recipeid The ID of the recipe that has been viewed.
# @param viewerid The ID of the user doing the viewing.
# @return true on success, undef on error.
sub set_viewed {
my $self = shift;
my $recipeid = shift;
my $viewerid = shift;
$self -> clear_error();
my $updateh = $self -> {"dbh"} -> prepare("UPDATE `".$self -> {"settings"} -> {"database"} -> {"recipes"}."`
SET `viewed` = UNIX_TIMESTAMP()
WHERE `id` = ?");
my $result = $updateh -> execute($recipeid);
return $self -> self_error("Update of recipe failed: ".$self -> {"dbh"} -> errstr) if(!$result);
return $self -> self_error("Recipe update failed: no rows updated") if($result eq "0E0");
return 1;
}
# ============================================================================
# Recipe retrieval
@ -474,6 +469,8 @@ sub load_recipe_relations {
# - `tagmatch`: control how tag searching works. As with `ingredmatch`, this
# may be "all" or "any", with corresponding behaviour.
# - `limit`: how many recipies may be returned by the find()
# - `original`: if set to true (the default) only search the most recent versions
# of recipes. If false, include edits.
# - `offset`: offset from the start of the query results.
# - `order`: optional ordering of results. Allowed values are 'added', 'updated',
# 'viewed', or 'name' (the default).
@ -561,7 +558,16 @@ sub find {
}
# Squish all the where conditions into a string
my $wherecond = join(($args -> {"searchmode"} eq "any" ? "\nOR " : "\nAND "), @where) || "1";
my $wherecond = join(($args -> {"searchmode"} eq "any" ? "\nOR " : "\nAND "), @where);
# Unless `original` is false, we can only match the most recent edits
unless(defined($args -> {"original"}) && !$args -> {"original"}) {
$wherecond .= "\nAND" if($wherecond);
$wherecond .= "`r`.`original_id` IS NULL";
}
# Allow for no search criteria
$wherecond = "1" unless($wherecond);
# Construct the limit term when limit (and optionally offset) are
# specified by the caller
@ -666,7 +672,7 @@ sub _add_ingredients {
}
# Likewise for preparation methods
if($ingred -> {"prep"} && lc($ingred -> {"units"}) ne "none") {
if($ingred -> {"prep"} && lc($ingred -> {"prep"}) ne "none") {
$prepid = $self -> {"entities"} -> {"prep"} -> get_id($ingred -> {"prep"})
or return $self -> self_error("Unable to get preparation method ID for '".$ingred -> {"prep"}."': ".$self -> {"entities"} -> {"prep"} -> errstr());
@ -814,8 +820,8 @@ sub _renumber_recipe {
# Duplicate the source recipe at the end of the table
my $moveh = $self -> {"dbh"} -> prepare("INSERT INTO `".$self -> {"settings"} -> {"database"} -> {"recipes"}."`
(`metadata_id`, `prev_id`, `name`, `method`, `notes`, `source`, `yield`, `timereq`, `timemins`, `temptype`, `temp`, `type_id`, `status_id`, `creator_id`, `created`, `viewed`)
SELECT `metadata_id`, `prev_id`, `name`, `method`, `notes`, `source`, `yield`, `timereq`, `timemins`, `temptype`, `temp`, `type_id`, `status_id`, `creator_id`, `created`, `viewed`
(`metadata_id`, `name`, `method`, `notes`, `source`, `yield`, `prepinfo`, `preptime`, `cooktime`, `temptype`, `temp`, `type_id`, `status_id`, `creator_id`, `created`, `viewed`)
SELECT `metadata_id`, `name`, `method`, `notes`, `source`, `yield`, `prepinfo`, `preptime`, `cooktime`, `temptype`, `temp`, `type_id`, `status_id`, `creator_id`, `created`, `viewed`
FROM `".$self -> {"settings"} -> {"database"} -> {"recipes"}."`
WHERE `id` = ?");
my $rows = $moveh -> execute($sourceid);
@ -826,6 +832,7 @@ sub _renumber_recipe {
my $newid = $self -> {"dbh"} -> {"mysql_insertid"}
or return $self -> self_error("Unable to obtain id for new recipe");
# Move all the old ingredient and tage relations to the copy we've just made
$self -> _fix_recipe_relations($sourceid, $newid)
or return undef;
@ -870,6 +877,13 @@ sub _fix_recipe_relations {
$moveh -> execute($destid, $sourceid)
or return $self -> self_error("Ingredient relation fixup failed: ".$self -> {"dbh"} -> errstr());
# And set the original ID in the renumbered recipe
my $origh = $self -> {"dbh"} -> prepare("UPDATE `".$self -> {"settings"} -> {"database"} -> {"recipes"}."`
SET `original_id` = ?
WHERE `id` = ?");
$origh -> execute($sourceid, $destid)
or return $self -> self_error("Ingredient origin fixup failed: ".$self -> {"dbh"} -> errstr());
return 1;
}
@ -1029,4 +1043,9 @@ sub _where_fragment {
return $frag;
}
sub _multi_where_fragment {
my $self = shift;
}
1;

View File

@ -11,6 +11,42 @@ use Webperl::ConfigMicro;
use ORB::System;
use Data::Dumper;
## @fn void clear_target_tables($dbh, $settings)
# Empty out tables in the new ORB database to allow easier reimport.
#
# @param dbh A reference to the new ORB database handle.
sub clear_target_tables {
my $dbh = shift;
my $settings = shift;
# The tables to truncate
my @truncate = (
'convert',
'ingredients',
'prep',
'recipes',
'recipeing',
'recipetags',
'states',
'tags',
'types',
'units'
);
foreach my $table (@truncate) {
$dbh -> do("TRUNCATE `".$settings -> {"database"} -> {$table}."`")
or die "Truncate failed: ".$dbh -> errstr."\n";
}
$dbh -> do("DELETE FROM `".$settings -> {"database"} -> {"metadata"}."`
WHERE `id` > 1")
or die "Metadata cleanup failed: ".$dbh -> errstr."\n";
$dbh -> do("ALTER TABLE `".$settings -> {"database"} -> {"metadata"}."`
AUTO_INCREMENT = 2")
or die "Metadata autoinc set failed: ".$dbh -> errstr."\n";
}
## @fn $ get_source_recipeids($dbh, $settings, $logger)
# Fetch a list of recipie IDs in the source ORB database.
@ -174,8 +210,10 @@ sub convert_recipe {
$recipe -> {"created"} = $recipe -> {"updated"};
# And fix up fields that need to do name mapping
$recipe -> {"type"} = $recipe -> {"typename"};
$recipe -> {"status"} = $recipe -> {"statusname"};
$recipe -> {"type"} = $recipe -> {"typename"};
$recipe -> {"status"} = $recipe -> {"statusname"};
$recipe -> {"prepinfo"} = $recipe -> {"timereq"};
$recipe -> {"cooktime"} = $recipe -> {"timemins"};
# And go through the list of ingredients tweaking as needed
foreach my $ingred (@{$recipe -> {"ingredients"}}) {
@ -189,6 +227,9 @@ sub convert_recipe {
}
}
# Nuke the source id
delete $recipe -> {"id"};
return $recipe;
}
@ -222,6 +263,8 @@ my $system = ORB::System -> new(dbh => $newdbh,
$system -> init()
or $logger -> die_log(undef, $system -> errstr());
clear_target_tables($newdbh, $targetcfg);
my $rows = get_source_recipeids($olddbh, $legacycfg, $logger);
foreach my $recipeid (@{$rows}) {

View File

@ -65,7 +65,8 @@ div.off-canvas .user {
.pagemenu > li > a {
width: 2rem;
padding: 0.75rem 0.75rem;
padding: 0.25rem 0.25rem;
display: inline-block;
}
.pagemenu > li.active > a {
@ -100,3 +101,7 @@ div.time-duration-picker-content td select {
.spacer {
margin-bottom: 1rem;
}
div.topspace {
margin-top: 0.5rem;
}

View File

@ -2,7 +2,3 @@
div.contextlink {
font-size: 0.75rem;
}
div.topspace {
margin-top: 0.5rem;
}

View File

@ -1,5 +1,6 @@
div.recipe {
margin: 0px 1.5rem;
width: 100%;
}
div.recipe h4 {
@ -8,6 +9,7 @@ div.recipe h4 {
div.title {
font-weight: bold;
white-space: nowrap;
}
div.ingredients ul {
@ -24,6 +26,7 @@ div.ingredients ul li.ingredient {
}
div.ingredients ul li.separator {
margin-left: 1rem;
font-weight: bold;
border-bottom: 1px solid #ccc;
}

View File

@ -1,3 +1,21 @@
var CKCONFIG = {
font_names: 'Arial/Arial, Helvetica, sans-serif;' +
'Book Antiqua/Book Antiqua, serif;'+
'Cambria/Cambria, serif;'+
'Courier New/Courier New, Courier, monospace;' +
'Georgia/Georgia, serif;' +
'Lucida Sans Unicode/Lucida Sans Unicode, Lucida Grande, sans-serif;' +
'Tahoma/Tahoma, Geneva, sans-serif;' +
'Times New Roman/Times New Roman, Times, serif;' +
'Trebuchet MS/Trebuchet MS, Helvetica, sans-serif;' +
'Verdana/Verdana, Geneva, sans-serif'
};
function check_name()
{
var $name = $('#name').val();
}
function add_separator()
@ -22,8 +40,43 @@ function add_ingredient(count)
}
function build_ingdata()
{
var values = new Array();
// Go through all the children of the ingredient list
// storing the value therein in elements of the values list
$('#ingredients').children().each(function() {
// Is this a separator row?
if($(this).hasClass('separator')) {
var name = $(this).find('input.separator').val();
values.push({ "separator": true,
"name": name });
} else {
var quantity = $(this).find('input.quantity').val();
var units = $(this).find('select.units').val();
var prep = $(this).find('select.preps').val();
var name = $(this).find('input.ingredient').val();
var notes = $(this).find('input.notes').val();
values.push({ "separator": false,
"quantity": quantity,
"units": units,
"prep": prep,
"name": name,
"notes": notes });
}
});
$('#ingdata').val(JSON.stringify({ "ingredients": values }));
}
$(function() {
$('#timemins').timeDurationPicker({
$('#preptime').timeDurationPicker({
lang: 'en_US',
seconds: false,
minutes: true,
@ -32,8 +85,22 @@ $(function() {
months: false,
years: false,
onSelect: function(element, seconds, humanDuration) {
$('#timemins').val(humanDuration);
$('#timesecs').val(seconds);
$('#preptime').val(humanDuration);
$('#prepsecs').val(seconds);
console.log(seconds, humanDuration);
}
});
$('#cooktime').timeDurationPicker({
lang: 'en_US',
seconds: false,
minutes: true,
hours: true,
days: true,
months: false,
years: false,
onSelect: function(element, seconds, humanDuration) {
$('#cooktime').val(humanDuration);
$('#cooksecs').val(seconds);
console.log(seconds, humanDuration);
}
});
@ -51,8 +118,8 @@ $(function() {
}
});
CKEDITOR.replace('method');
CKEDITOR.replace('notes');
CKEDITOR.replace('method', CKCONFIG);
CKEDITOR.replace('notes', CKCONFIG);
$('#ingredients').sortable({
placeholder: "ui-state-highlight"
@ -71,4 +138,7 @@ $(function() {
$('.deletectrl').on('click', function() {
$(this).parents('li').fadeOut(300, function() { $(this).remove(); });
});
// Build the ingredient list before submitting
$('#newrecipe').on('submit', function() { build_ingdata(); return true });
});

View File

@ -1,4 +1,4 @@
<div class="small-8 small-centered columns">
<div class="topspace cell small-8 small-offset-2">
<!-- Start messagebox core -->
<div class="messagebox callout %(class)s">
<h4>%(title)s</h4>

View File

@ -19,13 +19,19 @@
</div>
<div>
<label>{L_RECIPE_PREPINFO}
<input maxlength="255" data-tooltip aria-haspopup="true" class="has-tip top" data-disable-hover="false" title="{L_RECIPE_PREPINFO_DOC}" type="text" id="timereq" name="timereq" value="%(timereq)s" placeholder="{L_RECIPE_PREPINFO_PH}" required />
<input maxlength="255" data-tooltip aria-haspopup="true" class="has-tip top" data-disable-hover="false" title="{L_RECIPE_PREPINFO_DOC}" type="text" id="prepinfo" name="prepinfo" value="%(prepinfo)s" placeholder="{L_RECIPE_PREPINFO_PH}" required />
</label>
</div>
<div>
<label>{L_RECIPE_TIMEREQ}
<input data-tooltip aria-haspopup="true" class="has-tip top" data-disable-hover="false" title="{L_RECIPE_TIMEREQ_DOC}" type="text" id="timemins" name="timemins" value="%(timemins)s" placeholder="{L_RECIPE_TIMEREQ_PH}" />
<input type="hidden" name="timesecs" id="timesecs" value="%(timesecs)s" />
<label>{L_RECIPE_PREPTIME}
<input data-tooltip aria-haspopup="true" class="has-tip top" data-disable-hover="false" title="{L_RECIPE_PREPTIME_DOC}" type="text" id="preptime" name="preptime" value="%(preptime)s" placeholder="{L_RECIPE_PREPTIME_PH}" autocomplete="off" />
<input type="hidden" name="prepsecs" id="prepsecs" value="%(prepsecs)s" />
</label>
</div>
<div>
<label>{L_RECIPE_COOKTIME}
<input data-tooltip aria-haspopup="true" class="has-tip top" data-disable-hover="false" title="{L_RECIPE_COOKTIME_DOC}" type="text" id="cooktime" name="cooktime" value="%(cooktime)s" placeholder="{L_RECIPE_COOKTIME_PH}" autocomplete="off" />
<input type="hidden" name="cooksecs" id="cooksecs" value="%(cooksecs)s" />
</label>
</div>
<div>

View File

@ -2,7 +2,7 @@
<div class="top-bar-left">
<ul class="menu">
<li><button id="menubtn" class="menu-icon dark" type="button" data-open="offCanvas"></button></li>
<li><form action="%(url-search)s" method="POST"><input type="search" placeholder="Search"></form></li>
<li><form action="%(url-search)s" method="POST"><input type="search" name="search" id="search" placeholder="Search"></form></li>
</ul>
</div>
<div class="top-bar-right show-for-medium">