I am setting up some basic pagination of a table, and I have the following JS function:
function AddPagination() {
var paginationDiv = document.getElementById("pagination");
for (i = 0; i < 3; ++i) {
var page = document.createElement("a");
page.innerHTML = i + 1;
page.setAttribute("title", i + 1);
page.setAttribute("href", "javascript:RenderResultTable(this.innerHTML)");
paginationDiv.appendChild(page);
}
}
What I want to do is pass page number clicked on to the RenderResultTable method. I have this number stored as the innerHTML and title for the link element, how can I get this passed through using the above code?
Thanks.
Personally, I wouldn't use JavaScript for pagination but if that's the way you want to go, you need to use some string concatenation. I'm not sure what RenderResultTable() does but you can set that line up like this:
page.setAttribute("href", "javascript:RenderResultTable('" + page.innerHTML + "')");
I believe that should do the trick.
EDIT: Shouldn't you be using i++ in your loop instead of ++i? I think what you have right now will give 2 as the first page number. Please correct me if I am wrong.
EDIT: page.innerHTML will need to be escaped by this functions and then unescaped the in the RenderResultTable() function. escape() and unescape(). This is to prevent JavaScript injections and/or accidental bugs.
Related
Is there anyway to use jQuery to dynamically set the attributes of HTML elements that are stored in variables?
For example, at one point in my application, a user creates a varying number of select input fields. For eventual processing by PHP, the elements need to be named in the format name='input'+siteNumber+'['+x+']', where x is the number of elements created in a for loop.
Here's a rough sketch of what I'm thinking needs to be done - THIS IS NOT FUNCTIONAL CODE, IT IS ONLY AN ILLUSTRATION.
$(".number_select").change(function(){
numberFound = $(this).val();
siteNumber = $(this).parent().attr('data-site_number');
//HERE'S THE INPUT TO BE NAMED
selectInput = "<select></select>";
this['inputArray' + siteNumber] = [];
for(x = 1; x <= numberFound; x++){
//THIS IS WHAT I'D LIKE TO ACCOMPLISH - SETTING THE ATTRIBUTE - THOUGH THIS UNDERSTANDABLY DOES NOT WORK IN THIS PARTICULAR FORMAT
this['inputArray' + siteNumber].push(selectInput.attr("name", "species"+siteNumber+"["+x+"]"));
};
$(this).parent().append(this['inputArray' + siteNumber]);
};
Thank you.
Thanks everyone - I actually ended up deciding to handle this a little differently, but it works perfectly - rather than storing the elements in variables, I used a function instead...
function inputs(siteNumber, x){
return ("<select name='selectInput"+siteNumber+"["+x+"]'>"+list+"</select>");
};
$(".number_select").change(function(){
numberFound = $(this).val();
siteNumber = $(this).parent().attr('data-site_number');
this['inputArray' + siteNumber] = [];
for(x = 1; x <= numberFound; x++){
this['inputArray' + siteNumber].push(inputs(siteNumber, x));
};
$(this).parent().append(this['inputArray' + siteNumber]);
};
Don't know why I didn't think of this in the first place, it seems obvious to me now. Oh well, live and learn.
To vaguely answer your question, you can dynamically generate an element and use jQuery's attr for adjusting the name attribute pretty easily like so.
var select = $('<select>').attr('name', 'add-name-here');
$('<option>').attr('value', 'some-value').text('Option').appendTo(select);
$('#wrapper').html(select);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="wrapper"></div>
Which outputs
<select name="add-name-here">
<option value="some-value">Option</option>
</select>
In your case, instead of adding it to #wrapper you would build up the select box as you need and append it to whichever select box has the change? Not sure your specific use case. Hope it helps.
I'm learning JS but have hit a roadblock. I have links that have the attribute "number". I'd like to extract the value of "number" from each link, set it as a new variable, and then assign an onclick action to each link incorporating the corresponding value. I've been able to extract each value but don't know how to use them in the onclicks.
HTML
<a class="button call" href="#" number="6135555556">Call pager</a>
<a class="button call" href="#" number="6135555555">Call cell</a>
JS
var data = document.getElementsByClassName("call");
var numbers = '';
for (var i = 0; i < data.length; i++) {
numbers += data[i].getAttribute("number");
numbers[i].onclick = console.log("call " + numbers[i]);
}
If you want to the particular value on click of particular link then you can use this code.
var data = document.getElementsByClassName("call");
var numbers = [];
for (var i = 0; i < data.length; i++) {
data[i].onclick = getNumber;
}
function getNumber(){
numbers.push(this.dataset['number']);
alert(this.dataset['number']);
}
Here is the DEMO
There is no number property on anchor tag, so for your need we can use data-* property which allows you to store needful information on html.
This may not be entity correct, but assuming what you wanted was to console log the contained phone number whenever a link was clicked, there are probably 3 main changes you'd want to look at.
1) I'm guessing you wanted to connect your onclick event to the link element with the number in it data[i], rather to the number itself?
2) += will concatenate each found value on to the previous one. This may be what you wanted, although in the below code I've changed it only to log the current number
3) onclick expects to be passed a function, which it will then run when the click event is fired. Wrapping your console log in a function provides it to the onClick in the format it expects.
Assuming all that's right, the js to work with the above links should look something like this:
var data = document.getElementsByClassName("call");
for (var i = 0; i < data.length; i++) {
data[i].onclick = function() { console.log("call " + this.getAttribute("number")); }
}
Hope that helps :)
Edit: Updated the code to fix the bug james montagne pointed out below. The getAttribute is now performed within the context of the click event, meaning the issue with scoping is avoided. Sorry about that, completely missed the issue.
I have a checkbox contained within a form on my page. When the user clicks a button I need to find out which items in the checkbox have been selected.
I can get this to work with the following code without ay problems.
for (i=0; i < Form3.CBox1.length; i++)
if (Form3.CBox1[i].checked)
{
Answer = Answer + Form3.CBox1[i].value + ",";
}
alert(Answer);
The problem I have is that I call the above function several times on my page and I want to pass in variables instead of hard coding the name of the form and checkbox. Everytime I do this Javascript will not return anything. The variables vCurrForm & vCurrCBox, in the following code, have been set earlier in another function and I have tested to ensure that they are set correctly but I still can't get this piece of code to work.
for (i=0; i < vCurrForm.vCurrCBox.length; i++)
if (vCurrForm.vCurrCBox[i].checked)
{
Answer = Answer + vCurrForm.vCurrCBox[i].value + ",";
}
alert(Answer);
Any help would be greatly appreciated. Thanks
When working with variables as the keys to an object, you need to use the array syntax (ie. []s), which on its own would give us this (still broken) code:
for (i=0; i < vCurrForm[vCurrCBox].length; i++)
{
if (vCurrForm[vCurrCBox][i].checked)
{
Answer = Answer + vCurrForm[vCurrCBox][i].value + ",";
}
}
alert(Answer);
The problem is that vCurrForm is still being treated as a regular old variable, even though it's the string name of that variable. Because of this, you need to reference it from its parent; window:
for (i=0; i < window[vCurrForm][vCurrCBox].length; i++)
{
if (window[vCurrForm][vCurrCBox][i].checked)
{
Answer = Answer + window[vCurrForm][vCurrCBox][i].value + ",";
}
}
alert(Answer);
Without seeing how you are declaring and setting these values it is very difficult to ascertain the problem. It could be related to the type of object the variables are being set to, or their scope. Here are some things to check:
Ensure the variable vCurrForm.vCurrCBox is an array.
Ensure that vCurrForm and vCurrCBox are declared in a scope that is accessible to the function being called.
In this case make sure you are setting vCurrForm to a Form Object and vCurrCBox to an array of checkbox controls.
Looking at the code provided almost makes me think that the variable being referenced is for a single item (Current Checkbox). Your probably not going to get the results you are looking for in that case.
Something else to consider if it is possible would be to use JQuery to more easily grab the checked boxes and concatenate their values. In JQuery your code could be done with something like:
var Answers = "";
$("input[type='checkbox']:checked").each(function() { Answers += $(this).val() + ", "; });
Or, a better solution is to pass reference to the array that contains elements, instead of matching it with strings. For example:
function getAnswers(items) {
for (var i = 0; i < items.length; i++)
{
if (items[i].checked) {
Answer = Answer + items[i].value + ",";
}
}
}
Thank you ever so much for all you help. I've seen the error of my ways.
The following worked for me
**for (i=0; i < document[vCurrForm][vCurrCBox].length; i++)
if (document[vCurrForm][vCurrCBox][i].checked)
{
Answer = Answer + document[vCurrForm][vCurrCBox][i].value + ",";
}**
It appears that JavaScript auto-converts certain special characters into HTML entities when outputting content via the innerHTML() function. This is a problem, since I need to be able to output < and > without converting to gt; and lt;
Can this auto-conversion be prevented, reversed, or escaped? So far, no matter what I do, < and > are always automatically encoded into HTML entities.
Example code:
function DisplayQueries() {
var IDs = ['AllOpenedINC','AllOpenedCRQ','AllClosedINC','AllClosedCRQ','SameDayINC','SameDayCRQ','NotSameDayINC','NotSameDayCRQ',
'StillOpenINC','StillOpenCRQ','OpenOldINC','OpenOldCRQ','OtherQueuesINC','OtherQueuesCRQ']
for (var i = 0; i < IDs.length; i++) {
if (eval(IDs[i]))
document.getElementById(IDs[i]).innerHTML = eval(IDs[i]);
}
}
Example query variable:
AllOpenedINC = "('Company*+' = \"test\" OR 'Summary*' = \"%test%\") AND ('Submit Date' >= \"" + theDate +
" 12:00:00 AM\" AND 'Submit Date' <= \"" + theDate + " 11:59:59 PM\")" + nameINC;
You should focus on what you want to accomplish as a result, rather than the way of doing it. innerHTML() does encode, innerText() and textContent() do encoding too. So you should decode your strings if you want them as < or > back.
You can use this unescapeHTML() function to get your results as you want them.
function unescapeHTML() {
return this.stripTags().replace(/</g,'<').replace(/>/g,'>').replace(/&/g,'&');
}
I hope this helps. I've copied it from Prototype.
I think your question is based on a false premise. Just make a very simple test:
document.getElementById("testdiv").innerHTML = '<h1><em>Hello</em></h1>';
if this works fine then the problem is not on the JS side, instead you use some other components in your system which HTML-encode your characters.
I figured out what's going on. There's no easy way to prevent innerHTML from converting special characters to HTML entities, but since the problem was surfacing when copying the content of a DIV to the clipboard (using IE-only JS, which works since this is in a government environment where everyone has to use IE), I just used the replace() function to re-convert the HTML entities back to < and >.
You can use jquery and .append()
What I want to do is that: a webpage with continuously updating content. (In my case is updating every 2s) New content is appended to the old one instead of overwriting.
Here is the code I have:
var msg_list = new Array(
"<message>Hello, Clare</message>", "<message>Hello,Lily</message>",
"<message>Hello, Kevin</message>", "<message>Hello, Bill</message>"
);
var number = 0;
function send_msg()
{
document.write(number + " " + msg_list[number%4]+'<br/>');
number = number + 1;
}
var my_interval = setInterval('send_msg()', 2000);
However, in both IE and Firefox, only one line is printed out, and the page will not be updated anymore. Interestingly in Chrome, the lines are being printed out continuously, which is what I am looking for.
I know that document.write() is called when the page is loaded according to this link. So it's definitely not the way to update the webpage continuously. What will be the best way to achieve what I want to do?
Totally newbie in Javascript. Thank you.
Lily
I would have a div or some other container, like this:
<div id="msgDiv"></div>
Then write to it like using .innerHTML, like this:
var msg_list = new Array(
"<message>Hello, Clare</message>", "<message>Hello,Lily</message>",
"<message>Hello, Kevin</message>", "<message>Hello, Bill</message>"
);
var number = 0;
function send_msg()
{
document.getElementById("msgDiv").innerHTML += number + " " + msg_list[number%4]+'<br/>';
number++;
}
var my_interval = setInterval(send_msg, 2000);
You can see a working example of this here
You can append to the innerHTML property:
var number = 0;
function send_msg()
{
document.getElementById('console').innerHTML += (number + " " + msg_list[number%4]+'<br/>');
number = number + 1;
}
This code will append the message to an element with an id of console, such as
<div id="console"></div>
By the way, it is bad practice to call setInterval with a string.
Instead, pass the function itself, like this:
var my_interval = setInterval(send_msg, 2000);
I would start by looking at the jQuery library. This will save you a lot of pain.
What you want to do is keep inserted lines into a table, using eg:
$('table tbody').append('<tr><td>some value</td></tr>');
This would be an excellent opportunity for you to learn a little DOM programming.
Using the DOM to update the page should result in less overhead than simply concatenating more HTML into it. Find the node you want to put the updates into, and do an appendChild on each subsequent addition.
The answers to this question may be helpful: What's a simple way to web-ify my command-line daemon?