Can not change attribute value with jQuery - javascript

I have the following element:
<span class="field-validation-valid" data-valmsg-replace="true" data-valmsg-for="VariableDataList[0].VariableDataForLevel[1].Value"></span>
I want to replace the value of data-valmsg-for changing the number before .Value. To do it, I use this function (latestIdNumber and newIdNumber are values that I compute at the beginning of the function, but imagine that latestIdNumber is 1 and newIdNumber is 2):
clone.find("span[data-valmsg-for$='Value']").map(function () {
var reName = '[' + latestIdNumber + '].Value';
$(this).attr('data-valmsg-for').replace(reName, '[' + newIdNumber + '].Value');
});
reName value is [1].Value. And I want to replace this text in data-valmsg-for with [2].Value. After that, I will have in data-valmsg-for the value data-valmsg-for="VariableDataList[0].VariableDataForLevel[2].Value.
I have debugged it with Visual Studio and it stops inside the find but the value of the attribute doesn't change.
I know that the attribute value doesn't change because I have opened the Internet Explorer Debugger and I don't see the new value.
I have tried the same, changing id and name for input fields and replace functions works perfectly.
How can I replace the value for that attribute?

Firstly, you should use each() to iterate through a collection of elements. map() is intended to create an array from that collection, although in this case it's not required either if you use attr() correctly.
The issue with your code is because you're not calling the setter of attr(). Instead you get the value, preform the replacement but do nothing with the result.
To fix this you can provide a function to the attr() method which performs the logic on each instance of the elements in the collection. Try this:
var latestIdNumber = '1';
var newIdNumber = '999';
var reName = '[' + latestIdNumber + '].Value';
$("span[data-valmsg-for$='Value']").attr('data-valmsg-for', function(i, v) {
return v.replace(reName, '[' + newIdNumber + '].Value');
});
// to show it worked:
$("span[data-valmsg-for$='Value']").each(function() {
console.log($(this).attr('data-valmsg-for'));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span class="field-validation-valid" data-valmsg-replace="true" data-valmsg-for="VariableDataList[0].VariableDataForLevel[1].Value">Foo</span>
<span class="field-validation-valid" data-valmsg-replace="true" data-valmsg-for="VariableDataList[0].VariableDataForLevel[1].Value">Bar</span>
Also note that you should really use the data() method to work with data-* attributes. The caveat here is that data() does not update the DOM, so if you require that behaviour then you would need to continue to use attr() as you are.

Related

Jquery - Create dynamic name selector

I have been playing with this for the last hour, but just cant get it to work.
I have a reactJS component, that renders a grid. After the grid is rendered I need to do some DOM work on the component.
There are some checkboxes that need to be checked. After the DOM is available if I run this in console:
$('[name="checkbox0"]').prop('checked', true);
It works great.
I need to iterate my objects, and based on condition check it or not.
My question is how to make the selector dynamic? How do I make checkbox0 dynamic, so I can set it to checkbox1, checkbox5... etc.
This is my latest attempt to solve the issue, and it did not work:
this.state.rows.forEach(function (index, key, value){
var test = "'[name=" + "checkbox" + key + "]'" ;
if(index.selected){
//$('[name="checkbox0"]').prop('checked', true);
$(test).prop('checked', true);
}
});
You are trying to use an attribute selector, but the syntax is way off in the dynamic string
var test = '[name="checkbox' + key + '"]'
You are wrapping the entire string with a "" where it should have only for the attribute value

Can't get elements with specific id as attribute 'data-parent'

I have a element like this
<input type="checkbox" data-parent="0" value="1229">
and I want to get all the checkboxes with data-parent that have a value of N.
Here is what I tried in my click event handler method.
checkChildren = function (id) {
var cbs = $(input[type="checkbox"][data-parent=id]);
}
but there is some syntax error near 'data-parent=id'
Your CSS selector is wrong. Change it to:
var cbs = $('input[type="checkbox"][data-parent="' + id + '"]');
you need to pass a string selector to jquery, first building it with a javascript expression
additionally, the html tag attribute values ("checkbox" and "0") need to both be quoted
var selector = 'input[type="checkbox"][data-parent="' + id + '"]';
var cbs = $(selector);
edit, details why:
input[type="checkbox"][data-parent=id]
when the javascript parser hits this, it tries to execute it as javascript code, and give the result to $().
Here's what it (javascript parsing engine) tries:
looks for a variable named input
Finds an opening bracket [ after the input object and evaluates the contents, type="checkbox"
(this operation sets the variable type to the string "checkbox" and returns the string "checkbox")
substitutes the returned value into the first brackets, input["checkbox"]
(the bracket operator looks up the checkbox property of the input object, like input.checkbox, and returns the value of the property or undefined)
Similarly evaluates for the second set of brackets value[data-parent=id]
(but this time runs into an error because data-parent=id is ambiguous, it's trying to set the result of subtract parent from data to the variable id)

What is the best way to access an element through a data-attribute whose value is an object (JSON)?

Say I have the following element:
<div class='selector' data-object='{"primary_key":123, "foreign_key":456}'></div>
If I run the following, I can see the object in the console.
console.log($('.selector').data('object'));
I can even access data like any other object.
console.log($('selector').data('object').primary_key); //returns 123
Is there a way to select this element based on data in this attribute? The following does not work.
$('.selector[data-object.foreign_key=456]');
I can loop over all instances of the selector
var foreign_key = 456;
$('.selector').each(function () {
if ($(this).data('object').foreign_key == foreign_key) {
// do something
}
});
but this seems inefficient. Is there a better way to do this? Is this loop actually slower than using a selector?
You can try the contains selector:
var key_var = 456;
$(".selector[data-object*='foreign_key:" + key_var + "']");
I think that you may gain a little speed here over the loop in your example because in your example jQuery is JSON parsing the value of the attribute. In this case it's most likely using the JS native string.indexOf(). The potential downside here would be that formatting will be very important. If you end up with an extra space character between the colon and the key value, the *= will break.
Another potential downside is that the above will also match the following:
<div class='selector' data-object="{primary_key:123, foreign_key:4562}"></div>
The key is clearly different but will still match the pattern. You can include the closing bracket } in the matching string:
$(".selector[data-object*='foreign_key:" + key_var + "}']");
But then again, formatting becomes a key issue. A hybrid approach could be taken:
var results = $(".selector[data-object*='" + foreign_key + "']").filter(function () {
return ($(this).data('object').foreign_key == foreign_key)
});
This will narrow the result to only elements that have the number sequence then make sure it is the exact value with the filter.
With a "contains" attribute selector.
$('selector[data-object*="foreign_key:456"]')

How to grab using getAttribute or SetAttribute

init: function(element, options) {
this.$generic = element.find('.love');
this.type = this.$generic.data('type');
this.url = this.$generic.attr('href');
this.$count = this.$generic.setAttribute('data-love-count');
console.log(this.$count + ' 6');
//this.count = +this.$count.text();
},
<a data-love-count="${loveCount}" href="/love/${session.userId}">
<i class="icn-heart"></i>
${loved}
</a>
The console.log keeps on giving errors; Uncaught TypeError: undefined is not a function. I am not sure why. I tried to use getAttribute or setAttribute but I get same errors.
Also I couldn't figure how to add the loves as in commented line. Everytime user clicks, love will increase.
this.$count = this.$generic.setAttribute('data-love-count');
You're using a html attribute setter there, to get the data. replace that line with:
this.$count = this.$generic.attr('data-love-count');
And you should be fine.
setAttribute and getAttribute are native functions but your $generic variable is a jQuery object.
jQuery uses .attr instead: https://api.jquery.com/attr/
If you wanted your code to work you could do:
this.$count = +this.$generic[0].getAttribute('data-love-count');
(Note that it is get not set, and the + converts it to a number type)
get 0 will access the first native element that the jQuery selector found, which you can then call native methods on.
To increment:
this.$count += 6;

Can I return the value of document.getelementbyid inside a document.setcookie?

<input type=button value='Do Stuff' onClick='document.cookie = "Note_<% Response.Write(arrTest(0,i)) %> = ' + (Document.getElementById("StuffTest<% Response.Write(arrTest(0,i)) %>").value) + '"'>
What I'm trying to do here is when the user hits the button, I want a cookie created with the values: Note_(value of arrTest) = (Value of the text box).
The code below works just fine:
<input type=button value='Do Stuff' onClick='document.cookie = "Note_<% Response.Write(arrTest(0,i)) %> = Awesome!"'>
It creates a cookie with the value of: Note_(value of arrTest) = Awesome!
What have I done wrong to get the value of my text box into the cookie? I'm assuming it has to do with all those confusing single/double quotes, so I think I've just got typo-blindness, but part of me thinks I can't actually do what I'm trying to do here.
Any thoughts?
document.getElementById has document in all lower case. Your code example uses Document (with a capital D), which will fail.
Separately, your quotes such in the onClick attribute are not quite right. It's best to avoid putting any significant code in those attributes. Instead, define and call a function, like this:
<input type=button
value='Do Stuff'
onClick='setCookie("<% Response.Write(arrTest(0,i)) %>);'>
...where the function (inside a <script> tag or in a file referenced by one) looks like this:
function setCookie(name) {
document.cookie = "Name_" + name + "=" + document.getElementById("StuffTest" + name).value;
}
Depending on the contents of arrTest(0,i), you might need to HTML-encode it as you output it, since you're outputting it to HTML (yes, the code inside an onXYZ attribute is HTML, just like any other attribute's value, so for instance < would need to be <).

Categories

Resources