How to look for two-words id? - javascript

Right now my app offers certain functionality, which involves browsing through html for specific inputs. Those input have id's which are based on some information user provides. So if in, lets call it input1, user gives us "first", we gonna have
<input id="first">
somewhere in html.
Later on javascript needs to find this input basing only on "first" string, it is fairly easy with jquery and coffeescript:
query = "first"
$("#" + query)
Works like a charm!
Problems start when query is a composed of two words, like "first input". This time unfortunately, code i provided is not going to work. What should i do to improve it?

id values cannot contain a space, so you can't have an input with the id "first input", it's invalid HTML. That's almost the only rule HTML imposes on id values. (CSS imposes more unless you use escaping.)
Since it's invalid, a browser is free to do what it likes — it could use only the first word and ignore the second, it could use the whole thing, it could throw out the id entirely, etc.
In practice, Chrome at least allows the invalid ID, and you can use an attribute selector to match it: Live Example
// Don't do this, even if it works in some browsers
var query = "first input";
$("[id='" + query + "']");
Note the quotes around the value, you need them because of the space.
But again, those id values are invalid and browsers are not obligated to handle them correctly. You might consider replacing the spaces with dashes, e.g. <input id="first-input">.

That problem is caused by jquery naming rule. "$("#first query")" cannot be recognised. You can use "_" to replace the space between the words.
Strictly, $("#first query") can be recognized, but it gets the tag whose id is first, and tag is "query". Anyway, it hardly can be found.

It's fairly simple, use attribute selector:
<input id="first second">
Javascript:
var query = "first second";
alert($("[id='" + query + "']"));
working fiddle (updated) here

Related

How to use querySelectorAll with a variable?

