I managed to create a form in an Angular 5 , my question is how can I reload the page after user submits the form.
I need the page to be reloaded so the new added element would displayed in the datatable, which is getting the existing elements (using Async Subscribe from HTTP client method) from the DB
So this is what I need to do:
User fills form
POST query => my API (response OK)
Notification Displayed
At that time I need to find a way to
reload the page or to update the existing Datatable
This is the Form Code:
<form [formGroup]="BillForm" (ngSubmit)="onSubmit()">
<div class="col-12">
<div class="row">
........
...............
<div class="ml-auto">
<input type="submit" class="btn btn-finish btn-fill btn-rose btn-wd" name="finish" value="Confirm"
[disabled]="BillForm.invalid">
</div>
</form>
now this is the Onsubmit method :
onSubmit() {
var newBill = this.BillForm.value;
newBill.CreatedAt = new Date();
console.log(newBill);
this.billservice.getCustomerId()
.subscribe(
res1 => {
console.log('this.BillService.getMonitorId', res1['Customer_id']);
this.billservice.getMonitorId(res1['Customer_id'])
.subscribe(
result => {
this.billservice.addBill(result['Monitor_id'], newBill)
.subscribe(
res => {console.log(res);
if (res['result'] === 'Bill Added Successfully') {
this.showNotification('bottom', 'right', 'success');
}}
);
});
});
}
It's working perfectly I just need to make better for the user , now it just addds the element to the table but I need to reload manually to see the change on table
This is how I am getting the data for the dataTable :
this.BillService.getCustomerId()
.subscribe(
res1 => {
console.log('this.BillService.getMonitorId', res1['Customer_id']);
this.BillService.getMonitorId(res1['Customer_id'])
.subscribe(
result => {
this.BillService.getBills(result['Monitor_id'])
.subscribe(res => {
this.dataTable = {
headerRow: ['#', 'Amount', 'Created at', 'From', 'To', 'Payment Status', 'Payment Date', 'Actions'],
dataRows: res['result'][0]['Bills']
};
setTimeout(function () {
self.initTable();
}, 10); });
});
});
and in the view :
<tr *ngFor="let row of dataTable.dataRows">
<td>{{row.Amount}}</td>
<td>{{row.CreatedAt | date:'mediumDate'}}</td>
<td>{{row.From | date:'mediumDate'}}</td>
<td>{{row.To | date:'mediumDate'}}</td>
Related
I have an example Vue.js setup of two pages. A list of products and then an order form.
https://listorder.netlify.com
ISSUE 1 - The URL passed from products to order page input gets encoded. I have tried to decode with decodeURI() but it still outputs encoded.
<a class="btn btn-primary btn-pill" v-bind:href="'order.html?product=' + decodeURI(item.title) + '&' ?price=' + decodeURI(item.price)" style="color:white;">Buy Now</a>
ISSUE 2 - After POST has completed, I need to redirect to a Paypal page appending data from the "Price" field on the order page. Not sure whether Vue will be required here or to add into the existing javascript.
Paypal page to redirect to https://www.paypal.me/wereallcatshere/USD then append the "price" field
JAVASCRIPT
form.addEventListener('submit', e => {
e.preventDefault()
showLoadingIndicator()
fetch(scriptURL, { method: 'POST', body: new FormData(form) })
.then(response => showSuccessMessage(response))
.catch(error => showErrorMessage(error))
})
function showSuccessMessage(response) {
console.log('Success!', response)
setTimeout(() => {
successMessage.classList.remove('is-hidden')
loading.classList.add('is-hidden')
}, 500)
}
VUE
<script type="text/javascript">
const app = new Vue({
el: '#app',
data: {
items: []
},
created: function () {
fetch('listorder.json')
.then(resp => resp.json())
.then(items => {
this.items = items;
})
},
methods: {
redirect: function () {
window.location.href = "https://www.paypal.me/wereallcatshere/USD" + item.price;
}
}
});
i have problem. When I click the button, it receives an entire database, but I want laod part database. How can I do this?
For example: After every click I would like to read 10 posts.
Thx for help.
Messages.vue:
<div class="chat__messages" ref="messages">
<chat-message v-for="message in messages" :key="message.id" :message="message"></chat-message>
<button class="btn btn-primary form-control loadmorebutton" #click="handleButton">Load more</button>
</div>
export default{
data(){
return {
messages: []
}
},
methods: {
removeMessage(id){...},
handleButton: function () {
axios.get('chat/messagesmore').then((response) => {
this.messages = response.data;
});
}
},
mounted(){
axios.get('chat/messages').then((response) => {
this.messages = response.data
});
Bus.$on('messages.added', (message) => {
this.messages.unshift(message);
//more code
}).$on('messages.removed', (message) => {
this.removeMessage(message.id);
});
}
}
Controller:
public function index()
{
$messages = Message::with('user')->latest()->limit(20)->get();
return response()->json($messages, 200);
}
public function loadmore()
{
$messages = Message::with('user')->latest()->get();
// $messages = Message::with('user')->latest()->paginate(10)->getCollection();
return response()->json($messages, 200);
}
paginate(10) Loads only 10 posts
You can do it like this:
<div class="chat__messages" ref="messages">
<chat-message v-for="message in messages" :key="message.id" :message="message"></chat-message>
<button class="btn btn-primary form-control loadmorebutton" #click="handleButton">Load more</button>
</div>
export default{
data(){
return {
messages: [],
moreMessages: [],
moreMsgFetched: false
}
},
methods: {
removeMessage(id){...},
handleButton: function () {
if(!this.moreMsgFetched){
axios.get('chat/messagesmore').then((response) => {
this.moreMessages = response.data;
this.messages = this.moreMessages.splice(0, 10);
this.moreMsgFetched = true;
});
}
var nextMsgs = this.moreMessages.splice(0, 10);
//if you want to replace the messages array every time with 10 more messages
this.messages = nextMsgs
//if you wnt to add 10 more messages to messages array
this.messages.push(nextMsgs);
}
},
mounted(){
axios.get('chat/messages').then((response) => {
this.messages = response.data
});
Bus.$on('messages.added', (message) => {
this.messages.unshift(message);
//more code
}).$on('messages.removed', (message) => {
this.removeMessage(message.id);
});
}
}
-initialize a data property morMsgFetched set to false to indicate if more messages are fetched or not
if morMsgFetched is false make the axios request and st the response to moreMessages, then remove 10 from moreMessages and set it to messages[]..
After that set morMsgFetched to true
on subsequest click remove 10 from moreMessages and push it to 'messages[]`
Use Laravels built in pagination.
public function index()
{
return Message::with('user')->latest()->paginate(20);
}
It returns you next_page url which you can use to get more results calculated automatically
This might be too late but i believe the best way to do it is using pagination, Initially onMounted you'll send a request to let's say /posts?page=1, the one is a variable let's say named 'pageNumber', each time the user clicks on the "Load More" button, you'll increment the pageNumber and resent the request, the link will page /posts?page=2 this time, at this point you can append the results you've got to the already existing one and decide if the Load More button should be shown based on the last_page attribute returned by laravel paginator...
I'm sure you already solved your problem or found another alternative, this might be usefull for future developers.
Pretty new to vuejs here. I need to make an ajax call (key up event) for a text input in an update form (blade laravel), however in the form the input is blank.
My question is: How do I send the input value from the blade template when the form is loaded to the vue data instance (sn)?
The intention is to alert the user if that value (suite_number) already exists in the database.
Thanks in advance!!!
My blade template:
{!! Form::text('suite_number', null, ['class' => 'form-control', 'id' => 'suiteNumberLookup', 'v-on:keyup' => 'getSuiteNumber(suite_number, $event)', 'v-model' => 'sn']) !!}
My Vuejs:
new Vue({
el: '#suiteNumberLookup',
data:
{
sn: 'What should I set here to get the data that\'s loaded in the form?'
},
methods: {
getSuiteNumber(d) {
this.$http.get('/admin/tenantAjax/getSuiteNumberAjax/' + d).then((response) => {
// success callback
//this.tenant = response.data;
if(response.data){
this.loaded = true;
}
console.log(response.data);
}, (response) => {
this.error = response.body;
this.loadErrorMsg = true;
});
}
I have to add/post data form. But the form dynamically can increase as user 'click' on a button. I've already browse about it and there some answer i get like using $request->all() to fetch all data from input forms.
And then my problem is, my app using VueJS as front-end. Is there any some configuration on VueJS script to post all data from that dynamic form??
My Blade template that will be increase dynamically:
<div id="form-message">
{!! Form::text('rows[0][DestinationNumber]', null, [
'id' => 'recipient',
'class' => 'form-control',
'v-model' => 'newMessage.DestinationNumber'
])
!!}
{!! Form::textarea('rows[0][TextDecoded]', null, [
'rows' => '3',
'id' => 'recipient',
'class' => 'form-control',
'v-model' => 'newMessage.TextDecoded'
])
!!}
</div>
That zero number will increase depends on how much user click add button.
And then here my VueJS script
var newSingleMessage = new Vue({
el: '#newsinglemsg',
data: {
newMessage: {
DestinationNumber: '',
TextDecoded: ''
},
},
methods: {
onSubmitForm: function(e) {
e.preventDefault();
var message = this.newMessage;
this.$http.post('api/outbox', message);
message = { DestinationNumber: '', TextDecoded: '' };
this.submitted = true;
}
}
});
On laravel controller, i have simple logic to test result how data passed.
$input = $request->all();
$output = dd($input);
return $output;
And, I test it using 2 additional form. So, the data should be 3 rows. The result (checked from FireBug) to be like this
{"DestinationNumber":"1234567890","TextDecoded":"qwertyuio"}
Data passed just one, and then the type is JSON. Even I use return $output->toArray(), type still JSON.
Oh yeah, once more. Idk how to make the zero number increase dynamically using javascript. When testing, i just manual add the form. Here my add click function javascript
var i = 0,
clone = $('#form-message').clone(),
recipient = document.getElementById('recipient');
recipient.setAttribute('name', 'rows['+ i +'][DestinationNumber]');
clone.appendTo('.form-message:last');
i++;
For second and next rows, name attribute not added on the input elements.
Thanks
You're mixing blade and jquery and vue in a way that is pretty confusing. Check out this JS fiddle that accomplishes all of this with Vue:
https://jsfiddle.net/cr8vfgrz/10/
You basically have an array of messages that are automatically mapped to inputs using v-for. As those inputs change, your messages array changes. Then when submit is pressed, you just post this.messages and the array of messages is sent to server. Then you can clear the array to reset the form.
Template code:
<div id="form-message">
<button class="btn btn-default" #click="addNewMessage">New Message</button>
<template v-for="message in messages">
<input type="text" v-model="message.DestinationNumber" class="form-control">
<textarea rows="3" v-model="message.TextDecoded" class="form-control"></textarea>
</template>
<button class="btn btn-success" #click.prevent="submitForm">Submit</button>
</div>
Vue code:
var newSingleMessage = new Vue({
el: '#form-message',
data: {
messages: [
{
DestinationNumber: '',
TextDecoded: ''
}
],
submitted:false
},
methods: {
addNewMessage: function(){
this.messages.push({
DestinationNumber: '',
TextDecoded: ''
});
},
submitForm: function(e) {
console.log(this.messages);
this.$http.post('api/outbox', {messages:this.messages})
.then(function(response){
//handle success
console.log(response);
}).error(function(response){
//handle error
console.log(response)
});
this.messages = [{ DestinationNumber: '', TextDecoded: '' }];
this.submitted = true;
}
}
});
Edit:
In the controller you can use $request->input('messages'); which will be the array of messages. You can insert multiple new Outbox model using:
Outbox::insert($request->input('messages'));
or
foreach($request->input('messages') as $message){
Outbox::create($message);
}
I'm new to using ajax. For example after field title is filled, I want to search in database for specific data and return more fields based on that input. So far I can only receive my title data in /ajax/post page by pressing get data/post data or submit button. How do I receive my title input and data from Route::post while/after filling title? If I remove Form::model and Form::close() I do get my dummy data from Route::post without page refresh by clicking Post data button, but without title value.
I'm aware that checking title field involves some jQuery/js, but I have no idea how to actually bring that title field into my route to do some database searching and return some data with it.
View:
{!! Form::model($project = new \App\Project, ['url' => 'ajax/post', 'method' => 'post']) !!}
<!-- pass through the CSRF (cross-site request forgery) token -->
<meta name="csrf-token" content="<?php echo csrf_token() ?>" />
<!-- some test buttons -->
<button id="get">Get data</button>
<button id="post">Post data</button>
<div class="form-group padding-top-10">
{!! Form::label('title', 'Title') !!}
{!! Form::text('title', null, ['class' => 'form-control', 'placeholder' => 'Title']) !!}
</div>
{!! Form::submit('Submit Button', ['class' => 'btn btn-primary form-control']) !!}
{!! Form::close() !!}
Ajax script:
<script>
$.ajaxSetup({ headers: { 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') } });
function onGetClick(event)
{
// we're not passing any data with the get route, though you can if you want
$.get('/ajax/get', onSuccess);
}
function onPostClick(event)
{
// we're passing data with the post route, as this is more normal
$.post('/ajax/post', {payload:'hello'}, onSuccess);
}
function onSuccess(data, status, xhr)
{
console.log(data, status, xhr);
// JSON is deserialised into an object
console.log(String(data.value).toUpperCase())
}
$('button#get').on('click', onGetClick);
$('button#post').on('click', onPostClick);
</script>
And in route:
Route::get('/ajax/view', ['as' => 'home', 'uses' => 'AjaxController#view']);
Route::get('/ajax/get', function () {
$data = array('value' => 'some get');
return Response::json($data);
});
Route::post('/ajax/post', function () {
$data = array('value' => 'some data', 'input' => Request::input());
return Response::json($data);
});
What you need is to implement the jquery keypress function.
so here is you js:
$("input.title").keypress(function(){
var title = $(this).val();
// now do the ajax request and send in the title value
$.get({
url: 'url you want to send the request to',
data: {"title": title},
success: function(response){
// here you can grab the response which would probably be
// the extra fields you want to generate and display it
}
});
});
as far as in Laravel you can pretty much treat it the same as a typical request except you will return json:
Route::get('/url-to-handle-request', function({
// lets say what you need to populate is
//authors from the title and return them
$title = Route::get('title'); // we are getting the value we passed in the ajax request
$authors = Author::where('title' ,'=', $title)->get();
return response()->json([
'authors' => $authors->toArray();
]);
}));
Now I would probably use a controller and not just do everything within the route but I think you'll get the basic idea.