Execute custom script after page loaded with Ratchet\Push.js - javascript

So on the GitHub documentation for Ratchet 2.0.2 I found the following statement.
Script tags containing JavaScript will not be executed on pages that
are loaded with push.js. If you would like to attach event handlers to
elements on other pages, document-level event delegation is a common
solution.
Can someone please spell out exactly how to get a custom <script> to execute after being loaded by Push.js?
On my first page, I have a Table view, with several links to other pages, one of them being a link to a second page with a Twitter Feed widget on it.
<li class="table-view-cell media">
<a class="navigate-right" href="Twitter.php" data-transition="slide-in">
<span class="media-object pull-left icon icon-person"></span>
<div class="media-body">
Twitter Feed
</div>
</a>
</li>
The second page only contains the twitter feed widget code. When I browse to this page directly (without being loaded by Push.js) everything loads correctly, but when it is loaded via Push.js, the script is not executed.
Can someone please explain what I need to do to get this script to execute after being loaded by Push.js? I've searched Google, Stack Exchange, and Github\Ratchet issues and have not been able to find a good example of how to accomplish this.
One solution would be to add data-ignore="push" to the link, but I want to know how to do with WITH push.js.
<div class="content">
<a class="twitter-timeline" href="https://twitter.com/XXXX" data-widget-id="XXXX">Tweets by XXX</a>
</div>
<script>
!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+"://platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");
</script>

EDIT: below was how I originally solved this problem, which worked fine, but I came up with a better solution, which I posted as the answer to this question.
I finally figured it out.
On your first page, you need to do the following...
var checkPage = function(){
//Only run if twitter-widget exists on page
if(document.getElementById('twitter-widget')) {
loadTwitterFeed(document,"script","twitter-wjs");
}
};
window.addEventListener('push', checkPage);
checkPage() will execute for every time a new page is loaded via push.

