I am trying to check a series of buttons to see if they have been selected in order to generate a query string. So far as I can tell, the logic looks something like this:
if ($("input[name='ovr']")[0].checked)
{
...
}
This works, but since I don't want to use a series of if statements to generate the string (because more buttons might be added later, it's inefficient, etc), I generated an array representing the names associated with the buttons (I printed the array; it definitely contains the proper names). When I made a loop to run through each name in the array, however, the console suggested that 'input' was an unrecognized expression. Here is the loop:
for (i = 0; i < myList.length; i = i + 1) {
if ($("/"input[name='" + myList[i] + "']/"")[0].checked) {
string += myList[i] + "=" + myList[i] + "&";
}
}
string is a variable that appends the proper signature(?) onto itself if the button check should return true. myList is the array containing the names.
Unfortunately, I am new to all of this and don't really know where to begin. I did try to google the answer (really a novice here) but I wasn't even quite sure what to search for. I also messed around with the phrasing of the input expression, used different escape characters, etc., to no avail. Neither the HTML nor most of the javascript is mine (it's my supervisor's), so I am doubly lost. Any suggestions you could give would be sincerely appreciated.
Thanks!
Something like this would work (I don't really understand why you tried to add those backslashes, so I only show you the right way):
for (i = 0; i < myList.length; i = i + 1) {
if ($("input[name='" + myList[i] + "']")[0].checked) {
string += myList[i] + "=" + myList[i] + "&";
}
}
One note: if you are generating a query string, don't forget to use encodeURIComponent()!
something like this?
var query = "?";
$('input:checked').each(function(index) {
query += this.name + "=" + this.value + "&";
});
you can modify the selector to get only the checkboxes you need.
Related
I am trying to use JavaScript to have a dynamic list, and I need to use a lot of of quotes to make the <li> line work as it should, but I cannot get innerHTML to output the correct syntax to the html doc.
here is my JS:
function settabnumber() {
alert("set tab number function called");
var settabcount = 3;
var menucode;
var i=0;
for(basetabcount = 0; basetabcount < settabcount; basetabcount++){
i++;
menucode = menucode + "<li>" + tabnames[i] + "</li>";
}
document.getElementById("eetabmenu").innerHTML = menucode;
}
Any ideas?
Try...
menucode = menucode + '<li>' + tabnames[i] + '</li>';
Always use single quotes to hold HTML strings so you can then freely use the obligatory double quotes.
I made a JSFiddle attempting to reproduce your issue, but it wasn't occurring: https://jsfiddle.net/qf19wvr0/
Either way, as the other commenters said, you should use single quotes. OR, if you're working in an ES6 environment (using a transpiler like Babel), you can use template strings:
menucode += `<li>${tabnames[i]}</li>`
Which makes your snippet a lot more readable.
However:
If you're doing complex enough work that you're looping over a collection and building up DOM nodes from strings, you may want to consider using some kind of templating system (like Handlebars, Mustache, React, or anything of the sort) to abstract some of your view creation logic. Having HTML strings in your JavaScript is a pretty big code smell and likely means you're mixing view logic with business logic.
Use single quotes ' inside of your double quotes, or viseversa
menucode = menucode + '<li>' + tabnames[i] + '</li>';
OR
menucode = menucode + "<li><a href='#tabs-" + i + "'>" + tabnames[i] + "</a></li>";
The first one is preferred
This is my current code. It lists out page titles perfectly, but the links all return 'undefined'.
function func(json) {
var e = document.getElementById('wiki');
var i;
for (i=0; i < json.query.allpages.length; i++) {
e.innerHTML += i + ": " + '' + json.query.allpages[i].title + '' + "<br />";
}
}
function getFromWikipedia() {
var txt = document.getElementById('txt');
var e = document.getElementById('wiki');
var o = document.createElement("script");
o.setAttribute("src", "http://en.wikipedia.org/w/api.php?action=query&list=allpages&format=json&apfrom="+txt.value+"&generator=alllinks&callback=func");
e.appendChild(o);
}
Appending "&prop=links" and/or "&generator=alllinks" to the URL doesn't seem to affect the result.
I would like to know what should I include in this portion:
'<a href="' + json.query.link+ '">'
in order to list the page titles with their respective links.
I have tried "json.query.allpages[i].pageID" and "json.query.alllinks" but it has not been working.
Edit:
Gave up on finding URL and went to do the pageid method instead.
Solved it with this:
e.innerHTML += i + ": " + '' + json.query.allpages[i].title + '' + "<br />";
You can create the link directly using the pageid:
function func(json) {
var e = document.getElementById('wiki');
var i;
for (i=0; i < json.query.allpages.length; i++) {
e.innerHTML += i + ": " + '' + json.query.allpages[i].title + '' + "<br />";
}
}
The fact that you have both list= and generator= in the same query suggests to me that you don't fully understand how generators work in the MediaWiki API.
Basically, a generator is a way to use a list as the source of pages to retrieve properties for. It does not make any sense to use a generator as the input to another list query. That is, you'd normally use generator= with prop=, not with list=. The only reason MediaWiki (seemingly) allows that at all is because:
You can make a query with a page list (or a generator) but no prop= parameter, like this. If you do, you'll just get a minimal default set of properties (title, namespace and page ID) for the pages.
You can also combine a properties query and a list query into a single request, like this. You'll just get the results for both queries, merged into the same JSON/XML/etc. output, but they'll be otherwise completely separate. (You can also make multiple simultaneous list queries that way.)
Thus, when you combine a generator= with a list= query, you'll get both the usual output for the list and a minimal set of properties for the pages matched by the generator. The two outputs will not be connected in any real way, except for being part of the same API response.
Anyway, you wanted to know how to obtain the titles and URLs of all Wikipedia pages with links. Well, as schudel notes in their answer, to get the URLs for some pages you need prop=info with inprop=url; to run this query on all linked pages, you can use generator=alllinks. Thus, you end up with:
https://en.wikipedia.org/w/api.php?action=query&prop=info&inprop=url&generator=alllinks
Note that this gives information about all pages that have links from them. To run the query on all pages with links to them, you need to add the parameter galunique=true:
https://en.wikipedia.org/w/api.php?action=query&prop=info&inprop=url&generator=alllinks&galunique=true
(Yes, this is documented, although not as clearly as it perhaps could be.)
Obviously, the link targets will include a lot of missing pages. The fact that the link sources seemingly also include a missing page with an empty title is presumably due to a faulty record in Wikipedia's link database. This could be fixed by rebuilding the (redundant) links table, but, given Wikipedia's size, this would take quite a bit of time (during which, presumably, the site would have to be locked into read-only mode to avoid further inconsistencies).
To process this data in JavaScript, you could do something like this:
var apiURL = 'https://en.wikipedia.org/w/api.php?format=json&action=query&prop=info&inprop=url&generator=alllinks&callback=myCallback';
function myCallback(json) {
var e = document.getElementById('wiki');
for (var id in json.query.pages) {
var page = json.query.pages[id];
if (typeof(page.missing) !== 'undefined') continue;
e.innerHTML +=
id + ': ' + escapeHTML(page.title) + '<br />';
}
// handle query continuations:
if (json.continue) {
var continueURL = apiURL;
for (var attr in json.continue) {
continueURL += '&' + attr + '=' + encodeURIComponent(json.continue[attr]);
}
doAjaxRequest(continueURL);
}
doAjaxRequest(apiURL + '&continue=');
Note that I've also included a basic mechanism for handling query continuations, since you'll surely need to handle those when using alllinks. Implementing the helper functions escapeHTML() and doAjaxRequest() is left as an exercise. Also note that I haven't actually tested this code; I think it's OK, but there might be bugs that I've missed. It will also produce a ridiculously long list, and probably slow your browser to a crawl, simply because Wikipedia has a lot of pages. For a real application, you'd probably want to introduce some kind of an on-demand loading scheme (e.g. only loading more results when the user scrolls down to the end of the current list).
I'm following w3school beginner tutorial for JS. There's something I don't understand from code below:
<!DOCTYPE html>
<html>
<body>
<p id="demo"></p>
<script>
var cars = ["Saab","Volvo","BMW"];
var text = "";
for(var i = 0; i < cars.length; i++) {
text+=cars[i] + "<br>";
}
document.getElementById("demo").innerHTML = text;
</script>
</body>
</html>
Can someone explain me the logic of text+=cars[i]? I understand that += means increment, but I canĀ“t understand the logic behind adding the array element to variable text.
Thank you so much for your quick replies! I've got a follow up question: is there an alternative to display the same type of information with having to use the
var text = "";
and
text+=cars[i]
pieces of code? If so, how would the snippet of code look like and what should I insert into HTML if not
text
?
Thanks again!
a+=b is short for a=a+b. In your case you have text = text + cars[i] + "<br>".
text is a string, and you are using + to append a value from the array (that contains strings), and then append "<br>"
The value of text at the end of the loop is going to be
Saab<br>Volvo<br>BMW<br>
where br stands for line break. So that each of them gets printed on new line.
And the last line of code
document.getElementById("demo").innerHTML = text;
changes the value of html element which has id of demo to that of text.
text += cars[i] + '<br>';
Concatenates element i of the cars array to the text, separated by a <br> tag.
Consider it like this,
text+=cars[i] + "<br>";
is actually
text=text+cars[i]+"<br>";
so that rather than deleting the old value it will concatenate the new word with existing string.(String Concatenation).
PS:As a fellow beginner a small piece of advice rather than following W3 Schools please go to site like codecademy which helps you to learn along with practice and proper explanation.
Don't think of += as incrementing, that's ++.
a = a + b
a += b;
Those two statements are the same. The bottom one takes the variable on the left side (a) and appends the right side to it (b), and then assigns it all back to he left side (a). So it's just a shorthand.
So what you're doing in your code is appending the string from cars[i] to your variable text.
This would do the same thing:
text = text + cars[i] + "<br>";
Once the loop runs, you will have the following in text:
Saab<br>Volvo<br>BMW
In javascript + is used for string concatenation
The code
for(var i = 0; i < cars.length; i++) {
text+=cars[i] + "<br>";
}
is picking each element from the array and concatenating "" to it.
If you console log the text before setting the innerHTML, it looks something like this -
"Saab<br>Volvo<br>BMW<br>"
here they do it actually just to show theres no point of doing it this way they just wanna show to reach each individual inside an array and concatanate it into a string the very same thing you can do with Array.prototype.join() method dont think here that u must use as they show always concatanate into a string if you want you can simply use every single individual inside as u wish as well
+= is not increment. It's adding (in this case concatenation) and saving result in the same variable.
var a +=b;
Is the same to:
var = a + b;
In your case script concatenates all array elements into one string and adding <br> tags between them.
I'm experiencing a problem when I attempt to use the .change() event on select lists, using the jQuery .toChecklist plugin.
My page contains a number of select lists, which are changed to CheckLists, using jQuery.
Consider the following Javascript snippet:
for (var i=0;i<5;i++)
{
var selectListId = 'selectList' + i;
// Assume this line represents the outputting on a
// standard select list
// Convert to Checklist
$("#" + selectListId).toChecklist();
$("#" + selectListId).change
(
function ()
{
alert("SelectListId: " + selectListId);
}
);
}
For each iteration of this loop, I output a multi-select list, convert it to Checklist, and then add the .change() handler.
However, when the page renders (visually, everything is fine), choosing an option from ANY of the lists gives the alert text of "SelectListId: selectList4" (ie. the last list id of the loop). Thus it appears that each invocation of .change() globally replaces the change handler.
Does anyone know how to change the code so that each checklist has its own change handler (so that the first change handler would output "SelectListId: selectList0", etc).
Thanks,
Try pulling the change function out of the loop. I also added a line that adds a class to each list. The new change function references the lists by the class and will know which is actively being changed via this.
for (var i = 0; i < 5; i++) {
var selectListId = 'selectList' + i;
$("#" + selectListId).toChecklist();
$("#" + selectListId).addClass('newChecklist');
}
$('.newChecklist').change(function() {
alert( $(this).attr('id') );
});
So, after a lot of head scratching, I've found a work-around for this issue.
While concatenating strings together in the anonymous function behaves in an unexpected manner, quoting the whole line of code and wrapping it in an eval statement produces the required results.
Thus, instead of writing, as above:
$("#" + selectListId).change
(
function ()
{
alert("SelectListId: " + selectListId);
}
)
You would need to write this instead:
eval('$("#' + selectListId + '").change(function (){alert("SelectListId: ' + selectListId + '");});');
This may not be the best approach, but it works, and for now that's good enough! :-)
I want save multiple individual records for a single model. So my form will have <input> elements with IDs that look like this Author0Title; Author1Title; Author2Title, etc.
I will be getting values for these input's using jQuery.getJSON() method.
I want to assign individual values for these input like these automatically.
document.getElementById('Author0Title').value = respose.data[0].title;
something like..
for(i=0;i<response.data.length; i++){
var id = 'Author' + i + 'Title';
document.getElementById(id).value = respose.data[0].title;
}
But it is not working. I appreciate any help.
Thanks.
If you're using jQuery:
for (var i = 0; i < response.data.length; i++) {
$('#Author' + i + 'Title').val(response.data[i].title);
}
That's pretty close to your example, except that you've got '0' coded in as the index instead of 'i'.
Make sure that your <input> elements really are using both an "id" and a "name" that's constructed as you expect. If they're just getting the "name" attribute set, you could do this:
$('input[name=Author' + i + 'Title]').val(response.data[i].title);
Could it be that you're misspelling respose -> response?
Otherwise, "should work". Assuming your JSON actually matches what you're looking for in this code.
Since you're using jQuery, you might want to use $('#Author' + i + 'Title').val(response.data[i].title); instead - although it does the same.