Manipulating displayed value and committedValue on core-input - polymer

I need to manipulate values from a raw API data for display to the user and manipulate them again before sending the update through the API. I'm using core-input for each value, but I'm having difficulty setting the initial value and binding to the correct update event.
<input id="host" is="core-input">
My first problem is that I don't know how to set and manipulate the initial value without also binding to the live changes stream. I tried binding only to committedValue but it does not set the initial value for the field.
However, even when I set commitedValue, I am unable to trigger it. I enter text into the field and then switch fields or press the enter key and nothing happens.
<input id="host" commitedValue="{{record | setHost}}" is="core-input">
And the JavaScript:
setHost: {
toDOM: function(record) {
if(record.host === "#"){
return record.domain;
} else {
return record.host + "." + record.domain;
}
},
toModel: function(value) {
if(record.host === "#"){
return record.domain;
} else {
return record.host + "." + record.domain;
}
}
}

To set the initial value, I think you can do a one-time binding.
<template is="auto-binding">
<input is="core-input" type="text" value="[[foo]]">
</template>
<script>
var tmpl = document.querySelector('template');
tmpl.foo = 'bar';
</script>
It seems like the approach you're trying to take with commitedValue may not be supported, because you can't actually write to commitedValue.
From the core-input docs on commitedValue
Setting this property has no effect on the input value.
It might be better to listen to on-change or on-blur (or both), handle the change, and then manually update value

Related

Why does input type number doesn't accept value '+'? [duplicate]

Does anyone know if it's possible to add a plus sign in a html input type=number field? I have a scenario whereby users need to enter a modifier value which is either +1 to +10 or -1 to -10. I want to make it very explicit to the user that their inputted value increments the resulting value. therefore it would be great if a + sign is prepended to a positive inputted value.
I'm using this input in an Angular2 reactive form with bootstrap styling. so an Angular2 directive, a boostrap style or even a jquery solution are welcome
What I've seen so far is about adding currency symbols inside the form control or about adding + and minus buttons to increment and decrement the value. But that's not what I want, so I doubt if this is possible at all.
I don't think it is possible to manipulate the input.
The default behavior is "-" for negative and no sign for positive numbers.
Even if you checked some custom UI frameworks like:
JQuery UI, Bootstrap, Angular Material ... you will not get the wished behavior.
I guess the only solution for this is to write your own custom code.
Two scenarios are possible:
1- An input with Text and the manipulating will be done in Javascript.
2- Create a pipe in angular2 and give it to the element which I think is much easier than the first one.
No it's not possible. The number field only accepts -, 0-9 and e to be entered. As a workaround you could place the + in the HTML before the input, eg:
+ <input type="number" />
Alternatively you could use a standard type="text" input, but that would mean creating your own validation logic which would make the code much more complex.
I hope this will help on you guys!!
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
$(document).on('keypress','#input',function (e) {
var keyCode = e.which;
if ($(this).val().trim().charAt(0) == "\u002B") {
if ( keyCode == 43 ) {
return false;
}
}
else{
for (var i = 1; i < $(this).val().length+1; i++) {
if(i!=0){
if ( keyCode == 43 ) {
return false;
}
}
}
}
});
$(document).on('input', '#input', function() {
this.value = this.value.replace(/[^+{1}|^0-9]/g,'');
});
</script>

Reactive statement throws an error once it hits undefined variables. How to prevent it?

