I have a list of items (districts) on a page, and an iframe pulling in a map on the same page. When a user clicks on one of the districts, the JavaScript changes the source of the iframe to show a map of the district the user clicked.
My current code simply uses an "onclick" for each district, which then calls a function to change the source of the iframe.
I am wondering if I can simplify this code at all, possibly by using a loop? If I have 15 more districts to add to the page, will I have to add another "onclick" and another function for each one? Or is there an easier way that I am missing?
Simplified HTML:
<div id="districtlist">
Allen
Barren
Butler
<!--about 15 more links to follow-->
</div>
<iframe id="maparea" src="http://www.reddit.com"></iframe>
Javascript:
var a = document.getElementById("districtlist")
a.getElementsByTagName("a")[0].onclick = Allen;
a.getElementsByTagName("a")[1].onclick = Barren;
a.getElementsByTagName("a")[1].onclick = Butler;
//more lines...
function Allen() {
document.getElementById("maparea").src="http://www.youtube.com";
}
function Barren() {
document.getElementById("maparea").src="http://www.mentalfloss.com";
}
function Butler() {
document.getElementById("maparea").src="http://www.amazon.com";
}
//more functions...
I believe you could try this
var elems = document.getElementById("districtlist").querySelectorAll('a');
[].forEach.call(elems, function(elem) {
elem.onclick = function() {
var url = '';
switch(elem.innerText) {
case 'Allen':
url = "http://www.mentalfloss.com";
break;
case 'Barren':
url = "http://www.mentalfloss.com"
break;
case 'Butler':
url = "http://www.amazon.com";
break;
}
document.getElementById("maparea").src=url;
}
});
Related
This a basic question (Posting this again, as it was not re-opened after I updated the question). But I couldn't find any duplicates on SO.
This is a script I intend to use in my project on different pages. The purpose is to override the default ID shown in a span element to the order number from the URL parameter session_order. This doesn't affect anything and only enhances the UX for my project.
scripts.js (loaded in the header):
function get_url_parameter(url, parameter) {
var url = new URL(url);
return url.searchParams.get(parameter);
}
And in my HTML template, I call the function this way,
<div onload="this.innerHTML = get_url_parameter(window.location.href, 'session_order');">24</div>
Also tried this,
<div><script type="text/javascript">document.write(get_url_parameter(window.location.href, 'session_order'));</script></div>
When the page is rendered, nothing changes. No errors or warnings in the console either for the first case.
For the second case, console logged an error Uncaught ReferenceError: get_url_parameter is not defined, although script.js loads before the div element (without any errors).
Normally, I'd do this on the server-side with Flask, but I am trying out JavaScript (I am new to JavaScript) as it's merely a UX enhancement.
What am I missing?
Try this:
// This is commented because it can't be tested inside the stackoverflow editor
//const url = window.location.href;
const url = 'https://example.com?session_order=13';
function get_url_parameter(url, parameter) {
const u = new URL(url);
return u.searchParams.get(parameter);
}
window.onload = function() {
const el = document.getElementById('sessionOrder');
const val = get_url_parameter(url, 'session_order');
if (val) {
el.innerHTML = val;
}
}
<span id="sessionOrder">24</span>
Define the function you need for getting the URL param and then on the window load event, get the URL parameter and update the element.
Here you go. Try to stay away from inline scripts using document.write.
function get_url_parameter(url, parameter) {
var url = new URL(url);
return url.searchParams.get(parameter);
}
window.addEventListener('load', function() {
const url = 'https://yourpagesdomain.name/?session_order=hello'; //window.location.href;
const sessionOrder = get_url_parameter(url, 'session_order');
document.getElementById('sessionOrder').innerText = sessionOrder;
});
<div id="sessionOrder"></div>
The order of your markup and script matters...
<div></div>
<script>
function get_url_parameter(url, parameter) {
var url = new URL(url);
return url.searchParams.get(parameter);
}
</script>
<script>
document.querySelector('div').innerHTML = get_url_parameter('https://example.com?session_order=2', 'session_order');
</script>
I am trying to generate a view based on the current user's group name. Group Name I am gathering from the custom list.
My question is how to apply the gathered group name to 'Group Name' column as a view parameter.
The only solution I figured:
I have created a view with a parameter.
I have added an HTML Form Web Part into the same page and connected it to the list view (sending the value to the parameter via web part connection). Then with a window.onload function I gather the current user's group name and pass this value via Form Postback function. But since the Postback function triggers full page reload, it falls into the endless loop of form submission > page reload.
Another way I have tried is attaching a click event listener to the BY MY GROUPS tab and it works perfectly, but the only disadvantage is that the page reloads each time user clicks on this tab, which I would like to avoid.
So the solution that I need is a way to post the form without a page reload.
Another option suggested here is to use CSR (client side rendering), but that has its own problems:
This code does not work as it is supposed to. In the console it shows me correct items, but the view appears untouchable.
Even if it worked, the other column values are still viewable in the column filter, as in this screenshot:
So, it seems that CSR just hides items from the view (and they are still available). In other words its behavior is different from, for example, a CAML query.
Or am I getting it wrong and there's something wrong with my code?
Below you can find my CSR code:
<script type='text/javascript'>
(function() {
function listPreRender(renderCtx) {
SP.SOD.executeFunc('sp.js', 'SP.ClientContext', function() {
var currUserID = _spPageContextInfo.userId;
var cx = new SP.ClientContext('/sites/support');
var list = cx.get_web().get_lists().getByTitle('Group Members');
var items = list.getItems(SP.CamlQuery.createAllItemsQuery());
cx.load(items, 'Include(_x006e_x50,DepID)');
cx.executeQueryAsync(
function() {
var i = items.get_count();
while (i--) {
var item = items.getItemAtIndex(i);
var userID = item.get_item('_x006e_x50').get_lookupId();
var group = item.get_item('DepID').get_lookupValue();
if (currUserID === userID) {
var rows = renderCtx.ListData.Row;
var customView = [];
var i = rows.length;
while (i--) {
var show = rows[i]['Group_x0020_Name'] === group;
if (show) {
customView.push(rows[i]);
}
}
renderCtx.ListData.Row = customView;
renderCtx.ListData.LastRow = customView.length;
console.log(JSON.stringify(renderCtx.ListData.Row));
break;
}
}
},
function() {
alert('Something went wrong. Please contact developer')
}
);
});
}
function registerListRenderer() {
var context = {};
context.Templates = {};
context.OnPreRender = listPreRender;
SPClientTemplates.TemplateManager.RegisterTemplateOverrides(context);
}
ExecuteOrDelayUntilScriptLoaded(registerListRenderer, 'clienttemplates.js');
})();
</script>
I am creating html page which needs to create a list of links dynamically on a click of button. I know how to create this list when number of links to be created is known before like this:
//For 4 tags:
var mydiv = document.getElementById("myDiv");
var aTag = document.createElement('a');
aTag.innerHTML = "link1 text";
aTag.setAttribute('onclick',"func()");
mydiv.appendChild(aTag);
var bTag = document.createElement('b');
bTag.innerHTML = "link2 text";
bTag.setAttribute('onclick',"func()");
mydiv.appendChild(bTag);
var cTag = document.createElement('c');
cTag.innerHTML = "link3 text";
cTag.setAttribute('onclick',"func()");
mydiv.appendChild(cTag);
var dTag = document.createElement('d');
dTag.setAttribute('onclick',"func()");
dTag.innerHTML = "link4 text";
mydiv.appendChild(dTag);
But the problem is that the count will be known at run time and also on function call i need to identify the id of link that invoked function.. Can anybody help?
I don't know weather you receive or not the HTML to be shown in the anchor, but anyway, this should do the work:
function createAnchor(id, somethingElse) {
var anchor = document.createElement('a');
anchor.innerHTML = "link" + id + " text";
anchor.setAttribute("onclick", "func()");
return anchor;
}
Then you call the function like this:
function main(num_anchors) {
var mydiv = document.getElementById("myDiv");
for (var i = 0; i < num_anchors; i += 1) {
mydiv.appendChild(createAnchor(i));
}
}
Of course this code can be improved, but this is just for show how can this be possible.
Yes it is possible to do this at runtime .
JQuery provides very useful dom manipulation . So you can traverse the dom , filter what you need ..
you can find a lot of useful functions here .
http://api.jquery.com/category/traversing/
It would look something like this.
$( document ).ready(function() {
$( "a" ).each(function( index ) {
// enter code here..
}
});
document.ready gets invoked once the DOM has loaded.
Let's say a string contains http://google.com. When I linkify the whole string (that has both unlinked URLs and linked URLs, like the one shown above), it will become http://google.com">http://google.com</a>.
Is there a way to revert the incorrect links (which are the ones already linked before linkifying) back to http://google.com?
I found in WordPress, that it uses $ret = preg_replace("#(]+?>|>))]+?>([^>]+?)#i", "$1$3", $ret); (in wp-includes/formatting.php) to accomplish this. Can someone help me to do this in JavaScript?
Have a look at this http://jsfiddle.net/mplungjan/V5Qca/
<script>
function linkify(id,URL) {
var container = document.getElementById(id);
var links = container.getElementsByTagName("a");
if (links.length ==0) {
container.innerHTML=container.innerHTML.link(URL);
return;
}
var nodes = container.childNodes;
for (var i=nodes.length-1;i>=0;--i) {
if (nodes[i].nodeType ==3 && nodes[i].parentNode.nodeName!="A") {
var link = document.createElement("a");
link.href=URL;
link.innerHTML=nodes[i].nodeValue;
container.replaceChild(link, nodes[i]);
}
}
}
window.onload=function() {
linkify("div1","http://www.google.com/");
}
</script>
<div id="div1">
this is a test of replacing text with links with linkified content
</div>
I have an iframe and couple of tables on my aspx page. Now when the page loads these tables are hidden. The iframe is used to upload file to database. Depending on the result of the event I have to show a particular table on my main page (these tables basically have "Retry","next" buttons...depending on whether or not the file is uploaded I have to show respective button).
Now I have a JavaScript on the "onload" event of the iframe where I am hiding these tables to start with. When the control comes back after the event I show a particular table. But then the iframe loads again and the tables are hidden. Can any one help me with this problem. I don't want the iframe to load the second time.
Thanks
mmm you said you're on aspx page,
I suppose that the iframe do a postback, so for this it reload the page.
If you can't avoid the postback, you've to set a flag on the main page just before posting back, and check against that while you're loading...
...something like:
mainpage.waitTillPostBack = true
YourFunctionCausingPostBack();
..
onload=function(){
if(!mainpage.waitTillPostBack){
hideTables();
}
mainpage.waitTillPostBack = false;
}
I am not sure what your problem is, but perhaps your approach should be a little different. Try putting code into the iframe what would call functions of the parent. These functions would display the proper table:
<!-- in the main page --->
function showTable1() {}
<!-- in the iframe -->
window.onload = function () {
parent.showTable1();
}
This would put a lot of control into your iframe, away from the main page.
I don't have enough specifics from your question to determine if the iframe second load can be prevented. But I would suggest using a javascript variable to check if the iframe is being loaded a second time and in that case skip the logic for hiding the tables,
This is my code
function initUpload()
{
//alert("IFrame loads");
_divFrame = document.getElementById('divFrame');
_divUploadMessage = document.getElementById('divUploadMessage');
_divUploadProgress = document.getElementById('divUploadProgress');
_ifrFile = document.getElementById('ifrFile');
_tbRetry = document.getElementById('tbRetry');
_tbNext=document.getElementById('tblNext');
_tbRetry.style.display='none';
_tbNext.style.display='none';
var btnUpload = _ifrFile.contentWindow.document.getElementById('btnUpload');
btnUpload.onclick = function(event)
{
var myFile = _ifrFile.contentWindow.document.getElementById('myFile');
//Baisic validation
_divUploadMessage.style.display = 'none';
if (myFile.value.length == 0)
{
_divUploadMessage.innerHTML = '<span style=\"color:#ff0000\">Please select a file.</span>';
_divUploadMessage.style.display = '';
myFile.focus();
return;
}
var regExp = /^(([a-zA-Z]:)|(\\{2}\w+)\$?)(\\(\w[\w].*))(.doc|.txt|.xls|.docx |.xlsx)$/;
if (!regExp.test(myFile.value)) //Somehow the expression does not work in Opera
{
_divUploadMessage.innerHTML = '<span style=\"color:#ff0000\">Invalid file type. Only supports doc, txt, xls.</span>';
_divUploadMessage.style.display = '';
myFile.focus();
return;
}
_ifrFile.contentWindow.document.getElementById('Upload').submit();
_divFrame.style.display = 'none';
}
}
function UploadComplete(message, isError)
{
alert(message);
//alert(isError);
clearUploadProgress();
if (_UploadProgressTimer)
{
clearTimeout(_UploadProgressTimer);
}
_divUploadProgress.style.display = 'none';
_divUploadMessage.style.display = 'none';
_divFrame.style.display = 'none';
_tbNext.style.display='';
if (message.length)
{
var color = (isError) ? '#008000' : '#ff0000';
_divUploadMessage.innerHTML = '<span style=\"color:' + color + '\;font-weight:bold">' + message + '</span>';
_divUploadMessage.style.display = '';
_tbNext.style.display='';
_tbRetry.style.display='none';
}
}
tblRetry and tblNext are the tables that I want to display depending on the result of the event.