i am trying to build a small single page wordpress theme, but struggling to find a way to make the navigation menu work.
The pages are loaded with this function: http://pastebin.com/Di5MhS8y . Each page is displayed as a section of my homepage, based on its menu_order.
If i make a custom menu voice linking outsite my website (tried with www.google.com) the menu works just fine.
Problems arise when i try to link to a single section of my website. The whole page gets reloaded and i'm brought back at the top of it.
I reckon i should maybe give a specific id to each section, and link to it, but i'm not sure. Any suggestion would be super appreciated!
The best way would be to give each section an ID.
if you want clean URLS you can create a function with Jquery
here's one i used in a one page website
var locationPath = filterPath(location.pathname);
var scrollElem = scrollableElement('html', 'body', 'document', 'window');
//console.log(scrollElem);
$('a[href*=#]').each(function() {
var thisPath = filterPath(this.pathname) || locationPath;
if ( locationPath == thisPath
&& (location.hostname == this.hostname || !this.hostname)
&& this.hash.replace(/#/,'') ) {
var $target = $(this.hash), target = this.hash;
if (target) {
//console.log('Target: ' + target + ' offset: ' + targetOffset);
$(this).click(function(event) {
var targetOffset = $target.offset().top;
event.preventDefault();
$(scrollElem).animate({scrollTop: targetOffset}, 1000, function() {
//console.log($(scrollElem).scrollTop());
location.hash = target;
$(scrollElem).animate({scrollTop: targetOffset}, 0);
});
});
}
}
});
// use the first element that is "scrollable"
function scrollableElement(els) {
for (var i = 0, argLength = arguments.length; i <argLength; i++) {
var el = arguments[i],
$scrollElement = $(el);
if ($scrollElement.scrollTop()> 0) {
return el;
} else {
$scrollElement.scrollTop(1);
var isScrollable = $scrollElement.scrollTop()> 0;
//console.log(el + ': ' + $scrollElement.scrollTop());
$scrollElement.scrollTop(0);
if (isScrollable) {
return el;
}
}
}
return 'body';
}
Related
I have a php page with a nav and a content div. When I choose an option in the nav, the content is modified by loading another php file inside it. For this I use ajax with load function. My problem is that if I right click and select open in a new tab or a new window, evidently, only the content is open in the tab.
I know that I can have the whole page (container + content) in each php file and load only the content div, but I think there is no much sense in this.
Is there any way to get the container along the content in the new tab?
I already had a similar situation, the tabs have pages, and the menu was in the top page. you can apply this solution:
This logic will work with iframe, if you are using divs, you can adjust for this:
main page with the nav menu, here you need apply some logic like this:
<script>
//Object to get values of URL (GET)
var request = {
get get() {
var vars = {};
if (window.location.search.length !== 0)
window.location.search.replace(/[?&]+([^=&]+)=([^&]*)/gi, function (m, key, value) {
key = decodeURIComponent(key);
if (typeof vars[key] === "undefined") {
vars[key] = decodeURIComponent(value);
}
else {
vars[key] = [].concat(vars[key], decodeURIComponent(value));
}
});
return vars;
},
getParam: function (param) {
var vars = request.get;
if (vars[param] != undefined) {
return vars[param];
} else {
return null;
}
}, getParams: function () {
return request.get;
}
};
//variable that defines if the client are in mainWindow
window.mainWindowFrame = true;
var tabName = request.getParam("tab");
console.log("tabName",tabName);
//call some function to reload the content of iframe or div to requested tab.
//if(tabName != null || tabName != ""){
//tabs.load(tabName) ....
//}
</script>
In the pages of content you need aplly this piece of code to reload the page if the menu are not present:
<script>
//name of this tab
var tabName = "someTab";
//check if the menu are present here
if(window.top.mainWindowFrame == undefined){
window.location.href = "mainpage.html?tab="+tabName;
}
</script>
I'm affronted to another jQuery problem. Well I'm beginning by my code to understand my issue here:
<script type="text/javascript">
jQuery(document).ready(function() {
var current = <?php echo ($_GET['page']!='') ? $_GET['page'] : 1; ?>;
var idp;
$(window).scroll(function(e){
if($(window).scrollTop() + $(window).height() >= $(document).height()) {
current=current+1;
if(current<=1)
{
idp = '';
}
else
{
idp = '?page='+current;
}
loadMoreContent(idp);
history.pushState("state", "title: "+current, "index.php"+idp);
e.preventDefault();
}
if($(window).scrollTop() == 0) {
current=((current-1)<=0) ? 1 : current-1;
if(current<=1)
{
idp = '';
}
else
{
idp = '?page='+current;
}
loadMoreContent(idp);
history.pushState("state", "title: "+current, "index.php"+idp);
e.preventDefault();
}
});
window.onpopstate = function(event) {
if(current<=1)
{
idp = '';
}
else
{
idp = '?page='+current;
}
loadMoreContent(idp);
history.pushState("state", "title: "+current, "index.php"+idp);
};
function loadMoreContent(position) {
$('#loader').fadeIn('slow', function() {
$.get("index.php"+position+" #annonceis", function(data){
var dato = $(data).find("#annonceis");
$("#annonceis").html(dato);
$('#loader').fadeOut('slow', function() {
$(window).scrollTop(60);
});
});
});
}
});
</script>
My problem is based on infinite scroll but instead of "append" I used html() function to replace content in a div called annonceis.
The idea is that when I'm scrolling to bottom of the page I get content of new page called index.php?page=1 2 3. And replace old content in de div annonceis with the new content that I get with jQuery, but when I scroll to the bottom I Get content of next next page ex when the current page is index.php?page=2 normally when I scroll to bottom I must get content of index.php?page=3 but here I get content of index.php?page=3 and instantly index.php?page=4 so the page display index.php?page=4.
The main idea is scrolling to bottom and get the content of the next page instead of pagination, but it must take care about history.pushState for SEO purpose and Google suggestions see http://scrollsample.appspot.com/items and that https://googlewebmastercentral.blogspot.com/2014/02/infinite-scroll-search-friendly.html.
Thank you very much in advance.
So, what you're after really is pagination combined with infinite scroll. What the provided example is doing is using .pushState() to track the users scroll using page Waypoints. Notice, once page X reaches the center point in the page, the .pushState() is triggered.
Secondly, if you look at the example's source code for any of the pages, you'll see it will only render the selected page, then using listeners on the .scroll it will append or prepend content as needed.
So, at it's core, this is really just simple pagination. The infinite scroll feel is simply added on top for user experience. Basic overview to do this would look something like this:
Model or Controller
Your PHP file or whatnot, that runs the actual queries - class based for ease of use. The class will contain one function to grab a set of posts based on a request page. JavaScript will handle everything else.
<?php
Class InfiniteScroller {
// Set some Public Vars
public $posts_per_page = 5;
public $page;
/**
* __construct function to grap our AJAX _POST data
*/
public function __construct() {
$this->page = ( isset($_POST['page']) ? $_POST['page'] : 1 );
}
/**
* Call this function with your AJAX, providing what page you want
*/
public function getPosts() {
// Calculate our offset
$offset = ($this->posts_per_page * $this->page) - $this->posts_per_page;
// Set up our Database call
$SQL = "SELECT * FROM my_post_table ORDER BY post_date ASC LIMIT " . $offset . ", " . $this->posts_per_page;
// Run Your query, format and return data
// echo $my_formatted_query_return;
}
}
?>
AJAX Call
The next thing you'll want to take care of is your frontend and JavaScript, so your AJAX call can sit in a function that simply calls the above method and takes a page parameter.
<script type="text/javascript">
function getPageResults( page = 1, arrange = 'next' ) {
$.ajax({
url: url;
type: "POST",
data: "?page=" + page,
success: function(html) {
/* print your info */
if( arrange == 'prev' ) {
$( '#myResults' ).prepend(html);
else if( arrange == 'next' ) {
$( '#myResults' ).append(html);
}
},
error: function(e) {
/* handle your error */
}
});
}
</script>
The HTML View
Your HTML would be fairly basic, just a place to hold your displayed results and some creative triggers.
<html>
<head>
</head>
<body>
<div class="loadPrev"></div>
<div id="myResults">
<!-- Your Results will show up here -->
</div>
<div class="loadNext"></div>
</body>
</html>
Loading the Page You Want
In basic summation, the last piece of your puzzle is loading the page requested based on the querystring in the URL. If no querystring is present, you want page 1. Otherwise, load the requested page.
<script type="text/javascript">
$( document ).ready(function() {
var page = <?php echo ( isset($_GET['page'] ? $_GET['page'] : 1) ?>;
getPageResults( page, 'next' );
});
</script>
After that you can set up some creative listeners for your previous and next triggers and call the getPageResults() with the needed page, and the next or prev attribute as needed.
This can really be done in a much more elegant sense - look at the JS from the example you provided: http://scrollsample.appspot.com/static/main.js
Cleaning it up
Once you have the basic architecture in place, then you can start altering the .pushState() as well as changing out the canonical, next, and prev <link rel> header items. Additionally at this point you can start to generate the next / prev links you need, etc. It should all fall into place once you have that basic foundation laid.
Hey Bro #LionelRitchietheManatee Finnaly I have resolved the problem this is the code that I used.
<script type="text/javascript">
jQuery(document).ready(function() {
var current = <?php echo ($_GET['page']!='') ? $_GET['page'] : 1; ?>;
var idp;
var loaded = true;
$(window).scroll(function(e){
if(($(window).scrollTop() + $(window).height() == $(document).height())&&(loaded)) {
loaded = !loaded;
current=current+1;
if(current<=1)
{
idp = '';
}
else
{
idp = '?page='+current;
}
loadMoreContent(idp);
history.pushState("state", "title: "+current, "index.php"+idp);
e.preventDefault();
}
if($(window).scrollTop() == 0) {
loaded = !loaded;
current=((current-1)<=0) ? 1 : current-1;
if(current<=1)
{
idp = '';
}
else
{
idp = '?page='+current;
}
loadMoreContent(idp);
history.pushState("state", "title: "+current, "index.php"+idp);
e.preventDefault();
}
});
window.onpopstate = function(event) {
if(current<=1)
{
idp = '';
}
else
{
idp = '?page='+current;
}
loadMoreContent(idp);
history.pushState("state", "title: "+current, "index.php"+idp);
};
function loadMoreContent(position) {
$('#loader').fadeIn('slow', function() {
$.get("index.php"+position+" #annonceis", function(data){
var dato = $(data).find("#annonceis");
$("#annonceis").html(dato);
$('#loader').fadeOut('slow', function() {
loaded = !loaded;
$(window).scrollTop(60);
});
});
});
}
});
</script>
I had added a new var called "loaded" with initial value as TRUE, and it will be updated to FALSE state when content is loaded, and to the TRUE state when we begin scrolling.
I'ts very primitive as solution not very clean work as you did but it solved my problem.
Thank you anyway for your help, you are the BOSS.
I need help creating a split button in WordPress TinyMCE
(function() {
tinymce.create('tinymce.plugins.Wptuts', {
init : function(ed, url) {
ed.addButton('dropcap', {
title : 'DropCap',
cmd : 'dropcap',
image : url + '/dropcap.jpg'
});
ed.addButton('showrecent', {
title : 'Add recent posts shortcode',
cmd : 'showrecent',
image : url + '/recent.jpg'
});
ed.addCommand('dropcap', function() {
var selected_text = ed.selection.getContent();
var return_text = '';
return_text = '<span class="dropcap">' + selected_text + '</span>';
ed.execCommand('mceInsertContent', 0, return_text);
});
ed.addCommand('showrecent', function() {
var number = prompt("How many posts you want to show ? "),
shortcode;
if (number !== null) {
number = parseInt(number);
if (number > 0 && number <= 20) {
shortcode = '[recent-post number="' + number + '"/]';
ed.execCommand('mceInsertContent', 0, shortcode);
}
else {
alert("The number value is invalid. It should be from 0 to 20.");
}
}
});
},
// ... Hidden code
});
// Register plugin
tinymce.PluginManager.add( 'wptuts', tinymce.plugins.Wptuts );
})();
I can create simple buttons for the Wordpress TinyMCE Editor
But I don't know how to create a split button. I'm really having trouble with this. I already searched on Google but I can't find a good examples for creating split button, can someone help me for this?
try this
ed.createSplitButton('splitbutton', {
title : 'Splitbutton',
image : url + '/splitbutton.jpg'
});
I have an order form I'm working on, where I'm using jQuery to update the price in real time when the user selects different options. So, right now, the final project cost, package type, etc are set in jQuery variables, which I need to convert to PHP to insert into the database.
You can easily see the code: http://jsfiddle.net/cadengrant/uddPA/2/
And live preview of working code: http://www.htmlified.com/order-now/
function update_price() {
var base_cost = base_price;
var basic_price = base_price;
var pro_price = base_price;
jQuery('.packages .selected').each(function(index) {
base_cost += jQuery(this).data("price");
basic_price += base_cost;
pro_price += base_cost + 70;
});
jQuery('#markup-pages').each(function(index) {
var price = Number(jQuery(this).val());
var packages = jQuery('.packages .selected').data("price");
var pages = 0;
jQuery('#packages .selected').each(function(index) {
if(jQuery(this).hasClass('basic')) {
if(packages == 199) {
pages = price * 99 - 99;
} else if (packages == 189) {
pages = price * 94 - 94;
} else if (packages == 399) {
pages = price * 199 - 199;
}
} else if (jQuery(this).hasClass('pro')) {
if(pro_price == 269) {
pages = price * 134 - 134;
} else if (pro_price == 259) {
pages = price * 129 - 129;
} else if (pro_price == 469) {
pages = price * 234 - 234;
}
}
});
base_cost += pages;
/* Single or plural page text */
if(price == 1) {
var markup_pages = "markup page";
} else {
var markup_pages = "markup pages";
}
jQuery('.markup-pages').text(markup_pages);
});
jQuery('#packages .selected').each(function(index) {
if(jQuery(this).hasClass('pro')) {
base_cost += 70;
}
});
/* Update Doctype */
jQuery('input[name=page_doctype]:checked', '#order-form').each(function(index) {
var basic_doctype_text = "";
var pro_doctype_text = "";
if(jQuery(this).hasClass('doctypehtml')) {
var doctype_text = "W3C Valid HTML5 & CSS3";
} else if (jQuery(this).hasClass('doctypexhtml')) {
var doctype_text = "W3C Valid XHTML1 & CSS2";
basic_doctype_text += " Transitional";
pro_doctype_text += " Strict";
}
jQuery('.doctype-text').html(doctype_text);
jQuery('.basic-doctype').html(doctype_text + basic_doctype_text);
jQuery('.pro-doctype').html(doctype_text + pro_doctype_text);
});
jQuery('.price').html(base_cost);
jQuery('.basic-price').html(basic_price);
jQuery('.pro-price').html(pro_price);
}
I just need to figure out how to pass those variables (doctype text, basic doctype, pro doctype, base_cost, etc etc) in the JS section to my order.php form, so I can update amount paid, the package type they selected, etc. Any help would be greatly appreciated.
You already have a form in your page. I suggest you create hidden inputs in this form to be submitted with the form. Ex :
<input type="hidden" name="base_cost" value="999">
and you can adjust the value easily with jquery. After submitting the form to the php page you can capture these values using :
$base_cost = $_POST['base_cost'];
But don't forget to sanitize and validate every input from the user.
Hope this helps and excuse my English.
You are looking for a way to tell the Server information from the User? That my friend, without sending the form and without using ajax, will be hard :)
If I am understanding the issue properly, you want some parameters to change in Client side when user triggers some action. In that case you could load the possible parameters on page load and, when user triggers those actions, get the new parameters from those already loaded.
Then when you send the form you add to it the selected parameters.
Hope it helps!
Yes, I KNOW about Google Analytics. We use it for our overall site metrics, and I know we can track individual links. However, we needed a tracking solution for very specific links and we need that tracking data available to our web application in real time, so I wrote my own solution:
jQuery:
$.fn.track = function () {
var source, url, name, ref, $this;
$this = $(this);
if (window.location.search.substring(1) != '') {
source = window.location.pathname + "?" + window.location.search.substring(1);
} else {
source = window.location.pathname;
}
url = jQuery.URLEncode($this.attr('href'));
name = $this.attr('name');
ref = jQuery.URLEncode(source);
$this.live('click', function (click) {
click.preventDefault();
$.post('/lib/track.php', {
url: url,
name: name,
ref: ref
}, function () { window.location = $this.attr('href'); });
});
};
... using the jQuery URLEncode plugin (http://www.digitalbart.com/jquery-and-urlencode/).
Now, this code works fine with my PHP backend and on my machine, but it doesn't seem to work reliably for everyone else. Sometimes the parameters passed in via jQuery are NOT passed in, resulting in a record in the database with no name, url or ref.
For the life of me, I can't figure out why this might be happening; I know the $.post is triggering, since there are records in the database (in the PHP, I also record the IP of the request along with the timestamp), but in many cases the PHP script is receiving blank $_POST variables from jQuery.
I've tested it live on every browser I have access to at my workplace, and all of them work fine for me; however, about 75% of all the records created (not by my computers) come through as blank (most of them are using the same browsers I am).
Why could this be happening?
I think, in the end, my problem ended up being that it was taking too long for the request to be parsed by jQuery, and I'm pretty adamant about not wanting to make the links "dependent" on javascript (either that they wouldn't work without it or that the user would have to wait for the tracking request to complete before they hit the new page).
After browsing many other solutions online--borrowing from some and being inspired by others--I arrived at the solution below in native javascript:
if (document.getElementsByClassName === undefined) { // get elements by class name, adjusted for IE's incompetence
document.getElementsByClassName = function(className) {
var hasClassName, allElements, results, element;
hasClassName = new RegExp("(?:^|\\s)" + className + "(?:$|\\s)");
allElements = document.getElementsByTagName("*");
results = [];
for (var i = 0; (element = allElements[i]) !== null; i++) {
var elementClass = element.className;
if (elementClass && elementClass.indexOf(className) != -1 && hasClassName.test(elementClass)) {
results.push(element);
}
}
return results;
};
}
function addTracker(obj, type, fn) { // adds a tracker to the page, like $('xxx').event
if (obj.addEventListener) {
obj.addEventListener(type, fn, false);
} else if (obj.addEventListener) {
obj['e' + type + fn] = fn;
obj[type + fn] = function() {
obj['e' + type + fn]( window.event );
};
obj.attachEvent('on' + type, obj[type + fn]);
}
}
function save_click(passed_object) { // this function records a click
var now, then, path, encoded, to, from, name, img;
now = new Date();
path = '/lib/click.php';
from = (window.decode) ? window.decodeURI(document.URL) : document.URL;
to = (window.decodeURI) ? window.decodeURI(passed_object.href) : passed_object.href;
name = (passed_object.name && passed_object.name != '') ? passed_object.name : '[No Name]';
// timestamp the path!
path += '?timestamp=' + now.getTime();
path += '&to=' + escape(to) + '&from=' + escape(from) + '&name=' + name; // compile the path with the recorded information
img = new Image();
img.src = path; // when we call the image, we poll the php page; genius!
while (now.getTime() < then) {
now = new Date(); // resets the timer for subsequent clicks
}
}
function get_targeted_links(target) { // finds targeted elements and wires them up with an event handler
var links, link;
if (document.getElementsByClassName) {
links = document.getElementsByClassName(target);
for (var i = 0; i < links.length; i++) {
link = links[i];
if (link.href) {
addTracker(links[i], 'mousedown', save_click(links[i]));
}
}
}
}
addTracker(window, 'load', get_targeted_links('trackit'));
... which seems to be much snappier than the jQuery plugin I had written above, and so far has been fast enough to track all the requests I've thrown at it.
Hope that helps someone else!
These "clicks" might be coming from bots, or someone with JS disabled. If you the links clicked must be tracked why don't you consider JS only links, ie. put URL in a different attr other than href, then use your click handler to process it, add referral check in your track.php
Also have you checked if all elements are links?