Dynamic page navigation - custom event isn't triggered - javascript

I've created simple button:
<button type="button" class="btn btn-success link-accept" data-id="16">Accept</button>
with corresponding listener:
$(document).ready(function() {
$('.link-accept').on('click', function(event){
console.log('accepted');
});
});
Everything works okay.
Then I introduced AJAX-based dynamic (refreshless, you name it) navigation on my page using this function:
function ajaxLoadContent(pageurl){
$('#content').addClass("grey");
$.ajax({url:pageurl+'?rel=tab',success: function(data){
var title=$(data).filter('title').text();
var keywords=$(data).filter('meta[name=keywords]').attr('content');
var description=$(data).filter('meta[name=description]').attr('content');
var mdlTitle=$(data).find('.mdl-layout-title').html();
var content=$(data).find('#content').html();
var scripts=$(data).filter('#scripts').html();
document.title = title;
$('meta[name=keywords]').attr('content', keywords);
$('meta[name=description]').attr('content', description);
$('.mdl-layout-title').html(mdlTitle);
$('#content').html(content);
$('#scripts').html(scripts);
$('#content').removeClass("grey");
window.scrollTo(0, 0);
$(document).trigger("content-refreshed");
console.log('triggered content-refresh');
}});
}
And now my listener isn't working. I guess it's something about that dynamic refresh.
I've tried:
Listening to content-refreshed event - it fires, but isn't caught by my listener inside dynamically loaded page
Moved content of my $(document).ready anonymous function to separete function and called it at the bottom of the page - function is not defined.
Extracted content of my $('.link-accept').on('click') to separate function and called it with <button onclick="function()"> - function is not defined
I'm out of ideas now... It looks like it doesn't execute that code at all if loaded dynamically. What should I do? I guess eval is not an option here...
EDIT
I'm sure that dynamically loaded javascript isn't ran at all. Pure console.log at the top of <script> section doesn't work either. So I guess my primary task is to evaluate that code first - then it should work just right.

Change first snippet to:
$(document).on('click', '.link-accept', function(event){
console.log('accepted');
});
It will work then.
Otherwise it will just search for all .link-accept items first and then attach the handler once to the found objects. Nothing will update after your ajax request.
In my code snippets it is more dynamic. It binds the click to the document. If you click on any object on the document it will check if it is a .link-accept element. More dynamic and better performance.

Related

Bootstrap 3 modal doesnt always activate ajax code

I'm sure there is a simple answer to this I just don't seem to be able to resolve it.
I am using the bootstrap modal to return ajax content from specified url. (using $.removeData() between loads to remove content).
The problem comes with running JS on content from the form presented in the modal.
I am currently using (simplified) from within the final file (returned by ajax):
$('#myModalLg').on('shown.bs.modal', function(e) {
$(this).on('submit', 'form', function(ev) {
... event handler for form...
});
});
EDIT: along with other event handlers (datepicker for within modal included) but this code is only loaded once and then fails to activate again until the full page is reloaded
On close code:
$('#myModal, #myModalLg').on('hidden.bs.modal', function (e) {
$(e.target).removeData();
$(e.target).off('shown.bs.modal');
$('#myModal, #myModalLg').on('shown.bs.modal', function () {
$(this).find(':input:first')[0].focus();
});
});
I would be expecting the handlers to run each time #myModalLg is shown and then when it is closed it removed what has been entered and restores each time but doesn't seem to work like that.
you never turn off your shown.bs.modal have you looked into the One Event In JQuery:
I'm not sure if this will help but it seems like your redeclaring your shown.bs.modal multiple times you might want to change that to a one instead of on
$('#myModal, #myModalLg').one('shown.bs.modal', function () {
$(this).find(':input:first')[0].focus();
});

Set a JQuery function on the button HTML declaration

