I am trying to create a Ajax function which will create an article navigation according to their date of creation, so the user can navigate through articles using previous(older) and next(newer) links.
<div class="content clear">
<div class="article">
Article contents...
</div>
EELMINE<span class="arrow_left"></span>
Tagasi nimekirja juurde<span class="arrow_middle"></span>
JÄRGMINE<span class="arrow_right"></span>
</div> <!-- End content -->
<script type="text/javascript">
$.ajax({
url: '/admin/api/site/articles.json?per_page=100',
dataType: 'json',
success: function(articles) {
$(articles).each(function(index, article) {
console.log(article);
$('div.article').fadeOut(0);
$('div.article:first').fadeIn(500);
$('a.leftarrow, a.rightarrow').click( function (ev) {
//prevent browser jumping to top
ev.preventDefault();
//get current visible item
var $visibleItem = $('div.article:visible');
//get total item count
var total = $('div.article').length;
//get index of current visible item
var index = $visibleItem.prevAll().length;
//if we click next increment current index, else decrease index
$(this).attr('href') === '#Next' ? index++ : index--;
//if we are now past the beginning or end show the last or first item
if (index === -1){
index = total-1;
}
if (index === total){
index = 0
}
//hide current show item
$visibleItem.hide();
//fade in the relevant item
$('div.article:eq(' + index + ')').fadeIn(500);
});
});
}
});
I'm having difficulties constructing the function responsible for getting the articles according to their date value.
Using console.log(article), I get the following values:
body: "..."
comments_count: 0
comments_url: "..."
created_at: "date and time ..."
excerpt: "..."
title: "..."
url: "..."
So it should be possible to use the created_at variable for the navigation, but I don't know how at the minute.
Any ideas?
CMS used: Edicy
Note: The CMS does not support PHP.
EDIT: The article listing sample on the "blog" page provided by the CMS developer documentation.
The easier way to do it is use your model as much as you can, and do it with sql "limit"
I don't know what database do you use, so I'll make some steps with mysql database.
I'm confuse with your code, why you call ajax without nothing press? or you are hiding some code?
Let me try with this code:
assume that you have a container div and 2 static navigation button
Next
Back
<div id="container"></div>
<script>
$("#next, #back").click(function(){
//get page number
//0 means no page to load
var page = $(this).data("page");
if(page == 0)return false;
$.ajax({
url : "your/url/?page=" + page,
dataType: "json",
success : function(data){
var container = $("#container");
$.each(data, function(index, article){
container.append(article); // or do something you want
});
if($this.attr("id") == "next") $("#next, #prev").data("page", $this.data("page") + 1);
else $("#next, #prev").data("page", $this.data("page") - 1);
}
});
});
</script>
for the backend :
<?php
$page = $_GET["page"];
$perPage = 100;
$start = ($page - 1) * $perPage; // minus 1, because limit start from 0
$sql = "SELECT * FROM table WHERE 1=1 LIMIT $start, $perPage";
//execute the sql and get the result (ex. result)
echo json_encode($result);
I wish my answer will help you.
I checked the API on edicy, seems like it doesn't allow you to filter by created_at.
But based on your code, you can use query string to get the current index of the article in a specific page.
For example:
Start with http://insenerid.edicy.co/uudised/2013/, it is also called page 1. There are 4 articles and you have to add ?page=1&index={0..3} to each article URL like this:
from http://insenerid.edicy.co/uudised/2013/aasta-ehitusprojekt-2012-tiitli-kandidaadiks
to http://insenerid.edicy.co/uudised/2013/aasta-ehitusprojekt-2012-tiitli-kandidaadiks?page=1&index=1 (because it's the second article in page 1)
Then, modify your code:
// This is for example: page = 1, index = 1
// You have to write extra code to get the query string you need.
var page = 1, index = 1;
$.ajax({
url: '/admin/api/site/articles.json?per_page=100&page=' + page,
// ...
// Replace
// $('div.article:first').fadeIn(500);
// with
$('div.article:eq(' + index + ')').fadeIn(500);
If your question is how to sort the data received by your ajax call,
you could simply use the array.sort([compareFunction]) before to use them.
(see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort)
like this:
...
success: function(articles) {
articles.sort(function (a, b) {
var d1 = new Date(a.created_at);
var d2 = new Date(b.created_at);
if (d1 < d2) return -1;
if (d1 == d2) return 0;
return 1;
});
$(articles).each(function(index, article) {
// alert(article.created_at);
console.log(article);
....
Related
Below is the code.
under the function there is a resultContainer.innerHTML that populates a list of QR codes scanned. How can $_POST the values in PHP so that I can send it in an email format? I tried adding a name within the div (<div **name="qrOutput"**>[${countResults}] - ${qrCodeMessage}</div>) but PHP does not pick it up. Only returns an empty string.
I also tried giving the <div id="qr-reader-results"></div> element a name but because the output is within another div inside this div I also got an empty result.
Thanks a lot for any help.
<!-- start -->
<div id="qr-reader" style="width:500px"></div>
<div id="qr-reader-results"></div>
<div id="root"></div>
<script>
function docReady(fn) {
// see if DOM is already available
if (document.readyState === "complete" ||
document.readyState === "interactive") {
// call on next available tick
setTimeout(fn, 1);
} else {
document.addEventListener("DOMContentLoaded", fn);
}
}
docReady(function() {
var resultContainer = document.getElementById('qr-reader-results');
var lastResult, countResults = 0;
function onScanSuccess(qrCodeMessage) {
if (qrCodeMessage !== lastResult) {
++countResults;
lastResult = qrCodeMessage;
resultContainer.innerHTML += ***`<div">[${countResults}] - ${qrCodeMessage}</div>`;***
}
}
var html5QrcodeScanner = new Html5QrcodeScanner(
"qr-reader", {
fps: 10,
qrbox: 250
});
html5QrcodeScanner.render(onScanSuccess);
});
</script>
<p id="QRout"></p>
You can store your results in an other variable when you add it to the DOM.
Declare a variable to store your results
var myResults = [];
When you add the result to the DOM add also the results in array variable
// ...
resultContainer.innerHTML += `<div>[${countResults}] - ${qrCodeMessage}</div>`;
myResults.push({count: countResults, message: qrCodeMessage})
Then you can use myResult var on a POST request
myCustomPostFunction('/yourUrl/', myResult);
The "myCustomPostFunction" will depend on the way you want to send the data
Check this codepen: https://codepen.io/zecka/pen/VwKNpze
Post request like a form submit
If you want to send the data to the current page like a form post, you can find an example here: https://stackoverflow.com/a/133997/2838586
Post request to a rest api
Fetch: POST json data
I have been trying to debug for this days now, and I’m not sure what the problem is.
To give you a little background:
I'm working on a project that pulls the top headline on the politics section of a far left news source (Huffington Post), a moderate left (CNN), a moderate right (Fox), and a far right (Breitbart).
From here, I’m finding Reddit posts referencing that article and appending it to the html. All of this is being done through YQL.
Here's an example with how I'm using CNN.
//CNN
$(function getCNNNews() {
var statement = "select * from feed where url='http://rss.cnn.com/rss/cnn_allpolitics.rss'";
$.queryYQL(statement, "json", undefined, function (data) {
// do something with "data".
console.log(data.query.results.item);
//Get first object in array
console.log(data.query.results.item[0]);
var firstObjectCNN = data.query.results.item[0];
$("#col2").append("<h1 id='cnn'>" + firstObjectCNN.title + "</h1>");
$("#col2").append("<h4 id='cnn'> Published by CNN <br/>" + firstObjectCNN.pubDate + "</h4>");
//Search for the top post referencing that headline on Reddit
$(function getCNNPostReddit() {
var newStatement = encodeURIComponent(firstObjectCNN.title).replace(/'/g , "%27");
var statement = "select * from feed where url='https://www.reddit.com/search.xml?q=" + newStatement + "&sort=new'";
$.queryYQL(statement, "json", undefined, function (data) {
console.log(statement);
console.log(data);
var firstCNNEntryResults = data.query.results;
if (firstCNNEntryResults == null)
{
document.getElementById("loading2").style.display = 'inline-block';
}
else
{
// Get first entry's (which is the entry with the most comments) rss feed containing comments
var firstCNNEntry = data.query.results.entry[0];
console.log("select * from feed where url='" + firstCNNEntry.link.href + ".rss");
// Erase end of URL that's not needed
var firstCNNEntryLink = firstCNNEntry.link.href;
firstCNNEntryLink = firstCNNEntryLink.substring(0, firstCNNEntryLink.indexOf('?'));
console.log(firstCNNEntryLink);
//Create a dynamic rss feed based on link to first entry; this is where the comments will come from.
$(function getCNNRedditComments() {
var statement = "select * from feed where url='" + firstCNNEntryLink + ".rss'" ;
$.queryYQL(statement, "json", undefined, function (data) {
console.log(data.query.results.entry);
//Start with the 4th comment; since the first 3 comments are auto moderator
for (var i = 0; i < data.query.results.entry.length; i++) {
console.log(data.query.results.entry[i].content.content);
$("#col2 #comment-box").append("<div id='comment'><span id='username'>" + data.query.results.entry[i].author.name + "</span>" + ":" + data.query.results.entry[i].content.content + "</div>")
}
});
});
}
});
});
});
});
I've made it so when the results come out null, I replace the comments with a loading symbol. The issue I'm having is, sometimes the comments will show, and other times they won't.
The current state of the site is here:
leftright.info
Reddit has a limit to how often you can fetch their RSS feeds. I had that problem too, so I came up with a workaround. I've created a public tool for it on my website.
https://burkybang.com/reddit_rss
What my script does:
I open https://mylink.com/#script
The script in my chrome extension checks for the #script in the URL and calls a function
The function clicks some checkboxes and then a "submit" button
After 3 seconds the script refreshes the website with the hashtag to create an infinite loop
Problem:
The data from the checkboxes/submit need to go through to the server - that's why I have to wait some time before refreshing. The 3 seconds seem to be enough for that.
Sometimes the website takes 15 seconds until it redirects me to the new site after submitting, but sometimes it's lightning fast and opens the new website before the 3 seconds before the reload have passed - since the opened website doesn't have the #script, my loop stops working.
What I need help with:
How long does it take to send the information from the form so they get through to the server? I know that I don't have to wait for the server's answer and the redirection to the new page, but I think I can't refresh instantly.
Is there a way to detect at which point the new site will be opened so the script could call a function before that happens and redirect to the URL with the hashtag? Or even better: Detect the moment when the information is completely sent from the client side and then instantly refresh.
I would like to keep the time the whole loop needs as short as possible!
Code for understanding:
The submit form on the website:
<form action="/withdraw-request" method="post">
<input type="hidden" name="_csrf" value="YEZknGzr-HW1ThkFrf9bO1M_IuQRJSVk-W6M">
<div id="items">...contains checkboxes...</div>
<input class="button right blue" type="submit" value="Withdraw selected items">
</form>
My content.js (in the chrome extension):
chrome.extension.sendMessage({}, function(response) {
var readyStateCheckInterval = setInterval(function() {
if (document.readyState === "complete") {
clearInterval(readyStateCheckInterval);
if(window.location.hash=="#script") {
var tradestatus = document.getElementsByTagName("td");
console.log("Offer-status: " + tradestatus[8].innerHTML);
var oneKeyOnly = true;
function checkItem() {
var itemsArray = ["Apples", "Bananas", "Melons", ];
var matchingItems = [];
var x = document.getElementsByClassName("item");
for(var y = 0; y < x.length; y++){
if(itemsArray.indexOf(x[y].getAttribute("data-name")) >= 0){
var id = x[y].getElementsByClassName("item-checkbox")[0].getAttribute("id");
matchingItems.push(id);
}
}
return matchingItems;
}
function randomIntFromInterval(min,max)
{
return Math.floor(Math.random()*(max-min+1)+min);
}
function clickButton(val)
{
var buttons = document.getElementsByTagName('input');
for(var i = 0; i < buttons.length; i++)
{
if(buttons[i].type == 'submit' && buttons[i].value == val)
{
buttons[i].click();
console.log("Trying to withdraw!");
break;
}
}
}
var result = checkItem();
var lengthOfArray = result.length - 1;
if (oneKeyOnly == true) {
var rand = randomIntFromInterval(0,lengthOfArray);
document.getElementById(result[rand]).checked = true
console.log("Found: " + result[rand]);
}
else {
for(index=0, len = result.length; index < len; ++index) {
document.getElementById(result[index]).checked = true
keynr = index + 1;
console.log("Found " + result.length + " fruits - Selected Nr. " + keynr + "!");
}
}
clickButton("Withdraw selected items");
unloadready = true;
setTimeout((function(){ location.reload(true) }), 3000);
}
}
}, 10);
});
Withdraw.js:
Pastebin: http://pastebin.com/9q72Ti2b
It gets called from somewhere. I can see it in the "network" tab next to the chrome console.
Edit_1:
I tried to use google for a while now and found an ajax documentation and a piece of code that I tried to modify so it would work for me. There is still some really basic stuff that I don't understand.
The code:
$('#submit').click(function()
{
$.ajax({
url: withdraw-request,
type:'POST',
data:
{
items,
_csrf
},
success: function(msg)
{
alert('Success!');
location.reload(true);
}
});
});
Here is the form again from that website with one of the checkboxes added.
<form action="/withdraw-request" method="post">
<input type="hidden" name="_csrf" value="YEZknGzr-HW1ThkFrf9bO1M_IuQRJSVk-W6M">
<input type="checkbox" name="items" value="34155017" class="item-checkbox" id="item-34155017" data-price="562500">
<input class="button right blue" type="submit" value="Withdraw selected items">
</form>
So if I understand it right, then the website is using POST to send "_csrf" and "items" to "withdraw-request" (added the names to "data" in the code).
Why is there nothing like ".php" on "withdraw-request"?
How can I call this code if the form doesn't have a name for its own?
How can I add something like "onClick" or "onSubmit" to a website that is not my own and where I can't change the actual code? Solved that one myself!
document.getElementsByTagName("FORM")[1].setAttribute("onsubmit", "specialFunction()");
Edit_2:
Kind of made it work:
I added this to my 'content.js' to add a name to the form and an ajax function:
var formAdd = document.getElementsByTagName('FORM');
formAdd[1].setAttribute("id", "submitthisform");
var $form = $("#submitthisform");
// register handler for submit first
$form.submit(function (event) {
$.ajax({
type: $form.attr("method"),
url: $form.attr("action"),
data: $form.serialize()
})
.done(function (data) {
})
.fail(function (r, s, e) {
});
event.preventDefault();
});
I can call this by $form.submit();. It seems to work, but it still redirects to the new page. What am I doing wrong here?
I have a problem with javascript. I use google api and it contains ajax. The problem here is that, I need to catch values from URL like http://examplesite.com/index.php?s=some+values . I need to search values automatically. I try to do this for along time. However, I couldn't. How can I do this ?
This is my submit form:
<form id="searchForm" method="post">
<fieldset style="width: 520; height: 68">
<input id="s" type="text" name="s" />
<input type="submit" value="Submit" id="submitButton" />
Here is my javascript codes:
$(document).ready(function(){
var config = {
siteURL : 'stackoverflow.com', // Change this to your site
searchSite : true,
type : 'web',
append : false,
perPage : 8, // A maximum of 8 is allowed by Google
page : 0 // The start page
}
// The small arrow that marks the active search icon:
var arrow = $('<span>',{className:'arrow'}).appendTo('ul.icons');
$('ul.icons li').click(function(){
var el = $(this);
if(el.hasClass('active')){
// The icon is already active, exit
return false;
}
el.siblings().removeClass('active');
el.addClass('active');
// Move the arrow below this icon
arrow.stop().animate({
left : el.position().left,
marginLeft : (el.width()/2)-4
});
// Set the search type
config.type = el.attr('data-searchType');
$('#more').fadeOut();
});
// Adding the site domain as a label for the first radio button:
$('#siteNameLabel').append(' '+config.siteURL);
// Marking the Search tutorialzine.com radio as active:
$('#searchSite').click();
// Marking the web search icon as active:
$('li.web').click();
// Focusing the input text box:
$('#s').focus();
$('#searchForm').submit(function(){
googleSearch();
return false;
});
$('#searchSite,#searchWeb').change(function(){
// Listening for a click on one of the radio buttons.
// config.searchSite is either true or false.
config.searchSite = this.id == 'searchSite';
});
function googleSearch(settings){
// If no parameters are supplied to the function,
// it takes its defaults from the config object above:
settings = $.extend({},config,settings);
settings.term = settings.term || $('#s').val();
if(settings.searchSite){
// Using the Google site:example.com to limit the search to a
// specific domain:
settings.term = 'site:'+settings.siteURL+' '+settings.term;
}
// URL of Google's AJAX search API
var apiURL = 'http://ajax.googleapis.com/ajax/services/search/'+settings.type+'?v=1.0&callback=?';
var resultsDiv = $('#resultsDiv');
$.getJSON(apiURL,{q:settings.term,rsz:settings.perPage,start:settings.page*settings.perPage},function(r){
var results = r.responseData.results;
$('#more').remove();
if(results.length){
// If results were returned, add them to a pageContainer div,
// after which append them to the #resultsDiv:
var pageContainer = $('<div>',{className:'pageContainer'});
for(var i=0;i<results.length;i++){
// Creating a new result object and firing its toString method:
pageContainer.append(new result(results[i]) + '');
}
if(!settings.append){
// This is executed when running a new search,
// instead of clicking on the More button:
resultsDiv.empty();
}
pageContainer.append('<div class="clear"></div>')
.hide().appendTo(resultsDiv)
.fadeIn('slow');
var cursor = r.responseData.cursor;
// Checking if there are more pages with results,
// and deciding whether to show the More button:
if( +cursor.estimatedResultCount > (settings.page+1)*settings.perPage){
$('<div>',{id:'more'}).appendTo(resultsDiv).click(function(){
googleSearch({append:true,page:settings.page+1});
$(this).fadeOut();
});
}
}
else {
// No results were found for this search.
resultsDiv.empty();
$('<p>',{className:'notFound',html:'No Results Were Found!'}).hide().appendTo(resultsDiv).fadeIn();
}
});
}
function result(r){
// This is class definition. Object of this class are created for
// each result. The markup is generated by the .toString() method.
var arr = [];
// GsearchResultClass is passed by the google API
switch(r.GsearchResultClass){
case 'GwebSearch':
arr = [
'<div class="webResult">',
'<h2>',r.title,'</h2>',
'<p>',r.content,'</p>',
'',r.visibleUrl,'',
'</div>'
];
}
// The toString method.
this.toString = function(){
return arr.join('');
}
}
});
Look at my answer here. As you can see, it is not too difficult to set a get parameter. Now, I will show you how you can get a get parameter:
function getGetParameter(paramName)
{
var url = window.location.href;
if (url.indexOf(paramName + "=") >= 0)
{
var returnValue = url.substring(url.indexOf(paramName + "="));
if (returnValue.indexOf("&") >= 0)
{
returnValue = returnValue.substring(0, returnValue.indexOf("&"));
}
return returnValue.substring(returnValue.indexOf("=") + 1);
}
return null;
}
As about searching for values automatically, you need to specify what and how would you like to search for, as this can be needed/done literally in infinitely many ways.
maybe this is the problem: you're trying to use an API and it's no longer avaiable.
Object {responseData: null, responseDetails: "This API is no longer available.", responseStatus: 403}
More information here: https://developers.google.com/image-search/v1/jsondevguide
Now, I'm trying to find a migration to version 2.
I am writing some JavaScript code, where I am using a closure for a counter. The code is given below:
function userHandler(){
var counter = 0;
var limit = "<?php echo ($_SESSION['limit']); ?>";
return function(){
var args = {
n : $('#name').val(),
s : $('#ssn').val(),
i : $('#id').val()
};
$.post("adduser.php",args,function(data){
var response = JSON.parse(data);
console.log(args);
if(response.status == 0){
counter += 1;
alert(counter);
if (counter == limit){
$('#limit').text(limit-counter);
}
}
console.log(data);
});
};
}
var opcall = userHandler();
$('#addUser').on("click", opcall);
I am using this guide to write the code. The problem is, my counter always shows 1 in the alert box. It does not increment. Am I not calling the inner method correctly?
EDIT: There's a span in the HTML which is receiving the limit-counter value:
<p>
<span>Add User</span>
You can add <span id="limit"></span> more users. <a href='<?php echo $root; ?>editaccount.php?action=addOp'>Add another operator?</a>
</p>
It always shows (20-1)=19 every time I submit the form which uses the Javascript.
UPDATE: Thank you for pointing out my mistake, after clicking the "addUser" button, another page was opening with a confirmation message, where a link had to be clicked to return to the original page. I moved the confirmation message to the original page and now it works fine!!