Validate staking contract calls in JS and allow adding <1 POA to existing stake (#2573)
* Add input validation for "Become a Candidate" dialog - Mining address is trimmed before validation - Amount is checked against current token balance * Add input validation for "Make Stake" dialog - Amount is checked against current token balance - Incrementing stake by less than MIN_DELEGATOR_STAKE is allowed * Add input validation for "Move Stake" dialog - Moving stake is allowed only when resulting stakes are more that minimum * Add input validation for "Withdraw Stake" dialog - Either claim, or withdraw, or claim/withdraw dialogs are displayed depending on available amounts - Available amounts for immediate and ordered withdrawals are shown and taken into account - Remaining stake must not go under the minimal delegator stake - It is possible to reduce ordered amount, but not below zero * Validate input data in staking modals in real time (#2638) - Inputs in modal dialogs are validated on every input. - Errors are displayed on blur. - Submit button is enabled/disabled immediately.staking
parent
7ef37f0071
commit
821c3e7291
@ -0,0 +1,64 @@ |
|||||||
|
import $ from 'jquery' |
||||||
|
|
||||||
|
export function setupValidation ($form, validators, $submit) { |
||||||
|
const errors = {} |
||||||
|
|
||||||
|
updateSubmit($submit, errors) |
||||||
|
|
||||||
|
for (let [key, callback] of Object.entries(validators)) { |
||||||
|
const $input = $form.find('[' + key + ']') |
||||||
|
errors[key] = null |
||||||
|
|
||||||
|
$input |
||||||
|
.ready(() => { |
||||||
|
validateInput($input, callback, errors) |
||||||
|
updateSubmit($submit, errors) |
||||||
|
if (errors[key]) { |
||||||
|
displayInputError($input, errors[key]) |
||||||
|
} |
||||||
|
}) |
||||||
|
.blur(() => { |
||||||
|
if (errors[key]) { |
||||||
|
displayInputError($input, errors[key]) |
||||||
|
} |
||||||
|
}) |
||||||
|
.on('input', () => { |
||||||
|
hideInputError($input) |
||||||
|
validateInput($input, callback, errors) |
||||||
|
updateSubmit($submit, errors) |
||||||
|
}) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
function validateInput ($input, callback, errors) { |
||||||
|
if (!$input.val()) { |
||||||
|
errors[$input.prop('id')] = null |
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
const validation = callback($input.val()) |
||||||
|
if (validation === true) { |
||||||
|
delete errors[$input.prop('id')] |
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
errors[$input.prop('id')] = validation |
||||||
|
} |
||||||
|
|
||||||
|
function updateSubmit ($submit, errors) { |
||||||
|
$submit.prop('disabled', !$.isEmptyObject(errors)) |
||||||
|
} |
||||||
|
|
||||||
|
function displayInputError ($input, message) { |
||||||
|
const group = $input.parent('.input-group') |
||||||
|
|
||||||
|
group.addClass('input-status-error') |
||||||
|
group.find('.input-group-message').html(message) |
||||||
|
} |
||||||
|
|
||||||
|
function hideInputError ($input) { |
||||||
|
const group = $input.parent('.input-group') |
||||||
|
|
||||||
|
group.removeClass('input-status-error') |
||||||
|
group.find('.input-group-message').html('') |
||||||
|
} |
@ -0,0 +1,17 @@ |
|||||||
|
<div class="input-group <%= if assigns[:classes] do @classes end %>"> |
||||||
|
<input |
||||||
|
id="<%= if assigns[:id] do @id end %>" |
||||||
|
<%= if assigns[:attributes] do @attributes end %> |
||||||
|
type="<%= if assigns[:type] do @type end %>" |
||||||
|
class="<%= if assigns[:input_classes] do @input_classes end %>" |
||||||
|
placeholder="<%= if assigns[:placeholder] do @placeholder end %>" |
||||||
|
value="<%= if assigns[:value] do @value end %>" |
||||||
|
<%= if assigns[:disabled] do "disabled" end %> |
||||||
|
/> |
||||||
|
<%= if assigns[:prepend] do %> |
||||||
|
<div class="input-group-prepend last"> |
||||||
|
<div class="input-group-text"><%= @prepend %></div> |
||||||
|
</div> |
||||||
|
<% end %> |
||||||
|
<div class="input-group-message"><%= if assigns[:message] do @message end %></div> |
||||||
|
</div> |
Loading…
Reference in new issue