How to create a Dart form - dart

My problem: building a Dart form according to the book. Below, my basic sample that looks like JS. It works fine but I get this warning: The getter value is not defined for the class Element.
My question: how can I write a better Dart code to avoid this warning message? Thanks.
HTML:
<form>
<input type="number" min="0" id="enter-x">
<input type="number" min="0" id="enter-y">
<input type="button" id="result" value="Submit">
<input type="reset" id="raz" value="Reset">
<input type="text" id="s" readonly>
</form>
DART:
import 'dart:html';
import 'dart:core';
main() {
document.querySelector('#result').onClick.listen((e) {
calculateS();
});
}
calculateS() {
var x = int.parse(document.querySelector('#enter-x').value);
var y = int.parse(document.querySelector('#enter-y').value);
var surface = (x * y).toString();
document.querySelector('#s').value = surface;
}

Dart helps with hints and warning to find errors in your program.
The generic Element doesn't have a value field. The Dart program is still valid and should work as expected and doesn't cause any errors or warnings at runtime because the actually returned element is the more specialized TextInputElement or NumberInputElement which has a value field.
To silence the analyzer, make this more clear by adding a "cast"
calculateS() {
var x = int.parse((document.querySelector('#enter-x') as NumberInputElement).value);
var y = int.parse((document.querySelector('#enter-y') as NumberInputElement).value);
var surface = (x * y).toString();
(document.querySelector('#s') as TextInputElement).value = surface;
}
Try it at DartPad
See also:
https://api.dartlang.org/1.12.0/dart-html/InputElement-class.html
Dart 'query' explicit cast
What is the syntax for implicit cast operator in dart?
https://www.dartlang.org/docs/dart-up-and-running/ch02.html#operators

Related

prevent word counting of multiple spaces between words in textarea (html / javascript)

I have a textarea id="task", which has a word counter id="count" connected. The counter is set to count spaces between words, so a word is only accounted for if one puts a space after it. However, if for whatever reason one finds themself in a frenzy of hitting the spacebar, each and every space is then counted as a word which thwarts the final count. Below is the code for you to see for yourselves.
What I am asking is as follows:
1) Is there a way to count only one space after each word and ignore multiple spaces?
2) Can I prevent multiple spaces in the textarea?
Since I am suspecting that the solution dwells within the realm of javascript, I kindly ask for your help as I am still a noob. I will be grateful for any suggestions, be it 1) or 2).
HTML:
<div class="options">
Task:
<textarea type="text" rows="10" cols="97" name="task" id="task" onkeypress="onTestChange01();"
autocorrect="off" spellcheck="false"></textarea>
<p>Word count: <textarea cols="10" name="count" id="count" readonly>0</textarea></p>
</div>
JAVASCRIPT:
// WORD COUNTER FUNCTION
var count = document.getElementById('count');
var input = document.getElementById('task');
input.addEventListener('keyup', function(e){
wordCounter(e.target.value);
});
function wordCounter(text) {
var text = input.value;
var wordCount = 0;
for (var i = 0; i <= text.length; i++) {
if (text.charAt(i) == ' ') {
wordCount++;
}
}
count.innerText = wordCount;
}
I tried fiddling with the JS function and its values.
Also, I found a function to change multiple spaces to one space, which did not work as expected and it disrupted the original function and the counting.
Finally, I tried preventing 'space' altogether in the textarea properties but all in vain.
Looking forward to your ideas. Thanks.
tk

Conditional rendering of a Form.Item on Ant design

I'm trying to make a form using Ant design v4.0. The display of an Form.Item (Input text) depends of the value of other Form.Item (Radio button group). I'm using form.getFieldValue('fieldname') and it works initially but, when I changed the value of the radio Botton group the field is still showing up.
The code is similar to this
(...)
const [form] = useForm();
(...)
<Form form={form} (...)>
<Form.Item name="fieldname" initialValues={props.initialValues}>
// Here it is a radio button group
</FormItem>
{ form.getFieldValue('fieldname') === 'a_value' && (
<Form.Item name="a-text-field>
// here it is an input text
</Form.Item>
)}
</Form>
As I said before, it works with the initial value but if I changed the option it doesn't work. I also try the prop in the field a-text-field but it didn't work
hidden={form.getFieldValue('fieldname') !== 'a_value'}
it's because if the radio input changed, it does not change the form.item value so doing form.getFieldValue('fieldname') will not work. You may use a state instead and use onValuesChange prop of the form:
const [radioValue, setRadioValue] = useState("a_value");
const [form] = useForm();
(...)
const handleFormValuesChange = (changedValues) => {
const fieldName = Object.keys(changedValues)[0];
if(fieldName === "a-text-field"){
const value = changedValues[fieldName];
setRadioValue(value)
}
}
<Form form={form} onValuesChange={handleFormValuesChange}>
<Form.Item name="fieldname" initialValues={radioValue}>
// Here it is a radio button group
</FormItem>
{ radioValue === 'a_value' && (
<Form.Item name="a-text-field'>
// here it is an input text
</Form.Item>
)}
</Form>
here is the link of working sample
Check out this example in antd documentation.
https://ant.design/components/form/#components-form-demo-control-hooks
This doesn't require any state variables. The 'shouldUpdate' prop rerenders the specific form.item.

Svelte: How to bind a formatted input field to a property

