I have a method for adding likes to a page
blade.php
<a href="/article/{{ $article->id }}?type=heart" class="comments-sub-header__item like-button">
<div class="comments-sub-header__item-icon-count">
{{ $article->like_heart }}
</div>
<a href="/article/{{ $article->id }}?type=finger" class="comments-sub-header__item like-button">
<div class="comments-sub-header__item-icon-count">
{{ $article->like_finger }}
</div>
Adding a like on click
js
$(function() {
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content'),
},
});
$('.like-button').on('click', function(event) {
event.preventDefault();
let href = $(this).attr('href');
$.ajax({
url: href,
type: 'POST',
success: function() {
window.location.reload();
},
});
});
});
Next, I made an active class with styles, and when I click on the like to the class class="comments-sub-header__item like-button" this class should be added active
But there is one more thing, my likes are stored in cookies, and 24 hours after clicking we can put a new like, that is, the active class should also be disabled after 24 hours
This is how I implemented it adding a like to cookies
Route::post('article/{id}', 'App\Http\Controllers\ArticleController#postLike');
public function postLike($id, Request $request) {
$article = Article::find($id);
if(!$article){
return abort(404);
}
$type = $request->input('type');
if ($article->hasLikedToday($type)) {
return response()
->json([
'message' => 'You have already liked the Article '.$article->id.' with '.$type.'.',
]);
}
$cookie = $article->setLikeCookie($type);
$article->increment("like_{$type}");
return response()
->json([
'message' => 'Liked the Article '.$article->id.' with '.$type.'.',
'cookie_json' => $cookie->getValue(),
])
->withCookie($cookie);
}
public function hasLikedToday(string $type)
{
$articleLikesJson = Cookie::get('article_likes', '{}');
$articleLikes = json_decode($articleLikesJson, true);
if (!array_key_exists($this->id, $articleLikes)) {
return false;
}
if (!array_key_exists($type, $articleLikes[$this->id])) {
return false;
}
$likeDatetime = Carbon::createFromFormat('Y-m-d H:i:s', $articleLikes[$this->id][$type]);
return ! $likeDatetime->addDay()->lt(now());
}
public function setLikeCookie(string $type)
{
$articleLikesJson = Cookie::get('article_likes', '[]');
$articleLikes = json_decode($articleLikesJson, true);
$articleLikes[$this->id][$type] = now()->format('Y-m-d H:i:s');
$articleLikesJson = json_encode($articleLikes);
return cookie()->forever('article_likes', $articleLikesJson);
}
As I understand it, all this should be done in js, but I still do not really understand it, so I ask for a hint
Simply share a variable in the view where you show the "like" buttons somewhere in your controller:
// Your controller
public function show(Request $request, $postId)
{
$post = Post::find($postId);
$hasLikedToday = $post->hasLikedToday('heart');
return view('your.view.file', [
'article' => $article,
'hasLikedToday' => $hasLikedToday, // share this variable to check if you've liked today
]);
}
After sending the hasLikedToday variable to your blade where the like buttons are defined, you simply check if the variable is true, if so, show the active class. Now every time you refresh that page, it will check if the active class must be shown, no need for javascript to do that.
<a href="/article/{{ $article->id }}?type=heart" class=" ... {{ $hasLikedToday ? 'active' : '' }}">
<div class="comments-sub-header__item-icon-count">
{{ $article->like_heart }}
</div>
Related
I have table with a column for checkbox, When a certain button is clicked i send checked checkboxs with ajax request to a controller to download a pdf file after it has been made ,but unfortunately it doesn't fire the download box .i hope you help me out.
My Ajax :
<script>
$(document).ready(function()
{
$(document).on('click', '#minvoice', function(event)
{
//var alert = confirm('Are You Sure?');
var checkedValues = $('#chkbx:checked').map(function() {
return this.value;
}).get();
$.post('{{route('payments.multiple_invoices')}}', {'checkboxs' : checkedValues, '_token' : $('input[name=_token]').val() }, function(data){
console.log(data);
});
});
});
</script>
My Controller :
public function multiple_invoices(Request $request)
{
if ($request->isMethod('post'))
{
//export invoice
$requestData[] = $request->checkboxs;
$filenamepdf = public_path().'/export/invoices/multiple_invoices.pdf';
$data = self::getMulInvoiceData($requestData);
PDFHelper::export($data, $filenamepdf, true);
return Response::download($filenamepdf, 'Multiple_invoice_'.date('Y-m-d').'_'. time().'.pdf', []);
}
}
public static function getMulInvoiceData($requestData)
{
$payments = UnitPayment::whereIn('id', $requestData)->get();
return View::make('payments.mulInvoice', compact('payments'));
}
My Views:
<td><input id="chkbx" type="checkbox" value="{{ $payment->id }}" /></td>
MulInovices.blade.php :
#foreach($payments as $payment)
<div align="left" style="text-align: left;"><b>payment : {{$payment->id}} </b></div>
#endforeach
My Route:
Route::any('payments/multiple_invoices', ['uses' => 'PaymentsController#multiple_invoices','as' => 'payments.multiple_invoices']);
i hope you tell me how to get this to work . thanks
Try changing
return Response::download($filenamepdf, 'Multiple_invoice_'.date('Y-m-d').'_'. time().'.pdf', []);
to
return Response::download($filenamepdf, 'Multiple_invoice_'.date('Y-m-d').'_'. time().'.pdf', ['Content-Type' => 'application/pdf']);
(Difference is code below is added in to third parameter [] of Response::download)
'Content-Type' => 'application/pdf'
If you are using Laravel 5+ you can use code below
response()->($filenamepdf, 'Multiple_invoice_'.date('Y-m-d').'_'. time().'.pdf', ['Content-Type' => 'application/pdf']);
What we did is add headers to recognise response as a pdf file.
I want to also change my status message when I click on them. This is the image where I want to apply
As shown in image, the active status need to change to inactive when I click on it. I can do it with edit page but now I want to change status when I click on active on page load. this is my code ctp file
<td class="center">
<?php if($listings['status']=="1") { ?>
<span class="label label-success">Active</span>
<?php } else if($listings['status']=="0") {?>
<span class="label label-error">Inactive</span>
<?php } ?>
</td>
this is controller code
if ((!empty($this->request->data['action'])) && (!empty($this->request->data['ids'])))
{
$action=$this->request->data['action'];
$ids=$this->request->data['ids'];
switch($action)
{
case "active":
$this->request->data['status']="1";
foreach($ids as $id)
{
$this->Listing->id = $id;
$this->Listing->save($this->request->data);
}
$this->Session->setFlash(__('Active Successfully'),'default',array('class' => 'alert alert-success'), 'alert');
$this->redirect(array('controller'=>'Listing','action' => 'index'));
break;
case "inactive":
$this->request->data['status']="0";
foreach($ids as $id)
{
$this->Listing->id = $id;
$this->Listing->save($this->request->data);
}
$this->Session->setFlash(__('InActive Successfully!'),'default',array('class' => 'alert alert-success'), 'alert');
$this->redirect(array('controller'=>'Listing','action' => 'index'));
break;
Please help me and tell how to do that with ajax or jquery.
Try this:
HTML: <button type="button" class="active" data-id="2">Active/button>
//Note that data-id ...It's just an attribute I created, and the value "2" I //believe will be dynamic in your case -Probably that college ID in the DB
JAVASCRIPT (Jquery required)
<script>
$(document).on('click', 'button[data-id]', function(event) {
event.preventDefault();
var collegeID = $(this).attr('data-id');
$.ajax({
url: 'changeStatus',
type: 'POST',
dataType: 'json',
data: {id: collegeID},
success: function(data){
if (data['status'] == "success") {
$('button[data-id]').removeClass('active').addClass('inactive');
/*Class active and inactive should be in your CSS with color according to their names*/
};
}
});
});
</script>
CONTROLLER:
public function changeStatus(){
$this->autoRender = false;
if ($this->request->is('ajax')) {
$data = $this->request->data;
/*The id that was passed thru data-id attribute is here: */
//$data['id'] Use it to update your DB
//After successful update
$response = array('status' => 'success');
return json_encode($response);
}
}
Then Last but not the least, is your route:
Router::connect('/changeStatus', array('controller' => 'yourcontroller', 'action' => 'changeStatus'));
Hope that help.
Good luck
You can actually do as simple as this:
$("body").on("click", "#status", function(e) {
e.preventDefault();
var stat = find("span#span_id").val(); // get the status current value
$.get('./db_file', function(data) {
if (data.stat != stat)
$("#span_id").removeClass("label label-error").addClass("label label-success");
}, "json");
});
Something like that would work.
I am trying to implement a "like" button for my website. I am using Codigniter, Ajax and Jquery. When the like button is clicked data should be entered to database and if unlike button is pressed data should delete from database. But I am facing a problem in model, data is not added to database when I click like button. Please help me to find a solution.
This is my Jquery file "likeitem.js"
function likeItem(postId)
{
if ($("#likeItem_"+postId).text() == "Like")
{
$("#likeItem_"+postId).html('Unlike');
var purpose = "Like";
}
else
{
$("#likeItem_"+postId).html('Like');
var purpose = "UnLike";
}
$.ajax({
type : "POST",
url : "http://localhost/codeig_smarty/index.php/user/likeItem",
data : "postId=" + postId + "purpose=" + purpose,
success : function()
{
}
});
return false;
}
This is my model "usermodel.php"
public function itemLike()
{
$id = $this->session->userdata('userID');
$postId = $this->input->post('postId');
$purpose = $this->input->post('purpose');
if($purpose=="Like")
{
// echo 'test';
// exit();
$data = array(
"userID" => $id,
"postTextID" => $postId,
);
$this->db->insert('like', $data);
}
else
{
echo 'hai';
}
}
This is my view file "home.tpl"
<li><a class="like-unlike" href="#" id="likeItem_{$item['postID']}" onclick="likeItem({$item['postID']})">Like</a></li>
This is my Controller "user.php"
public function likeItem()
{
$this->usermodel->itemLike();
}
You mistake here. You forgot to put & symbol. Try this code.
data : "postId=" + postId + "&purpose=" + purpose,
Full code:
If you want to manipulate result returned from ajax, you can do something on success block as following code :
$.ajax({
type : "POST",
url : "http://localhost/codeig_smarty/index.php/user/likeItem",
data : "postId=" + postId + "&purpose=" + purpose,
success : function(data)
{
// do seomthing here with data
// console.log(data) --> to see data return or not
}
});
I have a problem using bootstrap modal for updating data.
On CGridView selectionChanged, it will trigger a function to show modal dialog form and insert the data to the form
Here is my CGridView :
<?php
$this->widget('customCGridView', array(
'id'=>'contactperson-grid',
'itemsCssClass' => 'table table-bordered',
'selectionChanged'=>'showmodal',
'dataProvider' => $contactperson->search(),
'emptyText' => '',
'enableSorting' => false,
'htmlOptions' => array('class' => ' '),
'columns' => array('nama', 'jabatan')
));
?>
On selectionChanged, it will trigger this script to open the update dialog modal and fill the form with selected CGridView column data :
function showmodal(grid_id) {
var keyId = $.fn.yiiGridView.getSelection(grid_id);
keyId = keyId[0]; //above function returns an array with single item, so get the value of the first item
$.ajax({
url: '<?php echo $this->createUrl("suppliertable/personview"); ?>',
data: {id: keyId},
type: 'GET',
success: function(data) {
$("#contact-person-modal").html(data);
$('#kontakmodalupdate').modal('show');
}
});
}
Here is the actionPersonView which will be executed upon selecting column :
public function actionPersonView($id) {
$contactperson = SupplierContactPersonTable::model()->findByPk($id);
if ($contactperson === null)
throw new CHttpException(404, 'The requested page does not exist.');
$this->renderPartial('updateForm', array('contactperson'=> $contactperson));
Yii::app()->end();
}
Now, here is the problem :
When I Click update button on update form, I need to pass ID to my action :
public function actionPersonUpdate($id) {
$model2=$this->loadModel2($id);
// Uncomment the following line if AJAX validation is needed
// $this->performAjaxValidation($model);
if(isset($_POST['SupplierContactPersonTable']))
{
if($model2 === null) {
throw new CHttpException(404, 'The requested page does not exist.');
}
$model2->attributes=$_POST['SupplierContactPersonTable'];
$model2->save();
}
}
To pass this value, I'm using AjaxButton on my form:
<div id="contact-person-modal">
<?php
$form = $this->beginWidget('CActiveForm', array(
'id' => 'suppliercontactmodalform',
'htmlOptions' => array(
'class' => 'smart-form',
'novalidate' => '1',),
'enableAjaxValidation' => false,));
?>
...
<footer>
<button type="button" class="btn btn-labeled btn-danger cancel-button" style="float: left">
Hapus Pengguna
</button>
<?php
echo CHtml::ajaxButton('Update', Yii::app()->createUrl('suppliertable/personupdate',array('id'=>$contactperson->contact_person_id)), array('type'=>'POST'), array('type'=>'submit',"class" => "btn btn-primary"));
?>
<button type="button" class="btn btn-default" data-dismiss="modal">
Batal
</button>
</footer>
...
However, it seems like ID isn't passed. Here is Firebug console :
POST http://localhost/webapp/index.php/suppliertable/personupdate/
400 Bad Request
As you can see, no ID is passed.
But, if I use static parameter value :
echo CHtml::ajaxButton('Update', Yii::app()->createUrl('suppliertable/personupdate',array('id'=>'5')), array('type'=>'POST'), array('type'=>'submit',"class" => "btn btn-primary"));
The ID is passed :
POST http://localhost/webapp/index.php/suppliertable/personupdate/5
So, I think the problem is here, is not outputing value :
$contactperson->contact_person_id
Here is generated jQuery from Yii :
jQuery('body').on('click','#yt0',function({
jQuery.ajax({
'type':'POST',
'url':'/webapp/index.php/suppliertable/personupdate id=',
'cache':false,
'data':jQuery(this).parents("form").serialize()
});
return false;
});
Thanks for your help :)
I've found my solution.
In case someone have the same problem, I need to update my actionPersonView method :
public function actionPersonView($id) {
if (Yii::app()->request->isAjaxRequest) {
Yii::app()->clientScript->scriptMap['jquery.js'] = false;
Yii::app()->clientScript->scriptMap['jquery.min.js'] = false;
$contactperson = SupplierContactPersonTable::model()->findByPk($id);
if ($contactperson === null)
throw new CHttpException(404, 'The requested page does not exist.');
$this->renderPartial('updateForm', array('contactperson'=> $contactperson),false,true);
Yii::app()->end();
}
}
I need to add in my actionPersonView method
$this->renderPartial('updateForm', array('contactperson'=> $contactperson),false,true);
And add
Yii::app()->clientScript->scriptMap['jquery.js'] = false;
Yii::app()->clientScript->scriptMap['jquery.min.js'] = false;
To prevent the script being executed multiple.
I am making a LIVE UPDATE in CodeIgniter and it is almost working.
Just one little issue: When I click the button it also appears my navigation inside the "responds" box which is very strange.
And when I refresh the page it is removed and the record is there.
Here is an image to explain what I mean
Here is the JavaScript:
<script type="text/javascript">
$(document).ready(function() {
//##### Add record when Add Record Button is click #########
$("#FormSubmit").click(function (e) {
e.preventDefault();
if($("#contentText").val() ==='')
{
alert("Please enter some text!");
return false;
}
var myData = 'content_txt='+ $("#contentText").val(); //build a post data structure
jQuery.ajax({
type: "POST", // Post / Get method
url: "<?php echo site_url('admin/dashboard/index'); ?>", //Where form data is sent on submission
dataType:"text", // Data type, HTML, json etc.
data:myData, //Form variables
success:function(response) {
$("#responds").append(response);
},
error:function (xhr, ajaxOptions, thrownError) {
alert(thrownError);
}
});
});
});
</script>
EDIT:
HERE IS THE CONTROLER
class Dashboard extends CI_Controller
{
public function __construct()
{
parent::__construct();
// Load libraries
$this->load->library('ion_auth');
$this->load->library('parser');
// Load models
$this->load->model('note_model');
// Load helpers
$this->load->helper('date');
// Set error delimiters
$this->form_validation->set_error_delimiters('<div class="alert alert-danger">', '</div>');
}
public function index()
{
// Check if user is loged in
if (!$this->ion_auth->logged_in())
{
redirect('auth/login');
}
else
{
// Create notes object
$notes = new Note_model();
// Order the notes by date post
$notes->order_by('date_post', 'desc')->get();
$recent_notes = array();
foreach ($notes as $note)
{
$single_note = array
(
'id' => $note->id,
'note_text' => $note->note_text,
'date_post' => $note->date_post,
);
array_push($recent_notes, $single_note);
}
// Get the user id as an object
$getinfo = $this->ion_auth->user($this->session->userdata('user_id'))->row();
// Create a new note
$createNote = new Note_model();
$createNote->note_text = $this->input->post('content_txt');
$created = date('Y-m-d H:i:s');
$createNote->date_post = $created;
// Validation rules
$rules = $this->note_model->rules;
$this->form_validation->set_rules($rules);
$data = array
(
'admin_content' => 'admin/dashboard',
'notes' => $recent_notes,
'username' => $getinfo->{'first_name'} . ' ' . $getinfo->{'last_name'},
);
if ($this->form_validation->run() == FALSE)
{
$this->parser->parse('admin/template_admin', $data);
}
else
{
$createNote->save();
redirect('admin/dashboard');
}
}
}
The problem is the action you are calling.
It seems admin/dashboard/index outputs the navigation as well as the data you want to display.
You should post to an action that ONLY displays the data you require, and nothing else