Determining if an event target is the child of another element - polymer

I'm trying to figure out the best way to determine to which parent node an event target belongs.
You have a custom polymer element with 2 or more forms in it. Each form has a submit button:
<form is="iron-form" id="form1" method="post" action="/action1">
<paper-button on-tap="_submitHandler">Send<paper-button>
</form>
<form is="iron-form" id="form2" method="post" action="/action2">
<paper-button on-tap="_submitHandler">Send<paper-button>
</form>
...
<form is="iron-form" id="formN" method="post" action="/action3">
<paper-button on-tap="_submitHandler">Send<paper-button>
</form>
Then in the tag you have the handler:
_submitHandler: function(e) {
var path = Polymer.dom(e).path;
var item = null;
var form = null;
for (var i = 0; i < path.length; i++) {
item = path[i];
switch (item) {
case this.$.form1:
form = this.$.form1;
break;
case this.$.form2:
form = this.$.form2;
break;
// ... N cases
}
}
if (form != null) {
form.submit()
}
}
There must be a better way to do this... What would be the right way to handle such a case?
I'm using Polymer 1.0

Try this:
_submitHandler: function(e) {
var form = var form = Polymer.dom(e).parentNode;
if (form != null) {
form.submit()
}
}
Or this:
_submitHandler: function(e) {
var form = var form = Polymer.dom(e.target).parentNode;
if (form != null) {
form.submit()
}
}

The way to do this is as follows:
_submitHandler: function(e) {
Polymer.dom(e).localTarget.parentNode.submit();
}

Related

email check and comma separated check jQuery codes work correctly in separation but not when mixed for disabling the submit button

