I am trying to get data to knockout from the database using Ajax. But I am not getting any data to my observableArray.
Here is the knockout js model:
self.alldata = ko.observableArray();
self.viewAllInvoice = function () {
$.ajax({
type: 'POST',
url: BASEURL + 'index.php/moneyexchange/learn_Ko/',
contentType: 'application/json; charset=utf-8'
})
.done(function(invoices) {
invoices.forEach(function(invoice) {
self.alldata.push(invoice);
});
})
.fail(function(xhr, status, error) {
alert(status);
})
.always(function(data){
});
};
self.viewAllInvoice();
And here is the html code I am trying to put my data in
<tbody data-bind="foreach: alldata">
<tr>
<td class="text-center"><span data-bind="text: $data.payment_amount "></span></td>
<td class="text-center"><span data-bind="text: $data.allocated_amount"></span></td>
</tr>
</tbody>
I did not create a viewmodel showing all the data from the database since I know what I need to show in the table. And for extra information, I am getting the data from a controller in codeigniter framework. Please do guide me in steps since I am totally new in all this.
Related
I need the guidance of somebody to help me building the function Update Database when using AJAX. When I click the button Accept so an Ajax request will send to the server and server will execute UPDATE value of field post_status. At the start, field post_status has value is "pending", and after execute query UPDATE so the value will change to "accepted".
What's I should do next? Please help me.
Thank you so much for help.
The database of the Posts table:
post_id user_id title content DateTime post_status
1 1 Title 1 Content 1 Time pending
2 2 Title 2 Content 2 Time pending
3 3 Title 3 Content 3 Time pending
4 4 Title 4 Content 4 Time pending
5 5 Title 5 Content 5 Time pending
The View:
<table class="table table-bordered">
<thead class="thead-inverse">
<tr>
<th>Post ID</th>
<th>User ID</th>
<th>Name User</th>
<th>Title</th>
<th>Content</th>
<th>Datetime</th>
<th>Status</th>
<th>Accept</th>
</tr>
</thead>
<tbody>
#foreach ($posts as $row)
<tr id="{{ $row->post_id }}">
<td>{{$row->post_id}}</td>
<td>{{$row->user_id}}</td>
<th>{{$row->users->name}}</th>
<td>{{$row->post_title}}</td>
<td>{{$row->post_content}}</td>
<td>{{$row->post_datetime}}</td>
<td>{{$row->post_status}}</td> {{-- The status of post that I wanna change the value to "accepted" --}}
<td>
<button class="btn btn-success accept-btn" data-postID="{{$row->post_id}}">Accept</button>
</td>
</tr>
#endforeach
</tbody>
</table>
The code Javascript:
<script>
$(document).ready(function () {
$('.accept-btn').click(function(){
var postId = $(this).attr('data-postID');
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$.ajax({
type: "POST",
url: "{{route('posts.list_post_ajax')}}",
data: { postId: postId },
dataType: 'JSON',
success :function(response) {
console.log(response);
},
});
})
});
</script>
The function list_post_ajax of Controller:
public function list_post_ajax(Request $request)
{
if(request()->ajax()){
$postId = $request->get('postId');
return response()->json(['success'=>$postId]);
// What's I should do next?
// Pls help me.
}
}
There are so many ways to do it. This one will work following your code. Use $myObject->save(); to save a new record or update a old one.
Change on view
<td id="td{{$row->post_id}}">{{$row->post_status}}</td>
On Controller
$postId = $request->get('postId');
$post = App\Post::find($postId);
$post->post_status= 'accepted';
$post->save();
return response()->json(['success'=>$postId,'message'=>'accepted']);
On JS
$.ajax({
type: "POST",
url: "{{route('posts.list_post_ajax')}}",
data: { postId: postId },
dataType: 'JSON',
success :function(response) {
console.log(response);
$('td'+postId).html(response.message);
},
});
Edit: I update my answer on Controller. You should take a look Eloquent Documentation
I started messing around with Vue.js earlier this week.
So far I created a list of MTG(a TCG) cards. The data comes from the database through an Ajax request. This all works like a charm.
What i want to do next is replace the string that contains the costs of a card e.g. something like '{1}{U}{G}' with images for the corresponding tag.
HTML:
<div v-for="(cards, key) in mainBoard" class="">
<table class="table">
<tr>
<th colspan="5">#{{ key }}</th>
</tr>
<tr>
<th>#</th>
<th>Name</th>
<th>ManaCost</th>
#if($deck->enableCommander())
<th>Commander</th>
#else
<th></th>
#endif
<th>Actions</th>
</tr>
<tr v-for="card in cards">
<td>#{{card.pivot.quantity}}</td>
<td>#{{card.name}}</td>s
<td v-html="replaceManaSymbols(card)"></td>
#if($deck->enableCommander())
<td>
<span v-if="card.pivot.commander" #click="preformMethod(card, 'removeCommander', $event)"><i class="fa fa-flag"></i></span>
<span v-else #click="preformMethod(card,'assignCommander', $event)"><i class="far fa-flag"></i></span>
</td>
#else
<td> </td>
#endif
<td>
<button #click="preformMethod(card,'removeCardFromDeck', $event)"><i class="fa fa-times-circle"></i></button>
<button #click="preformMethod(card,'plusCardInDeck', $event)"><i class="fa fa-plus-circle"></i></button>
<button #click="preformMethod(card,'minusCardInDeck', $event)"><i class="fa fa-minus-circle"></i></button>
</td>
</tr>
</table>
</div>
Vue.js
new Vue({
el: '#Itemlist',
data: {
mainBoard: [],
sideBoard: [],
},
methods:{
preformMethod(card, url){
var self = this;
var varData = {
slug: '{{ $deck->slug }}',
card: card.id,
board: card.pivot.mainboard
};
$.ajax({
url: '/vue/'+url,
data: varData,
method: 'GET',
success: function (data) {
self.mainBoard = data.mainBoard;
self.sideBoard = data.sideBoard;
},
error: function (error) {
console.log(error);
}
});
},
replaceManaSymbols(card){
var mc = card.manaCost;
var dump = mc.replace(/([}])/g, '},').split(',');
var html = '';
/**
* replace each tag with an image
*/
return html;
}
},
mounted(){
var self = this;
var varData = {
slug: '{{ $deck->slug }}'
};
$.ajax({
url: '/vue/getDeckList',
data: varData,
method: 'GET',
success: function (data) {
self.mainBoard = data.mainBoard;
self.sideBoard = data.sideBoard;
},
error: function (error) {
console.log(error);
}
});
}
})
I pass the card as a parameter to the replaceManaSymbols method. I can console.log the contents of mana without any issue. But as soon as a want to modify the string Vue throws the error TypeError: Cannot read property 'toLowerCase/split/replace' of null. I'm not really sure what's going wrong. Any idea's?
As a rule of thumb, you shouldn't use methods on the display side. Keep them for the update side - processing changes back into a store and such. Methods aren't reactive - they need to be called. You want your display to automatically reflect some underlying data, so you should use computed.
You should also avoid using v-html, because you end up with markup outside your templates, and that markup is static. It's not totally clear to me what will be in v-html, but you should try and keep markup in your template, and inject values using data, props or computed. Hope this helps!
If you want a div with some text that magically turns into an image tag, this could be a good use for <component :is>.
In the console,I am getting name based on id.How to bind that name into the html page.
Here is my code..
function getEventname(){
var clid=$('#eventid').val();
console.log("i am ok" + clid);
$.ajax({
type: "GET",
url: "EduManage.jsp",
data: {
control:'ajax',
ch:'1',
key:'1_0a1m_1',
eventid:clid
},
success: function(data) {
console.log("i am ok" + data);
(what to do to bind the name in the html page)
}
});
}
Now the HTML is;
<td class="bg1">
Event Id :
</td>
<td class="bg1" width="25%">
<input name="eventid" type="text" id="eventid" size="10" maxlength="10" onblur="getEventname()"/>
</td>
<td class="bg1" width="40%">
Event Name :
</td>
<td class="bg1" width="25%">
<input type="text" name="eventname" id="eventname">
</td>
In the console,I am getting name as i am ok seminar .How to bind that name in the HTML page automatically when id is given.
Can anyone help?
So your Javascript function should be;
function getEventname(){
var clid=$('#eventid').val();
console.log("i am ok"+clid);
$.ajax({
type: "GET",
url: "EduManage.jsp",
data: {
control:'ajax',
ch:'1',
key:'1_0a1m_1',
eventid:clid
},
success: function(data) {
console.log("i am ok"+data);
//The one line change
$("#eventname").val(data);
}
});
}
So you had already implemented everything. All you need to do is add data in some element. If you want to add it in td then use this:
$.ajax({type: "GET",url: "EduManage.jsp",data: {control:'ajax', ch:'1', key:'1_0a1m_1', eventid:clid},
success: function(data) {
console.log("i am ok"+data);
$("td.last").append(data);
(what to do to bind the name in the hmtl page)
}
});
and add a new html tag:
<td class="last"></td>
You can also update the html using jquery but its not a practice to do so.
Hope this works.
can anyone help please. I have a problem updating "div" inside of "table" to update "tr with_id". However when I run test and
place without_"id" outside of table my script runs greate and i'm getting server "TEST" response
<table style="border: none; border-bottom: 1px solid #2F2E2F;">
<tr>
<th colspan="4">Notifications</th>
</tr>
<div id="update_118">
<tr class="read_118">
</div>
<td>... </td>
<td> Comment on your Photo </td>
<td>today 21:43</td>
<td>... </td>
</tr>
</table>
Now I want to up update this "div" when mouseover on success: function() without page refreshing to have its value change to class="light" to have NOT TO CALL ajax url: "/alerts/ajax_read/118" over and over while mouse is over on it.
<div id="update_118">
<tr class="light">
</div>
here is my script,...
<script>
$(document).ready(function(){
$('.read_118').on('mouseover', function(){
var id = $(this).attr("id")
var data = 'id=' + id ;
$.ajax({
type: "GET",
url: "/alerts/ajax_read/118",
data: data,
cache: false,
success: function(){
$('#update_118').fadeOut('slow').load('/alerts/ajax_load/118').fadeIn("slow");
return false;
}
});
});
});
</script>
here is my server response file:
$response = " <tr class='light'> ";
echo $response;
thanks in advance,...
chris
Update following line
success: function(){
To
success: function(data){
and set the "data" variable value to your respective "div" or other place where you want.
I'm having troubles binding new DOM elements to my viewmodel. This elements are in a partial view loaded using an AJAX call (see the customizeQuote function below).
$(function () {
var mvcModel = ko.mapping.fromJS(initialData);
function QuoteViewModel() {
var self = this;
self.customizeQuote = function (quote) {
self.selectedQuote = quote;
//remove the disable attribute on all form controls before serializing data
$(".step").each(function () {
$(this).find('input, select').removeAttr('disabled');
});
//convert form data to an object
var formData = $('#etape').toObject();
$.ajax("getSelectedQuote", {
data: ko.toJSON({ model: self.selectedQuote, model1: formData }),
type: "post", contentType: "application/json",
success: function (result) {
$("#custom").html(result);
$("#etape").formwizard("show", "customize");
ko.applyBindings(self.selectedQuote, $("#covers"));
}
});
}
}
var myViewModel = new QuoteViewModel();
var g = ko.mapping.fromJS(myViewModel, mvcModel);
ko.applyBindings(g);
});
Here's the partial view html:
#model QuoteViewModel
<table id="covers">
<thead>
<tr>
<th>
ProductName
</th>
</tr>
</thead>
<tbody data-bind="foreach: CoverQuotesViewModel">
<tr>
<td>
<input data-bind="value: ProductName" />
</td>
</tr>
</tbody>
</table>
the line:
ko.applyBindings(self.selectedQuote, $("#covers"));
triggers an error:
"ko.applyBindings: first parameter should be your view model; second parameter should be a DOM node"
I'm fairly new to knockout and I don't see what I'm doing wrong. Any idea ?
$("#covers") is not a DOM node though, it is an jQuery object. Perhaps try using this instead:
ko.applyBindings(self.selectedQuote, $("#covers")[0]);
The [0] will get the first matched element of the selector in the jquery object.