In react-konva (the HTML canvas lib), How can I emulate a classical editable <input > and get or read the string value entered there? - konvajs

Considering this (buggy until other questions are answered) demo from here:
https://codesandbox.io/s/kanbanboard-lackofcarddnd-doce75?file=/src/index.js
where the red < Text /> emulates a button that inserts a < CustomCardContainer /> based on the 2nd that I wish it could be editable and readable as an < input >, I would ask:
How can I emulate an input and read its value where a string in {rows}x{cols} format is expected?
Edit: I'm not closed on just a DOM < input >, I'm open to any HTML canvas way in react for a text to be entered and get its value. I just want get the string value.
Until now I hard-coded the value in line 86 with let inputValue = "10x2"; but would like to insert < CustomCardContainer /> of different sizes in order to achieve this result from here:
sectioned custom kanban board

https://konvajs.org/docs/sandbox/Editable_Text.html
"Konva has not support for such case. We recommend to edit the user input outside of your canvas with native DOM elements such as input or textarea."
you can use contenteditable attribute for the textarea.
const pseudoInput = document.getElementById('input');
pseudoInput.addEventListener('keyup', (e) => {
console.log(e.target.innerHTML.split('x'));
})
<div contenteditable id="input">10x20</div>

Related

Is there material input type number in angular 2 dart

I was tring to use material component in angular 2 dart as a number input:
<material-input type="number"></material-input>
but it behaves like a normal input. In docs it sais it supports type "number". Am i doing anything wrong? Or isn't number type implemented yet?
Thank you for any suggestions.
I can share my personal experiment trying to have a number (integer) input. It does not work perfectly on all browsers but I wanted to have the proper keyboard shown on Android and iOS. What I did was forcing the type on the inner input element programmatically. It seems that on Firefox it does not prevent entering text but does display a message ("Please enter a number"). It does not handle decimal neither (i.e. it does expect an integer)
initInputNumber(MaterialInputComponent inputComponent) {
inputComponent.type = "number";
InputElement inputElement = inputComponent.inputEl.nativeElement;
inputElement.type = "number";
// http://stackoverflow.com/questions/6178556/phone-numeric-keyboard-for-text-input
// As of mid-2015, I believe this is the best solution:
// <input type="number" pattern="[0-9]*" inputmode="numeric">
inputElement.attributes["inputmode"] = "numeric";
inputElement.pattern = "[0-9]*"; // this and only this works 0-9
}
I don't know if that's the best solution but I find it hard to have a complete cross-browser solution
I think you need to set an errorMsg
<material-input type="number" errorMsg="That's not a number"></material-input>
This line https://github.com/dart-lang/angular2_components/blob/a0eff879a6cb347b8beb95ed758c02c6dd9dfaa0/lib/src/components/material_input/material_input.dart#L232 seems to indicate that type="tel" and type="number" are set to text for the internal input element, while this line https://github.com/dart-lang/angular2_components/blob/a0eff879a6cb347b8beb95ed758c02c6dd9dfaa0/lib/src/components/material_input/material_input.dart#L61 says that errorMsg is used when and invalid number is entered when type="number".

html5 input type number with regex pattern in mobile

