HTML5 number input field goes up very fast in Chrome - html

The issue I am having is on a booking form, where there are several number input fields. They have the up and down arrows which is fine, but when using the up arrow in Chrome, rather than going up by 1 it goes really easily up by several numbers at a time (without holding down the mouse).
Has anyone else experienced this? Is there a fix for it other than hiding it in Chrome?
Thanks
To add, here is the full code with event handler:
$(".product_holder input").bind('keyup change click', function (e) {
if ($('#startDate').val() != "" && $('#endDate').val() != "") {
if (!$(this).data("previousValue") || $(this).data("previousValue") != $(this).val() ) {
if ($(this).is("[max]") && ( $(this).val() >= $(this).attr('max') ) )
{
if (! $(this).parent().find(".validwarnning").length > 0)
{
$(this).parent().append("<div class='validwarnning'>The maximum number has been reached</div>");
}
$(this).val($(this).attr('max'));
}
else
{
$(this).data("previousValue", $(this).val());
//$(this).parent
$thisProduct = $(this).parent();
WriteItemRow($thisProduct);
updateTableTotal();
}
}
}
else
{
$('#startDate').addClass("error_input");
$('#endDate').addClass("error_input");
$('#dateError').html("Please select your dates first");
$(this).val("0");
}
});

You should include a step attribute on the input tag step='1'

Related

How can I avoid showing temporary values in <input>?

I created an input that only accepts multiples of 15 and 27. The code works but clicking the up/down arrows shows the not accepted values for a millisecond before the logic changes it to the accepted value.
Example: The current value is 15. After clicking the up arrow, the input first shows 16 and then changes it to 27.
How can I avoid this?
Here's my code:
Index.razor
<input type="number" #bind-value="#Foo">
Index.razor.cs
public partial class Index
{
private int _foo = 500;
private int Foo
{
get => _foo;
set
{
if (value != _foo)
{
if (value > _foo)
{
_foo = value;
while (_foo % 15 != 0 && _foo % 27 != 0)
{
_foo++;
}
}
else
{
_foo = value;
while (_foo % 15 != 0 && _foo % 27 != 0)
{
_foo--;
}
}
}
}
}
}
Many thanks!
Ok I've looked a bit more into this and it seems that the up and down arrows inside the input field are causing the problem. I've tested it with js and there's still some flickering that shows the next or previous number before applying the calculated number. While typing in your number or using the keyboard arrows-keys to increase or decrease them seems to work flawlessly.
So this might not be caused by Blazor itself as JS also struggles
The best bet would be to hide these arrows/spinners for the number input and only allow the user to enter a number and/or use the arrow keys on the keyboard to change them.
Here's an example of how it could work in JS (Should be applicable in Blazor as they also added input events):
Hide arrows/spinners of input field:
input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
input[type=number] {
-moz-appearance: textfield;
}
Hint: Edit to your needs as it removes them on all number inputs.
Add your number input element
<input type="number" min="15" max="5000" id="specialNumberInput"/>
Catch the input's events to calculate your values
var currentValue = 500;
document.getElementById('specialNumberInput').onchange = function (event) {
let minValue = parseInt(event.srcElement.getAttribute('min'));
let maxValue = parseInt(event.srcElement.getAttribute('max'));
let value = parseInt(event.srcElement.value);
if(value > maxValue) {
currentValue = maxValue;
event.srcElement.value = currentValue;
return;
}
if(value < minValue) {
currentValue = minValue;
event.srcElement.value = currentValue;
return;
}
if (value > currentValue)
{
while (value % 15 != 0 && value % 27 != 0)
{
value++;
}
}
else
{
while (value % 15 != 0 && value % 27 != 0)
{
value--;
}
}
currentValue = value;
event.srcElement.value = currentValue;
}
As mentioned above you could attach your Blazor code to the "onchange" event of your input and run your logic to calculate next or previous values. As js also flickers, removing the selection arrows/spinners might then also work flawlessly with Blazor.

Can I use duplicate IDs on multiple <template> fragments?