I'm trying to use AJAX loading a set of sucessive pages in a main page, as I show you in the next picture:
I learned (thanks to this community!) to call other pages' content, by assigning the load() function to the onclick event of a button, like this:
$(document).ready(function() {
$('#btn').click(function() {
$('#result').load('./poi-data-no-heading.html');
});
});
But what if I have one button with id="btn" on every page? The functionality of any button with that id will be the same always, because (I think) the document.ready is not triggered when I use the load() method, so it's never replaced with new functionality.
E.g. initial functionality should be navigate from page 1 to page 2, and when page 2 is loaded, the functionality should be to navigate from page 2 to page 3.
As Js developer, I would do the following:
<!-- In the HTML file -->
<button id="btn" onclick="loadContent()">Load</button>
<div id="result"></div>
/* In the JS file */
function loadContent(){
/*the code to retrieve content*/
$('#result').load('http://fiddle.jshell.net/webdevem/JfcJp/show/');
}
This way I could assign the functionality to every button, no matter what's the ID or if the document.ready is triggered. But mixing Js with JQuery is not an option... So, how do you think I should manage to do something similar with JQuery?
Thanks in advance.
P/d: Here is a useful fiddle I used to try ideas: http://jsfiddle.net/gal007/vkcug7t7/1/
You could use the on() event from jQuery, which can listen for events on elements dynamically rendered (you can't do that with the click() method). So in this case you have to listen to the event on a parent element, one that doesn't change with the load method. On that button, use an HTML5 data-* attribute to define the id that you wish to load.
HTML:
<btn id="result" data-load-id="1">Load</btn>
Javascript:
$('#container').on('click', '#result', function() {
var id_to_load = $(this).data('load-id');
load('/url?' + id_to_load);
});
I've updated your fiddle : jsfiddle

How to bind jquery function to specified element

I want to make function working only on page with specified element.
I have search page, search fields and results are in search-block div.
I want to bind function to this block, so function will not work on other pages (without <div id='search-block>...</div>)
I have next js code atm:
$(document).ready(function()
// instructions for another page (handlers for some links)
$(function(){
setInterval(findSomething,1000);
});
});
It working fine on page with search-block div, but it works fine on the other pages too. Browser tries to run this function on all other pages. I don't need this.
I tried jquery bind, but it now worked for me, don't know why :(
$("#search-block").bind(function(){
setInterval(findSomething,1000);
});
How I can bind handler to speciges too.fied block?
Instead of bind you have to check for the length of that elem:
$(document).ready(function(){
if($('#search-block').length > 0){ // <---checks the availability
setInterval(findSomething,1000);
}
});
Bind is always used with an event to bind to:
$( "#foo" ).bind( "mouseenter mouseleave", function() {
});
if you want to execute that only when the block is available on the page, use this:
if ($('#search-block').length) {
setInterval(findSomething,1000);
}
This checks the number of times #search-block is found on the page and if it is not 0(false) it executes the code.

Google FastButton Multiple Use

I've implemented the Google FastButton script into a web page. Following:
Trying to implement Google's Fast Button
The code works great. My question is how do I implement this for multiple buttons. I have several buttons that are dynamically created. I don't want to define each button with its own function. Can I use this script with another function that passes some variable.
For example, <button id="quick" onclick="someFunction(24);">button</button>
Current implementation
new FastButton(document.getElementById('quick'), function() {
alert("hello");
});
<button onclick="onLayerClick(8)">8</button>
Here's one way to do it: According to the link you pasted, the FastButton prototype accepts a function as its second argument (this.FastButton = function(element, handler)) and passes the click event to that function. So if you do something like this:
HTML:
<button id="quick">24</button>
JS:
var myHandler = function(event) {
var el = event.target;
console.log(el.innerHTML);
}
new FastButton(document.getElementById('quick'), myHandler);
Then the myHandler() function will have access to the DOM element where the click event originated (event.target), which will be whatever button was clicked. So you'll have access to that button's innerHTML, or you could put a data-mynumber="24" attribute on the button and use el.getAttribute("data-mynumber") instead of el.innerHTML... However you want to identify the button is up to you.

Jquery bind()/live() within a function

I wrote a little pager which removes and rewrites content. I have a function called after loading the page, it shall be executed after changing the page as well. Because I do not wat to implement the function twice (on initialisation and after changing the page) I tried bind()/live() and a simple function.
The function looks like this:
jQuery('.blogentry').each(function (){
jQuery(this).click(function(){
//Clicking on the element opens a layer, definitely works - I tested it
});
});
It is executed after initialisation, for executing it after page changes as well I tried the following:
jQuery('.nextPage, .prevPage').click(function changePage(){
// Changing page and rewriting content
showEntry();
});
//...
showEntry();
//...
function showEntry(){
jQuery('.blogentry').each(function (){
jQuery(this).click(function(){
//Clicking on the element opens a layer, definitely works - I tested it
});
});
}
But the function is not executed if put inside a function (lol) and called via showEntry();
Afterwards I tried to bind the function...
jQuery('.nextPage, .prevPage').click(function changePage(){
// Changing page and rewriting content
jQuery('.blogentry').bind("click", showEntry);
});
//...
jQuery(this).click(function showEntry(){
//Clicking on the element opens a layer, definitely works - I tested it
});
Did not work either. Code after the bind()-line would not execute as well.
I thought maybe it's a problem to bind to an event function, if an event is already given via the parameter so i also tried this:
jQuery('.nextPage, .prevPage').click(function changePage(){
// Changing page and rewriting content
jQuery('.blogentry').bind("click", showEntry);
});
//...
function showEntry(){
//Clicking on the element opens a layer, definitely works - I tested it
});
}
No success at all. Maybe I cannot call the function from inside the function regarding to the bind()? Maybe I just do not understand the bind()-function at all? I also tried the live() function since it seemed to fit better, as I am rewriting the content all the time. But it had the same effect: none...
The simplest way to implement this should be
jQuery('.blogentry').live('click', function() { /* onclick handler */ });
This should bind the function to every blogentry on the page at the moment of the call and all the blogentries that are added to the page later on.
Additional notes:
In $(foo).each(function() { $(this).click(fun); }); the each is unnecessary - $(foo).click(fun); is enough.
$(foo).bind('click', fun); is functionally equivalent to $(foo).click(fun) - it does not matter which one you use.
You can use delegate or bind. don't call the function like that, just create a delegate with .blogentry and it should update even after you load a new page via ajax. It will automatically do this.
$("#blogcontainer").delegate(".blogentry", "click", function(){ //open layer });
This should work for you
$(body).delegate(".blogentry", "click", function(){
showEntry();
});
alternaltivly you can use event delegation
$(document).ready(function () {
$('#blogcontainer').click( function(e) {
if ( $(e.target).is('.blogentry') ) {
// do your stuff
}
});
});
hence, no need to bind each blogentry at creation or reload, and it's (slightly) faster.

Categories