I am trying to use e.target.name in react to set the state as I have done before, however e.target.name seems to be undefined for some reason and I can't figure out why, if any one has a suggestion it will be welcome.
thanks!
<li
onMouseEnter={this.handleMouseEnter.bind(this)}
name="HOME"
id="some id"
style={main.element}
>
HOME
</li>
my event handler has only a debugger for me to play with
handleMouseEnter(e) {
debugger
}
and when i try to get the value of the name property i get undefined
e.target
//<li name="HOME" id="some id" style="padding: 10px;">HOME</li>
e.target.name
//undefined
e.target.id
//"some id"
name is an attribute and needs function getAttribute(...) to be fetched. As #Ele has pointed out, the suggested solution would be
var name = e.target.getAttribute('name'); //'HOME'
Form fields are the elements who must use the attribute name.
The JS engine will automatically set that attribute within the form elements (input, select, etc).
document.querySelector('li').addEventListener('click', function(e) {
console.log('Directly: ' + e.target.name);// prints null
console.log('Using getAttribute: ' + e.target.getAttribute('name')); // prints ele
});
document.querySelector('input').addEventListener('click', function(e) {
console.log('Directly: ' + e.target.name);
console.log('Using getAttribute: ' + e.target.getAttribute('name')); // prints ele
});
<input name="ele" placeholder="Click me!">
<li name="ele">Click me!</li>
Related
I am trying to have the input fields tab over to the next field once maxlength is met but I keep getting an error Failed to execute 'querySelector' on 'Document': 'name=2' is not a valid selector.. Ive read over mozialla's explanation of a querySelector and I've tried using the elements id to focus() on but that gives the same error. I guess Im not understanding how to properly craft a selector to pass to the querySelector.
My Input fields ill only show 2 i have 3:
<Input
onChange={dateChange("month")}
value={date.month}
id="1"
maxLength={2}
type="number"
/>
<span className="sep">/</span>
<Input
onChange={dateChange("day")}
value={date.day}
name="2"
id="2"
maxLength={2}
type="number"
/>
My onChange:
const dateChange = (field) => (e) => {
const fieldIndex = e.target.name;
let fieldIntIndex = parseInt(fieldIndex, 10);
// format to fit
let value = e.target.value;
if (value.length === e.target.maxLength) {
if (fieldIntIndex < 3) {
const nextfield = document.querySelector(
`name=${fieldIntIndex + 1}`
);
console.log(nextfield);
if (nextfield !== null) {
nextfield.focus();
}
}
}
const d = { ...date, [field]: value };
setDate(d);
debounceCallback(handleDateInputChange, d);
};
Im still learning so any advice on this would be great :) thanks in advance!
First of all, I think that it is incorrect to set event listeners like this:
onChange={dateChange("month")}
If you do it that way, you actually execute that function during rendering of the page. The function should be executed when the event occurs. The correct way to do this would be:
onChange={dateChange}
If you also wanted to add parameters to your function then you should do it like this:
onChange={dateChange.bind(this, "month")}
Moreover, regarding the query selector, I think the correct syntax would be:
const nextfield = document.querySelector(`input[name='${fieldIntIndex + 1}']`);
Your name prop is set to an input element, so we use input[name].
Also name has a string value, so we use input[name=''].
Finally we want to set name value parametrically, so we use `input[name='${parameter}']`.
You can find the MDN documentation of bind JavaScript function here and the documentation of querySelector here.
Edit: Another alternative for navigating among inputs would be the tabindex attribute. You can find more about it here.
Name is a string So i think you should do it like this(add brackets)
name='${fieldIntIndex + 1}'
I am unable to see the value attribute of input elements when using element.outerHTML. Problem is with all input types; example HTML:
<input type="text" id="copy-paste-textarea" />
Example JavaScript:
<script type="text/javascript">
$('#copy-paste-textarea').on('click', function(e) {
console.log("Text area's outerHTML???" + this.outerHTML + "|");
// Output: <input id="copy-paste-textarea" type="text">
$(this).val('hello!');
$(this).addClass('world!');
console.log("Text area's outerHTML???" + this.outerHTML + "|");
// Output: <input id="copy-paste-textarea" class="world!" type="text">
});
</script>
When I run this code above, I see that the change from addClass() is reflected in this.outerHTML, but the change of val() is not. BUT -- I see that the field is indeed actually being populated with the values. I want output to be this:
// Output: <input id="copy-paste-textarea" value="hello!" class="world!" type="text">
The html() function produces the same results. I would like a solution that works on any input type (select, textarea, etc.).
Similar answer here will only work on textareas: Cannot get outerHTML/value of a dynamically added textarea
This is because elements have "properties", which store dynamic information only in memory as expressed by the JavaScript DOM object and they also have "attributes" where the element's actual markup is recorded in memory and is accessible via the HTML parser.
JQuery's .val() method writes data to an in-memory only property.
To get what you want, you must set the value attribute using
JQuery's .attr() method.
The subtle, but important difference between properties and attributes is what contributes to the confusion between JQuery's .prop() and .attr() methods.
$('#copy-paste-textarea').on('click', function(e) {
console.log("input field's outerHTML???" + this.outerHTML + "|");
// You must set the attribute for it to be picked up in the HTML
$(this).attr("value", "hello!");
$(this).addClass('world!');
console.log("input field's outerHTML???" + this.outerHTML + "|");
});
// For a textarea, you need to get the content of the tags with .text()
$('textarea').on('click', function(e) {
console.log("Text area's outerHTML???" + this.outerHTML + "|");
// You must set the attribute for it to be picked up in the HTML
$(this).text("value", "hello!");
$(this).addClass('world');
console.log("Text area's outerHTML???" + this.outerHTML + "|");
});
.world {
background-color:yellow;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" id="copy-paste-textarea">
<textarea></textarea>
I have a select tag that uses ng-options and ng-model. When I select an option and then select the default option again, then submit the form, it seems like the selected value disappears. This is an optional select field, so I need to be able to check if nothing is selected when submitting.
I have found several questions similar to this, but none with this exact problem:
https://github.com/angular/angular.js/issues/11685 (I don't have a custom select tag directive)
AngularJS ng-options removed default blank value after selecting an option (I'm already using the format in the answer)
Angularjs - TypeError: Cannot read property 'name' of undefined" when work with dropdown (I'm already using a model property like suggested in the answer)
Cannot read property $scope.dropdownfield of null in angularjs (I declare my data beforehand)
Here's a simple fiddle I made illustrating my problem:
https://jsfiddle.net/tjadenad/tse4ans1/29/
Instructions for replicating error:
Open console in browser
Select an option from the select list.
Select the default ("Select an Option") option from the select list.
Press the submit button and see the error in the console
Here is the html:
<div ng-app="app">
<div ng-controller="TestController as ctrl">
<form data-ng-submit="ctrl.submit()">
<label for="test-select">
Label
</label>
<br />
<select id="test-select" name="optionId"
data-ng-model="ctrl.modelObject.selectedOption"
data-ng-options="option as option.description for option in ctrl.options track by option.id">
<option value="">Select an Option</option>
</select>
<br />
<button type="submit">Submit</button>
</form>
</div>
</div>
Here is the controller:
angular.module('app', []).controller('TestController', function() {
var vm = this;
vm.modelObject = { selectedOption: {id: '', description: ''} };
vm.submit = submit;
vm.options = [
{
id : 1,
description: 'Option 1'
},
{
id : 2,
description: 'Option 2'
}
];
function submit() {
var objectFromOptions = {
optionId : vm.modelObject.selectedOption.id
};
}
});
I need to create an object after submitting with the option's id as one of the properties. If the id is null or empty, that is fine, but I cannot find a way to check if it is null. I have tried using
angular.isDefined(vm.modelObject.selectedOption.id)
but that throws the same error when trying to access 'id'.
I also tried
vm.modelObject.selectedOption.hasOwnProperty('id')
to set the property of the new object like so:
function submit() {
var objectFromOptions = { };
if (vm.modelObject.hasOwnProperty('selectedOption')) {
console.log('selectedOption exists');
} else {
console.log('selectedOption does not exist');
}
if (vm.modelObject.selectedOption.hasOwnProperty('id')) {
console.log('id exists');
objectFromOptions.optionId = vm.modelObject.selectedOption.id
} else {
console.log('id does not exist');
}
}
This results in:
selectedOption exists
followed by the error:
TypeError: Cannot read property 'hasOwnProperty' of null
Please let me know if more information is necessary. Thanks in advance for any help!
vm.modelObject.selectedOption will pass an isDefined check -- because it's defined, but with no value assignment. Also, when the page is fresh, the .id property will pass that isDefined check too. The angular.isObject() function is useful here. Or you could just look at the object/properties and see if they are null or evaluates to falsey.
if (angular.isObject(vm.modelObject.selectedOption) && angular.isNumber(vm.modelObject.selectedOption.id)) {
console.log('id exists');
objectFromOptions.optionId = vm.modelObject.selectedOption.id
} else {
console.log('id does not exist');
}
Here's a fiddle with some console logging: https://jsfiddle.net/f3jym9zg/
Here's some examples of peeking at variables to determine if they exist. The same holds true for var.property.
var oops=null;//assign a value of null to the variable oops
console.log(Boolean(oops));//false
console.log(oops!=null);//false
console.log(oops==undefined);//true (== has type conversion baked in)
console.log(oops===undefined);//false (=== does not type conversion, and the types must be the same to be equal. typeOf(undefined)!==typeOf(null))
console.log(angular.isDefined(oops));//true (defined, but assigned a value of null)
console.log(angular.isDefined(oopsy));//false
if (oops){ //evaluates to falsey
//never hit
} else {
//will be hit
}
I have a button where i append inputs to the HTML DOM.
Later on i have a button to fetch input values if they matches with a keyword.
In this example "a".
HTML
<button class="btn btn-info" id="btnAddInput">Add input</button>
<button class="btn btn-info" id="fetchValue">Fetch value</button>
<div id="inputs"></div>
JS
$('#btnAddInput').on('click', function() {
$('#inputs').append('<input type="text" class="myInput"><br>');
});
$('#fetchValue').on('click', function() {
var value = $(document).find('input[value="a"]');
console.log(value);
});
Fiddle: https://jsfiddle.net/Ljrkdm53/
I´ve learned that, if you add HTML to the DOM with Jquery, you sometimes have to use document as selector, to find elements.
But i have no success in this case.
Inputs that you add is, in my code saved into mysql.
And if you load up all saved inputs at start, the js code find values.
So, what am i missing?
You're confusing the various values associated with inputs. You're not the only one!
The value attribute specifies the initial value of the input. It does not change when the input's value changes, and so since you're appending an input that has no value attribute, then typing in it, it doesn't suddenly get a value attribute — so you can't search for it by that value.
The value property on HTMLInputElement instances reflects the input's current value.
There's also the defaultValue property, which reflects the value attribute.
If you need to find an input based on its current value, there's no CSS selector that will do it, you need to use a broader search and filter:
var inputsWithA = $("input").filter(function() {
return this.value == "a";
});
Here's a quick example showing the values of an input's value property, defaultValue property, and value attribute:
$("button").on("click", function() {
var input = $("input");
msg("The input's <code>value</code> property is: '" + input.val() + "'");
msg("The input's <code>defaultValue</code> property is: '" + input.prop("defaultValue") + "'");
msg("The input's <code>value</code> <strong>attribute</strong> is: '" + input.attr("value") + "'");
msg("We can only use CSS with the attribute, so for instance <code>$('input[value=\"original\"]')</code> will find it but <code>$('input[value=\"" + input.val() + "\"]')</code> will not:");
msg("<code>$('input[value=\"original\"]')</code> found it? " +
($('input[value="original"]').length ? "Yes" : "No")
);
msg("<code>$('input[value=\"" + input.val() + "\"]')</code> found it? " +
($('input[value="' + input.val() + '"]').length ? "Yes" : "No")
);
});
function msg(html) {
$("<p>").html(html).appendTo(document.body);
}
<p>Type something in the input, then click the button:</p>
<input type="text" value="original">
<button type="button">Click Me</button>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
If I run that and change the input's value to "updated" before clicking the button, I get:
The input's value property is: 'updated'
The input's defaultValue property is: 'original'
The input's value attribute is: 'original'
We can only use CSS with the attribute, so for instance $('input[value="original"]') will find it but $('input[value="updated"]') will not:
$('input[value="original"]') found it? Yes
$('input[value="updated"]') found it? No
Here is the code you need.
$('#btnAddInput').on('click', function() {
$('#inputs').append('<input type="text" class="myInput"><br>');
});
$('#fetchValue').on('click', function() {
var value = $('.myInput').val();
console.log(value);
});
You can check it working here:
jsfiddle.net/Ljrkdm53/7
What you are missing is that the find returns an array of objects and not one value and that the value selector only uses the initial value. You need to use an each function on the value you have now to do something with it.
$(document).find('input').each(function () {
if( $(this).val() == "a")
console.log( $(this).val());
});
Try with each function.
$('input').each(function() {
if ($(this).val() == 'a') {
console.log('a');
}
});
I'm having two text boxes defined with an onblur event. On pressing tab, whenever the onblur event is get called field.validate is always undefined.
At the same time, when I'm trying to print field.name or field.getAttribute("validate") it does return the proper value.
<input width="100%" type="text" name="NV_active" id="NV_active" value="5" onblur="return doValidate(this);" validate=" return validateValueField(document.getElementById('NV_active'), 'Active' );">
<input width="100%" type="text" name="NV_throttled" id="NV_throttled" value="15" onblur="return doValidate(this);" validate=" return validateValueField(document.getElementById('NV_throttled'), 'Throttled' );">
function doValidate(field) {
console.log("field.validate- " + field.validate); //always printing undefined
console.log("getAttr- " + field.getAttribute("validate")); //return validateValueField(document.getElementById('NV_active'), 'Active' );
if (field.validate != null) {
var f = new Function(field.validate);
return f();
}
return true;
}
function validateValueField(field, displayName)
{
if ((field.name == 'NV_activePollingInterval') || (field.name == 'NV_throttledPollingInterval') )
{
//some validation code and error alert message
}
}
I am not able to figure it out why it's always undefined.
Using field.getAttribute('attr') you retrieve the value of the DOM element's attribute.
Using field.attr you retrieve the property attr of the DOM element and they are not always the same thing.
I recommend you to check this SO question: getAttribute() versus Element object properties? and the accepted answer, it should help you.