Twitter like "x new tweets" with .arte or .ajax? - javascript

I've found this great example to implement a twitter like "x new tweets" http://blog.hycus.com/2011/03/14/realtime-updates-like-twitter-using-phpmysqljquery/
In this example the .arte jQuery plug-in is used. However I think it can be done just as the same with .ajax and I've coded as:
$.ajax({
url:'async.php? main='+$('.boxOfMainPage:first').attr('id'),
success:function(results)
{
if(results!='')
{
if(results.indexOf('boxOfMainPage')>=0)
$('#tweetEveryone').prepend(results);
else
$('#newTweet').html("<center><a href=''>I found "+results+" new tweets</a></center>").show();
}
}
});
This checks the results and loads the result to tweetEveryone. Async.php simply makes a mysql_query and brings the new results. I've actually done exactly the same with the example however when I click the 'new tweet's like it sometimes causes a postback. In the example I haven't experience it. Can it be because of the difference between .arte and .ajax ?

It's nothing about the differences between arte and ajax (in fact and in a short way, arte is ajax that is called with an interval, trying to do something like "long polling")
So, u have a link without href value, this must "reload" ur page, ie, it will perform a GET request to the actual URL in window.location. A postback performs a POST request, this is really happening?
--- edited ---
If you wanna to do the same effect from twitter, it's simple.. In async.php, instead u write an link element that shows how many tweets has after the old state, make this page write a JSON object with all tweets, then, ur ajax function must get this JSON and convert it into a JS object. With this object, u'll be able to count how many updates u have to show and exactly which are they.
So, ur function could be like this (assuming that "#boxOfMainPage" is ur tweets container):
$.ajax({
url : 'async.php?main='+$('.boxOfMainPage:first').attr('id'),
success : function (tweets) {
window.NEW_TWEETS = tweets;
if ( NEW_TWEETS && NEW_TWEETS.length ) {
$('#newTweet').html("<center><a href='#' onclick='showNewTweets()'>I found "+NEW_TWEETS.length+" new tweets</a></center>").show();
}
}
});
The showNewTweets functions will be:
function showNewTweets() {
if ( window.NEW_TWEETS && NEW_TWEETS.length ) {
$('#newTweet').hide().html("");
for ( tweet in NEW_TWEETS ) {
$("#boxOfMainPage").prepend(buildTweetHTML(tweet));
}
}
}
And buildTweetHTML:
function buildTweetHTML(tweet) {
var $tweetElm = $("<div class='tweet'>");
$tweetElm.append("<h2>"+tweet.user+" said:</h2>");
$tweetElm.append("<p>"+tweet.content+"</p>");
$tweetElm.append("<p class='time'>"+tweet.time+"</p>");
return $tweetElm;
}
Finally, async.php should write JSON object like this:
[
{ user : 'Rafael', content : 'The content from tweet', time : 'X time ago' },
{ user : 'George', content : 'The content from tweet', time : 'Y time ago' }
{ user : 'Jack', content : 'The content from tweet', time : 'H time ago' }
]

Related

How to set time between reports of users?

