Find elements by text - javascript

I have input tags on the page that are generated dynamically using JS.
They are initialized using $("#input1").val(value). How can I find specific input elements base on text?
The values are initialized as follows:
$("input[name='DeviceIP']").each(function(index,elem){$(elem).val(value)});
The solution I am using now is to select all the inputs I want to inspect and then using find.
$("[name='DeviceIP']").filter(function(index, elem) {
var res = false;
var _this = this;
$("[name='DeviceIP']").each(function(index2, elem2) {
if(elem2 !== _this) {
if(_this.value === elem2.value) {
errMessage = "error text";
res = true;
}
}
});
return res;
}
I looked at the question here but the ":contains" didn't find them for some reason(maybe because there is no value attribute?)

"$("input[name='DeviceIP'][value='your_value_here']")
element.value is also an attribute, so You can define it in Your query ;)
Still, you shouldn't perform such query very often if You have a lot of elements.
I would also suggest You to create map, with values as keys, and nodes as values.

Suppose you have an input field like
<input type="text" value="5" name="DeviceIP">
<input type="text" value="8" name="DeviceIP">
you want the element with specific value. so you can do this,
alert($("input[name='DeviceIP'][value='5']").val());
Here is the fiddle.
If your value is dynamic, say for example your searching value is 8.so you can do this in a way,
var val = 8;
alert($("input[name='DeviceIP'][value='"+val+"']").val());

Related

Detect multiple Input fields value change from code in angularJS

