I currently have a very simple application which initially calls a php file to get data and then iterate through the dataset and create a table. Within the table I have an "Enable/Disable" button which when clicked would update the model, which in turn would push to the persistence layer. The issue I am running into is that while I am able to update the model which updates the view nicely, I am unable to figure out how to get the persistence layer part of it working. I added two custom functions for the service "enable/disable" to reflect the button click event, but am not really sure if I am heading in the correct direction or not but my code is below.
The View partial:
<table class="table table-hover">
<thead><tr><th>Name</th><th>Username</th><th>Details</th><th>Facility</th><th>Last Login</th><th>Days from last login</th></tr></thead>
<tbody>
<tr ng-class="{'error':user._accountDisabled,'success':user._accountDisabled==false}" ng-repeat="user in users | filter:query | orderBy:orderProp">
<td>{{user._firstName}} {{user._lastName}}</td>
<td>{{user._userName}}</td>
<td><a class="btn btn-primary" href="#/userExceptions/{{user._userName}}">Details</a></td>
<td>{{user._facilityName}}</td>
<td>{{user._hrLastLogon}}</td>
<td>{{user._daysLastLogon}}</td>
<td>
<ng-switch on="user._accountDisabled">
<button ng-switch-when=true class="btn btn-primary" ng-click="enable(user)">Enable</button>
<button ng-switch-when=false class="btn btn-danger" ng-click="disable(user)">Disable</button>
</ng-switch>
</td>
</tr>
</tbody>
</table>
The custom service for persistence:
angular.module('userServices', ['ngResource']).
factory('User', function($resource) {
return $resource('userActions.php', {}, {
query: {method: 'GET', params: {userName: 'userName'}, isArray: true},
enable: {method: 'GET',params: {action: 'enable', userName: 'userName'}}},
disable: {method: 'GET', params: {action: 'disable', userName: 'userName'}}
});
});
Finally the controller:
function UserExceptionsCtrl($scope, User) {
$scope.users = User.query();
$scope.orderProp = '_firstName';
$scope.enable = function(user) {
$scope.user = user;
$scope.user._accountDisabled = false;
$scope.user.$save();
User.enable({userName:user._userName});
};
$scope.disable = function(user) {
$scope.user = user;
$scope.user._accountDisabled = true;
$scope.user.$save();
User.disable({action: 'disable', userName: self._userName});
};
}
EDIT As requested server side code:
The useractions file processes the request and creates mappers to retrieve a user object. From the user object it updates the necessary property and saves it in the persistence layer.
userActions.php
$username = (isset($_REQUEST['userName']) ? $_REQUEST['userName'] : '');
$action = (isset($_REQUEST['action']) ? $_REQUEST['action'] : '');
require 'library/autoloader/src/autoload.php';
try {
$ADUserMapper = new UserMapper(new LDAPAdapter());
switch ($action) {
case 'enable':
$ADUserEditMapper = new UserMapper(new LDAPAdapter());
$user = $ADUserEditMapper->findByUsername($username);
if ($user) {
$user->enableADAccount();
$ADUserEditMapper->updateUAC($user);
}
break;
case 'disable':
$ADUserEditMapper = new UserMapper(new LDAPAdapter());
$user = $ADUserEditMapper->findByUsername($username);
if ($user) {
$user->disableADAccount();
$ADUserEditMapper->updateUAC($user);
}
break;
default:
$adapter = new PdoAdapter();
$employeeDBMapper = new EmployeeMapper($adapter);
$ADUsers = $ADUserMapper->findMultipleUsers(array('objectClass' => 'user'), "OU=Users,DC=domain,DC=com", TRUE);
$exceptions = array();
foreach ($ADUsers as $user) {
$employee = $employeeDBMapper->findByUserName($user->userName);
if (!$employee) {
array_push($exceptions, $user);
}
}
$result = array();
foreach ($exceptions as $user) {
array_push($result, $user->getExceptionData());
}
echo json_encode($result);
break;
}
} catch (Exception $e) {
echo json_encode(array('error' => true, 'errorMessage' => $e->getMessage()));
}
Related
I'm trying to build a simple website builder that allow users to save their generated html created with Vue component and see it at a certain URL.
Because of it I have to store and retrieve the html generated but I have some problems with retrieving of the code. Here is my step:
When user click "save" this function is fired, that select the portion of HTML that include the "website" built by the user:
saveBuilders: function () {
let pages = [];
let builders = $('[id*="builder-container-"]');
$.each(builders, function (key, builder) {
let singleElem = $(builder).attr('id');
pages.push(clearElement.html());
});
this.storeInDb(pages);
},
storeInDb: function (pagesList) {
axios.post("/landing-page/store", {
name: this.name,
description: this.description,
html: pagesList
})
.then(function (response) {
console.log('Cool');
})
.catch(function (error) {
console.log('ERROR', error.response);
});
},
The Axios request is handled by this function that store the html portion in DB
public function store(Request $request)
{
$data = $request->all();
$html = $data['html'];
$landingPage = new LandingPage();
$landingPage->name = $data['name'];
$landingPage->description = $data['description'];
$landingPage->user_id = Auth::user()->id;
$landingPage->html = json_encode($html);
try {
$landingPage->save();
return 'true';
} catch (exception $e) {
return $e;
}
}
Now when the user visit a certain URL, for keep thing simple suppose is example.it/website/0, this function is fired:
public function show($landing_id)
{
try {
$landingPage = LandingPage::where([
'id' => $landing_id,
'user_id' => Auth::user()->id
])->first();
} catch (\Exception $e) {
$landingPage = null;
}
if ($landingPage != null) {
//GET THE HTML
$page = json_decode($landingPage->html);
return view('landing_page.show')->with('page', $page)
} else {
abort(404, 'Error');
}
}
And this the blade where I'm trying to re-create the Vue.js environment
<body>
<span id="countdown"></span>
<div id="builder-pagina">
<builder>
{!! $page !!}}
</builder>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script src="{{asset('js/landing_page/app.js')}}"></script>
</body>
</html>
I thought that having the html generated by vue similar to something like that into the DB...
<div data-v-29b64d26="" >
<h1>This piece of code was stored into my DB</h1>
<div data-v-56f62f0a="">
</div>
</div>
...you could create everything working simply by pasting the code and by using the same js file used for compiling vue.js.
I've tried pass the entire code by props but is not working. Also tried with slot. Any suggestions?
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'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);
});
}
I'm trying to display the results from a submitted form, AngularJS > PHP > Back but I'm getting nothing. I've tried a lot of different ways and according to all of google I'm doing it right but the console log just says that it's undefined.
Here is the submit function:
$scope.testProcessForm = function() {
$http({
method : 'POST',
url : 'test.php',
data : $scope.formData,
headers : {'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8'}
})
.success(function(data) {
if (data.errors) {
// Showing errors.
$scope.errorselectedServices = data.errors.selectedservices;
$scope.errorincEmail = data.errors.incemail;
} else {
$scope.submissionMessage = data.messageSuccess;
$scope.test= data.test;
The PHP:
$data['test'] = $test;
echo json_encode($data);
HTML:
<div ng-show="test">{{test}}</div>
Why am I getting "test is undefined" and no div? If I put an echo into PHP I get the proper reply back. It doesn't appear to hang anywhere in the code after some debugging. What am I doing wrong?
// app.js
// create our angular app and inject ngAnimate and ui-router
// =============================================================================
angular.module('formApp', ['ngAnimate', 'ngMessages', 'ui.router'])
// configuring our routes
// =============================================================================
.config(function ($stateProvider, $urlRouterProvider) {
$stateProvider
// route to show our basic form (/form)
.state('form', {
url: '/form',
templateUrl: 'form.html',
controller: 'formController'
})
// nested states
// each of these sections will have their own view
// url will be nested (/form/profile)
.state('form.tjanst', {
url: '/tjanst',
templateUrl: 'form-tjanster.html'
})
// url will be /form/interests
.state('form.epost', {
url: '/epost',
templateUrl: 'form-epost.html'
})
// url will be /form/payment
.state('form.fax', {
url: '/fax',
templateUrl: 'form-fax.html'
})
// url will be /form/payment
.state('form.sms', {
url: '/sms',
templateUrl: 'form-sms.html'
})
// url will be /form/payment
.state('form.mcl', {
url: '/mcl',
templateUrl: 'form-mcl.html'
})
// url will be /form/payment
.state('form.review', {
url: '/review',
templateUrl: 'form-review.html'
});
// catch all route
// send users to the form page
$urlRouterProvider.otherwise('/form/tjanst');
})
.value('formSteps', [
{uiSref: 'form.tjanst', valid: false},
{uiSref: 'form.epost', valid: false},
{uiSref: 'form.fax', valid: false},
{uiSref: 'form.sms', valid: false},
{uiSref: 'form.mcl', valid: false},
{uiSref: 'form.review', valid: false}
])
.run([
'$rootScope',
'$state',
'formSteps',
function($rootScope, $state, formSteps) {
// Register listener to watch route changes
$rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams) {
var canGoToStep = false;
// only go to next if previous is valid
var toStateIndex = _.findIndex(formSteps, function(formStep) {
return formStep.uiSref === toState.name;
});
console.log('toStateIndex',toStateIndex)
if(toStateIndex === 0) {
canGoToStep = true;
} else {
canGoToStep = formSteps[toStateIndex - 1].valid;
}
console.log('canGoToStep', toState.name, canGoToStep);
// Stop state changing if the previous state is invalid
if(!canGoToStep) {
// Abort going to step
event.preventDefault();
}
});
}
])
// our controller for the form
// =============================================================================
.controller('formController', function($scope, $state, $http, formSteps) {
// we will store all of our form data in this object
$scope.formData = {};
$scope.submission = false;
$scope.formStepSubmitted=false;
$scope.formData.selectedServices = {};
$scope.messitServices = [{'name':'Fax', 'id':1}, {'name':'SMS', 'id':2}, {'name':'Minicall', 'id':3}];
$scope.someSelected = function (object) {
return Object.keys(object).some(function (key) {
return object[key];
});
};
var nextState=function(currentState) {
switch (currentState) {
case 'form.tjanst':
return 'form.epost'
break;
case 'form.epost':
return 'form.fax'
break;
case 'form.fax':
return 'form.sms'
break;
case 'form.sms':
return 'form.mcl'
break;
case 'form.mcl':
return 'form.review'
break;
default:
alert('Did not match any switch');
}
};
var updateValidityOfCurrentStep=function(updatedValidity) {
var currentStateIndex = _.findIndex(formSteps, function(formStep) {
return formStep.uiSref === $state.current.name;
});
formSteps[currentStateIndex].valid = updatedValidity;
};
$scope.goToNextSection=function(isFormValid) {
console.log('isFormValid ', isFormValid);
// set to true to show all error messages (if there are any)
$scope.formStepSubmitted = true;
if(isFormValid) {
// reset this for next form
$scope.formStepSubmitted = false;
// mark the step as valid so we can navigate to it via the links
updateValidityOfCurrentStep(true /*valid */);
$state.go(nextState($state.current.name));
} else {
// mark the step as valid so we can navigate to it via the links
updateValidityOfCurrentStep(false /*not valid */);
}
};
$scope.testProcessForm = function() {
$http({
method : 'POST',
url : 'kundreg.php',
data : $scope.formData,
headers : {'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8'}
})
.success(function(data) {
if (data.errors) {
// Showing errors.
$scope.errorselectedServices = data.errors.selectedservices;
$scope.errorincEmail = data.errors.incemail;
} else {
$scope.submissionMessage = data.messageSuccess;
$scope.faxSenderPhoneNo = data.faxSenderPhoneNo;
$scope.faxSender = data.messit.faxSender;
console.log(faxSender);
// $scope.formData = {};
}
});
};
});
<!DOCTYPE html>
<h3 class="text-center">Granskning</h3>
<h4 class="text-center">Vänligen kontrollera:</h4><br>
<div class="form-group row"></div>
<!-- <span ng-show="errorselectedServices">{{errorselectedServices}}</span>
<span ng-show="errorincEmail">{{errorincEmail}}</span>></div> -->
<div ng-show="faxSender">{{ faxSender }} ng show faxsenderphoneno</div>
<br>
<div class="form-group row">
<div class="col-xs-6 col-xs-pull">
<a ui-sref="form.fax" class="btn btn-block btn-info">
Föregående <span class="glyphicon glyphicon-circle-arrow-left"></span></a>
</div>
<div class="col-xs-6 col-xs-push">
<a ng-click="testProcessForm()">
Skapa <span class="glyphicon glyphicon-circle-arrow-right"></span>
</a>
</div>
</div>
<?php
$errors = array();
$data = array();
$selectedServices = array();
// Getting posted data and decodeing json
$_POST = json_decode(file_get_contents('php://input'), true);
// checking for blank values.
if (empty($_POST['selectedServices']))
$errors['selectedServices'] = 'Minst en tjänst måste väljas.';
if (empty($_POST['incEmail']))
$errors['incEmail'] = 'Epost som tillåts använda tjänsterna saknas';
$selectedServices = $_POST['selectedServices'];
if (!empty($errors)) {
$data['errors'] = $errors;
} else {
if (!empty($_POST["faxSenderPhoneNo"])) {
// ta bort allt som inte är siffror
$faxSender = preg_replace('/[^0-9\/+]/', '', $_POST["faxSenderPhoneNo"]);
// finns ingen nolla så lägger vi till den så vi kan matcha den i regexen
//regex med internationellt format så databasen blir glad
if (preg_match('/^0/', $faxSender) === 0) {
$faxSender = "0{$faxSender}";
}
$faxSenderPhoneNo = preg_replace("/(^0|^46)/", "+46", $faxSender);
$messit['faxSender'] = $faxSenderPhoneNo;
}
else {
$faxSenderPhoneNo = 'NULL';
}
if (!empty($_POST["deliveryReportFax"])) {
$deliveryReportFax = $_POST["deliveryReportFax"];
}
else {
$deliveryReportFax = '3';
}
}
}
if (!$error) {
// sql
echo json_encode($data);
?>
I found the error. Apparently you have to quote the variable into the array;
$data['faxSender'] = "$faxSenderPhoneNo";
Now works as intended.
EDIT:
Well it worked to a point. My divs still weren't displaying. After logging with console.log(data) I could see that I had a lot of undefined indexes but my data array was there so I didn't understand why I couldn't access it.
I fixed the undefined stuff and then suddenly every div was displayed. Not a clue why PHP decides to dump all that info into my $data array.
2nd edit: Apparently .success is deprecated. Using .then instead with error_reporting(1); seems to always give me an array with data that angular then can use.
Since you are JSON encoding data in php file, file returning a String. so, you will need decode JSON to Java script object first. Also, you $http returns angular promise($q service). I am not sure about using
.success
method. Instead use
.then
.then(function successCallback(response) {
// this callback will be called asynchronously
// when the response is available
// decode JSON firs since you are sending JSON from PHP
var data = JSON.parse(response);
$scope.test = data.test;
}, function errorCallback(response) {
// called asynchronously if an error occurs
// or server returns response with an error status.
// Handle error here
});