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%; 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 { .section {
margin-top: 3em; margin-top: 3em;
-14
View File
@@ -53,20 +53,6 @@ All rights reserved.
vertical-align: middle; 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 { td.icon {
width: 4.8em; width: 4.8em;
padding: 0 1em; padding: 0 1em;
+27 -3
View File
@@ -12,15 +12,39 @@ All rights reserved.
padding: 0.2em 0; 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; border-radius: 0.75em;
background: $color-ice; background: $color-ice;
color: $color-background-panel; color: $color-background-panel;
font-family: $font-family-normal;
font-size: $font-size-normal; font-size: $font-size-normal;
font-weight: bold; font-weight: bold;
text-align: center; 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 { td.icon {
@@ -43,12 +43,15 @@ module.exports = class InventoryController extends BaseController
# Event Methods ################################################################################ # Event Methods ################################################################################
onAddButtonClicked: -> onAddButtonClicked: ->
if @$nameField.val().trim().length is 0
@$nameField.focus()
return
item = @modPack.findItemByName @$nameField.val() item = @modPack.findItemByName @$nameField.val()
return unless item? return unless item?
@model.add item.slug, parseInt(@$quantityField.val()) @model.add item.slug, 1
@$nameField.val '' @$nameField.val ''
@$quantityField.val '1'
@$scrollbox.scrollTop @$scrollbox.prop 'scrollHeight' @$scrollbox.scrollTop @$scrollbox.prop 'scrollHeight'
@$nameField.autocomplete 'close' @$nameField.autocomplete 'close'
@@ -84,28 +87,6 @@ module.exports = class InventoryController extends BaseController
if event.which is Key.Return if event.which is Key.Return
@onAddButtonClicked() @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 ##################################################################### # BaseController Overrides #####################################################################
onDidRender: -> onDidRender: ->
@@ -114,7 +95,6 @@ module.exports = class InventoryController extends BaseController
@$icon = @$('.icon') @$icon = @$('.icon')
@$editPanel = @$('.edit') @$editPanel = @$('.edit')
@$nameField = @$('input[name="name"]') @$nameField = @$('input[name="name"]')
@$quantityField = @$('input[name="quantity"]')
@$scrollbox = @$('.scrollbox') @$scrollbox = @$('.scrollbox')
@$table = @$('table') @$table = @$('table')
@$toolbar = @$('.toolbar') @$toolbar = @$('.toolbar')
@@ -129,8 +109,6 @@ module.exports = class InventoryController extends BaseController
@$icon.attr 'src', @icon @$icon.attr 'src', @icon
@$title.html @title @$title.html @title
if _.isEmpty(@$quantityField.val()) then @$quantityField.val '1'
@_refreshStacks() @_refreshStacks()
@_refreshNameAutocomplete() @_refreshNameAutocomplete()
@_refreshButtonState() @_refreshButtonState()
@@ -142,13 +120,10 @@ module.exports = class InventoryController extends BaseController
events: -> events: ->
return _.extend super, return _.extend super,
'blur input[name="name"]': 'onNameFieldBlur' 'blur input[name="name"]': 'onNameFieldBlur'
'blur input[name="quantity"]': 'onQuantityFieldBlur'
'click button[name="add"]': 'onAddButtonClicked' 'click button[name="add"]': 'onAddButtonClicked'
'click button[name="clear"]': 'onClearButtonClicked' 'click button[name="clear"]': 'onClearButtonClicked'
'focus input[name="name"]': 'onNameFieldFocused' 'focus input[name="name"]': 'onNameFieldFocused'
'focus input[name="quantity"]': 'onQuantityFieldFocused'
'input input[name="name"]': 'onNameFieldChanged' 'input input[name="name"]': 'onNameFieldChanged'
'input input[name="quantity"]': 'onQuantityFieldChanged'
'keyup input[name="name"]': 'onNameFieldKeyUp' 'keyup input[name="name"]': 'onNameFieldKeyUp'
# Private Methods ############################################################################## # Private Methods ##############################################################################
@@ -156,9 +131,9 @@ module.exports = class InventoryController extends BaseController
_refreshButtonState: -> _refreshButtonState: ->
if @model.isEmpty then @$clearButton.attr('disabled', 'disabled') else @$clearButton.removeAttr('disabled') if @model.isEmpty then @$clearButton.attr('disabled', 'disabled') else @$clearButton.removeAttr('disabled')
noText = @$nameField.val().trim().length is 0
itemValid = @modPack.findItemByName(@$nameField.val())? itemValid = @modPack.findItemByName(@$nameField.val())?
quantityValid = @$quantityField.val().match(InventoryController.ONLY_DIGITS) disable = not (itemValid or noText)
disable = not (itemValid and quantityValid)
if disable then @$addButton.attr('disabled', 'disabled') else @$addButton.removeAttr('disabled') if disable then @$addButton.attr('disabled', 'disabled') else @$addButton.removeAttr('disabled')
_refreshNameAutocomplete: -> _refreshNameAutocomplete: ->
@@ -171,7 +146,6 @@ module.exports = class InventoryController extends BaseController
minLength: 0 minLength: 0
change: onChanged change: onChanged
close: onChanged close: onChanged
minLength: 3
select: onSelected select: onSelected
_refreshStacks: -> _refreshStacks: ->
@@ -6,13 +6,17 @@ All rights reserved.
### ###
BaseController = require './base_controller' BaseController = require './base_controller'
{Duration} = require '../constants'
{Event} = require '../constants' {Event} = require '../constants'
ImageLoader = require './image_loader' ImageLoader = require './image_loader'
{Key} = require '../constants'
######################################################################################################################## ########################################################################################################################
module.exports = class StackController extends BaseController module.exports = class StackController extends BaseController
@MAX_QUANTITY = 9999
constructor: (options={})-> constructor: (options={})->
if not options.imageLoader? then throw new Error 'options.imageLoader is required' if not options.imageLoader? then throw new Error 'options.imageLoader is required'
if not options.model? then throw new Error 'options.model 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 ################################################################################ # 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: -> onRemoveClicked: ->
@onRemove @model @onRemove @model
@@ -41,7 +86,7 @@ module.exports = class StackController extends BaseController
@$action = @$('.action') @$action = @$('.action')
@$image = @$('.icon img') @$image = @$('.icon img')
@$nameLink = @$('.name a') @$nameLink = @$('.name a')
@$quantityField = @$('.quantity p') @$quantityField = @$('.quantity input')
@$removeButton = @$('button.remove') @$removeButton = @$('button.remove')
super super
@@ -51,7 +96,14 @@ module.exports = class StackController extends BaseController
@_imageLoader.load display.iconUrl, @$image @_imageLoader.load display.iconUrl, @$image
@$nameLink.html display.itemName @$nameLink.html display.itemName
@$nameLink.attr 'href', display.itemUrl @$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') @$action.css display:(if @editable then 'table-cell' else 'none')
@@ -61,5 +113,9 @@ module.exports = class StackController extends BaseController
events: -> events: ->
return _.extend super, return _.extend super,
'blur .quantity input': 'onQuantityFieldBlur'
'click button.remove': 'onRemoveClicked' 'click button.remove': 'onRemoveClicked'
'click .name a': 'routeLinkClick' '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 stack.quantity -= quantity
if stack.quantity is 0 if stack.quantity is 0
@stopListening stack
delete @_stacks[itemSlug] delete @_stacks[itemSlug]
@_itemSlugs = _(@_itemSlugs).without itemSlug @_itemSlugs = _(@_itemSlugs).without itemSlug
@@ -184,6 +185,7 @@ module.exports = class Inventory extends BaseModel
stack = @_stacks[itemSlug] stack = @_stacks[itemSlug]
if not stack? if not stack?
stack = new Stack itemSlug:itemSlug, quantity:quantity stack = new Stack itemSlug:itemSlug, quantity:quantity
@listenTo stack, Event.change, => @trigger Event.change
@_stacks[itemSlug] = stack @_stacks[itemSlug] = stack
@_itemSlugs.push itemSlug @_itemSlugs.push itemSlug
@_sort() @_sort()
+2 -2
View File
@@ -13,8 +13,8 @@
.scrollbox .scrollbox
table table
tr.edit tr.edit
td.quantity: input(name="quantity") td.quantity
td.icon: img(src="/images/unknown.png") td.icon
td.name(width="*"): input(name="name") td.name(width="*"): input(name="name")
td.action: button(name="add") add td.action: button(name="add") add
.toolbar .toolbar
+1 -1
View File
@@ -6,7 +6,7 @@
//- //-
tr.view__stack tr.view__stack
td.quantity: p td.quantity: input
td.icon: img(src='') td.icon: img(src='')
td.name(width='*'): a td.name(width='*'): a
td.action td.action