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:
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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'
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user