I have two HTML elements that are alternatives of each other and I am trying to write a JS function that removes one if the other is present (they originated as words within <sic> and <corr> beneath <choice> in a TEI document). In my transformation, they are both assigned a code (not an #id: #id is randomly generated and has to remain so for other purposes) with a unique prefix:
<a id="abc" choicePOS="sic0">Element1</a>
<a id="xyz" choicePOS="corr0">Element2</a>
In a JS function that 'belongs' to Element1, I want to select Element2 so as to remove it. This is what I have tried (el is element1):
var choicePOS = el.getAttribute("choicePOS").slice(3); // produces 0
var corrID = "corr" + choicePOS; // produces corr0
var corr = document.querySelectorAll("a[choicePOS=corrID]");
This fails, presumably because the corrID variable in the last line is in quote marks and is being taken as a string. I have read various tutorials on CSS selectors and can't find any guidance on how to use them with a variable attribute value. Is this possible? If so, how? If not, any alternatives?
EDIT: A number of other questions relating how to concatenate strings with variables in JS have been suggested as duplicates of this one. To clarify, I am asking specifically about querySelectorAll, as I cannot find any examples this being used with variables. If the answer is that its selector is to be treated as any other JS string (i.e. variables can be concatenated in), then that is perfectly satisfactory.
Use template literals to evaluate that
var corr = document.querySelectorAll(`a[choicePOS=${corrID}]`);

Javascript regex to replace ampersand in all links href on a page

I've been going through and trying to find an answer to this question that fits my need but either I'm too noob to make other use cases work, or their not specific enough for my case.
Basically I want to use javascript/jQuery to replace any and all ampersands (&) on a web page that may occur in a links href with just the word "and". I've tried a couple different versions of this with no luck
var link = $("a").attr('href');
link.replace(/&/g, "and");
Thank you
Your current code replaces the text of the element within the jQuery object, but does not update the element(s) in the DOM.
You can instead achieve what you need by providing a function to attr() which will be executed against all elements in the matched set. Try this:
$("a").attr('href', function(i, value) {
return value.replace(/&/g, "and");
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
link
link
Sometimes when replacing &, I've found that even though I replaced &, I still have amp;. There is a fix to this:
var newUrl = "#Model.UrlToRedirect".replace(/&/gi, '%').replace(/%amp;/gi, '&');
With this solution you replace & twice and it will work. In my particular problem in an MVC app, window.location.href = #Model.UrlToRedirect, the url was already partially encoded and had a query string. I tried encoding/decoding, using Uri as the C# class, escape(), everything before coming up with this solution. The problem with using my above logic is other things could blow up the query string later. One solution is to put a hidden field or input on the form like this:
<input type="hidden" value="#Model.UrlToRedirect" id="url-redirect" />
then in your javascript:
window.location.href = document.getElementById("url-redirect").value;
in this way, javascript won't take the c# string and change it.

jQuery replacing spans in node+jade combo

Perhaps this is expected, but I found it odd since I am now starting with jQuery.
So, I am writing an application using node and jade. In the index.jade I have a statement of the form
p Welcome subscriber
span(id="subscriber") someID
Now once the connection is established between the client and the server, the server sends a welcome JSON message with some data. One of them is the id of the client which I want to replace above. Once the client receives the welcome JSON message it initializes the appropriate structures and then I make a call to a function loadStats:
function loadStats() {
var myText = "" + myData.id + ".";
$('#subscriber').text(myText);
$('#subscriber').html(myText);
};
In the screen I can see that the text "someID" is replaced by the ID of the client. However, when I actually inspect the html code of the page that I am looking at I see a statement of the form:
<p>Welcome subscriber <span id="subscriber">someID</span></p>
In other words in the actual HTML code the text "someID" has not been replaced. Is this something expected? How was the replacement done? Moreover, it appears that working with either of the statements
$('#subscriber').text(myText);
$('#subscriber').html(myText);
gives the replication on the screen but not on the actual html content of what is presented on screen. Is this the correct behavior? From what I understood (and expect) the .text() replaces the visual data of the element with the specific id and the .html() replaces the content. Am I missing something?
Thanks in advance. jQuery rookie here.
Two rules for expressions in pug:
In attributes you use quotes to output literal text and you leave the quotes out when you want to use a variable, and
For the content of a tag you use an equals sign when you want pug to evaluate an expression, or don't put anything if you want literal text
So with those rules in mind, looking at your code you will output the attribute "subscriber" as a literal and "someId" as a literal.
span(id="subscriber") someID
Results in:
<span id="subscriber">someId</span>
You wanted both to be dynamic so remove the quotes in the attribute and put an equals sign after the element:
span(id= subscriber)= someID
This will dynamically replace both with variables.

Adding Javascript variables to HTML elements

So, I have some code that should do four things:
remove the ".mp4" extension from every title
change my video category
put the same description in all of the videos
put the same keywords in all of the videos
Note: All of this would be done on the YouTube upload page. I'm using Greasemonkey in Mozilla Firefox.
I wrote this, but my question is: how do I change the HTML title in the actual HTML page to the new title (which is a Javascript variable)?
This is my code:
function remove_mp4()
{
var title = document.getElementsByName("title").value;
var new_title = title.replace(title.match(".mp4"), "");
}
function add_description()
{
var description = document.getElementsByName("description").value;
var new_description = "Subscribe."
}
function add_keywords()
{
var keywords = document.getElementsByName("keywords").value;
var new_keywords = prompt("Enter keywords.", "");
}
function change_category()
{
var category = document.getElementsByName("category").value;
var new_category = "<option value="27">Education</option>"
}
remove_mp4();
add_description();
add_keywords();
change_category();
Note: If you see any mistakes in the JavaScript code, please let me know.
Note 2: If you wonder why I stored the current HTML values in variables, that's because I think I will have to use them in order to replace HTML values (I may be wrong).
A lot of things have been covered already, but still i would like to remind you that if you are looking for cross browser compatibility innerHTML won't be enough, as you may need innerText too or textContent to tackle some old versions of IE or even using some other way to modify the content of an element.
As a side note innerHTML is considered from a great majority of people as deprecated though some others still use it. (i'm not here to debate about is it good or not to use it but this is just a little remark for you to checkabout)
Regarding remarks, i would suggest minimizing the number of functions you create by creating some more generic versions for editing or adding purposes, eg you could do the following :
/*
* #param $affectedElements the collection of elements to be changed
* #param $attribute here means the attribute to be added to each of those elements
* #param $attributeValue the value of that attribute
*/
function add($affectedElements, $attribute, $attributeValue){
for(int i=0; i<$affectedElements.length; i++){
($affectedElements[i]).setAttribute($attribute, $attributeValue);
}
}
If you use a global function to do the work for you, not only your coce is gonna be easier to maintain but also you'll avoid fetching for elements in the DOM many many times, which will considerably make your script run faster. For example, in your previous code you fetch the DOM for a set of specific elements before you can add a value to them, in other words everytime your function is executed you'll have to go through the whole DOM to retrieve your elements, while if you just fetch your elements once then store in a var and just pass them to a function that's focusing on adding or changing only, you're clearly avoiding some repetitive tasks to be done.
Concerning the last function i think code is still incomplete, but i would suggest you use the built in methods for manipulating HTMLOption stuff, if i remember well, using plain JavaScript you'll find yourself typing this :
var category = document.getElem.... . options[put-index-here];
//JavaScript also lets you create <option> elements with the Option() constructor
Anyway, my point is that you would better use JavaScript's available methods to do the work instead of relying on innerHTML fpr anything you may need, i know innerHTML is the simplest and fastest way to get your work done, but if i can say it's like if you built a whole HTML page using and tags only instead of using various semantic tags that would help make everything clearer.
As a last point for future use, if you're interested by jQuery, this will give you a different way to manipulate your DOM through CSS selectors in a much more advanced way than plain JavaScript can do.
you can check out this link too :
replacement for innerHTML
I assume that your question is only about the title changing, and not about the rest; also, I assume you mean changing all elements in the document that have "title" as name attribute, and not the document title.
In that case, you could indeed use document.getElementsByName("title").
To handle the name="title" elements, you could do:
titleElems=document.getElementsByName("title");
for(i=0;i<titleElems.length;i++){
titleInner=titleElems[i].innerHTML;
titleElems[i].innerHTML=titleInner.replace(titleInner.match(".mp4"), "");
}
For the name="description" element, use this: (assuming there's only one name="description" element on the page, or you want the first one)
document.getElementsByName("description")[0].value="Subscribe.";
I wasn't really sure about the keywords (I haven't got a YouTube page in front of me right now), so this assumes it's a text field/area just like the description:
document.getElementsByName("keywords")[0].value=prompt("Please enter keywords:","");
Again, based on your question which just sets the .value of the category thingy:
document.getElementsByName("description")[0].value="<option value='27'>Education</option>";
At the last one, though, note that I changed the "27" into '27': you can't put double quotes inside a double-quoted string assuming they're handled just like any other character :)
Did this help a little more? :)
Sry, but your question is not quite clear. What exactly is your HTML title that you are referring to?
If it's an element that you wish to modify, use this :
element.setAttribute('title', 'new-title-here');
If you want to modify the window title (shown in the browser tab), you can do the following :
document.title = "the new title";
You've reading elements from .value property, so you should write back it too:
document.getElementsByName("title").value = new_title
If you are refering to changing text content in an element called title try using innerHTML
var title = document.getElementsByName("title").value;
document.getElementsByName("title").innerHTML = title.replace(title.match(".mp4"), "");
source: https://developer.mozilla.org/en-US/docs/DOM/element.innerHTML
The <title> element is an invisible one, it is only displayed indirectly - in the window or tab title. This means that you want to change whatever is displayed in the window/tab title and not the HTML code itself. You can do this by changing the document.title property:
function remove_mp4()
{
document.title = document.title.replace(title.match(".mp4"), "");
}

Problem with regexp in userscript for chrome

This might be a noob question, but I have tried to find an answere here and on other sites and I have still not find the answere. At least not so that I understand enough to fix the problem.
This is used in a userscript for chrome.
I'm trying to select a date from a string. The string is the innerHTML from a tag that I have managed to select. The html structure, and also the string, is something like this: (the div is the selected tag so everything within is the content of the string)
<div id="the_selected_tag">
link
" 2011-02-18 23:02"
thing
</div>
If you have a solution that helps me select the date without this fuzz, it would also be great.
The javascript:
var pattern = /\"\s[\d\s:-]*\"/i;
var tag = document.querySelector('div.the_selected_tag');
var date_str = tag.innerHTML.match(pattern)[0]
When I use this script as ordinary javascript on a html document to test it, it works perfectly, but when I install it as a userscript in chrome, it doesn't find the pattern.
I can't figure out how to get around this problem.
Dump innerHTML into console. If it looks fine then start building regexp from more generic (/\d+/) to more specific ones and output everything into a console. There is a bunch of different quote characters in different encodings, many different types of dashes.
[\d\s:-]* is not a very good choice because it would match " 1", " ". I would rather write something as specific as possible:
/" \d{4}-\d{2}-\d{2} \d{2}:\d{2}"/
(Also document.querySelector('div.the_selected_tag') would return null on your sample but you probably wanted to write class instead of id)
It's much more likely that tag.innerHTML doesn't contain what you think it contains.

Categories