I am trying to add a second class to my element on click
Before
<div class="foo1">
<a class="class1" >Text</a>
</div>
After
<div class="foo1">
<a class="class1 class2" >Text</a>
</div>
here are my javascript codes; both of them work:
either this one (thanks to #Shomz)
var elements = document.getElementsByClassName('class1 ');
for (var i = 0; i < elements.length; i++) {
var element = elements[i];
element.className += ' class2';
}
or this one (thanks to #t-j-crowder)
[].forEach.call(document.querySelectorAll(".class1 "), function(element) {
element.className += " class2";
});
Question
The site allows the users to click on class1 and change it to class1 class2 . However, by running these codes, the class1 only temporarily changes to class1 class2, I mean the clicking event is not implemented, it has only visually changed. When the site is reloaded, it is back to the previous state. How to apply a fix to change permanently the class by clicking on it?How to achieve the class changing through a click event and to record this permanently? How can these js codes record this click and change it permanently?
Ok so based upon your comment you need to communicate the change to a server, then when the page loads it needs to request the data back from the server to reflect any stored changes. Theres a number of ways to do this depending on your programming capability, preference in language and compatibility requirements.
The most popular method would likely be a data file that is written dynamically by a php script. When the page is loaded it would generate your content based upon the contents of the datafile on the server(not to be confused with your HTML page). When the user modifies and element your page would call the php script using the AJAX POST method in javascript, then the php script would read the existing datafile, modify it accordingly and save it to the server.
For starters you will need a web server with PHP; if your testing locally MAMP is a good choice for Mac and I believe they now do a windows version as well.
Your would have 3 files( presuming all of your css and js is written in your HTML file):
index.htm
data.js
update.php
Assuming a linear list of div elements, each with a switchable class and child content.
index.htm
<html>
<head>
<script src='datafile.js'></script>
<script>
window.addEventListener('load',onload,false); //register the on load handler
function onload(){
var body = document.getElementsByTagName('body')[0];
var newelement;
for(var i = 0; i < elements.length; i++){
//for each element in the data file
newelement = document.createElement('div');
//create a div element
newelement.innerHTML = elements[i].content;
//place the content within the div
newelement.className = elements[i].class;
//set our classes
body.appendChild(newelement);
//add the div to the body
newelement.addEventListener('click',onclick,false);
//add a click listener to the element
}
}
function onclick(){ //on click function
var elementIndex = elements.indexOf(this); //this will be the element in the callback context
//modify class
postchange(elementIndex,classList);
}
function postchange(element,class){
// new post method
// data = {'element':element,'class':class};
// post data to update.php
}
</head>
<body>
</body>
</html>
data.js
var elements = [
{
"content":'Hello I am div 1',
"class":'classA'
},
{
"content":'Hi, I have been known as div 2... but you can call me Tim',
"class":'classA classB'
}
]
I've left the PHP out, it's not my main language so I don't feel happy improvising any code for you without looking it up and testing it first. That and it shouldn't be too hard for you to find information on POST methods on Stack Overflow.
Similarly I left the POST method in the JS out because the standard JS method is a little overcomplicated. Look up the jQuery POST method which is much more simple, again examples should be easy to find.
Related
Background My page creates a list of objects based on rows of an SQL Database. For each object, a DIV is dynamically generated that contains a few items including a LinkButton and a further child DIV that is initially hidden. I want the link button to toggle the child DIV's hidden property. The JavaScript is not dynamically generated and is included in the ASPX page.
Problem I don't know how to make this generated LinkButton fire JavaScript that is included in the ASPX page and pass in the correct DIV's ID.
I'm guessing I need to add an attribute to the button like so:
myButton.Attributes.Add(reference to JS function + parameter of DIV's ID)
Maybe like:
myButton.Attributes.Add("onclick", "Show_Hide_Display('"<%="' +idString+ '".ClientID%>"')");
Where the button is given an attribute of a JS onClick handler pointing to the function "Show_Hide_Display" and a parameter of a DIV's ID that is calculated as the rendered ID. This syntax is incorrect though.
How do I write this so it calls 'Show_Hide_Display' and passes the ID of the current child DIV? All of the DIVs have the same ID apart from a number that references their row number, for example '"myDiv_" + counter.ToString'
The JavaScript I am trying to add a call to on the button:
function Show_Hide_Display(divID) {
var div = document.getElementById(divID);
var style = document.defaultView.getComputedStyle(div);
var display = style.getPropertyValue('display');
if (display == '' || display == 'block') {
div.style.display = 'none';
} else {
div.style.display = 'block';
}
}
Use the following syntax ...
myButton.Attributes.Add("onclick", "Show_Hide_Display(this.id);");
the above syntax allows to call the function with id as its parameter.
suggestion:
Try to write a common function which does not depend on generated ids of controls.
If this is not useful for your requirement, please post your code which might gives me a better idea.
If you are using jQuery, you could you jQuery delegate method.
$(document).on("click", "div.parent", function(){
var subDivId = getSubDivByParent(this);
Show_Hide_Display(subDivId);
};
You need to implement getSubDivByParent according your DOM structure.
If you are not using jQuery, you need to attach event yourself. For each dynamically generated element. You need to manually add following script in your server code to register event.
... your html code ...
<script>
var elem = document.getElementById('new-created-element');
elem.addEventListener("click", function(){
var subDivId = getSubDivByParent(this);
Show_Hide_Display(subDivId);
};)
</script>
My suggestion is use jquery to achieve the functionality.
My solution works if you want to toggle the immediate div for the link.just call onclientclick method to toggle the div.
in linkbutton onclientclick="Show_Hide_Display(this)"
function Show_Hide_Display(id) {
$(id).next('div').toggle();
}
I hope this helps you .. Thanks
After much Googling, I resort to the chance at ridicule and moderation on Stack Exchange.
What I am trying to do sounds simple enough. I want to make a <div> id/class that will link automatically create a link to itself via some kind of scripting.
Let me put down some pseudocode, before I make it sound more complicated than it is:
#Let div.link = xxx.html
#Let div.pic = xxx.png/jpg
for div in HTMLdocument:
if div.class == "autolink":
div = "<img src=\"mysite/" + div.pic + ">"
Now, obviously that's Python pseudocode, but I am familiar(ish) with PHP and Javascript. Basically, I want to make the div generate an HTML link without having to actually type out the tags and links for every given div on a web page. I want to be able to type, in my index.html:
<html>
<head></head>
<body>
<div class = "1"></div>
<div class = "2"></div>
</body>
</html>
and then to be presented with a page that has the two divs linked, imaged, and, preferably, formatted.
Like I said, the problem seems simple, but I can't seem to get it to work right, in any language. This seems like a thing that would be very useful for begiiner web designers.
PERSONAL NOTE:
I would preferably like to see a solution in PHP or Javascript, but if you are good with Django and want to show me how to get it done in that, I would be just as grateful!
=========================================
EXAMPLE:
Let's say you have a browser based RPG, and you want to show your player's inventory. The Inventory page would display the items in a players inventory, complete with a link and image, based on whatever was in that user's inventory page. It would look like this (this is VERY rough output, Statements tagged in #these# are not code, and should be interpereted as what they describe):
<h1>User's Inventory:</h1>
<p><div class = "item_1">#Link to page of 'item_1', image of 'item_1'#</div></p>
<p><div class = "item_2">#Link to page of 'item_2', image of 'item_2'#</div></p>
The above would display, roughly, a header that said "User's Inventory", and then display a linked image of item_1, followed by a newline and then a linked image of item_2, where said items would be in a separate file OR a list that lists all the items and their respective links and images.
You can use jquery, and when page dom is loaded, you cycle through each div that has the class autolink and do your manipulations (add your desired html into each div). You can use the id of each div to place data inside. You can use a prefix to that id values for different types of data. For example, im using "inventory_" as a prefix.
<h1>User's Inventory:</h1>
<p><div class = "autolink" id="inventory_item_1">#Link to page of 'item_1', image of 'item_1'#</div></p>
<p><div class = "autolink" id="inventory_item_1">#Link to page of 'item_2', image of 'item_2'#</div></p>
then jquery on document ready:
<script type="text/javascript">
$(document).ready(function ()
{
// define your website here
var mysite = "http://www.example.com/";
// this will cycle through each div with class autolink. using `this` to reffer to each.
$(".autolink").each(function () {
// we get for div with id="inventory_item_1" ...
var mylink = $(this).attr('id').replace("inventory_",""); // ... a value item_1
var myimagesrc = $(this).attr('id').replace("inventory_","image_"); // ... image_item_1
$(this).html('<img src="'+mysite+'images/'+myimagesrc+'.jpg">');
// the above will add html code of this format:
// <img src="http://www.example.com/images/image_item_1.jpg">
});
});
</script>
try it here:
http://jsfiddle.net/5APhT/2/
I'll give a sample in php. Here is an example if you already have a set of links to use
<?php
//Create a multidimensional array to store all you need to create links
$links['1'][]="http://www.yahoo.com";
$links['1'][]="yahoo.com";
$links['2'][]="http://www.facebook.com";
$links['2'][]="yahoo.com";
$links['3'][]="http://www.google.com";
$links['3'][]="yahoo.com";
foreach($links as $class => $innerArray){
$link=innerArray[0];
$linktext=innerArray[1];
echo "<div class='$class'><a href='$link'>$linktext</a></div>";
}
?>
This creates the divs for you so you don't have to add them in advance.
You can add images in the same manner
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How may I reference the script tag that loaded the currently-executing script?
I am trying to make a javascript function that includes a html doc on a page via AJAX, as a way of making a PHP-esque include() with no serverside interaction. I want the script to include the file at the location on the page the function is called from. Here's my function (assuming ajax is a valid xmlhttp object):
function include(src, elem){
ajax.open('GET', src, false);
ajax.send(null);
elem.innerHTML = ajax.responseText;
}
So this would print the contents of "src.html" in the div when it is clicked:
<div onclick="include('src.html', this);"> </div>
But I want it to load when the page does. Considering there is no onload event for divs I have to include the script in the div, which is fine:
<div id=write>
<script>include('src.html', this);</script>
</div>
But then the script has no reference to the div it is called from. Sure I could put an id on the div and pass that to the function, but I don't want to. I want to be able to call this from any unidentified element. Any ideas?
You could change your div (or other element(s)) to use a data- attribute to specify what script to run:
<div data-include="src.html"></div>
And then run a script onload of the page (or in a script block just before the closing </body> tag) that finds all elements with that attribute.
var elements = document.querySelectorAll("[data-include]");
for (var i = 0; i < elements.length; i++)
include(elements[i].getAttribute("data-include"), elements[i]);
Here's a demo of the above (with a dummy include() function that just puts the required source url string in the element rather than doing Ajax, but it shows the elements are selected correctly): http://jsfiddle.net/nnnnnn/gm2LN/
For simplicity I've used querySelectorAll() to select the elements, but note that it isn't supported in IE7 and older. But obviously you can substitute whatever other element selection method you like if you want or need to support older browsers.
Here:
<div id=write>
<script>include('src.html', this);</script>
</div>
"this" points to the window object.
I think of putting an id to the script element and doing something like this:
<div id=write>
<script id='test'>include('src.html', document.getElementById('test').parentNode);</script>
</div>
Now elem in "include" function will point to the div containing the script element. In this case you are still relying on id but not on the div's side
When the page is loaded, all scripts will be executed sequencially, as soon as they are parsed. Therefore, you just need to get the last script that is apparent in the DOM to get the currently executed script:
var script = document.scripts[document.scripts.length-1];
ajax(url, function successCallback(html) {
script.insertAdjacentHTML("afterend", html);
});
(Demo to test - notice that document.scripts needs FF 9+)
However, I see no reason not to use serverside include().
nnnnnn was on the money, but I modified it ever so softly. I ended up making an include tag with a src attribute. On pageload I loop through all the "include" tags and fill them with the data from their src attribute:
function include(src, elem){
ajax.open('GET', src, false);
ajax.send(null);
elem.innerHTML = ajax.responseText;
}
window.onload = function(){
var includes = document.getElementsByTagName('include');
for(var i = 0; i <= includes.length; i++){
var elem = includes[i];
var src = elem.getAttribute('src');
include(src, elem);
}
}
Then anywhere I want to include a html file I just include my custom element:
<include src='includeme.html'> </include>
In practice this produces a bit of popup but for my application that's fine.
Thanks for the help!
Basically, i'm building a basic jquery modal plugin as practice, and as much as the many varieties out in the wild have been helpful for reference, I wasn't sure about the best method for pushing html into the modal that is being built in my jQuery.
This code is building my popups:
var container = $('<div class="container"></div>');
var header = $('<div class="modal"><div class="modal-header"></div></div>');
var content = $('<div class="modal-body"></div>');
var footer = $('<div class="modal-footer"><a class="secondary" href="#">Cancel</a><span id = "button-secondary-label">or</span><span class="green_btn"></span></div>');
$(".popup").append(container);
$(".container").append(header);
$(".modal").append(content);
$(".modal").append(footer);
In an html file that is calling the javascript file with the above code, I would like to pass html to modal-body. I know I could just write the following:
$(".modal-body").html("html goes here")
but I would like to make the plugin handle as much as possible, so what would be the best way to do the following:
in example.html:
...
<script type="text/javascript">
$(.popup).modal();
</script>
</head>
<body>
<div class="popup"><div class="body-text">I want this text in the .modal-body</div></div>
in the js file:
I would like to take the html that is in .body-text and move it into the .modal-body class, or something that will get me similar results.
Again, trying to accomplish this in the external js file, and not in example.html
It's common to use IDs (as it can be set as the href and can be used to point to the given content of a link) instead when trying to target DOm element from modal boxes. So you could do
Some content to be in the modal
Then just grab it and append it to the cmodal
$('#boo').appendTo(content);
You can also have an option so that it can be clone and left the original copy behind
$('#boo').clone().appendTo(content);
You can technically handle classes as well but after depends how your plugin is built. As you can grab all and generate a single modal content or create the multiple content to browse between using them.
$('.popup').each(function() {
$(this).appendTo(content);
});
var items = $('.popup'),
len = items.length,
cur = 0;
$next.click(function() {
cur++;
if (cur === len) cur = 0;
items.eq(cur).show();
});
I have a html component that includes some javascript.
The component is a file in a template engine, so it can be used
in the initial rendering of the whole html page
as stand-alone html rendered through an ajax request
The javascript should be applied to an object in the template, i.e. :
<div class="grid" >
<div class="item" id="item_13">
This is item 13
</div>
<div class="item" id="item_14">
This is item 14
</div>
</div>
<script type="text/javascript">
$(document).ready(function(){
$(HOW_DO_I_GET_PREVIOUS_ELEMENT???).someEffect(params)
})
</script>
I've checked this similar question but the best answers seem to rely on the current script being the last one in the 'scripts' variable as the next ones are not loaded yet. If I append the html and js with an ajax request, it will not be the case.
To be 100% clear : the question is about getting the previous object WITHOUT reference to any specific attribute : no unique id for the tag, no random id as there is theoretically always a chance it will show up twice, no unique class attribute,as exactly the same component could be displayed in another part of the HTML document.
Simple solution involving a two step process:
1) find out which element your script tag is
2) find the previous sibling of that element
in code:
<div id="grid">
<!-- ... -->
</div>
<script type="text/javascript">
var scripts = document.getElementsByTagName("script");
var current = scripts[scripts.length-1];
var previousElement = current.previousSibling;
// there may be whitespace text nodes that should be ignored
while(previousElement!==null && previousElement.nodeType===3) {
previousElement = previousElement.previousSibling; }
if(previousElement!==null) {
// previousElement is <div id="grid"> in this case
$(document).ready(function(){
$(previousElement).someEffect(params);
});
}
</script>
Is this good web programming? No. You should know which elements should have effects applied to them based on what you're generating. If you have a div with an id, that id is unique, and your generator can tell that if it generates that div, it will also have to generate the js that sets up the jQuery effect for it.
But let's ignore that; does it work? Like a charm.
If you can give your <script/> block an Id you could easily call prev() to get the previous element.
<script type="text/javascript" id="s2">
$(document).ready(function(){
$("#s2").prev().append("<h1>Prev Element</h2>");
})
</script>
Example on jsfiddle.
You will need to get a way to reference the script tag immediately after the "grid" div. As #Mark stated, the easiest way to do this is by giving the script tag a unique id. If this is beyond your control, but you do have control of the script contents (implicit by the fact that you are creating it) you can do something like this:
var UniqueVariableName;
var scripts = document.getElementsByTagName('script');
var thisScript = null;
for(var i = 0; i < scripts.length; i++){
var script = $(scripts[i]);
if(script.text().indexOf('UniqueVariableName') >= 0){
thisScript = script;
break;
}
}
if(thisScript){
thisScript.prev().append("<h1>Prev Element</h2>");
}
Hack? Yes. Does it Work? Also, yes.
Here's something that works in FF, Chrome and IE 8, untried anywhere else. It looks at the element before the last element on the page (which is the script being parsed), stores it locally (with a self calling function) so the load handler can use it.
http://jsfiddle.net/MtQ5R/2/
<div class="grid" >
<div class="item" id="item_13">
This is item 13
</div>
<div class="item" id="item_14">
This is item 14
</div>
</div><script>(function(){
var nodes = document.body.childNodes;
var prevSibling = nodes[nodes.length - 2];
$(document).ready(function(){
console.log( prevSibling );
})
})();</script>
Having said that. I still have to mention that you're tightly coupling the behavior (JS) and HTML, by putting them into the same file which kind of goes against the web flow of separating them. Also, I don't know how you'd expect this to work with an AJAX request since you're not just adding it to the HTML as it's being rendered. In that case, it would be very easy to get a reference to the html you just inserted though.