just playing around with Svelte. And I have noticed that when the reactive statement ($) is being calculated, it will throw an error when one of the depending variables is undefined.
While this behaviour is correct, how can I prevent it from calculating if the variable it depends on is undefined?
To see the error, type something in either of the fields, and then delete it, so it becomes empty.
<script>
let num = "";
let secondNum = "";
$: output = "prefix" + num.toString() + secondNum.toString() + "suffix";
function handleChange() {
console.log(num, secondNum);
}
function handleSubmit(e) {
e.preventDefault();
}
</script>
<form on:submit={handleSubmit}>
<input type="number" bind:value={num} on:change={handleChange}>
<input type="number" bind:value={secondNum} on:change={handleChange}>
<button type="submit">
Submit
</button>
</form>
Clearing a numeric input causes its bound value to be undefined. num.toString() is an error if num is undefined (that's a JavaScript thing, not a Svelte thing).
Easiest fix would be this:
$: output = `prefix${num || ''}${secondNum || ''}suffix`;

How to define a variable that's gonna be retrieved from localstorage (Chrome extension)?

I have a variable defined like this (not sure if it should be with let or var in the first place):
let activated = false;
The first thing that the extension should do is check the value of activated. I think this is the correct syntax:
chrome.storage.local.get(['activated'], function(result) {
activated = result.activated
alert ("activated: " + result.activated)
});
After some logic, I want to change activetedto true, with this syntax:
chrome.storage.local.set({activated: true}, function() {
console.log("activated changed to true: " + activated)
});
However, when I close and open the browser again, activatedis set to false again.
How should I structure this in order to achieve the desired result?
The way to acess a localstorage variable isn't by defining as I was doing in let activated = false;.
The way to add the variable retrieved from localstorage to the program's control flow should be done this way:
chrome.storage.local.get(['activated'], function(result) {
if (result.activated == value) { // Do something }
});

Adding properties for a Polymer element to observe based on content or a better way to handle forms

I need to create a form using the Polymer Paper-Input elements, and I need a way to know when all required content has been filled out.
I looked for a built in element, but didn't see one. So I wanted to create a polymer form element that would wrap all of the input tags. The resulting element would have an Invalid attribute which lets you know if any of the input tags are invalid.
The use of the tag would look like this:
<test-form id="testform">
<paper-input label="test" required error="This field is required"></paper-input>
</test-form>
Invalid: {{ $.testform.invalid }}
However, it appears that by the time in the elements lifecycle that I can loop over all the elements inside of the content tag, that anything added to the observe object is ignored.
Here is the code I was working on below:
<polymer-element name="test-form" attributes="invalid">
<template>
<content id="content">
</content>
</template>
<script>
Polymer('test-form', {
domReady: function () {
this.observe = {};
for (var i = 0; i < this.children.length; i++) {
this.observe["this.children[" + i + "].invalid"] = "valChanged";
}
},
invalid: false,
valChanged: function (oldValue, newValue) {
// TODO: If newValue is true set invalid to true
// If newValue is false, loop over all elements to see if all are now valid and invalid can be set to false.
alert("VALUE CHANGED" + oldValue + newValue);
}
});
</script>
Is there a better way to handle this or does anyone know how to make changes to what polymer is observing at this point in the lifecycle?
As far as checking the form's validity, you could simply check each form element's invalid property:
validate: function() {
var invalid = false;
Array.prototype.forEach.call(this.children, function(child) {
if (child.invalid === true) {
invalid = true;
}
});
this.invalid = invalid;
}
Then you could add an input event listener and run this method each time a form element's input changes.
Here's a working jsbin.
If I understand your question, your high level goal is form validation?
As has been detailed in polycasts and other places, I have used iron-form which has some very powerful validate() functionality, including what you mention above and much more.
It does sometimes require some odd usages of hidden <input> fields to get all of the work done, but this is easy to learn in the polycasts, such as polycast 55 and 56
If you stumbled upon this question in 2017, you would definitely now want to use more primitive tech, after you've seen what this has to offer.

How to make two checkboxes required out of three in HTML?

<input type="checkbox" name="Package1" value="packagename">
<input type="checkbox" name="Package2" value="packagename">
<input type="checkbox" name="Package3" value="packagename">
How to make any two checkboxes required for the user to submit the form. The user should not be able to submit the form unless he has checked atleast two checkboxes?
How to achieve that?
Rename checkboxes to name=package[] and values 1, 2, 3.
Then in PHP you'll have o condition (if you send form with GET method, just change POST to GET):
if (isset($_POST['package']) && count($_POST['package']) >= 2) {/* continue */}
If you want to validate it in browser (JS), than:
<script>
var i = 0;
$('[type="checkbox"]').each(function() {
if ($(this).is(':checked')) {
i++;
}
});
if (i <= 1) {
return false; // disable sending form when you've checked 1 checkbox in maximum
}
</script>
Add a class that refers only these checkboxes and then count how many are checked.
A quick and dirty way to validate the checkboxes using JavaScript:
JavaScript
checkCheckboxes = function() {
var numberOfCheckedCheckboxes = 0;
var checkbox1 = document.getElementsByName("Package1")[0];
var checkbox2 = document.getElementsByName("Package2")[0];
var checkbox3 = document.getElementsByName("Package3")[0];
if (checkbox1.checked)
{
numberOfCheckedCheckboxes++;
}
if (checkbox2.checked)
{
numberOfCheckedCheckboxes++;
}
if (checkbox3.checked)
{
numberOfCheckedCheckboxes++;
}
alert(numberOfCheckedCheckboxes >= 2);
}
DEMO: JSFiddle
This code isn't the cleanest block of code, however it does get the job done, and will return true if there are at least 2 checkboxes checked, and will return false otherwise. To make it cleaner, you can change the name value of each checkbox to the same name, such as "packages", and then use document.getElementByName("packages"), then use a for-each loop to loop through each element and check its checked state (I would provide a demo in JSFiddle or JSBin, however it seems that Google Chrome is blocking the script in that case). Using the for-each implementation would allow you to use the same amount of code, regardless of the number of checkboxes.
In HTML, you cannot.
You can impose restrictions in client-side JavaScript or in server-side processing of form data, or both. As usual, client-side restrictions are inherently unreliable and should be regarded as convenience to the user, not a reliable method of doing anything. Server-side processing depends on the server-side technology used.