Edit quantity per row in inventory view

Change the inventory view to make editing of quantities happen on
the individual rows instead of having to get the quantity right
before adding the item.
This commit is contained in:
Andrew Miner
2015-02-24 19:55:32 -08:00
parent 4f1faab2e8
commit c78828426f
8 changed files with 107 additions and 65 deletions
+2 -2
View File
@@ -18,9 +18,9 @@ All rights reserved.
width: 100%;
}
.error { background: $color-error; }
.error { background: $color-error !important; }
.error-new { background: $color-error-new; }
.error-new { background: $color-error-new !important; }
.section {
margin-top: 3em;
-14
View File
@@ -53,20 +53,6 @@ All rights reserved.
vertical-align: middle;
}
td.quantity {
position: relative;
width: 2.4em;
input {
position: absolute; top: 50%; height: $font-size-small; width: 100%;
@include transform(translateY(-50%));
border-radius: 0.75em;
margin: 0 auto;
text-align: center;
max-width: 2.8em;
}
}
td.icon {
width: 4.8em;
padding: 0 1em;
+27 -3
View File
@@ -12,15 +12,39 @@ All rights reserved.
padding: 0.2em 0;
}
td.quantity p {
td.quantity {
position: relative;
width: 4em;
input {
position: absolute; top: 50%; height: $font-size-small; width: 100%;
@include transform(translateY(-50%));
border-radius: 0.75em;
background: $color-ice;
color: $color-background-panel;
font-family: $font-family-normal;
font-size: $font-size-normal;
font-weight: bold;
text-align: center;
min-width: 3em;
padding: 0.1em 0.5em;
&.editable {
&:focus {
background: $color-background-panel;
color: $color-text;
font-family: $font-family-input;
font-weight: normal;
outline: none;
}
&:hover {
background: $color-background-panel;
color: $color-text;
font-family: $font-family-input;
font-weight: normal;
}
}
}
}
td.icon {
@@ -43,12 +43,15 @@ module.exports = class InventoryController extends BaseController
# Event Methods ################################################################################
onAddButtonClicked: ->
if @$nameField.val().trim().length is 0
@$nameField.focus()
return
item = @modPack.findItemByName @$nameField.val()
return unless item?
@model.add item.slug, parseInt(@$quantityField.val())
@model.add item.slug, 1
@$nameField.val ''
@$quantityField.val '1'
@$scrollbox.scrollTop @$scrollbox.prop 'scrollHeight'
@$nameField.autocomplete 'close'
@@ -84,28 +87,6 @@ module.exports = class InventoryController extends BaseController
if event.which is Key.Return
@onAddButtonClicked()
onQuantityFieldBlur: ->
value = @$quantityField.val().replace /[^0-9]/g, ''
if value.length is 0 then value = '1'
value = Math.min value, InventoryController.MAX_QUANTITY
@$quantityField.val value
@onQuantityFieldChanged()
onQuantityFieldChanged: ->
if not @$quantityField.val().match /^[0-9]*$/
@$quantityField.addClass 'error', 0
@$quantityField.addClass 'error-new', 0
@$quantityField.removeClass 'error-new', Duration.slow
@$quantityField.focus()
return
@$quantityField.removeClass 'error', Duration.normal
@$quantityField.removeClass 'error-new', Duration.normal
@_refreshButtonState()
onQuantityFieldFocused: ->
@$quantityField.val ''
# BaseController Overrides #####################################################################
onDidRender: ->
@@ -114,7 +95,6 @@ module.exports = class InventoryController extends BaseController
@$icon = @$('.icon')
@$editPanel = @$('.edit')
@$nameField = @$('input[name="name"]')
@$quantityField = @$('input[name="quantity"]')
@$scrollbox = @$('.scrollbox')
@$table = @$('table')
@$toolbar = @$('.toolbar')
@@ -129,8 +109,6 @@ module.exports = class InventoryController extends BaseController
@$icon.attr 'src', @icon
@$title.html @title
if _.isEmpty(@$quantityField.val()) then @$quantityField.val '1'
@_refreshStacks()
@_refreshNameAutocomplete()
@_refreshButtonState()
@@ -142,13 +120,10 @@ module.exports = class InventoryController extends BaseController
events: ->
return _.extend super,
'blur input[name="name"]': 'onNameFieldBlur'
'blur input[name="quantity"]': 'onQuantityFieldBlur'
'click button[name="add"]': 'onAddButtonClicked'
'click button[name="clear"]': 'onClearButtonClicked'
'focus input[name="name"]': 'onNameFieldFocused'
'focus input[name="quantity"]': 'onQuantityFieldFocused'
'input input[name="name"]': 'onNameFieldChanged'
'input input[name="quantity"]': 'onQuantityFieldChanged'
'keyup input[name="name"]': 'onNameFieldKeyUp'
# Private Methods ##############################################################################
@@ -156,9 +131,9 @@ module.exports = class InventoryController extends BaseController
_refreshButtonState: ->
if @model.isEmpty then @$clearButton.attr('disabled', 'disabled') else @$clearButton.removeAttr('disabled')
noText = @$nameField.val().trim().length is 0
itemValid = @modPack.findItemByName(@$nameField.val())?
quantityValid = @$quantityField.val().match(InventoryController.ONLY_DIGITS)
disable = not (itemValid and quantityValid)
disable = not (itemValid or noText)
if disable then @$addButton.attr('disabled', 'disabled') else @$addButton.removeAttr('disabled')
_refreshNameAutocomplete: ->
@@ -171,7 +146,6 @@ module.exports = class InventoryController extends BaseController
minLength: 0
change: onChanged
close: onChanged
minLength: 3
select: onSelected
_refreshStacks: ->
@@ -6,13 +6,17 @@ All rights reserved.
###
BaseController = require './base_controller'
{Duration} = require '../constants'
{Event} = require '../constants'
ImageLoader = require './image_loader'
{Key} = require '../constants'
########################################################################################################################
module.exports = class StackController extends BaseController
@MAX_QUANTITY = 9999
constructor: (options={})->
if not options.imageLoader? then throw new Error 'options.imageLoader is required'
if not options.model? then throw new Error 'options.model is required'
@@ -32,6 +36,47 @@ module.exports = class StackController extends BaseController
# Event Methods ################################################################################
onQuantityFieldBlur: ->
quantityText = @$quantityField.val().trim()
if quantityText.length is 0
quantity = @_priorValue
else if not quantityText.match /^[0-9]*$/
quantity = 1
else
quantity = parseInt quantityText, 10
if _.isNaN quantity then quantity = 1
quantity = Math.min quantity, StackController.MAX_QUANTITY
quantity = Math.max 1, quantity
if quantity?
@$quantityField.val "#{quantity}"
@$quantityField.removeClass 'error', Duration.snap
@$quantityField.removeClass 'error-new', Duration.snap
@model.quantity = quantity
onQuantityFieldChanged: ->
quantityText = @$quantityField.val().trim()
if not quantityText.match /^[0-9]*$/
@$quantityField.addClass 'error', 0
@$quantityField.addClass 'error-new', 0
@$quantityField.removeClass 'error-new', Duration.fast
else
@$quantityField.removeClass 'error', Duration.snap
@$quantityField.removeClass 'error-new', Duration.snap
onQuantityFieldFocused: ->
if @editable
@_priorValue = @model.quantity
@$quantityField.val ''
else
@$quantityField.blur()
onQuantityKeyUp: (event)->
if event.which is Key.Return
@$quantityField.blur()
onRemoveClicked: ->
@onRemove @model
@@ -41,7 +86,7 @@ module.exports = class StackController extends BaseController
@$action = @$('.action')
@$image = @$('.icon img')
@$nameLink = @$('.name a')
@$quantityField = @$('.quantity p')
@$quantityField = @$('.quantity input')
@$removeButton = @$('button.remove')
super
@@ -51,7 +96,14 @@ module.exports = class StackController extends BaseController
@_imageLoader.load display.iconUrl, @$image
@$nameLink.html display.itemName
@$nameLink.attr 'href', display.itemUrl
@$quantityField.html @model.quantity
@$quantityField.val @model.quantity
if @editable
@$quantityField.removeAttr 'readonly'
@$quantityField.addClass 'editable'
else
@$quantityField.attr 'readonly', 'readonly'
@$quantityField.removeClass 'editable'
@$action.css display:(if @editable then 'table-cell' else 'none')
@@ -61,5 +113,9 @@ module.exports = class StackController extends BaseController
events: ->
return _.extend super,
'blur .quantity input': 'onQuantityFieldBlur'
'click button.remove': 'onRemoveClicked'
'click .name a': 'routeLinkClick'
'focus .quantity input': 'onQuantityFieldFocused'
'input .quantity input': 'onQuantityFieldChanged'
'keyup .quantity input': 'onQuantityKeyUp'
+2
View File
@@ -115,6 +115,7 @@ module.exports = class Inventory extends BaseModel
stack.quantity -= quantity
if stack.quantity is 0
@stopListening stack
delete @_stacks[itemSlug]
@_itemSlugs = _(@_itemSlugs).without itemSlug
@@ -184,6 +185,7 @@ module.exports = class Inventory extends BaseModel
stack = @_stacks[itemSlug]
if not stack?
stack = new Stack itemSlug:itemSlug, quantity:quantity
@listenTo stack, Event.change, => @trigger Event.change
@_stacks[itemSlug] = stack
@_itemSlugs.push itemSlug
@_sort()
+2 -2
View File
@@ -13,8 +13,8 @@
.scrollbox
table
tr.edit
td.quantity: input(name="quantity")
td.icon: img(src="/images/unknown.png")
td.quantity
td.icon
td.name(width="*"): input(name="name")
td.action: button(name="add") add
.toolbar
+1 -1
View File
@@ -6,7 +6,7 @@
//-
tr.view__stack
td.quantity: p
td.quantity: input
td.icon: img(src='')
td.name(width='*'): a
td.action