Initial work on New page
This commit is contained in:
parent
0b2e7b691d
commit
49387912c2
279
blocks/ORB/New.pm
Normal file
279
blocks/ORB/New.pm
Normal file
@ -0,0 +1,279 @@
|
|||||||
|
## @file
|
||||||
|
# This file contains the implementation of the new page.
|
||||||
|
#
|
||||||
|
# @author Chris Page <chris@starforge.co.uk>
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see http://www.gnu.org/licenses/.
|
||||||
|
|
||||||
|
## @class
|
||||||
|
package ORB::New;
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use parent qw(ORB); # This class extends the ORB block class
|
||||||
|
use experimental qw(smartmatch);
|
||||||
|
use v5.14;
|
||||||
|
|
||||||
|
# How many ingredient rows should appear in the empty form?
|
||||||
|
use constant DEFAULT_INGREDIENT_COUNT => 5;
|
||||||
|
|
||||||
|
|
||||||
|
## @method private $ _build_timereq($seconds)
|
||||||
|
# Given a time requirement in seconds, generate a string representing
|
||||||
|
# the time required in the form "X days, Y hours and Z minues",
|
||||||
|
# optionally dropping parts of the string depending on whether
|
||||||
|
# X, Y, or Z are zero.
|
||||||
|
#
|
||||||
|
# @param seconds The number of seconds required to make the recipe.
|
||||||
|
# @return A string representing the seconds.
|
||||||
|
sub _build_timereq {
|
||||||
|
my $self = shift;
|
||||||
|
my $seconds = shift;
|
||||||
|
|
||||||
|
my $days = int($seconds / (24 * 60 * 60));
|
||||||
|
my $hours = ($seconds / (60 * 60)) % 24;
|
||||||
|
my $mins = ($seconds / 60) % 60;
|
||||||
|
|
||||||
|
# localisation needed...
|
||||||
|
my @parts = ();
|
||||||
|
push(@parts, "$days days") if($days);
|
||||||
|
push(@parts, "$hours hours") if($hours);
|
||||||
|
push(@parts, "$mins minutes") if($mins);
|
||||||
|
|
||||||
|
my $count = scalar(@parts);
|
||||||
|
if($count == 3) {
|
||||||
|
return $parts[0].", ".$parts[1]." and ".$parts[2];
|
||||||
|
} elsif($count == 2) {
|
||||||
|
return $parts[0]." and ".$parts[1];
|
||||||
|
} elsif($count == 1) {
|
||||||
|
return $parts[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
sub _build_temptypes {
|
||||||
|
my $self = shift;
|
||||||
|
my $default = shift;
|
||||||
|
|
||||||
|
# Supported types are in the column enum list
|
||||||
|
my $tempenum = $self -> get_enum_values($self -> {"settings"} -> {"database"} -> {"recipes"}, "temptype");
|
||||||
|
return $tempenum
|
||||||
|
unless(ref($tempenum) eq "ARRAY");
|
||||||
|
|
||||||
|
# convert to something build_optionlist will understand
|
||||||
|
map { $_ = { name => $_, value => $_ } } @{$tempenum};
|
||||||
|
|
||||||
|
return $self -> {"template"} -> build_optionlist($tempenum, $default);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
sub _get_units {
|
||||||
|
my $self = shift;
|
||||||
|
|
||||||
|
return $self -> {"units"}
|
||||||
|
if($self -> {"units"});
|
||||||
|
|
||||||
|
$self -> {"units"} = [
|
||||||
|
{ value => "None", name => "None" },
|
||||||
|
@{ $self -> {"system"} -> {"entities"} -> {"units"} -> as_options(1) }
|
||||||
|
];
|
||||||
|
|
||||||
|
return $self -> {"units"};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
sub _build_ingredients {
|
||||||
|
my $self = shift;
|
||||||
|
my $args = shift;
|
||||||
|
my $units = shift;
|
||||||
|
my $preps = shift;
|
||||||
|
|
||||||
|
my @ingreds = ();
|
||||||
|
|
||||||
|
# If any ingredients are present in the argument list, push them into templated strings
|
||||||
|
if($args -> {"ingredients"} && scalar(@{$args -> {"ingredients"}})) {
|
||||||
|
foreach my $ingred (@{$args -> {"ingredients"}}) {
|
||||||
|
# Ensure we never try to deal with undef elements in the array
|
||||||
|
next unless($ingred);
|
||||||
|
|
||||||
|
# Which template to use depends on whether this is a separator
|
||||||
|
my $template = $ingred -> {"separator"} ? "new/separator.tem" : "new/ingredient.tem";
|
||||||
|
|
||||||
|
my $unitopts = $self -> {"template"} -> build_optionlist($units, $args -> {"units"});
|
||||||
|
my $prepopts = $self -> {"template"} -> build_optionlist($preps, $args -> {"prep"});
|
||||||
|
|
||||||
|
push(@ingreds,
|
||||||
|
$self -> {"template"} -> load_template($template,
|
||||||
|
{ "%(quantity)s" => $ingred -> {"quantity"},
|
||||||
|
"%(name)s" => $ingred -> {"name"},
|
||||||
|
"%(notes)s" => $ingred -> {"notes"},
|
||||||
|
"%(units)s" => $unitopts,
|
||||||
|
"%(preps)s" => $prepopts,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
# if the ingredient list is empty, generate some empties
|
||||||
|
} else {
|
||||||
|
# Only need to calculate these once for the empty ingredients
|
||||||
|
my $unitopts = $self -> {"template"} -> build_optionlist($units);
|
||||||
|
my $prepopts = $self -> {"template"} -> build_optionlist($preps);
|
||||||
|
|
||||||
|
for(my $i = 0; $i < DEFAULT_INGREDIENT_COUNT; ++$i) {
|
||||||
|
push(@ingreds,
|
||||||
|
$self -> {"template"} -> load_template("new/ingredient.tem",
|
||||||
|
{ "%(quantity)s" => "",
|
||||||
|
"%(name)s" => "",
|
||||||
|
"%(notes)s" => "",
|
||||||
|
"%(units)s" => $unitopts,
|
||||||
|
"%(preps)s" => $prepopts,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return join("", @ingreds);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
sub _generate_new {
|
||||||
|
my $self = shift;
|
||||||
|
my ($args, $errors);
|
||||||
|
|
||||||
|
if($errors) {
|
||||||
|
$self -> log("new", "Errors detected in addition: $errors");
|
||||||
|
|
||||||
|
my $errorlist = $self -> {"template"} -> load_template("error/error_list.tem", {"%(message)s" => "{L_NEW_ERRORS}",
|
||||||
|
"%(errors)s" => $errors });
|
||||||
|
$errors = $self -> {"template"} -> load_template("error/page_error.tem", { "%(message)s" => $errorlist });
|
||||||
|
}
|
||||||
|
|
||||||
|
# Prebuild arrays for units and prep methods
|
||||||
|
my $units = $self -> _get_units();
|
||||||
|
my $preps = $self -> {"system"} -> {"entities"} -> {"prep"} -> as_options(1);
|
||||||
|
|
||||||
|
# And convert them to optionlists for the later template call
|
||||||
|
my $unitopts = $self -> {"template"} -> build_optionlist($units);
|
||||||
|
my $prepopts = $self -> {"template"} -> build_optionlist($preps);
|
||||||
|
|
||||||
|
# Build the list of ingredients
|
||||||
|
my $ingredients = $self -> _build_ingredients($args, $units, $preps);
|
||||||
|
|
||||||
|
# Build up the type and status data
|
||||||
|
my $typeopts = $self -> {"template"} -> build_optionlist($self -> {"system"} -> {"entities"} -> {"types"} -> as_options(),
|
||||||
|
$args -> {"type"});
|
||||||
|
|
||||||
|
my $statusopts = $self -> {"template"} -> build_optionlist($self -> {"system"} -> {"entities"} -> {"states"} -> as_options(0, 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
# And squirt out the page content
|
||||||
|
my $body = $self -> {"template"} -> load_template("new/content.tem",
|
||||||
|
{
|
||||||
|
"%(errors)s" => $errors,
|
||||||
|
"%(name)s" => $args -> {"name"} // "",
|
||||||
|
"%(source)s" => $args -> {"source"} // "",
|
||||||
|
"%(yield)s" => $args -> {"yield"} // "",
|
||||||
|
"%(timereq)s" => $args -> {"timereq"} // "",
|
||||||
|
"%(timemins)s" => $timemins,
|
||||||
|
"%(timesecs)s" => $timesecs,
|
||||||
|
"%(temp)s" => $args -> {"temp"} // "",
|
||||||
|
"%(temptypes)s" => $self -> _build_temptypes($args -> {"temptype"}),
|
||||||
|
"%(types)s" => $typeopts,
|
||||||
|
"%(units)s" => $unitopts,
|
||||||
|
"%(preps)s" => $prepopts,
|
||||||
|
"%(status)s" => $statusopts,
|
||||||
|
"%(ingreds)s" => $ingredients,
|
||||||
|
"%(method)s" => $args -> {"method"} // "",
|
||||||
|
"%(notes)s" => $args -> {"notes"} // "",
|
||||||
|
});
|
||||||
|
|
||||||
|
return ($self -> {"template"} -> replace_langvar("NEW_TITLE"),
|
||||||
|
$body,
|
||||||
|
$self -> {"template"} -> load_template("new/extrahead.tem"),
|
||||||
|
$self -> {"template"} -> load_template("new/extrajs.tem"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# UI handler/dispatcher functions
|
||||||
|
|
||||||
|
## @method private @ _fatal_error($error)
|
||||||
|
# Generate the tile and content for an error page.
|
||||||
|
#
|
||||||
|
# @param error A string containing the error message to display
|
||||||
|
# @return The title of the error page and an error message to place in the page.
|
||||||
|
sub _fatal_error {
|
||||||
|
my $self = shift;
|
||||||
|
my $error = shift;
|
||||||
|
|
||||||
|
return ("{L_VIEW_ERROR_FATAL}",
|
||||||
|
$self -> {"template"} -> load_template("error/page_error.tem",
|
||||||
|
{ "%(message)s" => $error,
|
||||||
|
"%(url-logout)s" => $self -> build_url(block => "login", pathinfo => ["signout"])
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
## @method private $ _dispatch_ui()
|
||||||
|
# Implements the core behaviour dispatcher for non-api functions. This will
|
||||||
|
# inspect the state of the pathinfo and invoke the appropriate handler
|
||||||
|
# function to generate content for the user.
|
||||||
|
#
|
||||||
|
# @return A string containing the page HTML.
|
||||||
|
sub _dispatch_ui {
|
||||||
|
my $self = shift;
|
||||||
|
|
||||||
|
my ($title, $body, $extrahead, $extrajs) = $self -> _generate_new();
|
||||||
|
|
||||||
|
# Done generating the page content, return the filled in page template
|
||||||
|
return $self -> generate_orb_page(title => $title,
|
||||||
|
content => $body,
|
||||||
|
extrahead => $extrahead,
|
||||||
|
extrajs => $extrajs,
|
||||||
|
active => '-',
|
||||||
|
doclink => 'summary');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# Module interface functions
|
||||||
|
|
||||||
|
## @method $ page_display()
|
||||||
|
# Generate the page content for this module.
|
||||||
|
sub page_display {
|
||||||
|
my $self = shift;
|
||||||
|
|
||||||
|
# Is this an API call, or a normal page operation?
|
||||||
|
my $apiop = $self -> is_api_operation();
|
||||||
|
if(defined($apiop)) {
|
||||||
|
# API call - dispatch to appropriate handler.
|
||||||
|
given($apiop) {
|
||||||
|
default {
|
||||||
|
return $self -> api_response($self -> api_errorhash('bad_op',
|
||||||
|
$self -> {"template"} -> replace_langvar("API_BAD_OP")))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return $self -> _dispatch_ui();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
47
lang/en/new.lang
Normal file
47
lang/en/new.lang
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
NEW_TITLE = Create Recipe
|
||||||
|
|
||||||
|
NEW_NAME = Name
|
||||||
|
NEW_NAME_DOC = The name of the recipe
|
||||||
|
NEW_NAME_PH = Recipe name
|
||||||
|
|
||||||
|
NEW_SOURCE = Source
|
||||||
|
NEW_SOURCE_DOC = Information about the source this recipe was based on
|
||||||
|
NEW_SOURCE_PH = http://source.url
|
||||||
|
|
||||||
|
NEW_YIELD = Yield
|
||||||
|
NEW_YIELD_DOC = How many servings does this recipe make?
|
||||||
|
NEW_YIELD_PH = X servings
|
||||||
|
|
||||||
|
NEW_PREPINFO = Prep info
|
||||||
|
NEW_PREPINFO_DOC = How much time each step of the recipe take?
|
||||||
|
NEW_PREPINFO_PH = 10 min prep + 20 min cook
|
||||||
|
|
||||||
|
NEW_TIMEREQ = Time required
|
||||||
|
NEW_TIMEREQ_DOC = How long does this recipe take in total?
|
||||||
|
NEW_TIMEREQ_PH = 1 hour 10 minutes
|
||||||
|
|
||||||
|
NEW_OVENTEMP = Oven preheat
|
||||||
|
NEW_OVENTEMP_DOC = Initial oven temperature (show changes in method)
|
||||||
|
NEW_OVENTEMP_PH = None
|
||||||
|
|
||||||
|
NEW_TYPE = Type
|
||||||
|
NEW_STATUS = Status
|
||||||
|
NEW_TAGS = Tags
|
||||||
|
|
||||||
|
NEW_ADD_SEP = Add Separator
|
||||||
|
NEW_ADD_INGRED = Add Ingredient
|
||||||
|
NEW_ADD_INGRED5 = Add 5 Ingredients
|
||||||
|
NEW_ADD_INGRED10 = Add 10 Ingredients
|
||||||
|
|
||||||
|
|
||||||
|
NEW_INGREDIENTS = Ingredients
|
||||||
|
NEW_ING_QUANT_PH = Quantity
|
||||||
|
NEW_ING_ING_PH = Ingredient
|
||||||
|
NEW_ING_NOTE_PH = Notes
|
||||||
|
NEW_ING_SEP_PH = Separator text
|
||||||
|
NEW_ING_DELETE = Delete
|
||||||
|
|
||||||
|
NEW_METHOD = Method
|
||||||
|
NEW_NOTES = Notes
|
||||||
|
|
||||||
|
NEW_CREATE = Add Recipe
|
@ -16,3 +16,5 @@ BLOCK_VALIDATE_RANGEMAX = The value provided for '***field***' is out of range
|
|||||||
BLOCK_ERROR_TITLE = Fatal System Error
|
BLOCK_ERROR_TITLE = Fatal System Error
|
||||||
BLOCK_ERROR_SUMMARY = The system has encountered an unrecoverable error.
|
BLOCK_ERROR_SUMMARY = The system has encountered an unrecoverable error.
|
||||||
BLOCK_ERROR_TEXT = A serious error has been encountered while processing your request. The following information was generated by the system, please contact moodlesupport@cs.man.ac.uk about this, including this error and a description of what you were doing when it happened!<br /><br /><span class="error">***error***</span>
|
BLOCK_ERROR_TEXT = A serious error has been encountered while processing your request. The following information was generated by the system, please contact moodlesupport@cs.man.ac.uk about this, including this error and a description of what you were doing when it happened!<br /><br /><span class="error">***error***</span>
|
||||||
|
|
||||||
|
BLOCK_ERROR_BADENUM = Unable to fetch enum values from ***table***.***col***: ***errstr***
|
27
templates/default/css/new.css
Normal file
27
templates/default/css/new.css
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
|
||||||
|
#ingredients {
|
||||||
|
margin: 0px;
|
||||||
|
padding: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ingredients li {
|
||||||
|
list-style: none;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
padding-left: 1rem;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-image: url('../images/draghandle.png');
|
||||||
|
background-position: left center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ingredients li input,
|
||||||
|
#ingredients li select,
|
||||||
|
#ingredients li button
|
||||||
|
{
|
||||||
|
margin: 0px;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ingredients .ui-state-highlight {
|
||||||
|
height: calc(2.75rem - 2px);
|
||||||
|
background-image: none;
|
||||||
|
}
|
BIN
templates/default/images/draghandle.png
Executable file
BIN
templates/default/images/draghandle.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 366 B |
BIN
templates/default/images/draghandle.xcf
Executable file
BIN
templates/default/images/draghandle.xcf
Executable file
Binary file not shown.
74
templates/default/js/new.js
Normal file
74
templates/default/js/new.js
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
|
||||||
|
|
||||||
|
function add_separator()
|
||||||
|
{
|
||||||
|
var $new = $('#templates li.separator').clone(true);
|
||||||
|
$new.hide().appendTo($('#ingredients')).fadeIn(300);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function add_ingredient(count)
|
||||||
|
{
|
||||||
|
for(i = 0; i < count; ++i) {
|
||||||
|
var $new = $('#templates li.ingred').clone(true);
|
||||||
|
$new.hide().appendTo($('#ingredients')).fadeIn(300);
|
||||||
|
|
||||||
|
$new.find(".ingredient").autocomplete({
|
||||||
|
source: api.ingredients,
|
||||||
|
minLength: 2
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$(function() {
|
||||||
|
$('#timemins').timeDurationPicker({
|
||||||
|
lang: 'en_US',
|
||||||
|
seconds: false,
|
||||||
|
minutes: true,
|
||||||
|
hours: true,
|
||||||
|
days: true,
|
||||||
|
months: false,
|
||||||
|
years: false,
|
||||||
|
onSelect: function(element, seconds, humanDuration) {
|
||||||
|
$('#timemins').val(humanDuration);
|
||||||
|
$('#timesecs').val(seconds);
|
||||||
|
console.log(seconds, humanDuration);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#tags').select2({
|
||||||
|
theme: "foundation",
|
||||||
|
tags: true,
|
||||||
|
tokenSeparators: [','],
|
||||||
|
minimumInputLength: 2,
|
||||||
|
multiple: true,
|
||||||
|
ajax: {
|
||||||
|
delay: 250,
|
||||||
|
dataType: 'json',
|
||||||
|
url: api.tags
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
CKEDITOR.replace('method');
|
||||||
|
CKEDITOR.replace('notes');
|
||||||
|
|
||||||
|
$('#ingredients').sortable({
|
||||||
|
placeholder: "ui-state-highlight"
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#ingredients .ingredient").autocomplete({
|
||||||
|
source: api.ingredients,
|
||||||
|
minLength: 2
|
||||||
|
});
|
||||||
|
|
||||||
|
// Handle addition of separators and ingredients
|
||||||
|
$('#addsep').on('click', function() { add_separator(); });
|
||||||
|
$('.adding').on('click', function() { add_ingredient($(this).data('count')); });
|
||||||
|
|
||||||
|
// Handle removal of separators and ingredients
|
||||||
|
$('.deletectrl').on('click', function() {
|
||||||
|
$(this).parents('li').fadeOut(300, function() { $(this).remove(); });
|
||||||
|
});
|
||||||
|
});
|
142
templates/default/new/content.tem
Normal file
142
templates/default/new/content.tem
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
%(errors)s
|
||||||
|
<div class="small-8 small-offset-2 cell">
|
||||||
|
<form class="nomargin" method="POST" id="newgrade">
|
||||||
|
<h4 class="underscore">{L_NEW_TITLE}</h4>
|
||||||
|
<div>
|
||||||
|
<label>{L_NEW_NAME}
|
||||||
|
<input maxlength="80" data-tooltip aria-haspopup="true" class="has-tip top" data-disable-hover="false" title="{L_NEW_NAME_DOC}" type="text" id="name" name="name" value="%(name)s" placeholder="{L_NEW_NAME_PH}" required />
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label>{L_NEW_SOURCE}
|
||||||
|
<input maxlength="255" data-tooltip aria-haspopup="true" class="has-tip top" data-disable-hover="false" title="{L_NEW_SOURCE_DOC}" type="text" id="source" name="source" value="%(source)s" placeholder="{L_NEW_SOURCE_PH}" required />
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label>{L_NEW_YIELD}
|
||||||
|
<input maxlength="80" data-tooltip aria-haspopup="true" class="has-tip top" data-disable-hover="false" title="{L_NEW_YIELD_DOC}" type="text" id="yeild" name="yield" value="%(yield)s" placeholder="{L_NEW_YIELD_PH}" />
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label>{L_NEW_PREPINFO}
|
||||||
|
<input maxlength="255" data-tooltip aria-haspopup="true" class="has-tip top" data-disable-hover="false" title="{L_NEW_PREPINFO_DOC}" type="text" id="timereq" name="timereq" value="%(timereq)s" placeholder="{L_NEW_PREPINFO_PH}" required />
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label>{L_NEW_TIMEREQ}
|
||||||
|
<input data-tooltip aria-haspopup="true" class="has-tip top" data-disable-hover="false" title="{L_NEW_TIMEREQ_DOC}" type="text" id="timemins" name="timemins" value="%(timemins)s" placeholder="{L_NEW_TIMEREQ_PH}" />
|
||||||
|
<input type="hidden" name="timesecs" value="0" id="timesecs" value="%(timesecs)s" />
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label>{L_NEW_OVENTEMP}
|
||||||
|
<div class="grid-x">
|
||||||
|
<div class="small-6 cell">
|
||||||
|
<input data-tooltip aria-haspopup="true" class="has-tip top" data-disable-hover="false" title="{L_NEW_OVENTEMP_DOC}" type="number" id="temp" name="temp" value="%(temp)s" placeholder="{L_NEW_OVENTEMP_PH}" />
|
||||||
|
</div>
|
||||||
|
<div class="small-6 cell">
|
||||||
|
<select id="temptype" name="temptype">
|
||||||
|
%(temptypes)s
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="grid-x">
|
||||||
|
<div class="medium-6 cell form-left">
|
||||||
|
<label>{L_NEW_TYPE}
|
||||||
|
<select id="type" name="type">
|
||||||
|
%(types)s
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="medium-6 cell form-right">
|
||||||
|
<label>{L_NEW_STATUS}
|
||||||
|
<select id="status" name="status">
|
||||||
|
%(status)s
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="spacer">
|
||||||
|
<label>{L_NEW_TAGS}
|
||||||
|
<select id="tags" name="tags" size="1" multiple="multiple">
|
||||||
|
%(tags)s
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<ul id="ingredients">
|
||||||
|
%(ingreds)s
|
||||||
|
</ul>
|
||||||
|
<div class="button-group">
|
||||||
|
<button type="button" class="button" id="addsep" >{L_NEW_ADD_SEP}</button>
|
||||||
|
<button type="button" class="button adding" data-count="1">{L_NEW_ADD_INGRED}</button>
|
||||||
|
<a class="dropdown button arrow-only" data-toggle="count-dropdown">
|
||||||
|
<span class="show-for-sr">Show menu</span>
|
||||||
|
</a>
|
||||||
|
<div class="dropdown-pane bottom float-left" id="count-dropdown" data-dropdown data-auto-focus="true">
|
||||||
|
<ul class="menu vertical">
|
||||||
|
<li><button type="button" class="adding" data-count="5" data-toggle="count-dropdown">{L_NEW_ADD_INGRED5}</button></li>
|
||||||
|
<li><button type="button" class="adding" data-count="10" data-toggle="count-dropdown">{L_NEW_ADD_INGRED10}</button></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="spacer">
|
||||||
|
<label>{L_NEW_METHOD}
|
||||||
|
<textarea id="method" name="method">
|
||||||
|
%(method)s
|
||||||
|
</textarea>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="spacer">
|
||||||
|
<label>{L_NEW_NOTES}
|
||||||
|
<textarea id="notes" name="notes">
|
||||||
|
%(notes)s
|
||||||
|
</textarea>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="clearfix">
|
||||||
|
<input type="submit" name="newgrade" class="button float-right" value="{L_NEW_CREATE}" />
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<ul class="hide" id="templates">
|
||||||
|
<li class="ingred">
|
||||||
|
<div class="grid-x">
|
||||||
|
<div class="small-1 cell">
|
||||||
|
<input type="text" placeholder="Quantity">
|
||||||
|
</div>
|
||||||
|
<div class="small-2 cell">
|
||||||
|
<select>
|
||||||
|
%(units)s
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="small-2 cell">
|
||||||
|
<select>
|
||||||
|
%(preps)s
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="small-3 cell">
|
||||||
|
<input type="text" class="ingredient" placeholder="Ingredient">
|
||||||
|
</div>
|
||||||
|
<div class="small-3 cell">
|
||||||
|
<input type="text" placeholder="Notes">
|
||||||
|
</div>
|
||||||
|
<div class="small-1 cell">
|
||||||
|
<button class="button alert deletectrl" type="button" title="Delete"><i class="fa fa-trash" aria-hidden="true"></i></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
<li class="separator">
|
||||||
|
<div class="grid-x">
|
||||||
|
<div class="small-11 cell">
|
||||||
|
<input type="text" placeholder="Separator text">
|
||||||
|
</div>
|
||||||
|
<div class="small-1 cell">
|
||||||
|
<button class="button alert deletectrl" type="button" title="Delete"><i class="fa fa-trash" aria-hidden="true"></i></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
1
templates/default/new/extrahead.tem
Normal file
1
templates/default/new/extrahead.tem
Normal file
@ -0,0 +1 @@
|
|||||||
|
<link rel="stylesheet" href="{V_[csspath]}new.css" />
|
8
templates/default/new/extrajs.tem
Normal file
8
templates/default/new/extrajs.tem
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
</script>
|
||||||
|
<script src="{V_[templatepath]}3rdparty/timepicker/jquery-time-duration-picker.js"></script>
|
||||||
|
<script src="{V_[templatepath]}3rdparty/ckeditor/ckeditor.js"></script>
|
||||||
|
<script src="{V_[jspath]}new.js"></script>
|
||||||
|
<script>
|
||||||
|
api = { ingredients: '{V_[scriptpath]}rest/api/ingredients',
|
||||||
|
tags: '{V_[scriptpath]}rest/api/tags',
|
||||||
|
};
|
26
templates/default/new/ingredient.tem
Normal file
26
templates/default/new/ingredient.tem
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
<li>
|
||||||
|
<div class="grid-x">
|
||||||
|
<div class="small-1 cell">
|
||||||
|
<input type="text" placeholder="{L_NEW_ING_QUANT_PH}" value="%(quantity)s" />
|
||||||
|
</div>
|
||||||
|
<div class="small-2 cell">
|
||||||
|
<select>
|
||||||
|
%(units)s
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="small-2 cell">
|
||||||
|
<select>
|
||||||
|
%(preps)s
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="small-3 cell">
|
||||||
|
<input type="text" class="ingredient" placeholder="{L_NEW_ING_ING_PH}" value="%(name)s" />
|
||||||
|
</div>
|
||||||
|
<div class="small-3 cell">
|
||||||
|
<input type="text" placeholder="{L_NEW_ING_NOTE_PH}" value="%(notes)s" />
|
||||||
|
</div>
|
||||||
|
<div class="small-1 cell">
|
||||||
|
<button class="button alert deletectrl" type="button" title="{L_NEW_ING_DELETE}"><i class="fa fa-trash" aria-hidden="true"></i></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
10
templates/default/new/separator.tem
Normal file
10
templates/default/new/separator.tem
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<li class="separator">
|
||||||
|
<div class="grid-x">
|
||||||
|
<div class="small-11 cell">
|
||||||
|
<input type="text" placeholder="{L_NEW_ING_SEP_PH}" value="%(name)s" />
|
||||||
|
</div>
|
||||||
|
<div class="small-1 cell">
|
||||||
|
<button class="button alert deletectrl" type="button" title="{L_NEW_ING_DELETE}"><i class="fa fa-trash" aria-hidden="true"></i></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
@ -6,6 +6,9 @@
|
|||||||
<title>%(title)s</title>
|
<title>%(title)s</title>
|
||||||
<link rel="stylesheet" href="{V_[templatepath]}3rdparty/jquery-ui/jquery-ui.min.css" />
|
<link rel="stylesheet" href="{V_[templatepath]}3rdparty/jquery-ui/jquery-ui.min.css" />
|
||||||
<link rel="stylesheet" href="{V_[templatepath]}3rdparty/foundation/css/foundation.min.css" />
|
<link rel="stylesheet" href="{V_[templatepath]}3rdparty/foundation/css/foundation.min.css" />
|
||||||
|
<link rel="stylesheet" href="{V_[templatepath]}3rdparty/fontawesome/css/fontawesome-all.css" />
|
||||||
|
<link rel="stylesheet" href="{V_[templatepath]}3rdparty/select2/css/select2.min.css" />
|
||||||
|
<link rel="stylesheet" href="{V_[templatepath]}3rdparty/select2-foundation/select2-foundation-theme.min.css" />
|
||||||
|
|
||||||
<link rel="stylesheet" href="{V_[csspath]}notebox.css" />
|
<link rel="stylesheet" href="{V_[csspath]}notebox.css" />
|
||||||
<link rel="stylesheet" href="{V_[csspath]}messagebox.css" />
|
<link rel="stylesheet" href="{V_[csspath]}messagebox.css" />
|
||||||
@ -22,9 +25,9 @@
|
|||||||
<!-- Start top bar -->
|
<!-- Start top bar -->
|
||||||
%(userbar)s
|
%(userbar)s
|
||||||
<!-- End top bar -->
|
<!-- End top bar -->
|
||||||
<!-- Start content -->
|
|
||||||
<div class="grid-container fluid">
|
<div class="grid-container fluid">
|
||||||
%(pagemenu)s
|
%(pagemenu)s
|
||||||
|
<!-- Start content -->
|
||||||
<div class="grid-x grid-margin-x" id="content">
|
<div class="grid-x grid-margin-x" id="content">
|
||||||
%(content)s
|
%(content)s
|
||||||
</div>
|
</div>
|
||||||
@ -35,9 +38,9 @@
|
|||||||
|
|
||||||
<!-- Foundation and other javascript shenanigans -->
|
<!-- Foundation and other javascript shenanigans -->
|
||||||
<script src="{V_[templatepath]}3rdparty/foundation/js/vendor/jquery.js"></script>
|
<script src="{V_[templatepath]}3rdparty/foundation/js/vendor/jquery.js"></script>
|
||||||
<script src="{V_[templatepath]}3rdparty/jquery-ui/jquery-ui.min.js"></script>
|
<script src="{V_[templatepath]}3rdparty/jquery-ui/jquery-ui.js"></script>
|
||||||
<script src="{V_[templatepath]}3rdparty/foundation/js/vendor/foundation.min.js"></script>
|
<script src="{V_[templatepath]}3rdparty/foundation/js/vendor/foundation.min.js"></script>
|
||||||
<script src="{V_[templatepath]}3rdparty/fontawesome/js/fontawesome-all.js"></script>
|
<script src="{V_[templatepath]}3rdparty/select2/js/select2.full.min.js"></script>
|
||||||
<script src="{V_[jspath]}foundation.js"></script>
|
<script src="{V_[jspath]}foundation.js"></script>
|
||||||
<script src="{V_[jspath]}clear-input.js"></script>
|
<script src="{V_[jspath]}clear-input.js"></script>
|
||||||
<script>
|
<script>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user