How do you pass in the post id in angular if your using laravel ?
this is what i currently have, i tried referencing this
https://docs.angularjs.org/api/ng/service/$http
but im not really understanding.
Main.js
$scope.like = function() {
var post = {
// this doesn't work and i dont know how to pull in the post id.
id: "<% $post->id %>"
};
$http.post('post/like/'+ post).success(function(result) {
checkLike();
});
};
function checkLike(){
var post = {
id: "<% $post->id %>"
};
$http.get('post/'+ post '/islikedbyme').success(function(result) {
if (result == 'true') {
$scope.like_btn_text = "Delete Like";
} else {
$scope.like_btn_text = "Like";
}
});
};
Route
Route::get('post/{id}/islikedbyme', 'PostController#isLikedByMe');
Route::post('post/like', 'PostController#like');
Controller
public function isLikedByMe($id)
{
$post = Post::findOrFail($id)->first();
if (Like::whereUserId(Auth::id())->wherePostId($post->id)->exists()){
return 'true';
}
return 'false';
}
public function like(Post $post)
{
$existing_like = Like::withTrashed()->wherePostId($post->id)->whereUserId(Auth::id())->first();
if (is_null($existing_like)) {
Like::create([
'post_id' => $post->id,
'user_id' => Auth::id()
]);
} else {
if (is_null($existing_like->deleted_at)) {
$existing_like->delete();
} else {
$existing_like->restore();
}
}
}
this work i got the post id by using ng-init to pass in post id.
Html
<div id="mypost" class="col-md-8 panel-default" ng-repeat="post in myposts ">
<div id="eli-style-heading" class="panel-heading"><% post.user.name %></div> // i need someway to pull in the post id. so i used ng-init not sure if this best practices.
<div class="panel-body panel" ng-init="getL(post)">
<i style="color:tomato; float:right; font-size:24px;" ng-click="like(post)" class="glyphicon glyphicon-heart"></i>
<figure>
<p ng-model="post.body" editable-text="post.body" e-form="textBtnForm"> <% post.body %></p>
<p name="created_at" ng-model="post.created_at"> <% post.user.created_at | phpDate : "human" %></p>
</figure>
<span>
<i style="color:red;" class="glyphicon glyphicon-remove" ng-click="deletePost(post)" ng-if="post.deletable"></i>
<button ng-if="post.update" class="btn btn-default" ng-click="textBtnForm.$show()" ng-hide="textBtnForm.$visible">
Edit
</button>
<span><button ng-if="post.update" type="submit" class="btn btn-primary" ng-click="updatePost(post)">Update</button></span>
</span>
</div>
</div>
Main.js
$scope.like = function(post) {
$http.post('/post/like/'+ post.id).then(function(result) {
getL();
});
};
$scope.getL = function(post){
$http.get('/post/'+ post.id +'/islikedbyme').then(function(result) {
if (result == 'true') {
$scope.like_btn_text = "Delete Like";
} else {
$scope.like_btn_text = "Like";
}
});
}
Route
Route::get('post/{id}/islikedbyme', 'PostController#isLikedByMe');
Route::post('post/like/{post}', 'PostController#like');
Post Controller
public function like(Post $post, Request $request)
{
$existing_like = Like::withTrashed()->wherePostId($post->id)->whereUserId(auth()->id())->first();
if (is_null($existing_like)) {
Like::create([
'post_id' => $post->id,
'user_id' => auth()->user()->id
]);
} else {
if (is_null($existing_like->deleted_at)) {
$existing_like->delete();
} else {
$existing_like->restore();
}
}
}
Related
I have a view in which I need after a click to send a javascript variable to a controller which contains a form that I send to the database.
So after the click, I'm using ajax to call my controller and load the html on the same view like this:
$(".month").click(function(){
var click = $(this);
var month = click.val();
var year = $("#years").val();
var url = Routing.generate('av_platform_formulaire');
$.ajax(url,
{
type: 'GET',
data: {"month": month,
"year" : year},
dataType: "html",
success: function (data) {
$('#content').empty();
$('#content').append(data);
},
error : function(jqXHR, textStatus, errorThrown){}
});
});
So far there is no problem, my view containing the form is loading correctly and I receive the data I sent via the ajax request but when I fill my form and try to submit it, the page is refreshing and it's like nothing happens...
Here is my 2 controllers (the second is the problematic one):
public function saisieAction(Request $request){
$thisyear = date("Y");
return $this->render('AvPlatformBundle:Platform:saisie.html.twig',
array(
'year' => $thisyear
));
}
public function formulaireAction(Request $request){
$user = $this->getUser();
$em = $this->getDoctrine()->getManager();
//$repository = $em->getRepository('AvPlatformBundle:NoteDeFrais');
// Create the form
$form = $this->get('form.factory')->createBuilder(FormType::class)
->add('ndf', CollectionType::class, array(
'entry_type' => NoteDeFraisType::class,
'label' => false,
'allow_add' => true,
'allow_delete' => true,
))
->getForm();
if ($request->isXmlHttpRequest()){
$month = $request->get('month');
$year = $request->get('year');
$sub_date = $month . '/' . $year;
}
if ($request->isMethod('POST') && $form->handleRequest($request)->isValid()) {
// After debugging, the code inside the if is not executed
$notesDeFrais = $form['ndf']->getData();
foreach ($notesDeFrais as $ndf) {
$ndf->setUser($user);
$ndf->setMois($sub_date);
$em->persist($ndf);
}
$em->flush();
}
return $this->render('AvPlatformBundle:Platform:formulaire.html.twig',
array(
'form' => $form->createView()
));
}
My view containing the form:
<div id="ms_form">
{{ form_start(form) }}
<div id="bloc_saisie" class="fieldset">
<fieldset>
<div id="form_ndf" class="form_ndf" data-prototype="
{% filter escape %}
{{ include('AvPlatformBundle:Platform:prototype.html.twig', { 'form': form.ndf.vars.prototype }) }}
{% endfilter %}">
</div>
<div class="buttons">
<button type="button" class="fas fa-plus" id="add_ndf"></button>
<input type="submit" class="btn btn-primary btn-lg" id="next_button" >
</div>
</fieldset>
</div>
{{ form_row(form._token) }}
{{ form_end(form, {'render_rest': false}) }}
</div>
Can someone please tell me how to output data from my controller to an HTML form. I want to change the label of an anchor from "Like" to "Liked" if the user has already clicked the link previously.
Here is the HTML.
<section class="row posts">
<div class="col-md-6 col-md-3-offset">
<header><h3>other posts</h3></header>
#foreach($posts as $post)
<article class="post">
<p>{{ $post->content }}</p>
<div class="info">Posted by {{ $post->user->username }} on {{ $post->created_at }}</div>
<div class="interaction">
Like
#if(auth()->user() === $post->user)
|
Edit |
Delete
#endif
</div>
</article>
#endforeach
</div>
<script>
var token = '{{ session()->token() }}';
var urlLike = '{{ route('like') }}';
</script>
</section>
The JavaScript to get the postid from the form:
...
$('.like').on('click', function (event) {
event.preventDefault();
postId = event.target.dataset.postid;
var isLike = event.target.previousElementSibling==null ? true:false;
$.ajax({
method: 'POST',
url: urlLike,
data: {isLike: isLike, postId: postId, _token: token}
})
.done(function () {
//change the page
})
})
...
The route:
Route::post('/like',[
'uses' => 'PostController#postLikePost',
'as' => 'like'
]);
Finally, can someone please tell me how to send the output from the controller to the HTML form?
public function postLikePost(Request $request)
{
$post_id = $request['postId'];
$is_like = $request['isLike'] === 'true' ? true : false;
$post = Post::find($post_id);
if (!$post) {
return null;
}
$user = Auth::user();
$like = $user->likes()->where('post_id', $post_id)->first();
if ($like) { // user already liked the post
$like->delete();
return null; // output to "Like" in the html form here
}
$like = new Like();
$like->post_id = $post->id;
$like->user_id = $user->id;
$like->save(); // output to "Liked" in the html from here
return null;
}
The label of the Like anchor should change from Like to Liked if the user has already like the post.
I'd set up both as POSTs and then in your success block query the result and set to either like or liked. Something like:
success: function (data) {
document.getElementById("something").innerHTML = "Liked";
}
You can do it something like this, change it as per your need though.
public function postLikePost(Request $request)
{
$post = Post::where('id', $request->get('post_id'))->first();
if(!$post){
return response()->json(['status' => 1, 'message' => 'post not found']);
}
if($post->liked == 1)//change it as per your model
{
return response()->json(['status' => 2, 'message' => 'already liked']);
}
$post->status = 1;
$post->save();
return response()->json(['status' => 3, 'message' => 'liked']);
}
and in your ajax success
success: function(response){
if(response.status == 1){
window.alert('Post Not Found')
}
else{
document.querySelector('#likeBtn').innerHTML = 'liked'
}
like button
Like
I was wondering how I am able to blacklist certain words from being entered in my form. Specifically, the username field. I'm not sure if I need access to the PHP/JS files, but I have limited access to those.
<div class="form-group">
<label for="username" class="control-label">{{ lang('signup.username') }}</label>
<input type="text" class="form-control" id="username" value="{{ data['login'] }}" name="RegistrationForm[login]" placeholder="Enter username">'===
</div>
{% if name_fields %}
<script>
function is_banned_name($data) {
$banned_names = array(
'socialwizards', 'socialwizard', 'bulkfollow', 'bulkfollows'
);
foreach($banned_names as $banned_name) {
$pattern = '/('.$banned_name.')/';
$match = preg_match($pattern,$data);
if($match) {
return true;
}
}
return false;
}
if(is_banned_name($_POST['username'])) {
<div class="alert alert-dismissible alert-danger {% if site['rtl'] %} rtl-alert {% endif %}">
<button type="button" class="close" data-dismiss="alert">×</button>
{{ errorMessage }}
</div>
}
</script
(Added this to the end of my form)
You can do it with PHP using javascript is not secure as user can manipulated or disable JavaScript.
function is_banned_name($data) {
$banned_names = array(
'admin', 'test', 'user', 'fake', 'hack', 'error'
);
foreach($banned_names as $banned_name) {
$pattern = '/('.$banned_name.')/';
$match = preg_match($pattern,$data);
if($match) {
return true;
}
}
return false;
}
Then you can say
if(is_banned_name($_POST['username'])) {
// do something
}
You can do it with JavaScript but its not advisable. The code below is an example of how JavaScript code will do it. The code will return true if the name consist of the banned names.
function is_banned_name(str) {
var banned_names = ['admin', 'hacker', 'test', 'user', 'free']; banned_names.forEach(element => {
if(str.match(element)) { return true; }
});
} ```
I'm only able to fetch data with title and body attribute, but when i get data for the name it shows up empty when i refresh the page but shows when i submit automatically.
For some reason angularjs is not retrieving the name successfully.
Note: I'm using laravel.
For example here:
Here is the server side:
PostController
public function getPosts() {
$posts = Post::with('user')->get();
$response = new Response(json_encode($posts));
$response->headers->set('Content-Type', 'application/json');
return $response;
}
public function storePost(Request $request) {
$data = request()->validate([
'title' => 'required|max:120',
'body' => 'required|max:1000'
]);
$data['user_id'] = auth()->user()->id;
$data['name'] = auth()->user()->name;
$post = Post::create($data);
$response = new Response(json_encode($data));
$response->headers->set('Content-Type', 'application/json');
// return redirect('/home')->withMessage('A new post was created.');
return $response;
}
main.js
$scope.myposts = {};
$scope.addPost = function() {
$http.post('/auth/post', {
title: $scope.post.title,
body: $scope.post.body
}).then(function(data, status, headers, config) {
console.log(data);
$scope.myposts.push(data.data);
});
$scope.post.title = '';
$scope.post.body = '';
};
$scope.deletePost = function(post) {
var index = $scope.myposts.indexOf(post);
if (index != -1) {
$scope.myposts.splice(index, 1);
}
$http.delete('auth/post/' + post.id);
};
$scope.getPosts = function() {
$http.get('/auth/posts').then(function(data) {
$scope.myposts = data.data;
}).then(function(data, status, header, config) {});
};
HTML:
<div id="mypost" class="col-md-8 panel-default" ng-repeat="post in myposts">
<div id="eli-style-heading" class="panel-heading">
<% post.title %>
</div>
<div class="panel-body panel">
<figure>
<p>
<% post.body %>
</p>
by:
<p>
<% post.user.name %>
</p>
</figure>
<span><button ng-click="deletePost(post)">x</button></span>
</div>
</div>
When i first add content without refresh(asynchronously)
on page refresh
above
(different log for different post)
Your reload page is okay since
$posts = Post::with('user')->get();
returns
{
"title": "title",
"body": "body",
"user": {
"name": "name"
}
}
and in your angular you display it by
<% post.user.name %>
So the solution to display it when you added is to restructure your json object before pushing to array
$scope.addPost = function() {
$http.post('/auth/post', {
title: $scope.post.title,
body: $scope.post.body
}).then(function(data, status, headers, config) {
console.log(data);
data.data['user'] = {
name: data.data.name
}
$scope.myposts.push(data.data);
});
$scope.post.title = '';
$scope.post.body = '';
};
I trying to build a CRUD using Vue.js and Laravel, but... I can Save, Read and Update the only problem is the Delete, can someone help me?
My index.blade.php: (to get id)
<div class="modal inmodal" id="delete" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content animated bounceInRight">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">Fechar</span></button>
<h4 class="modal-title">Delete</h4>
</div>
<div class="modal-body">
<div class="form-group">
<p>Do you want delete this row <strong>ID: </strong> #{{competency.id}} <strong>Nome: </strong> #{{competency.name}} </p>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-white" data-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-danger" v-on:click="remove(competency.id)">Delete</button>
</div>
</div>
</div>
My Vue.js
var competency = new Vue({
el: '#competency',
filters: {
moment: function (date) {
return moment(date).format('DD/MM/YYYY');
}
},
data: {
competency: "",
searchQuery: '',
search: {
name: ""
},
list: [],
},
methods: {
fillCompetency: function(comp){
if (comp == null)
this.competency = {
id : "",
name : "",
description : "",
}
else
this.competency = comp;
},
del: function(index){
this.fillCompetency(this.list[index]);
$("#delete").modal('show');
},
remove: function(id){
var self = this;
self.competency._token = window.Laravel.csrfToken;
$.ajax({
url: "competency",
type: "POST",
dataType: 'json',
traditional: true,
data: id
}).done(function(data){
self.filter();
$("#delete").modal('hide');
fillCompetency(null);
});
}
},
mounted: function () {
this.filter();
},
watch: {
}
});
My Controller
class CompetencyController extends Controller {
public function __construct(){
$this -> middleware('auth');
}
public function index(){
return view('competency/index');
}
public function filter(){
$list = Competency::all();
return response()->json($list);
}
public function create(){
}
public function store(Request $request){
$entity = new Competency;
if ($request->id != null){
$entity = Competency::find($request->id);
}
if ($request->name == null && $request->description == null){
$entity = Competency::find($id);
return response()->json($entity->delete());
}
$entity->name = $request->name;
$entity->description = $request->description;
return response()->json($entity->save());
}
public function delete($id){
$entity = new Competency;
$entity = Competency::find($id);
return response()->json($entity->delete());
}
public function show($id){
}
public function edit($id){
}
public function update(Request $request){
}
public function destroy($id){
$entity = new Competency;
$entity = Competency::find($id);
return response()->json($entity->delete());
}
}
My route:
Route::resource('competency', 'CompetencyController');
The problem is, i have tried to send DELETE method on remove from Vue, but i get an error called 500 (Internal Error Serve) but on laravel.log dont show anything, i have tried send DELETE method because the desroy method is called correct? so i get error instead i send by POST method to store and check if just id is not null, if not i called method delete by laravel, so any method that i hev tried dont work, can someone help me?
I think that the error is on Route, but i tried everything too
Try changing your delete method to this
// your route for delete should be
Route::delete('competency/{id}', 'Controller#delete');
// controller
public function delete($id){
$responseMsg = "Competency not found";
$status = 404;
$entity = Competency::find($id);
if ($entity != null ){
$responseMsg = "Competency deleted";
$status = 204;
$entity->delete(); // delete method is void, doen't return any value
}
return response()->json(['message' => $responseMsg], $status);
}
Vue.js remove method
remove: function(id){
var self = this;
self.competency._token = window.Laravel.csrfToken;
$.ajax({
url: "competency/"+id,
type: "DELETE", //
traditional: true
// if you use POST method, data has to be a json object
// {id: id} then in laravel you could do $request->input('id');
}).done(function(data){
self.filter();
$("#delete").modal('hide');
fillCompetency(null);
});
}