First of all: Svelte is still new to me. I hope the question is not too trivial.
Within a simple component I want to use the content of a formatted input field for a calculation.
For example:
In the input field a Euro amount should be displayed formatted (1.000).
Next to it a text with the amount plus VAT should be displayed (1.190).
How I do this without formatting is clear to me. The example looks like this:
export let net;
export let vat;
$: gross = net + (net * vat / 100);
$: grossPretty = gross.toLocaleString('de-DE',{ minimumFractionDigits: 0, maximumFractionDigits: 0 });
with a simple markup like this:
<form>
<label>Net amount</label>
<input type="text" step="any" bind:value={net} placeholder="Net amount">
</form>
<div>
Gros = {grossPretty} €
</div>
In vue i used a computed property. Its getter delivers the formatted string and its setter takes the formatted string and saves the raw value.
(In data() I define net, in the computed properties i define netInput. The input field uses netInput as v-model).
It looks like this:
netInput: {
get(){
return this.net.toLocaleString('de-DE',{ minimumFractionDigits: 0, maximumFractionDigits: 0 });
},
set(s){
s = s.replace(/[\D\s._-]+/g, "");
this.net = Number(s);
}
}
How can I handle it in svelte?
You can do something somewhat similar, you create another computed variable that stores the deformatted string from the input field and is used in the calculation instead of the direct input
export let net;
export let vat;
$: net_plain = Number(net.replace(/[\D\s._-]+/g, ""));
$: gross = net_plain + (net_plain * vat / 100);
$: grossPretty = gross.toLocaleString('de-DE',{ minimumFractionDigits: 0, maximumFractionDigits: 0 });
But maybe find a better name for the variable :)
Thanks to Stephane Vanraes I found a solution.
It has not the charm of the vue approach but it's ok. First I inserted 'net_plain'. To have the input field formatted during input, I added an event listener for the keyup event.
<input type="text" step="any" bind:value={net} on:keyup={handleKeyUp} placeholder="Net amount">
The event is handled from the function handleKeyUp as follows:
function handleKeyUp(event){
if ( window.getSelection().toString() !== '' ) {
return;
}
// ignore arrow keys
let arrows = [38,40,37,39];
if ( arrows.includes( event.keyCode)) {
return;
}
let input = event.target.value.replace(/[\D\s._-]+/g, "");
input = input ? parseInt( input, 10 ) : 0;
event.target.value = ( input === 0 ) ? "" : input.toLocaleString( "de-DE" );
}
BUT: If anyone has a solution using getter and setter I would appreciate the anwer!

Omniture tagging - Fire a start event on Onchange (Not Working !!!!)

I am a newbie to Omniture tagging. The company has provided specs and I am following that. I want to fire a start event when the value in the dropdown changes. I don't know what I am missing because it refuses fire the event. I am using Omnibug to test.
<select name="seltest" onChange = "var s=s_gi('ds-prod');tmsomni.linkTrackVars=
'prop6,prop64';tmsomni.linkTrackEvents = 'event54';tmsomni.prop6 = 'vehicle
request';tmsomni.prop64 = 'vehicle'; s.tl(true, 'o');">
<option>1</option>
<option>2</option>
</select>
Your setting the tracking object to s and then using tmsomni to set values in the tracking object. It should look more like this:
<select name="seltest" onchange="window.tmsomni=s_gi('ds-prod');tmsomni.linkTrackVars= 'prop6,prop64';tmsomni.linkTrackEvents = 'event54';tmsomni.prop6 = 'vehicle request';tmsomni.prop64 = 'vehicle'; tmsomni.tl(true, 'o');">
<option>1</option>
<option>2</option>
</select>
Or perhaps the inverse where you would replace all tmsomni with s.
Also set the events variable as below:
<select name="seltest" onchange="window.tmsomni=s_gi('ds-prod');tmsomni.linkTrackVars= 'prop6,prop64';tmsomni.linkTrackEvents = 'event54';tmsomni.events = 'event54';tmsomni.prop6 = 'vehicle request';tmsomni.prop64 = 'vehicle'; tmsomni.tl(true, 'o');">
<option>1</option>
<option>2</option>
</select>
It worked , I was missing the name of the link.

pass Polymer data binding through a Javascript function

I'm using Polymer and Dart to produce a list of point coordinates. It renders a list of points in html. Nevertheless I want to convert the points from one coordinate system to another using a javascript function.
In HTML dart-polymer:
<template repeat="{{ p in grid_points }}">
<core-item>{{ p }}</core-item>
</template>
The javascript I found in a library:
grid_to_geodetic(x, y);
grid_points is a List of Points. How can I pass p.x and p.y through the js function and get the result rendered in place of p in the HTML template?
You could use expression filter for that:
<template repeat="{{ p in grid_points }}">
<core-item>{{ p | grid_to_geodetic }}</core-item>
</template>
...
<script>
Polymer('your-element', {
grid_to_geodetic: function(point){
return point.x + point.y;
}
});
</script>
Filter takes one value and returns one, if you need to convert x and y separately you have to use an constant parameter to indicate which part of the point you want to convert, something like
<template repeat="{{ p in grid_points }}">
<core-item>{{ p | grid_to_geodetic(1) }}</core-item>
<core-item>{{ p | grid_to_geodetic(2) }}</core-item>
</template>
...
<script>
Polymer('your-element', {
grid_to_geodetic: function(point, part){
if(part == 1) return point.x;
else return point.y;
}
});
</script>
I did manage to invoke it thanks to some ideas from ain:
So with the expression filter you are telling the template to invoke a Dart function:
<template repeat="{{ p in start_points }}">
<core-item>{{ p | rt90_to_wgs84 }}</core-item>
</template>
Then in the Dart backing class you add a function with the same name as in the filter and you call a global js function with context.callMethod('funcion_name', [args_list]);:
rt90_to_wgs84(p) {
return context.callMethod('grid_to_geodetic', [p.x, p.y]);
}

Resources