Just made a change for Ratchet.js to make individual js works for each page more elegant.(https://github.com/mazong1123/ratchet-pro)
By using the new ratchetPro.js, we can do followings:
(function () {
var rachetPageManager = new window.RATCHET.Class.PageManager();
rachetPageManager.ready(function () {
// Put your logic here.
});
})();

Related

Jquery script doesn't work in jquery loaded page

I have tried to search for similar questions, but I could not find anything, so if you know any similar question please let me know.
Let me explain what Im doing:
I have a script that validates forms in a js file, It works fine in any page with a form I have, the problem is that when I load a form using jquery it just doesn't work, I have tried using the next line in different places: Header, footer, etc
<script src='myFile.js'></script>
By far the only thing that has worked for is writing the line of code above inside the form itself.
I think it has something to do with the form that the DOM works, I have also tried using and not using it.
$(document).ready(function (){ //code});
It only will work when I add the script tag with the src attribute inside the form itself.
It would not represent a big problem for me to add the script tag to any form I load using jquery but it's a little bit more of work an unefficient, and also when I add the script tag to any form and load it using ajax I get the next console warning that only goes away when I remove the script tag from the form file:
jquery-3.2.1.min.js:4 [Deprecation] Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
Here is a part of my code:
<!--home.html-->
<div id='formFrame'>
</div>
<script>
$("#formFrame").load("html/loginForm.html");
</script>
<!--end of home.html-->
<!--loginForm.html-->
<form action='somePage.php' method='post' id='loginForm'>
<input type='email' name='email' placeholder='email'>
<input type='password' name='password' placeholder='password'>
<input type='submit' name='submit' value='Login'>
</form>
<script src='js/validate.js'></script>
<!--end of loginForm.html-->
<!--validation script (validate.js)-->
$(document).ready(function (){
$("#loginForm").submit(function (e){
e.preventDefault();
alert("Working");
});
});
Thanks for spending some of your valuable time on reading this, I appreciate it a lot!
As I can't comment, putting my comment in answer!
I am not sure what you have written in validate.js, but if you are using jQuery unobtrusive validation, then you must rebind the validators to the form if you are loading it dynamically.
I was facing same issue in ASP.NET MVC while loading forms using AJAX. I am not sure will it help you or not but below is the code.
$("#formFrame").load("html/loginForm.html", function(){
var $form = $("formSelector");
$form.removeData('validator');
$form.removeData('unobtrusiveValidation');
$.validator.unobtrusive.parse($form);
});
Well guys I found a solution:
As there seems to be a conflict when loading an external page using ajax (.load) I opted to use php instead of javascript which worked fine:
I removed the next code
<script>
$("#formFrame").load("html/loginForm.html");
</script>
And added the next to the div where I want to load my content:
<!--home.php (changed html to php)-->
<div id='formFrame'>
<?php
require 'html/loginForm.html';
?>
</div>
I would have prefered to use the load method from ajax to avoid loading the content befere the user could request it, but by far that's the only solution I have been able to think about.
Thanks to everybody for your help it was really helpful!

Can I store HTML fragments in different files but access via JavaScript

Not sure if I have phrased my question correctly but I shall try to explain clearer in the body of my question.
I am using ASP.NET C#.
I have a single WebForm page.
In this page, for example I have this:
<div id="page1" style="display:block">
page 1 contents
<a href='#' id="liPage1" onclick='Page2();'>Page2</a>
</div>
<div id="page2" style="display:block">
page 2 contents
<a href='#' id="liPage2" onclick='Page1();'>Page1</a>
</div>
<script>
//this is just sudo code
Page1 function will hide div page2 and show div page1
Page2 function will hide div page1 and show div page2
</script>
Now I do not need any help with the script.
What I am asking is whether I can have the HTML for page1 in 1 file and the HTML for page2 in another file and load these HTML 'fragments' via client-side.
I can easily do this in server code by encapsulating the HTML in a user-control.
I want to know if I can do the same using client calls. But I really do not want to 'write' the HTML within JavaScript code itself.
I am asking this because I intend to have quite a few pages and I want to render it all via client-coding rather than calling back to the server each time. It is all a question of readability and management.
I was thinking along the lines like resource files but not sure how.
I hope this is all clear?
Yes, you can simply do some ajax calls, and then set the response as the content of a container element.
So, let's say yo have file1.html, file2.html and file3.html, and you want to include all those "fragment files" in a #container.
The script will look something like this:
[
"file1.html",
"file2.html",
"file3.html"
].forEach(function(file) {
var xhr = new XMLHttpRequest();
xhr.open("GET", file, true);
xhr.addEventListener("load", function() {
document.querySelector("#content").html += xhr.response;
});
xhr.send();
});

Problems with event binding on dynamically created elements

I have code that is behaving one way on jsfiddle, one way on localhost, and another when uploaded to my website. I've been wrestling with the problem for a few days now. I don't know what tests or trial and errors I can run at this point.
This jsfiddle is working exactly as I want it to work.
http://jsfiddle.net/2ZLse/10/
When I insert this code into my project, and run it on localhost with WAMP, the javascript for the page does not work. The javascript is valid when run through jslint.
Stranger still, when I upload the exactly same files to my website, the javascript is functional, and I can even click on the watch button and render the form, but the nevermind button does not return me to the original state. I'm not receiving any errors on my cPanel.
When I replace
$(document).on('click', '.nevermind', function() {
$('#imagebox').html(imagebox);
});
with
$('.nevermind').click(function(){
$('#imagebox').html(imagebox);
});
The localhost will function the same as the website functions, with functioning javascript, but without a functioning nevermind button.
Below is the code, but let me tell you more about the rest of the page incase it's relevant. I'm using php. It's a .php file, bootstrap is loaded and working, jquery is loaded, and the javascript is run at the bottom of the page, not the header. There is ajax running elsewhere on the page, which works on the website but not the localhost, and I have the correct connect.php file for each. My best guess is that ajax has something to do with it.
What is the problem, or what tests can I run?
Here is the HTML
<div id="inputbox">
<form><button type="button" id="watchcontrol" class="btn btn-default">Watch</button>
</form>
<br>
</div>
<!-- images and continued input extension-->
<!-- imagebox also acts as control panel -->
<div id="imagebox">
ORIGINAL STATE
</div>
Here is the javascript.
var imagebox = 'ORIGINAL STATE';
var watchform = '<form action="post/watchpost.php" method="post">' +
'<input type="text" name="watchid" /><br>' +
'<input type="submit" class="btn btn-default" value="Contribute" />' +
'</form>' +
'<br><br><button type="button" class="btn btn-default nevermind">nevermind</button>';
$(document).ready(function(){
//control functionality
$(document).on('click', '.nevermind', function() {
$('#imagebox').html(imagebox);
});
$('#watchcontrol').click(function(){
$('#imagebox').html(watchform);
});
});
Event binding on dynamically created elements?
This question, while helpful, did not solve my issue. I believe my issue is separate from that one.
The following only binds event handler to the EXISTING DOM element:
$('.nevermind').click(function(){
$('#imagebox').html(imagebox);
});
which does not include what you append after clicking on #watchcontrol.
The following would work though, binding the event everytime when you create the dynamic element (even though I suggest that you free the element before removing it from the DOM):
$('#watchcontrol').click(function(){
$('#imagebox').html(watchform);
$('.nevermind').click(function(){
$('#imagebox').html(imagebox);
});
});
http://jsfiddle.net/2ZLse/11/

How to call LinkedIn authorize javascript from button

This line of sample code from LinkedIn API works perfectly.
<script type="IN/Login" data-onAuth="loadData"></script>
but it runs automatically as the web page loads. I'd like to invoke this script using a button or link on a webpage. The idea being that the webpage loads and waits until the user is ready to authenticate.
Ideally I would like the LinkedIn Login image to appear, and wait, until clicked.
Thanks.
Based on your comment, it looks like you only want to display the SignIn plugin if the user has manually clicked a button/element on the page. Something like this, using jQuery, should work:
On your page, you have a button:
<div id="buttonControl">
<input type="button" id="showLinkedIn" value="Show LinkedIn" onclick="showLinkedIn();" />
</div>
<div id="buttonContent" style="display: none;"></div>
In a script block in the <head> of the page, you have the showLinkedIn() onclick function:
function showLinkedIn() {
// insert the SignIn plugin
$('#buttonContent').html('<script type="IN/Login" data-onauth="loadData"><\/script>');
// tell the LinkedIn JavaScript code to re-parse the element containing the SignIn plugin
IN.parse($('#buttonContent')[0]);
// hide button trigger, if needed
$('#buttonControl').hide();
// show the LinkedIn control
$('#buttonContent').show();
}
$('#buttonControl').click(function(){
$('#buttonContent').html('<script type="IN/Login" data-onauth="loadData"></script>');
$('#buttonControl,#buttonContent').toggle();
IN.User.authorize(loadData);
});
slightly different as the 'IN.parse($('#buttonContent')[0]);' does not seem to work...
tested 'IN.User.authorize(loadData)' and it works well! Got it from: http://developer.linkedin.com/documents/inauth-inevent-and-inui
You need to clear the cookies from the following method like
IN.User.logout(callbackFunction, callbackScope);
You need to call this function on that button from which you want to log out.
Example using jquery:
$('#demo') .click(function()
{
IN.User.logout(console.log("logged out..."));
});

Embedding a Twitter share button (with JS and everything) into a Mustache template

How can I embed a Twitter (with JS and everything) share button into a Mustache template?
The problem which I have is that my AJAX app does not reload the page, but simply switches views based on Mustache templates. I noticed that functionality provided by widjets.js simply does not get turned on, because the JS files gets loaded only once per application lifetime, and searches for tags decorated with a "twitter" tag on DOM_READY. This however, completely excludes the cases when HTML gets rendered from a template later on.
I know that I can use a raw hyperlink to twitter and customize it to o look like a button, but that is just too primitive.
Here's a solution that worked for me using a template inside my HTML file:
social.js:
$(function() {
var socialFeeds = {
twitter: {
account: "your-twitter-account",
script: function() {
// twitter code goes here, minus the script tags
!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");
// in my case, I had to re-render the twitter button, see here:
// http://stackoverflow.com/a/6536108/805003
$.ajax({ url: 'http://platform.twitter.com/widgets.js', dataType: 'script', cache:true});
}
}
}
$.Mustache.addFromDom('social-template');
$('#social').mustache('social-template', socialFeeds);
}
index.html:
<script id="social-template" type="text/html">
<div id='social'>
<p>Twitter button:</p>
Tweet
{{ twitter.script }}
</div>
</script>
You could call the init functions not on document ready but from the views where you want the twitter button to appear.

Categories