I'm building a website that is heavily built on ajax. Some of my JS comes as part of the pages that I load through ajax. The functions from the JS cannot be called from other JS scripts that has been loaded earlier. As I have understand it, it has to with the code not being really declared and that I could use eval() on the code. But that feels like waste of resources since the code runs and works aslong it don't need to work with code that is already declared.
My little short ajax page loader.
$(document).ready(function(){
var old = "home"
$("#topMenu a").on("click",function(){
if(typeof edit_menu !== 'undefined' && edit_menu){
return;
}
var link = $(this).attr("data-link");
//Load Ajax
LoadPage(link, old);
});
});
function LoadPage(link, old){
$.ajax({
url: "pages/" + link + ".php",
}).done(function(data){
$("#content").html(data);
});
Hide();
history.pushState(old,null,"?page=" + link);
}
If I login as admin I will then also have an admin JS file loaded as part of the DOM. The script calls a function in another JS file thats is loaded dynamically. The function doesn't run because the admin JS file is not aware of the new funciton.
The dynamically added JS file is a script tag part of other HTML code.
Example of dynamically added code.
<script src="/javascript/projects.js"></script>
<header>Projects</header>
<article>
<h1>First project</h1>
<section class="summary">
Lorem ipsum is da shit
</section>
<section class="text">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed diam orci, hendrerit a justo sit amet, egestas ullamcorper orci. Aliquam quis facilisis urna. Fusce blandit pellentesque elit. Vivamus ullamcorper luctus felis in rutrum. Nam quis facilisis mauris. Nunc iaculis sagittis sollicitudin. Ut imperdiet, purus et fermentum tempor, leo mauris feugiat libero, eu pulvinar odio felis sed tortor. Mauris vel libero orci. Suspendisse a mollis turpis. Maecenas egestas felis eget ultrices porta. Nulla non metus ut augue faucibus ultrices. Phasellus arcu magna, vulputate eget sollicitudin a, ullamcorper a ipsum. Suspendisse potenti. Pellentesque eget vulputate ipsum.</p> <p>Ut ultricies faucibus sapien, ut sodales turpis rhoncus molestie. Vivamus luctus auctor pellentesque. Phasellus ut ex vulputate, congue felis nec, pharetra odio. Ut ligula ante, luctus nec enim ac, lobortis ultrices elit. Quisque sed justo a nibh congue tempor sit amet ut mauris. In non enim nulla. Nulla et dolor sollicitudin, finibus ante eu, egestas purus. Phasellus sit amet eros dignissim, pellentesque elit tempor, sagittis eros. Donec sollicitudin velit ipsum, semper ultrices sapien blandit non. Phasellus vehicula orci in ipsum blandit hendrerit. Vestibulum facilisis dolor ac tincidunt fermentum.</p>
</section>
<span>Update text</span> <input type="checkbox" class="update_projects" data-id="First project" /><br /><button class="update_text">Update</button><input type="hidden" class="token" value="4926dd431992894a8364ca4d89733038be0cb0ec4897eb2a417637685554b6df40149522a858b5bfaaa91526b84718cdd54b301229371841dc2f022bbd0f804eaf31abb51caef55b26cca3209cc3b0838f194176f78f0931b2217669cd2912faa25a3c3e469ce686d79ac7a7852fbfee9d6d4dc5da18b499e703b4ef57fc88c1a99ccf8943af5853433f911ce276ff13e9ecbfb074d747f1a07f26c141f80383a149902dfe7469262724e2f67aae48d9919d486855a892b17681660ab3e0d25f98e714c3d98cc903" /><input type="hidden" class="id" value="1" /><br /><input type="text" name="tag" class="tag" value="php" />
</article><article>
<h1>Secons project</h1>
<section class="summary">
And I'm not lying
</section>
<section class="text">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed diam orci, hendrerit a justo sit amet, egestas ullamcorper orci. Aliquam quis facilisis urna. Fusce blandit pellentesque elit. Vivamus ullamcorper luctus felis in rutrum. Nam quis facilisis mauris. Nunc iaculis sagittis sollicitudin. Ut imperdiet, purus et fermentum tempor, leo mauris feugiat libero, eu pulvinar odio felis sed tortor. Mauris vel libero orci. Suspendisse a mollis turpis. Maecenas egestas felis eget ultrices porta. Nulla non metus ut augue faucibus ultrices. Phasellus arcu magna, vulputate eget sollicitudin a, ullamcorper a ipsum. Suspendisse potenti. Pellentesque eget vulputate ipsum.</p>
<p>Ut ultricies faucibus sapien, ut sodales turpis rhoncus molestie. Vivamus luctus auctor pellentesque. Phasellus ut ex vulputate, congue felis nec, pharetra odio. Ut ligula ante, luctus nec enim ac, lobortis ultrices elit. Quisque sed justo a nibh congue tempor sit amet ut mauris. In non enim nulla. Nulla et dolor sollicitudin, finibus ante eu, egestas purus. Phasellus sit amet eros dignissim, pellentesque elit tempor, sagittis eros. Donec sollicitudin velit ipsum, semper ultrices sapien blandit non. Phasellus vehicula orci in ipsum blandit hendrerit. Vestibulum facilisis dolor ac tincidunt fermentum.</p>
</section>
<span>Update text</span> <input type="checkbox" class="update_projects" data-id="Secons project" /><br /><button class="update_text">Update</button><input type="hidden" class="token" value="4926dd431992894a8364ca4d89733038be0cb0ec4897eb2a417637685554b6df40149522a858b5bfaaa91526b84718cdd54b301229371841dc2f022bbd0f804eaf31abb51caef55b26cca3209cc3b0838f194176f78f0931b2217669cd2912faa25a3c3e469ce686d79ac7a7852fbfee9d6d4dc5da18b499e703b4ef57fc88c1a99ccf8943af5853433f911ce276ff13e9ecbfb074d747f1a07f26c141f80383a149902dfe7469262724e2f67aae48d9919d486855a892b17681660ab3e0d25f98e714c3d98cc903" /><input type="hidden" class="id" value="2" /><br /><input type="text" name="tag" class="tag" value="" />
</article></section>
UPDATE
After some more testing I have found the JS can't find any of my added HTML while the js added on the same time can.
I am trying to understand the question but as i can't comment for the moment some parts of it are not enugh clear, i work with jsfiddle if it can help, is it possible to make a little example not all the code to help me understand what's going on. Starting with
this function for example :
function LoadPage(link, old){
$.ajax({
url: "pages/" + link + ".php",
}).done(function(data){
$("#content").html(data);
});
Hide();
history.pushState(old,null,"?page=" + link);
}
https://jsfiddle.net/3z62n8c2/
Try the following script, this will remove the script from the loaded HTML and load them on to the page before adding the content. Also it makes sure that the same javascript file does not get added multiple times.
function LoadPage(link, old){
$.ajax({
url: "pages/" + link + ".php",
}).done(function(data){
$loadedData = $("<div>"+data+"</div>");
$loadedData.find('script[src]').each(function(i,v){
var jsPath = $(this).attr('src');
if($('[src="'+jsPath+'"]').length == 0){
var tag = document.createElement('script');
tag.src = jsPath;
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
}
});
$loadedData.find('script[src]').remove();
$("#content").html($loadedData.html());
});
Hide();
history.pushState(old,null,"?page=" + link);
}
To load the script you must append it as an HTML element, like this :
}).done(function(data) {
var el = $(document.createElement('div')).html(data);
var scripts = el.find('script');
for(var i = 0; i < scripts.length; i++) {
window.eval(scripts[i].innerHTML);
scripts[i].remove();
}
$('#content').html(el.html());
});
Related
The $("body").load("myUrl") function in jQuery allows the html content of a file to be loaded into the body, in which case all the scripts in the html file in the body are loaded and executed correctly.
How to provide html content from a variable to body instead of loading it from a file. For example, consider that:
in index.html:
<script>
window.keeper = null;
function callForm2() {
window.keeper = window.document.body;
$("body").load(
"Form2.html"
);
}
function closeForm2() {
window.document.body = window.keeper;
}
</script>
in callForm2 Before the body content is called from a file, the current body content stored in a window.keeper variable.
in closeForm2() , I want to take the content from the window.keeper variable (old body content) and set to current body, in which case the content of the variable is not equal to the previously saved one, and I can not return the original content of the variable.
So how do I save the current body content of a variable for the next call?
What is the correct way to save and call in this case?
here is my code: (you can also see https://github.com/yarandish/Challenge2)
Consider the following.
window.keeper = {};
$(function() {
$("#psudo_body > p").click(function() {
window.keeper.html = $("#psudo_body").html();
window.keeper.text = $("#psudo_body").text();
console.log("Stored", window.keeper);
var form = $("<form>", {
id: "myForm"
});
$("<button>", {
type: "submit"
}).html("Done").appendTo(form);
$("#psudo_body").html(form);
});
$("body").on("submit", "#myForm", function(event) {
event.preventDefault();
$("#psudo_body").html(keeper.html);
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="psudo_body">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. In condimentum elit sit amet mi molestie, ac commodo nibh blandit. Proin a tellus efficitur dui commodo varius. Nullam massa nunc, mollis in finibus ac, volutpat eu urna. Maecenas quis sodales
felis, non finibus lorem. Aliquam tristique, dolor vitae consequat commodo, augue sem porta ex, eu tincidunt lectus orci ut elit. Integer nec enim eu erat pulvinar pretium eu id lorem. Sed et dapibus ligula, a rhoncus augue. Fusce et purus in diam
aliquet accumsan. Curabitur mattis, ante quis tempor luctus, ante sapien dignissim metus, sit amet maximus ante lorem eu turpis. Praesent in sodales velit. Suspendisse varius ornare faucibus. Suspendisse maximus erat sodales, tincidunt nulla sit amet,
fermentum ligula. Donec sed sollicitudin nunc. Phasellus vitae mauris bibendum, fringilla orci id, sodales libero. Donec at ullamcorper lectus. Proin dui enim, venenatis quis euismod vulputate, blandit sit amet nibh.</p>
</div>
This would work for body element as well.
You can also use .data() in a similar way.
$(function() {
$("#psudo_body > p").click(function() {
$("#psudo_body").data("keeper", $("#psudo_body").html());
var form = $("<form>", {
id: "myForm"
});
$("<button>", {
type: "submit"
}).html("Done").appendTo(form);
$("#psudo_body").html(form);
});
$("body").on("submit", "#myForm", function(event) {
event.preventDefault();
$("#psudo_body").html($("#psudo_body").data("keeper"));
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="psudo_body">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. In condimentum elit sit amet mi molestie, ac commodo nibh blandit. Proin a tellus efficitur dui commodo varius. Nullam massa nunc, mollis in finibus ac, volutpat eu urna. Maecenas quis sodales
felis, non finibus lorem. Aliquam tristique, dolor vitae consequat commodo, augue sem porta ex, eu tincidunt lectus orci ut elit. Integer nec enim eu erat pulvinar pretium eu id lorem. Sed et dapibus ligula, a rhoncus augue. Fusce et purus in diam
aliquet accumsan. Curabitur mattis, ante quis tempor luctus, ante sapien dignissim metus, sit amet maximus ante lorem eu turpis. Praesent in sodales velit. Suspendisse varius ornare faucibus. Suspendisse maximus erat sodales, tincidunt nulla sit amet,
fermentum ligula. Donec sed sollicitudin nunc. Phasellus vitae mauris bibendum, fringilla orci id, sodales libero. Donec at ullamcorper lectus. Proin dui enim, venenatis quis euismod vulputate, blandit sit amet nibh.</p>
</div>
See Also: Storing a variable in the JavaScript 'window' object is a proper way to use that object?
I Solved you problem and putting demo here.
Your Solution is here:
https://github.com/Master2V/FormCallSolution.git
In index.html put this script in head:
<script>
window.keeper = null;
function callForm2() {
var $body_page = $('body #Page');
window.keeper = $body_page;
$body_page.detach();
$.ajax({
type: "GET",
url: "Form2.html",
data: "",
dataType: "html",
success: function (response) {
$("body").html(response);
}
});
}
function closeForm2() {
var $body_page = $('body #Page');
$body_page.detach();
var $body = $('body');
$body.append(window.keeper);
}
</script>
And you must have a div tag with id="Page" in index.html and any other forms that you want to call.
I am almost positive that this question has been answered before, but the reason that I am asking this question is because I am not sure how to implement the answers into my code without breaking it. I have an accordion menu and it utilizes headers, paragraph tags, divs for the structure of the accordion. Well what I am trying to do is use a div inside of the accordion to display images, but here is the thing: divs are used for the structure of the accordion.
So, what I am asking is how to have jQuery treat this div as purely
content and not part of the structure?
I am pretty sure that the answer is to use .not(), but not sure. I only understand the basics when it comes to JavaScript and jQuery. I am really sorry for this guys... I am the type of person that learns by doing, not by reading a book.
var headers = ["H1", "H2", "H3", "H4", "H5", "H6"];
$(".accordion").click(function(e) {
var target = e.target,
name = target.nodeName.toUpperCase();
if ($.inArray(name, headers) > -1) {
var subItem = $(target).next();
//slideUp all elements (except target) at current depth or greater
var depth = $(subItem).parents().length;
var allAtDepth = $(".accordion p, .accordion div:not(.exclude)").filter(function() {
if ($(this).parents().length >= depth && this !== subItem.get(0)) {
return true;
}
});
$(allAtDepth).slideUp("fast");
//slideToggle target content and adjust bottom border if necessary
subItem.slideToggle("fast", function() {
$(".accordion :visible:last").css("border-radius", "0 0 10px 10px");
});
$(target).css({
"border-bottom-right-radius": "0",
"border-bottom-left-radius": "0"
});
}
});
<aside class="accordion">
<div class="opened-for-codepen">
<h2>How do I recruit members?</h2>
<div class="exclude image_legend">
<span>Image legend for "How do I recruit members?" section</span>
<br />
<br />
<img src="includes/images/clan/clan-tab.png" height="40px" style="display: inline;" />
<img src="includes/images/clan/clan-bottom-bar.png" height="40px" style="display: inline\;" />
<img src="includes/images/clan/clan-recruit.png" height="40px" style="display: inline-block;" />
<img src="includes/images/clan/clan-tab.png" height="40px" style="display: inline-block;" />
</div>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec quis arcu augue. Donec varius semper interdum. Sed condimentum ipsum enim, a egestas nunc blandit a. Aenean varius dapibus suscipit. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Quisque et lectus sapien. Nulla dapibus porta libero ac efficitur. Phasellus condimentum ornare porta. Aliquam erat volutpat. Nullam nec orci vitae felis mattis suscipit consectetur sit amet urna. Nulla lobortis augue ac commodo condimentum. Maecenas
ac dui cursus, congue felis quis, varius elit. Curabitur nulla lacus, dignissim ut pellentesque at, posuere sit amet eros. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Donec nec sapien diam. Nulla
accumsan viverra tellus sed laoreet. In eleifend nulla libero, vehicula consectetur magna condimentum vitae. Suspendisse non rhoncus justo. Nullam eleifend elit nec neque efficitur, quis fermentum metus pretium. Quisque tellus mauris, molestie in
ultrices eu, tincidunt ut nibh. Fusce eu volutpat felis. Integer ligula nulla, mattis quis pulvinar pharetra, vehicula nec arcu. Vivamus tincidunt nulla a nisi vehicula lobortis. In hendrerit, neque quis convallis lacinia, nisl ipsum varius lorem,
nec laoreet nisi odio vitae est. Nulla vitae diam enim. Suspendisse a dignissim magna. Pellentesque convallis maximus mollis. Nullam tellus est, accumsan sit amet facilisis sit amet, semper sed lorem. Mauris laoreet tortor at odio aliquet, ut porta
lacus rhoncus. Nullam laoreet dolor et velit malesuada feugiat. Vestibulum a erat elementum, hendrerit massa non, ornare enim. Phasellus iaculis diam eros, sit amet dapibus elit finibus id.
</p>
</div>
</aside>
Edit: The above html is consolidated because there is a lot of content to include all of it, but I provide you with the basic structure that makes the accordion
Assign a class to your div (Ex. 'my-class')
Then use not :not() to filter the selection
var headers = ["H1","H2","H3","H4","H5","H6"];
$(".accordion").click(function(e) {
var target = e.target,
name = target.nodeName.toUpperCase();
if($.inArray(name,headers) > -1) {
var subItem = $(target).next();
//slideUp all elements (except target) at current depth or greater
var depth = $(subItem).parents().length;
var allAtDepth = $(".accordion p, .accordion div:not(.my-class)").filter(function() {
if($(this).parents().length >= depth && this !== subItem.get(0)) {
return true;
}
});
$(allAtDepth).slideUp("fast");
//slideToggle target content and adjust bottom border if necessary
subItem.slideToggle("fast",function() {
$(".accordion :visible:last").css("border-radius","0 0 10px 10px");
});
$(target).css({"border-bottom-right-radius":"0", "border-bottom-left-radius":"0"});
}
});
I am trying to figure out how to have a scrollable div scroll to the top of the most recently appended child div.
The html of the chatbox is as follows
<div class="character-chat-log">
<div class="character-chat-message"><strong>Test 1:</strong> test</div>
<div class="character-chat-message"><strong>Test 1:</strong> test</div>
<div class="character-chat-message"><strong>Test 1:</strong> hey</div>
<div class="character-chat-message"><strong>Test 1:</strong> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam ac dictum est. Ut auctor feugiat lectus, consectetur adipiscing lacus scelerisque eleifend. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed dignissim, tortor sit amet feugiat feugiat, ante urna luctus est, ut varius velit diam sed sem. Etiam ut eleifend risus. Maecenas vulputate arcu ipsum, ut tempus lectus pulvinar non. Donec non tellus sed diam semper tempus et eget eros. Mauris quis auctor lorem, non sodales urna. Ut dui dolor, ultricies sit amet lacinia in, ultrices eu mauris. Donec eros tellus, laoreet sagittis hendrerit id, scelerisque id mi. Praesent fringilla ligula id suscipit malesuada. Vivamus risus magna, lobortis a congue sit amet, consequat eget lorem. Vestibulum imperdiet ultricies rutrum. Donec a blandit enim, nec euismod ante. Phasellus dignissim molestie urna.</div>
</div>
Currently I am trying to scroll to the top of the latest "character-chat-message" as follows:
var newMessage = $(
'<div class="character-chat-message"><strong>'
+ sender
+ ':</strong> '
+ messageText
+ '</div>').appendTo(_messageBoxes[sender]);
_messageBoxes[sender].scrollTop(newMessage.position());
However this of course does not work at all.
It sounds like you're doing something similar to this question
Is that right?
Ive got a js that runs to see if a maximum amount of characters is reached. Its got text along with href, but when the max amount of characters is reached, the link doesnt work and converts it to just text. When the limit of less then 580 characters, link works. When it does reach the limit, the read more link does work. Any advice or help please and thanks
$(document).ready(function () {
var stylistText = $('#stylistText');
var stylistText2 = document.getElementById("stylistText").innerHTML;
var countActualText = stylistText2.valueOf().length;
var maxLength = 580;
var aElement = document.createElement('a');
var linkText = document.createTextNode(" ...Read more");
aElement.appendChild(linkText);
aElement.href = "#";
if (countActualText > maxLength) {
stylistText.text(stylistText.text().substring(0, 580));
stylistText.append(aElement);
}
});
here is the html
<div class="stylistInfo">
<img id="stylistPhoto" src="images/Test.jpg" alt="peekaboo beans stylist" />
<p id="stylistText">
This is supposed to be a link Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis nec mauris odio. Sed varius, felis eget rutrum scelerisque, enim ligula porta nulla, id rhoncus orci nisi at nunc. Fusce cursus, libero a sagittis viverra, arcu eros luctus arcu, sit amet euismod sapien purus quis nisl. Praesent aliquam aliquam ante ornare pulvinar. Mauris ultrices dictum quam, at ornare dui blandit id. Sed erat elit, fringilla quis diam at, euismod rhoncus massa. Curabitur at arcu nisl. Nullam tincidunt lacus sapien, sed porttitor odio sodales sit amet. Nunc tincidunt nisi et nulla aliquam cras amet.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis nec mauris odio. Sed varius, felis eget rutrum scelerisque, enim ligula porta nulla, id rhoncus orci nisi at nunc. Fusce cursus, libero a sagittis viverra, arcu eros luctus arcu, sit amet euismod sapien purus quis nisl. Praesent aliquam aliquam ante ornare pulvinar. Mauris ultrices dictum quam, at ornare dui blandit id. Sed erat elit, fringilla quis diam at, euismod rhoncus massa. Curabitur at arcu nisl. Nullam tincidunt lacus sapien, sed porttitor odio sodales sit amet. Nunc tincidunt nisi et nulla aliquam cras amet.
</p>
</div>
Change stylistText.text(stylistText.text().substring(0, 580));
to stylistText.html(stylistText.html().substring(0, 580));
However, truncating a block of text that contains HTML may cause other problems, especially if the truncation occurs in the middle of an element. I would recommend rethinking your whole strategy on this.
http://jsfiddle.net/h2vMN/1/
I have a text box text inside it already, in the actual application this will be filled dynamically, but for the sake of this question it has been pre filled.
<textarea id="textarea">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed tempor commodo ornare. Donec lobortis dui sed lectus egestas tristique. Vivamus vel metus turpis, faucibus varius risus. Aenean ante mauris, ultrices id facilisis vitae, dignissim eget sem. Quisque sed justo lectus, eget aliquet leo. Curabitur in mauris et diam fermentum venenatis. Proin ullamcorper, neque a vehicula euismod, odio enim aliquam ipsum, eu tristique urna sapien nec erat.
Aliquam erat volutpat. In in lacus cursus dolor pellentesque posuere. Cras eu metus urna, a rhoncus ligula. Ut hendrerit orci in arcu dignissim id fermentum orci vulputate. Sed ante ligula, volutpat eu convallis vel, auctor in metus. Mauris euismod, metus eget venenatis sodales, risus tellus volutpat elit, et aliquet massa tellus ut sapien. Mauris tempor posuere massa et consectetur. Duis dignissim enim a nulla ultricies vitae vulputate felis commodo. Phasellus mollis est eget odio porttitor consequat. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Phasellus ut nibh auctor libero sagittis semper vitae quis erat.
</textarea>
When I run the above code, it shows a tiny text area with scroll bars all over it. In other words, completely useless in terms of being user friendly. How do I automatically resize the text box according to the amount of content their is and it has a set width of 600px.
#textarea{width:600px;}
I would like a javascript/jquery solution.
I have tried the .autoresize solution unsuccessfully, which can be found here:
http://james.padolsey.com/demos/plugins/jQuery/autoresize.jquery.js/view
Note, the height should be resized automatically
Thy this:
$(document).ready(function(){
tx = $('#textarea')
tx.height(tx.prop('scrollHeight'));
})
DEMO
$(document).ready(function(){
var heightFudgeFactor = 10;
var id = 'tempid' + Date.now();
$('#textarea').after( $('<div>').css('font-family','monospace').css('white-space','pre-wrap').css('word-wrap','break-word').attr('id',id).css('width',$('#textarea').width()).text( $('#textarea').text() ) );
$('#textarea').css('height',$('#'+id).outerHeight() + heightFudgeFactor).next().remove();
});
Here's one way of doing it, I'm creating a secondary div that's the height of the textarea, based on content, but you'll need to play with it a little more to get it to your actual liking
I once used this plugin: http://www.jacklmoore.com/autosize
It worked fine.