I'm trying to get regex pattern in input type number to show only numbers and dots.
I tried something like this.
<input type="number" pattern="[0-9.]*">
<input type="tel">
Both are showing only numbers (0-9), but not displaying . (dot). I need to use dot in input field.
Is it possible thru html5? Or Shall I go with javascript?
Note: This is working fine in Android, but . (dot) not displaying in iphones
I need to display mobile keypad like this..
Any help regarding this?
If you only specify "type=number" it will display keypad on iPhone like:
And if you specify pattern like <input type="number" pattern="\d*"/> or <input type="number" pattern="[0-9]*" />, then keypad on iPhone will be like :
Still it cannot display dot(.), currently there is no pattern to handle such case.
So you may opt for <input type="tel" /> which will provide keypad like:
Please refer to below links for more details on inputs for iOS:
http://bradfrost.com/blog/mobile/better-numerical-inputs-for-mobile-forms/
http://blog.pamelafox.org/2012/05/triggering-numeric-keyboards-with-html5.html
https://about.zoosk.com/nb/engineering-blog/mobile-web-design-use-html5-to-trigger-the-appropriate-keyboard-for-form-inputs/
http://mobiforge.com/design-development/html5-mobile-web-forms-and-input-types
http://www.petefreitag.com/item/768.cfm
http://html5tutorial.info/html5-contact.php
Hope this will help you. :)
Updates for customization (reference: https://stackoverflow.com/a/20021657/1771795)
You can do some customization using javascript.
Lets take example of currency input with decimals pattern in which e.which to read CharCode entered and then push it into an array (before) which represents digits before decimal mark and another array (after) to move values from (before) array past the decimal mark.
complete fiddle link
HTML:
<input type="tel" id="number" />
JS
Variables and functions:
// declare variables
var i = 0,
before = [],
after = [],
value = [],
number = '';
// reset all values
function resetVal() {
i = 0;
before = [];
after = [];
value = [];
number = '';
$("#number").val("");
$(".amount").html("");
}
// add thousand separater
function addComma(num) {
return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
Main code:
// listen to keyup event
$("#number").on("keyup", function (e, v) {
// accept numbers only (0-9)
if ((e.which >= 48) && (e.which <= 57)) {
// convert CharCode into a number
number = String.fromCharCode(e.which);
// hide value in input
$(this).val("");
// main array which holds all numbers
value.push(number);
// array of numbers before decimal mark
before.push(value[i]);
// move numbers past decimal mark
if (i > 1) {
after.push(value[i - 2]);
before.splice(0, 1);
}
// final value
var val_final = after.join("") + "." + before.join("");
// show value separated by comma(s)
$(this).val(addComma(val_final));
// update counter
i++;
// for demo
$(".amount").html(" " + $(this).val());
} else {
// reset values
resetVal();
}
});
Reset:
// clear arrays once clear btn is pressed
$(".ui-input-text .ui-input-clear").on("click", function () {
resetVal();
});
Result:
Not every input type and attribute is supported in all browsers. In general, most modern browsers from IE10+ include basics such as email and number.
The browser will revert to a standard text input when a specific type and ignore attributes when those values are not supported.
So you should use a good regular expression pattern.
for example
<input type="tel" name="tel" pattern="^(?:\(\d{3}\)|\d{3})[- . ]?\d{3}[- . ]?\d{4}$" />
1234567899
123 456 7899
123-456-7899
123.456.7899
supported
Browser support for 'tel' type
Android (yes)
iOS (yes)
IE (yes)
Mobile (yes)
Opera (yes)
Mobile (yes)
Opera (yes)
Classic (yes)
Opera Mini (no)
Firefox (yes)
Mobile (yes)
Chrome for Android (yes)
(Sources: caniuse.com, DeviceAtlas, mobilehtml5.org)
Browser support for pattern attribute
But the pattern attribute is supported in Internet Explorer 10, Firefox, Opera, and Chrome.
And is not supported in Internet Explorer 9 and earlier versions, or in Safari.
For iOS use the input attribute type="number", inputmode="decimal".
This will show the number pad with the “dots” on iOS 12.3+.
I had a similar scenario whereby I needed to support both comma and point as both the decimal mark and digit grouping [see here]
E.g.
1.00 / 1,00
1,000,000.00 / 1.000.000,00
At the same time the scenario required that the number keypad was displayed on mobile devices.
The initial implementation combined the 'number' type with the pattern attribute.
<input type="number" pattern="^(0*[,.]*[0-9][0-9]*([,.][0-9]+)*|[0-9]?[,.][0-9]*[1-9][0-9]*)$" required />
However the number validation failed inputs that the pattern would allow. This meant the field and thus form were marked as invalid.
The solution was to change the type to 'tel'.
<input type="tel" pattern="^(0*[,.]*[0-9][0-9]*([,.][0-9]+)*|[0-9]?[,.][0-9]*[1-9][0-9]*)$" required />
Mobile users would now see a number keypad by default, and the pattern validation would be used to validate the input.
Unfortunately it's not possible to achieve the exact functionality that you're looking for is not possible. However there is a kind of "hack" available which will give similar functionality:
http://www.brownphp.com/2011/05/iphone-currency-input-web-apps/ (Link broken)
It's a bit of JS which fills in the decimal automatically when the user starts typing, like this: 0.01 -> 0.12 -> 1.23 -> 12.34 . So this can be used for similar effect.

iPhone / iOS : Presenting HTML 5 Keyboard for Postal Codes

There are several tricks for displaying different keyboards on mobile devices for HTML 5 inputs (i.e. <input> tags).
For example, some are documented on Apple's website, Configuring the Keyboard for Web Views.
These are great for usability, but when it comes to an input for for international postal codes (mostly numeric, but letters allowed), we're left with some poor options. Most people recommend using the pattern="\d*" trick to show the numeric keyboard, but that doesn't allow for letter input.
The type="number" input type shows the regular keyboard but shifted to the numeric layout:
This works well for iOS devices, but it makes Chrome think the input must be a number and even changes the input's behavior (up/down increment and decrement the value).
Is there any way to get iOS to default to the numeric layout, but still allow for alphanumeric input?
Basically, I want the iOS behavior for type="number" but I want the field to behave like a regular text field on desktop browsers. Is this possible?
UPDATE:
Sniffing the user-agent for iOS and using the type="number" input type is not an option. type="number" is not meant for string values (like postal codes), and it has other side effects (like stripping leading zeros, comma delimiters, etc) that make it less than ideal for postal codes.
Will this work?
HTML:
<input type="tel" pattern="[0-9]*" novalidate>
This should give you the nice numeric keyboard on Android/iOS phone browsers, disable browser form validation on desktop browsers, not show any arrow spinners, allows leading zeros, and allows commas and letters on desktop browsers, as well as on iPad.
Android / iOS phones:
Desktop:
iPad:
Browsers currently have no proper way of representing numeric codes like postcodes and credit card numbers. The best solution is to use type='tel' which will give you a number keypad and ability to add any character on desktop.
Type text and pattern='\d*' will give you a number keypad but only on iOS.
There is an HTML5.1 proposal for an attribute called inputmode which would allow you to specify keypad regardless of type. However not is not currently supported by any browser.
I would also recommend having a look at the Webshim polyfill library which has a polyfill method for these types of inputs.
A quick google search found this Stackoverflow question.
HTML
<input type="text">
Javascript
$('input[type="text"]').on('touchstart', function() {
$(this).attr('type', 'number');
});
$('input[type="text"]').on('keydown blur', function() {
$(this).attr('type', 'text');
});
The input type is switched before the form can be validated, showing the correct keyboard without messing up the value. If you only want it to run on iOS, you will probably have to use the user agent.
Stackoverflow on detecting iOS
An update to this question in iOS 11. You can get the number keypad by simply adding the pattern attribute (pattern="[0-9]*") to any input with a number type.
The following works as expected.
<input type="number" pattern="[0-9]*">
This also works.
<input type="number" pattern="\d*">
#davidelrizzo posted part of the answer, but the comments from #Miguel Guardo and #turibe give a fuller picture but are easy to miss.
This will make the numerical side of the ios keyboard display by default and maintains the ability to switch to the alphabetical side. When the html input type changes, the device changes the keyboard to match the appropriate type.
(function ($) {
var control = $('#test2');
var field = $('#test1');
control.bind('click', function () {
if (control.is(':checked')) {
field.attr('type', 'text');
} else {
field.attr('type', 'number');
}
})
}(jQuery));
<input type="number" id="test1" value="123" />
<input id="test2" type="checkbox" />Change
alternate demo: http://jsfiddle.net/davidcondrey/dbg1L0c0/3/embedded/result/
If you want the large numerical format keyboard (the telephone style) you can adjust the code accordingly and it still works:
(function ($) {
var control = $('#test2');
var field = $('#test1');
control.bind('click', function () {
if (control.is(':checked')) {
field.attr('type', 'text');
} else {
field.attr('type', 'tel');
}
})
}(jQuery));
<input type="tel" id="test1" value="a" />
<input id="test2" type="checkbox" />Change
You can use the native HTML API attribute called inputmode="numeric", inputmode="decimal". (This is the preferred way to implement it)
You can read further about input mode at the MDN here
<input type="number" inputmode="numeric" />
Try this:
<input type="text" name="postalcode" class="js-postal">
<script src="https://code.jquery.com/jquery-2.1.1.js" type="text/javascript"></script>
<script type="text/javascript">
$(function() {
if('ontouchstart' in window) { // ensure we are in touch device.
$('input.js-postal').on('focus', function() {
var $this = $(this);
// memorize current value because...
var val = $this.val();
// this may cause reset value.
$this.attr('type', 'number');
setTimeout(function() {
// Asynchronously restore 'type' and value
$this.attr('type', 'text');
$this.val(val);
}, 0);
});
}
});
</script>
I know this is very hackish way, but this apparently works.
I haven't tested on Android devices though.
Note this may causes a little noticeable glitches when $this.attr('type', 'number') because this reset the value when input has non numerical characters.
Basic ideas are stolen from this answer :)
<input type="tel" inputmode="decimal">
Above has been working for me for several years. By working, I mean that on mobile devices, a numeric virtual keyboard is displayed when the input receives focus. On iOS devices, the keyboard allows users to enter numbers, decimals, and characters. My keyboard event handler inserts thousand separators, and there is no issue with passing validation, so I assume that users could also type in commas. Negative values can be entered, so hyphens are allowed, though I don't see a hyphen on the iOS keyboard.
If you would like to try this, you may try any calculator at my site.
Why not check the header of the HTTP request (user agent), and serve up the numeric layout to the iOS devices, while serving up the alphanumeric layout to the rest?

jquery-mobile create dynamic controlgroup and apply jquery-ui css [duplicate]

This question already has answers here:
Dynamic controlgroup and checkboxes unstyled
(6 answers)
Closed 8 years ago.
This is my code:
http://jsfiddle.net/YKvR3/34/
I would create a controlgroup with values that are in my array (name).
The problem is that when I click load button the values are added in a controlgroup but the jquery-ui styles are not loaded like in the image.
The controlgroup is not styled with jquery-ui mobile css.
$("#load").click(function(){
var name=["one","two"];
var html='<fieldset id="listPlayers" data-role="controlgroup"><legend><h1>Choose as many players as youd like to remove:</h1></legend>';
for ( var int = 0; int < 2; int++) {
html+='<input type="checkbox" name="checkbox-'+int+'a" id="checkbox-'+int+'a" class="custom" /><label for="checkbox-'+int+'a">'+name[int]+'</label>';
}
alert('<legend><h3>Choose as many players as you would like to remove:</h3></legend>'+html+'</fieldset');
$("#list").html(html+'</fieldset');
//$("#list").page();});​
What I am doing wrong?
Thanks.
$("#list").trigger('create');
From: jqm docs
if you generate new markup client-side or load in content via Ajax and inject it into a page, you can trigger the create event to handle the auto-initialization for all the plugins contained within the new markup. This can be triggered on any element (even the page div itself), saving you the task of manually initializing each plugin (listview button, select, etc.).
I do applogies if this post is too old and if my post isn't by the correct standard since it's the first time ever posting so please correct me if it's horribly bad :-]
But in case someone else comes across it, I had similar problems with how the dynamic data is displayed and I used the jsfiddles and comments above as a help, and this is what got mine to work, well somewhat near my solution, I don't have a button to load the data it's loaded automatically when the page is loaded.
Updated In my .html-file:
<div id="members"></div>
<input type="button" id="load" value="test"/>
Updated In my .js-file:
$("#load").click(function(){
var name = ["NameOne","NameTwo", "NameThree"];
var fset = '<fieldset data-role="controlgroup" id="members-ctrlgroup"><legend>This is a legend:</legend>';
var labels='';
for ( var i = 0; i < name.length; i++) {
labels += '<input type="checkbox" class="checkbox" id="c'
+ i
+ '"><label for="c'
+ i
+ '" data-iconpos="right">'
+ name[i]
+'</label>';
}
$("#members").html(fset+labels+'</fieldset>');
$("#members").trigger("create");
});
I know the "field" looks a bit weird how I divided it but I find it somewhat easier when it comes to getting the whole html-string correct in these cases.
Updated In order to have the rounded corners and have it as one controlgroup you'll have to have this approach instead. Just like the former posters showed.
Do note that the id with the checkbox and the label for= can tend to screw the output if they're not the same :-]
fiddle
In order to replace the content you should use .html(); instead of .append(), which adds the new content after the existing one.
After adding content to a jQuery Mobile Page you need to enhance the content, using for instance $("input[type='radio']").checkboxradio();
I was using
for( var i=0 ; i < html.length ; i++ ){
var spline = html[i].split("|");
inHTML = inHTML + " <input type=\"checkbox\" name=\"checkbox-"+i+"a\" id=\"checkbox-"+i+"a\" class=\"custom\" /> <label for=\"checkbox-"+i+"a\">"+ spline[0] +" , "+ spline[2] +"</label> ";
}
jq("fieldset#myFieldSet").empty();
jq("fieldset#myFieldSet" )
// Append the new rows to the body
.append( inHTML )
// Call the refresh method
.closest( "fieldset#myFieldSet" )
// Trigger if the new injected markup contain links or buttons that need to be enhanced
.trigger( "create" );

Dynamically change textbox to multiline

I am working on a Firefox extension. I have a simple single-line textbox. When a user pastes in text, I want to detect if the text has newlines and if it does, I want to expand the textbox into a multiline textbox.
I have
<textbox id="textbox" rows="5" wrap="off" newlines="pasteintact" oninput="adjustTextbox(this)" flex="1"/>
and on the JS side, I have
adjustTextbox(txtBox) {
if(!txtBox.getAttribute('multiline') && txtBox.value.match(/[\r\n]/)) {
txtBox.setAttribute('multiline', true);
}
}
The problem is that, while the textbox does get converted to a 5 row multiline textbox, the value that is pasted in is lost and the textbox is blank. Am I doing something wrong here?
Short answer: no, you aren't doing anything wrong, the value is expected to be cleared when you switch from single-line to multi-line. Long answer: the <textbox> element doesn't actually hold the value itself, it rather contains an anonymous <html:input type="text>. When you add the multiline attribute a different XBL binding applies to the element and that anonymous text field is replaced by <html:textarea>. Obviously, the value gets lost in the process.
You could try to save the value and to restore it after you add the multiline attribute. The problem is that it is hard to tell when the binding actually applies, there is a delay that is not really predictable. So the better solution would be to have both a single-line and a multi-line text box in your document and make sure that one of them is always collapsed:
<textbox id="textbox" newlines="pasteintact" oninput="adjustTextbox(this)" flex="1"/>
<textbox id="textbox2" collapsed="true" multiline="true" rows="5" wrap="off" flex="1"/>
And on the JavaScript side:
function adjustTextbox(txtBox) {
if(!txtBox.getAttribute('multiline') && txtBox.value.match(/[\r\n]/)) {
var txtBox2 = document.getElementById("textbox2");
txtBox2.value = txtBox.value;
txtBox.collapsed = true;
txtBox2.collapsed = false;
}
}

Resources