Why does HTML5 validation fail when having duplicate element IDs but on different <template>. I'm planning to use only one template at a time so the actual DOM ID won't be duplicated.
something like:
<template id="companyAccount">
<li><label>Company: <input type="text" id="account_name"></label></li>
<li><label>Street: <input id="account_street" ...
...
</template>
<template id="residentialAccount">
<li><label>Name: <input type="text" id="account_name"></label></li>
<li><label>Street: <input id="account_street" ...
...
</template>
<script>
...
let template = $(isResidential ? '#residentialAccount' : '#companyAccount').get(0).content;
$('#account_info').empty().append(template.cloneNode(true));
</script>
As TJBlackman mentioned each value for id attributes must be unique. However when working with code it's up to you to determine if the code being imported contains a duplicate id. Additionally I've pretty much stopped using validators for the most part as they aren't well maintained (and the W3C's CSS validator is atrocious) and the consoles, proper error handling and using the XML parser for HTML5 will tell you pretty much everything you need to know.
You have a couple of options. You can use data-account="residential" (don't make the mistake of using camelCasing as that will eventually put you in direct conflict with the standards bodies) and detect the attribute via document.querySelectorAll:
function $(o)
{
var a = true;
try {document.querySelectorAll(o);}
catch(err) {a = false; console.log('Error: "'+o+'" is not a valid CSS selector.'); sound.notice();}
return (a && document.querySelectorAll && document.querySelectorAll(o)) ? document.querySelectorAll(o) : false;
}
Usage: $('[data-account="residential"]')[0].length and $('[data-account="residential"]')[0].value.
Alternatively you can do what I do with my platform which has things tightly integrated though this is the function I use that you might decide to slim down for your specific purposes. You can use document.createTreeWalker and literally go through every single element to scan for walker.currentNode.hasAttribute('id') to test against document.getElementById. This code is used before importing XML in to the DOM on my platform:
/******** part of larger ajax() function ********/
if (xhr.readyState == 4 && xhr.status != 204)
{}
//This code occurs within the above condition.
var r = jax_id_duplication_prevention(xhr.responseXML,param_id_container_pos,id_container);
if (r)
{
if (param_id_container_pos=='after') {id_container.parentNode.insertBefore(xml.getElementsByTagName('*')[0],id_container.nextSibling);}
else if (param_id_container_pos=='before') {id_container.parentNode.insertBefore(document.importNode(xml.getElementsByTagName('*')[0],true),id_container);}
else if (param_id_container_pos=='first')
{
if (id_container.childNodes.length > 0) {id_container.insertBefore(document.importNode(xml.getElementsByTagName('*')[0],true),id_container.firstChild);}
else {id_container.appendChild(document.importNode(xml.getElementsByTagName('*')[0],true));}
}
else if (param_id_container_pos=='inside') {id_container.appendChild(document.importNode(xml.getElementsByTagName('*')[0],true));}
else if (param_id_container_pos=='replace') {id_container.parentNode.replaceChild(document.importNode(xml.getElementsByTagName('*')[0],true),id_container);}
else if (param_id_container_pos=='fragment')
{
if (option.fragment) {delete option.fragment;}
option.fragment = document.importNode(new DOMParser().parseFromString(xhr.responseText,'application/xml').childNodes[0],true);
if (id_container && typeof id_container == 'function') {id_container();}
}
else {alert('Error: unknown position to import data to: '+id_container_pos);}
}
/******** part of larger ajax() function ********/
function ajax_id_duplication_prevention(xml,param_id_container_pos,id_container)
{
var re = true;
if (typeof id_container == 'string' && id_container.length > 0 && id_(id_container)) {id_container = id_(id_container);}
if (typeof option.id_fade == 'string' && option.id_fade.length > 0 && id_(option.id_fade)) {element_del(option.id_fade); option.id_fade = '';}
if (typeof xml.firstChild.hasAttribute == 'function')
{
if (xml.firstChild.hasAttribute('id') && xml.firstChild.getAttribute('id').length > 0 && id_(xml.firstChild.getAttribute('id')) && id_(xml.firstChild.id).parentNode.id=='liquid') {change(xml.firstChild.id,'fade');}
if (xml.firstChild.hasAttribute('id') && xml.firstChild.getAttribute('id').length > 0 && id_(xml.firstChild.id) && !id_(xml.firstChild.id).parentNode.id=='liquid') {re = false;}
else if (typeof document.createTreeWalker=='function')
{
var idz = [];
try
{
var walker = document.createTreeWalker(xml,NodeFilter.SHOW_ELEMENT,null,false);
while (walker.nextNode())
{
if (walker.currentNode.hasAttribute('id') && walker.currentNode.getAttribute('id').length > 0)
{
if (walker.currentNode.id==undefined && walker.currentNode.nodeName.toLowerCase()=='parsererror') {console.log('Error: a parser error was detected.');}
else if (walker.currentNode.id==undefined) {alert('walker.currentNode.nodeName = '+walker.currentNode.nodeName+'\n\n'+document.serializeToString(xml));}
else
{
for (var i = 0; i<id_('liquid').childNodes.length; i++)
{
if (id_('liquid').childNodes[i].nodeType==1 && id_(walker.currentNode.id) && is_node_parent(walker.currentNode.id,id_('liquid').childNodes[i]) && (param_id_container_pos!='replace' || walker.currentNode.id!=id_container.id))
{
if (param_id_container_pos != 'replace' && id_container != walker.currentNode.id) {element_del(id_('liquid').childNodes[i]);}//If changing operator test: ajax('get','?ajax=1&web3_url=/'+url_section()+'/'+url_page(),'replace',push_current_id());
}
}
var n = id_(walker.currentNode.id);
if (in_array(walker.currentNode.id,idz))
{
var fd = new FormData();
fd.append('ajax','error_xml');
fd.append('post_error','Duplicate id <code>'+walker.currentNode.id+'</code>.');
fd.append('post_url',url_window().split(url_base())[1].split('?')[0]);
fd.append('post_xml',new XMLSerializer().serializeToString(xml));
if (fd) {ajax('post',path+'/themes/',fd);}
modal.alert('Error: can not import XML, the id \''+walker.currentNode.id+'\' was detected twice in the layer being imported. Duplicated ID\'s break expected functionality and are illegal. While the XML content was not imported it is still possible that the related request was successful. It is possible to override this problem by simply doing a full request (press the Go button in your browser\'s graphic user interface) however if the id is referenced programmatically the website may exhibit unusual behavior.');
break;
setTimeout(function()
{
history.back();
push_reload();
console.log('Developer: duplicate id '+walker.currentNode.id+' was encounterted.');
if (status >= 9) {modal.xml('Duplicate ID Error', '%3Cp%3EError%3A%20the%20id%20%3Ccode%3E'+walker.currentNode.id+'%3C%2Fcode%3E%20occurred%20twice%20and%20therefore%20the%20page%20can%20not%20be%20viewed.%3C%2Fp%3E%3Cp%3EFor%20debugging%20and%20fixing%20purposes%20you%20should%20consider%20opening%20the%20URL%20in%20a%20new%20tab.%3C%2Fp%3E%3Cdiv%20class%3D%22center%20margin%22%3E%3Cinput%20onclick%3D%22modal.close()%3B%22%20tabindex%3D%223%22%20type%3D%22button%22%20value%3D%22Close%22%20%2F%3E%3C%2Fdiv%3E');}
else {modal.xml('Duplicate ID Error', '%3Cp%3EError%3A%20the%20id%20%3Ccode%3E'+walker.currentNode.id+'%3C%2Fcode%3E%20occurred%20twice%20and%20therefore%20the%20page%20can%20not%20be%20viewed.%3C%2Fp%3E%3Cdiv%20class%3D%22center%20margin%22%3E%3Cinput%20onclick%3D%22modal.close()%3B%22%20tabindex%3D%223%22%20type%3D%22button%22%20value%3D%22Close%22%20%2F%3E%3C%2Fdiv%3E');}
re = false;
},4000);
}
else {idz.push(walker.currentNode.id);}
}
if (id_(walker.currentNode.id) && (param_id_container_pos!='replace' && walker.currentNode.id!=id_container.id && !is_node_parent(walker.currentNode.id,id_container)))
{//ajax replace (carousel loader) complications if changed.
re = false;
modal.alert('Error: unable to import page, the id \''+walker.currentNode.id+'\' already exists in the DOM.');
break;
}
}
}
}
catch (err) {}//IE9
}
}
return re;
}
Regardless of how you approach addressing the issue it is not one addressed by the standards bodies and must be explicitly handled by developers. Failure to handle duplicate id attribute/values will result in the wrong element being chosen at some point which may quietly accrue compromised/malformed data over time that no one might notice for years and thus could easily hinder if not outright destroy any business relations effected by it. Good luck!

How to force CKEditor to preserve <br> tags

I am using the latest version of CKEditor (4.7 to date) with the standard package, and I want to be able to force it to preserve line break elements (<br>).
I have attempted to use the following config, without success:
CKEDITOR.replace('ck', {
allowedContent: true,
enterMode: CKEDITOR.ENTER_BR
});
As you can see in this jsfiddle, when you open Source mode, <br> tags have been replaced with a .
How do you achieve that?
A workaround (or at least partial workaround) was given on this CKEditor ticket, which forces the CKEditor to preserve <br> tags:
editor.on( 'pluginsLoaded', function( evt ){
evt.editor.dataProcessor.dataFilter.addRules({
elements :{
br : function( element ) {
//if next element is BR or <!--cke_br_comment-->, ignore it.
if( element && element.next && ( element.next.name == 'br' || element.next.value == 'cke_br_comment' ) ){
return;
}else {
var comment = new CKEDITOR.htmlParser.comment( 'cke_br_comment' );
comment.insertAfter( element );
}
}
}
});
evt.editor.dataProcessor.htmlFilter.addRules({
comment : function( value, node ) {
if( value.indexOf('cke_br_comment') >= 0 ) {
return false;
}
}
});
Updated fiddle here.
EDIT: you might also want to check my other answer which may work better depending on your needs.
I think I have found a better answer which will work in more cases: introducing the "brangel" plugin:
CKEDITOR.plugins.add('brangel', {
init: function (editor) {
editor.on('toHtml', function( evt ) {
protectBRs(evt.data.dataValue);
}, null, null, 5);
editor.on('toHtml', function( evt ) {
unprotectBRs(evt.data.dataValue);
}, null, null, 14);
editor.on('toDataFormat', function( evt ) {
protectBRs(evt.data.dataValue);
}, null, null, 5);
editor.on('toDataFormat', function( evt ) {
unprotectBRs(evt.data.dataValue);
}, null, null, 14);
function protectBRs(element) {
var children = element.children;
if (children) {
for (var i = children.length; i--; ) {
var child = children[i];
if (child.name == "br") {
var placeholder = new CKEDITOR.htmlParser.text('{cke_br}');
placeholder.insertAfter(child);
child.remove();
} else {
protectBRs(child);
}
}
}
}
function unprotectBRs(element) {
var children = element.children;
if (children) {
for (var i = children.length; i--; ) {
var child = children[i];
if (child instanceof CKEDITOR.htmlParser.text && child.value === "{cke_br}") {
var br = new CKEDITOR.htmlParser.element('br');
br.insertAfter(child);
child.remove();
} else {
unprotectBRs(child);
}
}
}
}
}
});
The idea is to save the <br> elements from destruction by temporarily replacing them with some placeholder text ({cke_br}) before the filtering phase of the CKEditor occurs (see toDataFormat and toHtml events), and then restore them back at the end. This is all transparent to the user.
Updated fiddle here.
The developers of CKeditor have reportedly told that br to nbsp auto conversion is not an issue but CKeditors ways of normalizing things.
It wont create any problem for you. So, you need not worry about your br tags being converted to nbsp
Go through the following link for more.
If you wish to remove the &nbsp from the source code, One way if to include the following :
basicEntities: false,
entities_additional: 'lt,gt,amp,apos,quot'

Button hide and show reset

Hello I have a question I want to reset button if the fields are empty, the reset is not displayed if a value is entered, the reset is displayed
Reset
for jquery ill recomand this
$( "input" ).change(function() {
var val = $(this).val();
if(val == ""){
$("#yourresetbutton").hide();
}else{
$("#yourresetbutton").show();
}
});
I'm not sure what you mean by this but I take it you want a button to appear only if a textbox if left blank. If so you this is some code you can use:
<input id='textbox' type='text'></input>
<button id='resetButton'></button>
setInterval(checkText, 10)
function checkText() {
if(document.getElementById('textbox').value == '') {
document.getElementById('resetButton').visibility = 'visible';
}
else() {
document.getElementById('resetButton').visibility = 'hidden';
}
}

_blank is affecting current tab as well as opening new tab. Why?

The website in question: http://www.chicagoswimschool.com/
When you click any of the Social Icons in the footer, it will open a new tab with the desired URL, but at the same time it will affect the current tab and redirect it to the desired URL. How can I make _blank ONLY open up a new tab and leave the previous tab unaffected?
The code for the links are pretty simple too
<span class="inner">twitter</span>
This is done by the following code of /wp-content/themes/passage/js/ajax.min.js
$j(document).on('click', 'a', function (e) {
if ($j(this).hasClass('bx-prev')) {
return false
}
if ($j(this).hasClass('bx-next')) {
return false
}
if ($j(this).parent().hasClass('load_more')) {
return false
}
if ($j(this).parent().hasClass('comments_number')) {
var t = $j(this).attr('href').split('#') [1];
$j('html, body').scrollTop($j('#' + t).offset().top);
return false
}
if ($j(this).closest('.no_animation').length === 0) {
if (document.location.href.indexOf('?s=') >= 0) {
return true
}
if ($j(this).attr('href').indexOf('wp-admin') >= 0) {
return true
}
if ($j(this).attr('href').indexOf('wp-content') >= 0) {
return true
}
document.location.href = $j(this).attr('href');
if ($j(this).attr('href') !== 'http://#' && $j(this).attr('href') !== '#') {
disableHashChange = true;
var n = $j(this).attr('href');
var r = n.indexOf(root);
if (r === 0) {
e.preventDefault();
e.stopImmediatePropagation();
e.stopPropagation();
onLinkClicked($j(this))
}
} else {
return false
}
}
})
You may try deleting that code, or specifically the line which changes document.location.href. But this approach could break other things.
A safer approach would be adding no_animation class to an ancestor of the icons, this way $j(this).closest('.no_animation').length won't be 0.