I have to functions that each of them looks for an email being valid and the other one looks for an input being comma separated (not sure if I have the best comma separated jQuery code).
However, when I write a proper comma separated input in the input box, it still allows me to click on the submit button which is strange because the email is empty and I expect the submit button to stay disabled. Each of these two functions work correctly separately.
$("#category_names").on('keyup', function (event) {
$(".error").hide();
let hasError = false;
let isValid = true;
$('#category_names').each(function() {
if (($.trim($(this).val()).indexOf(",") == -1)) {
//alert('Please separate multiple keywords with a comma.');
$('#commaerror').show();
hasError = true;
} else {
$('#commaerror').hide()
hasError = false;
}
});
$('button[type="submit"]').prop('disabled', hasError);
})
$("#email").on('keyup', function() {
$(".error").hide();
let hasError = false;
let emailReg = /^([\w-\.]+#([\w-]+\.)+[\w-]{2,4})?$/;
let emailAddressVal = $(this).val();
if (emailAddressVal == '') {
$("#email").after('<span class="error">Please enter your email address.</span>');
hasError = true;
}
else if (!emailReg.test(emailAddressVal)) {
$("#email").after('<span class="error">Enter a valid email address.</span>');
hasError = true;
}
$('button[type="submit"]').prop('disabled', hasError);
})
You need to check both (all, if there are other inputs as well) conditions are valid in each event handler. It's probably simplest to put all the validation code into a function and call that in the event handler. For example:
function validate() {
$(".error, #commaerror").hide();
let hasError = false;
// validate category names
$('#category_names').each(function() {
if ($(this).val().indexOf(",") == -1) {
//alert('Please separate multiple keywords with a comma.');
$('#commaerror').show();
hasError = true;
}
});
// validate email
let emailReg = /^([\w-\.]+#([\w-]+\.)+[\w-]{2,4})?$/;
let emailAddressVal = $('#email').val();
if (emailAddressVal == '') {
$("#email").after('<span class="error">Please enter your email address.</span>');
hasError = true;
}
else if (!emailReg.test(emailAddressVal)) {
$("#email").after('<span class="error">Enter a valid email address.</span>');
hasError = true;
}
return hasError;
}
$("#category_names, #email").on('keyup', function(event) {
$('button[type="submit"]').prop('disabled', validate());
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="col-md-3">
<label data-error="wrong" data-success="right">Enter your email</label>
<input type="email" class="form-control validate purple-border" id="email">
<br/>
<label>Enter categories:</label>
<input type="text" id="category_names" />
<br/>
</div>
<button type="submit" class="btn btn-purple purple-border" disabled="disabled">Perform Frame Classification</button>
Note I've cleaned up your category_names code a bit, but you need to add further checking so that if there is only one value it still passes, or that something like abc, doesn't pass. You might find something like
$(this).val().match(/^\s*\w+(\s*,\s*\w+)*\s*$/)
more useful.

How to get form submit object keys and iterate over them in google apps script?

I have a form that looks like this:
<form id="myForm" onsubmit="handleFormSubmit(this)">
<label for="Identity">Identity</label>
<select class="input-combobox" id="parentAttr" value="Identity" name="Identity">
<? var dropdownOptions = getDropdownOptions(); ?>
<option name="Identity" value="placeholder"></option>
<?
for(i=0; i<dropdownOptions.length;i++){
?>
<option value= "<?= dropdownOptions[i] ?> "> <?= dropdownOptions[i] ?> </option>
<? } ?>
</select>
<input name="myFile" type="file" />
<input type="submit" value="Submit" />
</form>
<script>
// Prevent forms from submitting.
function preventFormSubmit() {
var forms = document.querySelectorAll('form');
for (var i = 0; i < forms.length; i++) {
forms[i].addEventListener('submit', function(event) {
event.preventDefault();
});
}
}
window.addEventListener('load', preventFormSubmit);
function handleFormSubmit(formObject) {
google.script.run.withSuccessHandler(updateUrl).processForm(formObject);
}
function updateUrl(url) {
var div = document.getElementById('output');
div.innerHTML = 'Got it!';
}
</script>
and in Code.gs
function processForm(formObject) {
Logger.log(formObject); //logs {myFile=FileUpload, Identity=c } Those are the values I picked in my form.
}
After I log the formObject. I want to Log formObject.keys- im not sure what the call is as the formObject doesn't seem to be a valid javascript object. Further I would like to do something like for (var key in formObject.keys) {execute something} but Im not sure how to iterate through this formObject either.
Have you actually tried this and run into any errors? The for loop for iterating over object properties is
for(var key in object) {
Logger.log(key); // logs property name
Logger.log(object[key]); //logs value for the property
}
Another option to log property names
Logger.log(Object.keys(yourFormObject));

Get the value of all checkbox when checkall checkbox is checked

I'am new to angularjs, I'm creating an application of attendance. When i check the checkall checkbox all the checkbox of name is also check and What i really wanted to achieve is to get the value of checked checkboxes. I'm done with checking all checkboxes. I just want to store all the value of checkboxes in an array. I can only get data when i check those checkboxes one by one. Thank you in advance.
In my html here is my code.
<ion-checkbox ng-model="Selected" ng-click="checkAll()">
<div class="wew">
Check All Checkbox
</div></ion-checkbox>
</label></div>
<table><tr><th><center>
List of Names
</center></th>
<th colspan="3">
Actions
</th></tr><tr><td><label>
<ion-checkbox ng-repeat="role in roles" ng-model="isChecked" ng-
change="format(isChecked,role,$index)"><div class="wew">
{{role}}
</div></ion-checkbox>
</label></td>
And in my controllers code. First this is my code where i get the list of names.
$http.post(link1, {section: section}).success(function(attendance){
for(a = 0; a<attendance.length; a++){
$scope.roles = [
attendance[0].Full_Name,
attendance[1].Full_Name,
attendance[2].Full_Name,
attendance[3].Full_Name,
attendance[4].Full_Name,
attendance[5].Full_Name,
attendance[6].Full_Name,
attendance[7].Full_Name,
attendance[8].Full_Name,
attendance[9].Full_Name,
]
}
})
.error(function(err) {
console.log(err)
})
And this is my code where i wanted to execute the checkall and automatically store the data in $scope.selected = []; if i click the check all checkbox..
$scope.checkAll = function () {
if ($scope.Selected) {
$scope.Selected = false;
} else {
$scope.Selected = true;
}
$scope.isChecked= $scope.Selected;
$scope.selected = [];
$scope.format = function (isChecked, role, $index) {
if (isChecked == true) {
$scope.selected.push(role);
}
else {
var _index = $scope.selected.indexOf(role);
$scope.selected.splice(_index, 1);
}
var students = $scope.selected;
console.log(students);
}
}
try this code
<script>
$(function(){
var numbers = $("input[type='checkbox']:checked").map(function(_, el) {
return $(el).val();
}).get();
});
</script>

Angular 2 Datalist Option click event in Angular 2 [duplicate]

I'm using a <datalist>
<datalist id="items"></datalist>
And using AJAX to populate the list
function callServer (input) {
xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function(){
if (xmlhttp.readyState == 4 && xmlhttp.status == 200){
//return the JSON object
console.log(xmlhttp.responseText);
var arr = JSON.parse(xmlhttp.responseText);
var parentDiv = document.getElementById('items');
parentDiv.innerHTML = "";
//fill the options in the document
for(var x = 0; x < arr.length; x++) {
var option = document.createElement('option');
option.value = arr[x][0];
option.innerHTML = arr[x][1];
//add each autocomplete option to the 'list'
option.addEventListener("click", function() {
console.log("Test");
});
parentDiv.appendChild(option);
};
}
}
xmlhttp.open("GET", "incl/search.php?value="+input.value, true);
xmlhttp.send();
}
However I can't get it to perform an action when I click on a selection in the datalist, for example if I type in "Ref F" and the item "Ref flowers" comes up, if I click on it I need to execute an event.
How can I do this?
option.addEventListener("click", function() {
option.addEventListener("onclick", function() {
option.addEventListener("change", function() {
Sorry for digging up this question, but I've had a similar problem and have a solution, that should work for you, too.
function onInput() {
var val = document.getElementById("input").value;
var opts = document.getElementById('dlist').childNodes;
for (var i = 0; i < opts.length; i++) {
if (opts[i].value === val) {
// An item was selected from the list!
// yourCallbackHere()
alert(opts[i].value);
break;
}
}
}
<input type='text' oninput='onInput()' id='input' list='dlist' />
<datalist id='dlist'>
<option value='Value1'>Text1</option>
<option value='Value2'>Text2</option>
</datalist>
This solution is derived from Stephan Mullers solution. It should work with a dynamically populated datalist as well.
Unfortunaltely there is no way to tell whether the user clicked on an item from the datalist or selected it by pressing the tab-key or typed the whole string by hand.
Due to the lack of events available for <datalist> elements, there is no way to a selection from the suggestions other than watching the input's events (change, input, etc). Also see my answer here: Determine if an element was selected from HTML 5 datalist by pressing enter key
To check if a selection was picked from the list, you should compare each change to the available options. This means the event will also fire when a user enters an exact value manually, there is no way to stop this.
document.querySelector('input[list="items"]').addEventListener('input', onInput);
function onInput(e) {
var input = e.target,
val = input.value;
list = input.getAttribute('list'),
options = document.getElementById(list).childNodes;
for(var i = 0; i < options.length; i++) {
if(options[i].innerText === val) {
// An item was selected from the list!
// yourCallbackHere()
alert('item selected: ' + val);
break;
}
}
}
<input list="items" type="text" />
<datalist id="items">
<option>item 1</option>
<option>item 2</option>
</datalist>
Use keydown
Contrary to the other answers, it is possible to detect whether an option was typed or selected from the list.
Both typing and <datalist> clicks trigger the input's keydown listener, but only keyboard events have a key property. So if a keydown is triggered having no key property, you know it was a click from the list
Demo:
const opts = document.getElementById('dlist').childNodes;
const dinput = document.getElementById('dinput');
let eventSource = null;
let value = '';
dinput.addEventListener('keydown', (e) => {
eventSource = e.key ? 'input' : 'list';
});
dinput.addEventListener('input', (e) => {
value = e.target.value;
if (eventSource === 'list') {
alert('CLICKED! ' + value);
}
});
<input type="text" id="dinput" list="dlist" />
<datalist id="dlist">
<option value="Value1">Text1</option>
<option value="Value2">Text2</option>
</datalist>
Notice it doesn't alert if the value being clicked is already in the box, but that's probably desirable. (This could also be added by using an extra tracking variable that will be toggled in the keydown listener.)
Datalist actually don't have an event (not all browsers), but you can detect if a datalist option is selected in this way:
<input type="text" list="datalist" />
<datalist id="datalist">
<option value="item 1" />
<option value="item 2" />
</datalist>
window.addEventListener('input', function (e) {
let event = e.inputType ? 'input' : 'option selected'
console.log(event);
}, false);
demo
Shob's answer is the only one which can detect when an option gets clicked as well as not trigger if an intermediary written text matches an option (e.g.: if someone types "Text1" to see the options "Text11", "Text12", etc. it would not trigger even if "Text1" is inside the datalist).
The original answer however did not seem to work on newer versions of Firefox as the keydown event does not trigger on clicks so I adapted it.
let keypress = false;
document.getElementById("dinput").addEventListener("keydown", (e) => {
if(e.key) {
keypress = true;
}
});
document.getElementById("dinput").addEventListener('input', (e) => {
let value = e.target.value;
if (keypress === false) {
// Clicked on option!
console.debug("Value: " + value);
}
keypress = false;
});
<input type="text" id="dinput" list="dlist" />
<datalist id="dlist">
<option value="Value1">Text1</option>
<option value="Value2">Text2</option>
</datalist>
Datalist don't support click listener and OnInput is very costly, checking everytime all the list if anything change.
What I did was using:
document.querySelector('#inputName').addEventListener("focusout", onInput);
FocusOut will be triggered everytime a client click the input text and than click anywhere else. If they clicked the text, than clicked somewhere else I assume they put the value they wanted.
To check if the value is valid you do the same as the input:
function onInput(e) {
var val = document.querySelector('#inputName').value;
options = document.getElementById('datalist').childNodes;
for(var i = 0; i < options.length; i++) {
if(options[i].innerText === val) {
console.log(val);
break;
}
}
}
<input type="text" id="buscar" list="lalista"/>
<datalist id="lalista">
<option value="valor1">texto1</option>
<option value="valor2">texto2</option>
<option value="valor3">texto3</option>
</datalist>
//0 if event raised from datalist; 1 from keyboard
let idTimeFuekey = 0;
buscar.oninput = function(){
if(buscar.value && idTimeFuekey==0) {
alert('Chévere! vino desde la lista')
}
};
buscar.onkeydown = function(event){
if(event.key){ //<-- for modern & non IE browser, more direct solution
window.clearInterval(idTimeFuekey);
idTimeFuekey = window.setInterval(function(){ //onkeydown --> idTimeFuekey++ (non 0)
window.clearInterval(idTimeFuekey);
idTimeFuekey = 0 //after 500ms onkeydown --> 0 (could work 500, 50, .. 1)
}, 500)
}
}
Well, at least in Firefox the onselect event works on the input tag
<input type="text" id="dinput" list="dlist" onselect="alert(this.value)"/>
<datalist id="dlist">
<option value="Value1">Text1</option>
<option value="Value2">Text2</option>
</datalist>
After having this problem and not finding a suitable solution, I gave it a shot.
What I did was look at the "inputType" of the given input event on top of the event toggle variable from above, like so:
eventSource = false;
const selector = document.getElementById("yourElementID");
selector.addEventListener('input', function(evt) {
if(!eventSource) {
if(evt.inputType === "insertReplacementText") {
console.log(selector.value);
}
}
});
selector.addEventListener('keydown', function(evt) {
eventSource = !evt.key;
});
This works if you want to allow the user to search a field but only hit a specific function/event on selection from the datalist itself. Hope it helps!
Edit: Forgot to mention this was done through Firefox and has not been tested on other browsers.

How to support placeholder attribute in IE8 and 9

I have a small issue, the placeholder attribute for input boxes is not supported in IE 8-9.
What is the best way to make this support in my project (ASP Net). I am using jQuery.
Need I use some other external tools for it?
Is http://www.hagenburger.net/BLOG/HTML5-Input-Placeholder-Fix-With-jQuery.html a good solution?
You could use this jQuery plugin:
https://github.com/mathiasbynens/jquery-placeholder
But your link seems to be also a good solution.
You can use any one of these polyfills:
https://github.com/jamesallardice/Placeholders.js (doesn't support password fields)
https://github.com/chemerisuk/better-placeholder-polyfill
These scripts will add support for the placeholder attribute in browsers that do not support it, and they do not require jQuery!
the $.Browser.msie is not on the latest JQuery anymore...
you have to use the $.support
like below:
<script>
(function ($) {
$.support.placeholder = ('placeholder' in document.createElement('input'));
})(jQuery);
//fix for IE7 and IE8
$(function () {
if (!$.support.placeholder) {
$("[placeholder]").focus(function () {
if ($(this).val() == $(this).attr("placeholder")) $(this).val("");
}).blur(function () {
if ($(this).val() == "") $(this).val($(this).attr("placeholder"));
}).blur();
$("[placeholder]").parents("form").submit(function () {
$(this).find('[placeholder]').each(function() {
if ($(this).val() == $(this).attr("placeholder")) {
$(this).val("");
}
});
});
}
});
</script>
if you use jquery you can do like this. from this site Placeholder with Jquery
$('[placeholder]').parents('form').submit(function() {
$(this).find('[placeholder]').each(function() {
var input = $(this);
if (input.val() == input.attr('placeholder')) {
input.val('');
}
})
});
these are the alternate links
Placeholder jquery library
HTML5 polyfills -- go for placeholder section
I had compatibility issues with several plugins I tried, this seems to me to be the simplest way of supporting placeholders on text inputs:
function placeholders(){
//On Focus
$(":text").focus(function(){
//Check to see if the user has modified the input, if not then remove the placeholder text
if($(this).val() == $(this).attr("placeholder")){
$(this).val("");
}
});
//On Blur
$(":text").blur(function(){
//Check to see if the use has modified the input, if not then populate the placeholder back into the input
if( $(this).val() == ""){
$(this).val($(this).attr("placeholder"));
}
});
}
$(function(){
if($.browser.msie && $.browser.version <= 9){
$("[placeholder]").focus(function(){
if($(this).val()==$(this).attr("placeholder")) $(this).val("");
}).blur(function(){
if($(this).val()=="") $(this).val($(this).attr("placeholder"));
}).blur();
$("[placeholder]").parents("form").submit(function() {
$(this).find('[placeholder]').each(function() {
if ($(this).val() == $(this).attr("placeholder")) {
$(this).val("");
}
})
});
}
});
try this
I use thisone, it's only Javascript.
I simply have an input element with a value, and when the user clicks on the input element, it changes it to an input element without a value.
You can easily change the color of the text using CSS. The color of the placeholder is the color in the id #IEinput, and the color your typed text will be is the color in the id #email. Don't use getElementsByClassName, because the versions of IE that don't support a placeholder, don't support getElementsByClassName either!
You can use a placeholder in a password input by setting the type of the original password input to text.
Tinker: http://tinker.io/4f7c5/1
- JSfiddle servers are down!
*sorry for my bad english
JAVASCRIPT
function removeValue() {
document.getElementById('mailcontainer')
.innerHTML = "<input id=\"email\" type=\"text\" name=\"mail\">";
document.getElementById('email').focus(); }
HTML
<span id="mailcontainer">
<input id="IEinput" onfocus="removeValue()" type="text" name="mail" value="mail">
</span>
For others landing here. This is what worked for me:
//jquery polyfill for showing place holders in IE9
$('[placeholder]').focus(function() {
var input = $(this);
if (input.val() == input.attr('placeholder')) {
input.val('');
input.removeClass('placeholder');
}
}).blur(function() {
var input = $(this);
if (input.val() == '' || input.val() == input.attr('placeholder')) {
input.addClass('placeholder');
input.val(input.attr('placeholder'));
}
}).blur();
$('[placeholder]').parents('form').submit(function() {
$(this).find('[placeholder]').each(function() {
var input = $(this);
if (input.val() == input.attr('placeholder')) {
input.val('');
}
})
});
Just add this in you script.js file.
Courtesy of http://www.hagenburger.net/BLOG/HTML5-Input-Placeholder-Fix-With-jQuery.html
Since most solutions uses jQuery or are not this satisfying as I wished it to be I wrote a snippet for myself for mootools.
function fix_placeholder(container){
if(container == null) container = document.body;
if(!('placeholder' in document.createElement('input'))){
var inputs = container.getElements('input');
Array.each(inputs, function(input){
var type = input.get('type');
if(type == 'text' || type == 'password'){
var placeholder = input.get('placeholder');
input.set('value', placeholder);
input.addClass('__placeholder');
if(!input.hasEvent('focus', placeholder_focus)){
input.addEvent('focus', placeholder_focus);
}
if(!input.hasEvent('blur', placeholder_blur)){
input.addEvent('blur', placeholder_blur);
}
}
});
}
}
function placeholder_focus(){
var input = $(this);
if(input.get('class').contains('__placeholder') || input.get('value') == ''){
input.removeClass('__placeholder');
input.set('value', '');
}
}
function placeholder_blur(){
var input = $(this);
if(input.get('value') == ''){
input.addClass('__placeholder');
input.set('value', input.get('placeholder'));
}
}
I confess that it looks a bit more MORE than others but it works fine.
__placeholder is a ccs-class to make the color of the placeholder text fancy.
I used the fix_placeholder in window.addEvent('domready', ... and for any additinally added code like popups.
Hope you like it.
Kind regards.
I used the code of this link
http://dipaksblogonline.blogspot.com/2012/02/html5-placeholder-in-ie7-and-ie8-fixed.html
But in browser detection I used:
if (navigator.userAgent.indexOf('MSIE') > -1) {
//Your placeholder support code here...
}
<input type="text" name="Name" value="Name" onfocus="this.value = ''" onblur=" if(this.value = '') { value = 'Name'}" />
Add the below code and it will be done.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script>
<script src="https://code.google.com/p/jquery-placeholder-js/source/browse/trunk/jquery.placeholder.1.3.min.js?r=6"></script>
<script type="text/javascript">
// Mock client code for testing purpose
$(function(){
// Client should be able to add another change event to the textfield
$("input[name='input1']").blur(function(){ alert("Custom event triggered."); });
// Client should be able to set the field's styles, without affecting place holder
$("textarea[name='input4']").css("color", "red");
// Initialize placeholder
$.Placeholder.init();
// or try initialize with parameter
//$.Placeholder.init({ color : 'rgb(255, 255, 0)' });
// call this before form submit if you are submitting by JS
//$.Placeholder.cleanBeforeSubmit();
});
</script>
Download the full code and demo from https://code.google.com/p/jquery-placeholder-js/downloads/detail?name=jquery.placeholder.1.3.zip
Here is a javascript function that will create placeholders for IE 8 and below and it works for passwords as well:
/* Function to add placeholders to form elements on IE 8 and below */
function add_placeholders(fm) {
for (var e = 0; e < document.fm.elements.length; e++) {
if (fm.elements[e].placeholder != undefined &&
document.createElement("input").placeholder == undefined) { // IE 8 and below
fm.elements[e].style.background = "transparent";
var el = document.createElement("span");
el.innerHTML = fm.elements[e].placeholder;
el.style.position = "absolute";
el.style.padding = "2px;";
el.style.zIndex = "-1";
el.style.color = "#999999";
fm.elements[e].parentNode.insertBefore(el, fm.elements[e]);
fm.elements[e].onfocus = function() {
this.style.background = "yellow";
}
fm.elements[e].onblur = function() {
if (this.value == "") this.style.background = "transparent";
else this.style.background = "white";
}
}
}
}
add_placeholders(document.getElementById('fm'))
<form id="fm">
<input type="text" name="email" placeholder="Email">
<input type="password" name="password" placeholder="Password">
<textarea name="description" placeholder="Description"></textarea>
</form>
<script>
if ($.browser.msie) {
$('input[placeholder]').each(function() {
var input = $(this);
$(input).val(input.attr('placeholder'));
$(input).focus(function() {
if (input.val() == input.attr('placeholder')) {
input.val('');
}
});
$(input).blur(function() {
if (input.val() == '' || input.val() == input.attr('placeholder')) {
input.val(input.attr('placeholder'));
}
});
});
}
;
</script>