Is it possible to pull out a data attribute value without grabbing the data attribute via camel case?
Example: Take this button:
<button id="my-button" type="button" data-some-url=<%=some_dynamic_path%>>Lookup</button>
When this button is clicked I want to do some ajax stuff. Currently I only know how to grab the data attribute value by camel casing:
$("#my-button").on("click", function(){
url = $(this).data("someUrl");
});
Instead I would prefer to grab the data attribute value like so, but of course it doesn't work:
url = $(this).data("some-url");
Question: Is there some way I can grab the data attribute value by keeping the hyphens in there?
Update:
I made a simple typo. The second version does in fact work:
url = $(this).data("some-url");
That will successfully get you the data attribute value.
Just pass the name as a string to the data method.
$('#my-button').data('some-url')
You could ignore it's data-semantics and treat it like any other attribute:
url = $(this).attr( 'data-some-url' );
Related
I looked at this thread but it didn't help: Find an element in DOM based on an attribute value
I need a Vanilla JS solution to select a username that is in a custom attribute of an <a> tag in the DOM. I used const users = document.querySelectorAll('a[metadata]') which returns a NodeList of all the <a> tags with all their attributes. If I type console.log(users[0]), I get:
<a href="#" class="btn-normal" metadata="
{
'username':'johnny134',
'category':'shoes',
'summary':'Just a guy called Johnny',
'userId':1223432432
}"
</a>
To access the username, I have tried const usernames = document.querySelectorAll('a[metadata="username"]'); but just get back undefined. I think my issue is that username is in an object and I can't figure out how to select it.
Thanks in advance
First, note that document.querySelectorAll returns a list of elements that match the given query, not a list of the values of attributes of those elements that you specify in the query.
From const users = document.querySelectorAll('a[metadata]'), you can get the metadata attribute of, say, the first element, like so:
const metadata0 = users[0].getAttribute("metadata");
And then, since it's a JSON string, you parse it:
const user0 = JSON.parse(metadata0);
Now you can use user0 like a regular JavaScript object:
user0.username
// johnny134
P.S. The JSON in the metadata attribute is not valid, and you may get an error when you try to parse it. Use double quotes in JSON, not single quotes.
I've got div like
<div data-a="aa"> </div>
Then I'm getting its data with:
var data = $("div").data();
And its working fine. Then I'm adding new data like this via data- attribute:
$("div").attr("data-b", "bb");
Then I'm getting data again like
var updatedData = $("div").data();
However, the new value ( data-b attr with bb value ) is not there. Why is that? (I want to manage data via data- attributes)
Fiddle playground
Using attributes is suitable in my case, so I dont want to use .data("key", "val"). data- attributes are valid anyway
Interesting thing is that when I add data- attribute before first call of .data() - it works ok. Is there a way to ignore or 'rebuild' cache of data then? example here
Use .data("key","value") to set the value
$("div").data("b", "bb");
Also use .data("key") to get the value
var data = $("div").data("b");
When you use the data() api, jquery uses an internal private data structure to store the data so the attribute value is not updated.
When you use the data api, there is no need to use the data- prefix.
So once you use the data api to read the values the attribute values are copied to the internal data structure thereafter any changes done to the attribute will not be reflected in the data api.
Demo: Fiddle
There are two ways to add data to an element either you can use data() function by jQuery or you can manually add the 'data-attribute'
The issue you're facing is you can always GET as well as SET the data-attribute's value with data() function. But the attribute SET by this function won't be visible in HTML file.
In the below, 'data-c' won't be visible in the HTML file.
<div class='bar' data-a='avalue' data-b='bvalue'></div>
<script>
console.log($( "div" ).data());
$( "div" ).data('c','cvalue');
console.log($( "div" ).data());
</script>
Try using dataset
var article = document.querySelector('#div1'),
updatedData = article.dataset;
Demo
Reference JavaScript Access
Maybe I am missing something, but I use data-* attribute, namely data-content with such entries like "apple", "cow", etc. Suddenly I was hit when I set my data-content with string "null" (I checked using Chromium HTML is:
<p class="text" data-content="null">null</p>
But when I read data-content using jQuery:
text_elem.data('content')
I get null value, not "null" string.
So my question is, how to read it in raw form, so I could get "null" string exactly as it is in HTML?
If you want to read it in the raw form you would need to use .attr instead of .data. Because that is what data api does it parses the content of the data attribute (ex JSON --> object, numeric string value to number etc...).
text_elem.attr('data-content');
Or you could use dataset (Not supported in older browsers) with the DOM element.
text_elem[0].dataset.content; //this will return a string
You get null instead of "null" because jQuery has for some reason decided to parse data- attributes as JSON when fetching using .data().
To get the raw data, use .attr() instead. This will be faster, and it doesn't make a copy of the value into jQuery.cache, which is very often unnecessary.
Basically, only use .data() for data- attributes if you need the data stored in jQuery.cache and if you're alright with it being parsed as JSON.
The .find() method could be use to search an XML document for the element name specified. For the HTML document, if you want to access the attribute you must use the .attr() method.
I'm developing a portlet for WebSphere Portal 6.1, with JSP/JSTL, pure javascript, no AJAX frameworks, with a JSP that shows a send feedback form and, when submitted, redirects to another JSP to show the user the success of the operation.
I use javascript to get the values of the form fields by using document.getElementById() function. For example:
var valorAsunto = document.getElementById("asunto").value;
where "asunto" is the ID of a text field in my form. Also my form has the following structure:
<form name="formularioCorreo" id="formularioCorreo" method="post" action="<portlet:renderURL><portlet:param name="nextTask" value="sendFeedback"/></portlet:renderURL>">
That works OK, but I'm having trouble when trying to build the <portlet:renderURL> tag from that javascript values: when I try to concatenate a string for the renderURL and then reassign to form action like this:
var valorAction = '<portlet:renderURL><portlet:param name="nextTask" value="sendFeedback"/><portlet:param name="asunto" value="'+valorAsunto+'"/></portlet:renderURL>';
document.formularioCorreo.action = valorAction;
document.formularioCorreo.submit();
The resulting string, when application is deployed, has the structure:
/wps/myportal/<portletpath>/!ut/p/c5/<a very long random sequence of
numbers and letters>/
So one can't figure out where the parameter values are, but if I print the assigned values it shows something like:
asunto: '+valorAsunto+'
instead of
asunto: this is a sample subject
I've been trying to use some other ways to concatenate the string; for instance with a StringBuffer, as shown on http://www.java2s.com/Tutorial/JavaScript/0120__String/StringBufferbasedonarray.htm
and also javascript functions like encodeURI()/decodeURI(), replace(), etc. but I just can't get either the URL with the right parameter values or the URL encoded in the structure shown above (the one with the long sequence of chars).
Sometimes I manage to get the right parameter values, by manually replacing in the valorAction assignation all the "<" for "<" and all the ">" for ">" before the concatenation, and then doing the following:
var valorAction = valorAction.replace(/</g,"<").replace(/>/g,">");
Then I get the following string:
<portlet:renderURL><portlet:param name="nextTask" value="sendFeedback"/><portlet:param name="asunto" value="this is a sample subject"/></portlet:renderURL>
which is OK, but when it has to redirect to the results page it shows an error like this
Error 404: EJPEI0088E: The resource <portlet:renderURL><portlet:param
name="nextTask" value="sendFeedback"/><portlet:param name="asunto"
value="this is a sample subject"/></portlet:renderURL> could not be
found.
Does someone know how to transform that string to the right format to be rendered?
Does someone know any other way to "inject" that parameter values to the renderURL?
I'd like to know also if it is possible to pass that parameter values from javascript to JSP so I could put that values in a HashMap of parameters to use with the PortletURLHelper.generateSinglePortletRenderURL() method, in case the former is not possible.
Thank you.
Update 1:
In my doView() I use the following, in order to make the redirection:
String targetJsp = "/_Feedback/jsp/html/FeedbackPortletView.jsp";
String nextTask = request.getParameter("nextTask");
//(... I have omitted code to conditionally select targetJsp value, according to nextTask value ...)
PortletRequestDispatcher rd = getPortletContext().getRequestDispatcher(targetJsp);
rd.include(request, response);
This is just a new JSP inside my portlet, not a different portal page. I do use request.getParameter() to get the values for my form fields from my doview():
String subjectFeedback = request.getParameter("asunto");
String bodyFeedback = request.getParameter("mensaje");
String emailFeedback = request.getParameter("emailFeedback");
I don't see the need to include hidden fields if my form has the fields named above. In fact, what I'm trying to do is to pass the values the user entered in these fields as request parameters, but the values I get by this means are the following:
subjectFeedback: "'+valorAsunto+'"
bodyFeedback: "'+valorMensaje+'"
emailFeedback: "'+valorEmailFeedback+'"
I get the above values when using concatenation by "+"; when I use StringBuffer I get the following values:
subjectFeedback: "'); buffer.append(valorAsunto); buffer.append('"
bodyFeedback: "'); buffer.append(valorMensaje); buffer.append('"
emailFeedback: "'); buffer.append(valorEmailFeedback); buffer.append('"
Does someone know any other way to "inject" that parameter values to the renderURL?
There are two IBM guides on that topic.
Portal 6.1 and 7.0 Advanced URL Generation Helper classes
How to create a link to a portlet (Standard API) that passes parameters to that portlet
How are you redirecting to the other page? Is it a different portal page or just a new JSP page inside your portlet?
You don't need to inject any parameters to the render URL. Have a form whose action targets to a renderURL. Now to pass information to your portlet's doView() method, you can have hidden fields in the form ,then populate them using JavaScript and then submit the form. In the doView() method, you can use request.getParameter() to get the parameters.
Well, sometimes the most obvious things happen to be the way to the solutions.
I was too busy trying to find elaborated causes for that situation that I did not checked for this at all:
My form fields were correctly identified by different id, but they weren't set their name properties.
With the help of a work partner we could figure out that, so assigning the same value of id for name on each form field did the trick.
So, I ended up skipping that reassigning action thing, because the field values are being set as request parameters, as it should be.
Thanks for the help.
In my MVC3 application, I have a view model that I Json encode so I can manipulate it in JavaScript.
So let's say I have the following code:
var model=#Html.Raw(Json.Encode(Model));
Currently, model.Name has value "Name".
What I want to do now is create another JavaScript object "obj" that has a field called "Value". When you change obj.Value, it also changes model.Name.
So I want something like:
var obj=new Object();
obj.Value=model.Name;
So right now, if I change the value of obj.Value, it doesn't also change model.Name. I want that to happen and I'm not sure how I can do it in JavaScript. How do I do implement that?
Why don't just just put the name in a hidden input field. Change the value with whatever JavaScript you choose in the usual way. Then when the form is posted back you can bind to the name value in the controller action, and set the Model name server-side.
What you are attempting is unnecessarily complicated.
If you really wanted to make it work - then on submit put the entire JSON string in a hidden input field. Then again in the controller action bind to the JSON as a string and deserialize it server-side to reconstruct your Model.