I have an input field as
<input type="text" ng-model="sampleValue" >
In some situations i am clearing the value of input as
$scope.sampleValue = "";
Is there any way to detect the change in value of input field from code?
In this case ng-change is not working as the value is changing from code. I have a number of such input fields, so using multiple $watch is not a good solution.
You may try $watchGroup instead of multiple $watch:
var fieldList = ['sample1', 'sample2', 'sample3'];
$scope.$watchGroup(filedList, function(newVal, oldVal) {
console.log(newVal[0], newVal[1], newVal[2]);
);
if possible make use of rxJs and Observable value , like in below example it observe string s, in you code it can observe $scope.sampleValue = "";
let s = "Hello World";
Observable.of(s).subscribe(val => {
console.log(val);
});

Get multiple attributes with .attr() to get both "id" and ":checked" from element using "this" | jQuery

my question is very simple and doesn't seem to be around as often as setting or applying value in multiple cases.
Using $(this) how can I achieve to get multiple attributes from a single element using as the title informs simply .attr().
$(this).attr('id', "checked") // Pseudo code
For the use to be stored in an array or variable for example. Thank you.
The syntax you used will set the value to the attribute. Hence, you can use
something like ['id', 'checked'].map(a => $el.attr(a)) as mentioned by lxe in the comment or you can create a jQuery wrapper attrs as below.
To get the value of checked property, you can use prop as below instead of attr.
Working snippet:
$(document).ready(function() {
$.fn.attrs = function() {
return Object.keys(arguments).map(k => $(this).prop(arguments[k]));
};
$('input[type="checkbox"]').click(function() {
globalCallback($(this).attrs('id', 'checked'));
});
});
function globalCallback(attrs) {
console.log(attrs);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Click the checkbox and see the console:
<br/>
<input type="checkbox" id="checkbox1" /> Checkbox 1
<input type="checkbox" id="checkbox2" /> Checkbox 2
<input type="checkbox" id="checkbox3" /> Checkbox 3
You can't do this, according to jQuery documentation:
Get the value of an attribute for the first element in the set of matched elements.
Moreover your $(this).attr('id', "checked") code will set to the id attribute the checked value, since attr can be used to set values with exactly such syntax.
However you can create a helper methods like the one mentioned by lxe
You can get the attributes using Array#reduce on the Element.attributes to create an object of attributes:
// get all elements attributes, and convert them to array
var attributes = [].slice.call($('#v-box').get(0).attributes, 0);
// reduce the array to key value pairs
var object = attributes.reduce(function(r, attr) {
r[attr.name] = attr.value;
return r;
}, {});
console.log(object);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="v-box" type="checkbox" checked="checked">
You can easily extend the jQuery function to accommodate what your looking for.
If you aren't interested in extending you could create a new function/ plugin as well
Here's an example:
(function($)
{
var oldAttr = $.fn.attr;
$.fn.attr = function() {
var args= arguments[0];
if(Object.prototype.toString.call(args)=="[object Array]") {
return [args.map((e=> oldAttr.apply(this, [e])))];
//if you want to get a string you could just try `return args.map((e=> oldAttr.apply(this, [e])))`
}
return oldAttr.apply(this, arguments);
};
})(jQuery);
Demo: https://jsfiddle.net/eztukwj9/

Hiding Text inside of an input element

I have a text input, and I want to hide the text inside, on a given event(I disable the input, when it is not needed). I would like to display the hidden text, when the given event is reversed.
I know I can store the value and retrieve as needed. I'd like to avoid moving data, since this is a purely cosmetic operation.
Can the input text be hidden, or is manipulating the data in the input the only way? I would like the simplest solution.y?
I can use pure JS and jQuery.
I would use "value" attribute of the same input object, since the attribute is the default value. In this case you don't even need any additional variables. The idea of this approach comes from the difference between properties and attributes. It means that if you change value property of the object, the attribute value remains the same as it was before.
var input = document.querySelector('input');
function hide() {
input.value = "";
}
function show() {
input.value = input.getAttribute('value');
}
<input type="text" value="Some text">
<button onclick="hide()">Hide</button>
<button onclick="show()">Show</button>
An example on how to store the value of an input element inside the dataset of the element.
and show/hide it on hover.
var hello = document.getElementById('hello');
hello.dataset.value = hello.value;
hello.value = '';
hello.addEventListener('mouseover', function() {
hello.value = hello.dataset.value;
});
hello.addEventListener('mouseout', function() {
hello.value = '';
});
<input id="hello" value="Hello World" />

How to differentiate between DOM elements in jQuery

I have some code that loops over each row of the table and creates a json object. The elements in the rows can be either of the following:
<input type="text" id="myelem"/>
or
<p id="myelem">foo</p>
Notice that the id attribute for the both is same. This is because on the table there is a button Add a new Row when this button is clicked another row is added to the table with a checkbox. When user submits the form the checkbox goes away and the value they entered turns into <p id="myelem">value they entered</p>
Below is the code I'm using for this.
$('.input-row').each(function(index, row) {
var innerObject = {};
var key = $('#myelem', row).val().toUpperCase();
jsonObject[key] = "bar";
});
The above works fine for textboxes becuse I'm using the .val() function. However, how do I get the data from the row if it contains <p id="myelem">foo</p> ??
my pseudo code would be something like this:
$('.input-row').each(function(index, row) {
var innerObject = {};
/*
if #myelem is a text box then use .val()
if #myelem is a <p> tag then use .html()
*/
var key = $('#myelem', row).val().toUpperCase();
jsonObject[key] = "bar";
});
ids should always be globally unique on a page. If you need multiple elements to be referenced, you should use classes. If you set myelem as a class rather than an id you could then reference it like this
$('.input-row .myelem')
You can check which type the element is with
var value = null;
if($('#myid').is('input')) {
value = $('#myid').val();
}
else if($('#myid').is('p')) {
value = $('#myid').html();
}
IDs are unique. You cannot use more than one ID in the same page. If you do so how should you decide which element to use?
You could use jQuery is() eg if $('#myelem').is ('p'){...}
If still want to stick your development way then below might help you:
$('.input-row').each(function(index, row) {
var innerObject = {};
var c = $('#myelem', row);
var isInputField = c.get(0).tagName.toUpperCase()=="INPUT";
var key =isInputField ? c.val().toUpperCase():c.html().toUpperCase();
jsonObject[key] = "bar";
});
This is to just get you started. You are using .each on class input-row but you have not shown the class in your code that you provided. I have used class instead of id in this example. Use it to work ahead.
Fiddle

find ID of previous button

I'm looking to find the id of the previous button. It is pretty far away - lots of table rows, tables, divs, etc. between the target and the button but I thought this would still work:
alert( $(this).prevAll("input[type=button]").attr('id') );
Unfortunately this returns alerts 'undefined'. Help?
function getPrevInput(elem){
var i = 0,
inputs = document.getElementsByTagName('input'),
ret = 'Not found';
while(inputs[i] !== elem || i >= inputs.length){
if(inputs[i].type === 'button'){
ret = inputs[i];
}
i++;
}
return (typeof ret === 'string') ? ret : ret.id;
}
That probably isn't the most efficient solution, but it's the only one I can think of. What it does is goes through all the input elements and finds the one right before the one you passed into the function. You can use it like this, assuming you're calling it correctly and this is the input element:
getPrevInput(this);
Demo
That kind of lookup might be expensive. What about doing a select for all your input[type=button] elements, and traversing that array until you find the element matching your id. Then you can simply reference the array index - 1 to get your answer.
Is the previous button a sibling of the current button? If not, prevAll() won't work. The description of prevAll():
Get all preceding siblings of each element in the set of matched elements, optionally filtered by a selector.
Depending on your DOM structure, you can use a combination of parents() and then followed by find().
This function looks up all input[type=button] elements and uses the jQuery index function to find your current element in this group.
If it could be found and there is a previous element it is returned.
$.fn.previousElem = function(lookup){
var $elements = $(lookup),
index = $elements.index(this);
if(index > 0){
return $elements.eq(index-1)
}else{
return this;
}
}
HTML:
<div><div><div><div>
<input type=button id=1 value=1 />
</div></div></div></div>
<div><div><div><div>
<input type=button id=2 value=2 />
</div></div></div></div>
JS:
alert ($("#2").previousElem('input[type=button]').attr('id'))
http://jsfiddle.net/SnScQ/1/
Here's a different version of Amaan's code, but jqueryfied and his solution wasn't looking for a button. The key to the solution is that jQuery returns the elements in document order, as do document.getElementsByTagName and similar functions.
var button = $('#c');
var prevNode;
$("input[type=button]").each(function() {
if (this == button[0]) {
return false;
}
prevNode = this;
});
alert(prevNode && prevNode.getAttribute('id'));
http://jsfiddle.net/crFy6/
have you tried .closest? ...
alert( $(this).closest("input[type=button]").attr('id') );

Categories