Is it possible to add a timer between reports of a user?I want to add 5 minutes between the reports of a user, or to make disable the button for reports for 5 minutes, even if the user refresh the page.It is possible?
Here is my button for report
<li class="share-link" style="float: right;left: 20px"><a data-toggle="modal" data-target="#exampleModal" href="javascript:void(0)" ><i class="rounded-x icon-flag"></i></a></li>
and after that I have a modal which send the report.
Here is the controller
public function careerReportCareerSolution(requ $request)
{
$reportExists = \App\Reports::where('user_id', $request['user_id'])
->whereDate('created_at', '>', Carbon::now()->subMinutes(5)->toDateTimeString())
->exists();
if($reportExists) {
// report has been created within 5 minutes
return Redirect::back()->withErrors(['error', 'Report created within the last 5 minutes']);
}
$report = \App\Reports::create([
'user_id' => $request['user_id'],
'username' => $request['username'],
'user_id_posted' => $request['user_id_posted'],
'username_posted' => $request['username_posted'],
'career_solution_id' =>$request['career_solution_id'],
'subject' =>$request['subject'],
'why_reporting' =>$request['why_reporting'],
'why_reporting_message' =>$request['why_reporting_message'],
'additional_message' =>$request['additional_message'],
'comment' =>$request['comment'],
'comment_user' =>$request['comment_user'],
'comment_id' =>$request['comment_id'],
]);
$id = $request['career_solution_id']; // looks like this is the ID you ar looking for
$career = CareerSolution::findOrfail($id);
$career->active = $request['active'];
$career->save();
if($report != ""){
flash('Career solution report submited', 'success');
}else{
flash('Career solution report', 'warning');
}
return Redirect::back();
}
}
So, I to set a time between reports, 3-5 minutes a user shouldn't be able to make a report.
Untested, however assuming you are using timestamps (created_at, updated_at) on the Report table, you should be able to achieve this with the following logic:
$reportExists = \App\Report::where('user_id', $request['user_id'])
->whereDate('created_at', '>', now()->subMinutes(5)->toDateTimeString())
->exists();
if ($reportExists) {
// report has been created within 5 minutes
return Redirect::back()->withErrors(['error', 'Report created within the last 5 minutes');
}
...
This will check whether or not a report has been created for that user within the last 5 minutes using the ->whereDate() eloquent query method.
The ->exists() method is used to find out if there is at least one occurance of the report.
A check is made to see if $reportExists is true. If so, the application will redirect the user to the same page with an error message (fill the ->withErrors() method with the appropriate message).
This should be placed before all other controller logic.

Populate data from groovy controller in pop up

I have a gsp page with a delete button for each row of a table. On the button click I want a pop up which tells the consequences of the delete. These consequences depends on the data present in the row and a few other constraints known to the grails service which is called from the grails controller associated to the gsp page. If the user confirms these consequences the row should be deleted from the table, else the table remains unchanged.
How should i go about to achieve this behavior?
Currently, I have in my gsp
<tr>
<td>name</td>
<td>parentName</td>
<td>data</td>
<td>
<g:link action="deleteRow" params="${[name: row.name, parentName: row.parentName]}">
<button class="deleteSnapshot">Delete</button>
</g:link>
</td>
</tr>
and in my .js file
$(document).on('click', ':button', function (e) {
var btn = $(e.target);
btn.attr("disabled", "disabled"); // disable button
alert('getting deletion details');
//var deletionDetails -->not sure how to get these
//var deletionDetails will get data from controller action:"getDetails"
if (confirm('/*print deletion details and ask*/ Do you want to proceed?')) {
alert('will delete')
return true
}
else {
btn.removeAttr("disabled"); // enable button
return false
}
});
and in my controller
class DeleteController{
DeleteService deleteService
def index() {
[list:deleteService.getTableList()]
}
def getDeletionDetails(string name, String parentName){
return deleteService.getDetails(name,parentName)
}
def deleteRow(String name, String parentName){
service.deleteRow(name, parentName)
redirect controller:"DeleteController", action:"index"
}
}
I know the deletion works fine, because it works even with in the current state. Just that the confirmation box asks Do you want to proceed, without displaying the details.
Any help on how i could achieve what I am looking for will be appreciated.
P.S. I am new to stackoverflow, so if i missed out on certain convention do let me know.
Thanks in advance.
I can think of two ways of doing it:
The first one is using ajax to both get deletion details and delete the row
Assuming that deleteService.getDetails(name, parentName) returns a String,
first you need to change an getDeletionDetails action so it renders the response:
def getDeletionDetails(String name, String parentName){
render deleteService.getDetails(name, parentName)
}
and change g:link-s to buttons in gsp:
<button data-name="${row.name}" data-parent-name="${row.parentName}">
Delete
</button>
In your .js then put:
$(document).on('click', ':button', function (e) {
var btn = $(e.target);
btn.attr("disabled", "disabled"); // disable button
var name = btn.data('name');
var parentName = btn.data('parentName');
$.ajax({
url: "/delete/getDeletionDetails",
data: {
name: name,
parentName: parentName
},
success: function (data) {
if (confirm(data + '\nDo you want to proceed?')) {
$.ajax({
url: '/delete/deleteRow',
data: {
name: name,
parentName: parentName
},
success: function (d) {
console.log("Success: " + d);
}
});
} else {
btn.removeAttr("disabled"); // enable button
}
}
});
});
What this code does is it sends an ajax call to /delete/getDeletionDetails, then uses its response (rendered by getDeletionDetails action in DeleteController) to show a confirmation alert. If user confirms the question, another ajax call is sent - now to deleteRow action of DeleteController - with parameters taken from data attributes of clicked button. If user cancels - nothing happens, except for reenabling a button.
Your deleteRow should only change the return statement - it also must render the response:
def deleteRow(String name, String parentName){
service.deleteRow(name, parentName)
render "You deleted an item $name - $parentName."
}
You don't need redirect here, because - thanks to using ajax - user will never leave delete/index. You can just display some kind of confirmation on page after successful ajax call.
The second option is to put deletion details in hidden fields or data- attributes in each row and then just retrieve them in js:
You can create a method getDeletionDetails() in row's domain class (presumably Row) that returns the details (using services in domain classes is not perfect, but is should work ok if the service is not very complex). Then, in your .gsp place:
<td>
<g:link action="deleteRow" params="${[name: row.name, parentName: row.parentName]}">
<button class="deleteSnapshot" data-details="${row.deletionDetails}">Delete</button>
</g:link>
</td>
You should then be able to get details in .js like this:
var deletionDetails = btn.data('details');

Grails RemoteFunction creates bad javascript

I am taking over a project from an engineer that left my company, and am having to quickly come up to speed on Grails, so if this is a noob question, well, I'm a noob.
In one of one of my GSP files, I've got a remoteFunction call in the middle of a javaScript function:
function fnCreateEntitiesPerForceChart() {
var interval = $("#entitiesPerForceTimeIntervalSelect").val();
var url = '${createLink(controller: 'federation', action: 'createEntitiesPerForceChart')}?interval='+escape(interval);
$("#entitiesPerForceChart").attr("src", url);
${remoteFunction(controller: 'federation',
action: 'getEntitiesPerForceTable',
params: '\'interval=\'+interval',
onSuccess: 'fnUpdateEntitiesPerForceTable(data,textStatus)')};
}
That remoteFunction call is being sent to the client as:
try{DojoGrailsSpinner.show();}catch(e){} dojo.xhr('Get',{content:{'interval='+interval}, preventCache:true, url:'/FederationReporter/federation/getEntitiesPerForceTable', load:function(response){ fnUpdateEntitiesPerForceTable(data,textStatus); }, handle:function(response,ioargs){try{DojoGrailsSpinner.hide();}catch(e){} }, error:function(error,ioargs){try{DojoGrailsSpinner.hide();}catch(e){} } });;
Which is causing a error:
SyntaxError: missing : after property id
...){} dojo.xhr('Get',{content:{'interval='+interval}, preventCache:true, url:'/Fed...
federation (line 400, col 60) (which is the bolded '+' before the second 'interval'
What am I missing?
Dojo content should be a key-value pair.
{content:{'interval': interval}

Javascript Error,Escaping Problem,Grid not working,Error on Firebug

we are just started with Sigma Grid ,and it is awesome in its functionality when we compared to other Grids.
But i encountered some problem with Sigma Grid ,or may be with javascript.
I dont know whether the problem is with Grid or with my code.
I have a table with 3 fields namely MailID,MailName,MailData.
MailID is int ,MailName and MailData contains HTML content and it save as string in database.
When i load the Grid,i have some problems.
Problem 1 :
As i said above the Maildata contain html content,the following image is just a example with <*b> ,u can see that the HTML is automatically rendering on the grid itself ,i need the exact string.
please check the following image.
Problem 2 :
as u can see i have links on the grid,for edit,send,delete but on one filed its damaged.[check the image below ]
the code i used to render links is following .
{id: 'mailid' , header: "Action", width :120 , resizable : false, sortable : false , printable : false ,
renderer : function(value ,record,columnObj,grid,colNo,rowNo){
var no= record[columnObj.fieldIndex];
var cod = (record['maildata']);
return 'Edit | Delete';
Problem 3 :
The third value of MailData is 5 and it is integer ,when i alert the value its shows it correctly.
check the following image.
But when i alert the second value of maildata it giving error ,the second value of MailData is "hai newuser" ,it showing the following error on firebug.
missing ) after argument list
alert(hai newuser)
check the image below.
But when i alert 9th value of MailData it run correctly ,the content is <b>poy</b> ,this one is also save as string,but the grid automatically BOLD [which i dnt like].Check the image below.
also there are some others the 7the value contain ;".: etc ,also /b ,when i alert the data it showing the following error,
unexpected end of XML source
alert(<b>jjfdslkdjflsdnfsldfnf
dsOptions and ColOptions are following .
var dsOption= {
fields :[
{name : 'mailid' },
{name : 'mailname',type:"text" },
{name : 'maildata',type:"text" }
],
recordType : 'object',
}
function my_renderer(value ,record,columnObj,grid,colNo,rowNo)
{
var no= record[columnObj.fieldIndex];
return "<img src=\"./images/flag_" + no.toLowerCase() + ".gif\">";
}
function showalert(no)
{
$(document).ready(function()
{
$.post("http://localhost/power/index.php/power/give",{ name: no}, function(data)
{
//alert("Data Loaded: " + data);
$("#editor").show("fast");
$( '#txtar' ).ckeditor();
$('#txtar' ).val( data.maildata );
//$("#editor").html(data);
},"json"
);
});
}
var colsOption = [
{id: 'mailid' , header: "Mail ID" , width :60},
{id: 'mailname' , header: "Mail Name" , width :160 ,type:"text"},
{id: 'maildata' , header: "Mail Data" , width :190,type:"text" },
{header: "Group" , width :70,
editor : { type :"select" ,options : {'php':'php','asp':'asp'}
,defaultText : 'php' } },
{id: 'mailid' , header: "Action", width :120 , resizable : false, sortable : false , printable : false ,
renderer : function(value ,record,columnObj,grid,colNo,rowNo){
var no= record[columnObj.fieldIndex];
var cod = (record['maildata']);
return 'Edit | Delete';
} }
];
I am littlebit new in Javascript and Sigmagrid,i think that i am doing something worst with codes,pls help me to success.
Thank you.
Note : i posted the same Question on Sigma Grid Forum too,i think that it is not a problem.
Problem 2
The string cod contains a >
Problem 3
The string hai newuser needs to be contained in " or ' or it is considered a variable name
Basically you have to decide -- are you going to validate the html or not. If you don't validate the HTML then html errors in the data will show as errors on your page. You could also HTML escape the html so you will see the HTML codes -- this is probably the best plan.
Other sites use (like this one) use markdown -- this is easier to validate -- then they generate the actual HTML before display.
In addition you are having problems with the alert. Alert displays strings not HTML so you will see what you are seeing -- different results than expected depending on the HTML.
I would take a step back and ask yourself -- what is the type of the data, how am I going to display it. How am I going to validate that if it is HTML it is valid.
There are the problems you need to address -- your examples all stem from this problem.

JQuery-Ui Autocomplete not displaying results

I am trying to display autocomplete results for a list of managers. I have the following code:
Application.js
function log(message) {
$( "<div/>" ).text( message ).prependTo("#log");
}
$("#managers").autocomplete({
source : function(request, response) {
$.ajax({
url : "/managerlist",
dataType : "json",
data : {
style : "full",
maxRows : 12,
term : request.term
},
success : function(data) {
var results = [];
$.each(data, function(i, item) {
var itemToAdd = {
value : item,
label : item
};
results.push(itemToAdd);
});
return response(results);
}
});
}
});
Project controller
def manager_list
list=Project.all.map{|i|i.manager_user_id}
arr= [].concat(list.sort{|a,b| a[0]<=>b[0]}).to_json
render :json =>arr
end
Routes.rb
match '/managerlist' => 'projects#manager_user_id'
_form.html.erb
<p>
<%= f.label :manager_user_id %><br />
<input id="managers" />
</p>
The following code is fine, I don't recieve no errors in firebug. However when I try to enter a managers name for example James Johnson the name won't appear. I have also tried putting the whole function in the _form.html.erb and wrapped it in tags this didn't work. Is there any idea why this is happening
So I've managed to fix my error, which was because of the ordering of Jquery core and Jquery ui.
I've got the managers to be listed. In the image below.
From the image it can be seen that when I type 'Arm' it brings the entire list of managers, when it should display 'Deshawn Armstrong'. I understand that this is most probably to do with my project controller below
Project controller
def manager_list
list=Project.all.map{|i|i.manager_user_id}
arr= [].concat(list.sort{|a,b| a[0]<=>b[0]}).to_json
render :json =>arr
end
Check the response in the Firebug console and make sure the string is in proper json format for the autocomplete.
It appears that you are just returning an array. The dataType setting in .ajax doesn't convert to json; it's just expecting that format back. If you are not sending json back from your url : "/managerlist", this may be the problem.
Actually, provided your ajax function is working correctly, you could just:
return response(JSON.stringify({ results: results }));
jsfiddle example of JSON.stringify: http://jsfiddle.net/xKaqL/
Based on your new information, you need to add a minLength option to your autocomplete.
$("#managers").autocomplete({
minLength: 2, // 2 or whatever you want
// rest of your code

Categories

Resources