I shyly trying to make friends Angular and backend database.
Simple operations. Get database to angular model. Save entry in database, and delete entry.
I'm stacked on DELETE action. When i delete entry that loaded from database it's ok. But when i delete newly created row by push method, i got error.
This occurs because in the model absent id. After inserting entry to database, i trying repeatedly refresh Angular model from database.($http.get) But in this case, a view didn't refresh (only blinks). I saw new entry only refresh page F5.
Help!
Books
<div ng-app="App" ng-controller="MyCtrl">
<table class="">
<th>
<tr style="font-size: 20px">
<td>ID</td>
<td>Name</td>
<td>Price</td>
<td>Action</td>
</tr>
</th>
<tr ng-repeat="book in books">
<td style="width: 200px">{{book.id}}</td>
<td style="width: 200px">{{book.name}}</td>
<td style="width: 50px">{{book.price |currency}}</td>
<td>
<button ng-click="removeItem($index)">Удалить</button>
</td>
</tr>
<tr>
<td></td>
<td><input type="text" ng-model="name"/></td>
<td><input type="number" ng-model="price"/></td>
<td>
<button ng-click="addBook()">Добавить книгу</button>
</td>
</tr>
</table>
</div>
<script>
var App = angular.module('App', []);
App.controller('MyCtrl', function ($scope, $http) {
$http.get('http://ang:8888/index.php?r=site/api2').success(function (data) {
$scope.books = data;
});
$scope.removeItem = function (index) {
var id = $scope.books[index].id;
$scope.books.splice(index, 1);
$http.post('http://ang:8888/index.php?r=site/del2', {id: id});
}
$scope.addBook = function () {
var newBook = ({name: $scope.name, price: $scope.price});
$scope.books.push(newBook);
$http.post("http://ang:8888/index.php?r=site/post2", {name: $scope.name, price: $scope.price})
.success(function (data, status, headers, config) {
console.log("inserted Successfully");
});
$http.get('http://ang:8888/index.php?r=site/api2').success(function (data) {
$scope.books = data;
});
}
})
The problem is due to async nature of all remote calls. You call the post and get methods in sequence without realizing that both are sync in nature. So your post is immediately followed by get.
Change the code for post to
$http.post("http://ang:8888/index.php?r=site/post2", {
name: $scope.name,
price: $scope.price
}).success(function (data, status, headers, config) {
console.log("inserted Successfully");
$http.get('http://ang:8888/index.php?r=site/api2').success(function (data) {
$scope.books = data;
});
});
In the above code you only do get when post is done.
Related
I am trying to alert something but on click function is running only once on the first button. but I have buttons on many rows.
I am fetching Data through Laravel from Database in a table. Only one button runs a function, then nothing happens with other buttons.
Jquery:
jQuery(document).ready(function(e) {
$('#restore-data').on('click', function(e) {
var val = $("#thisr").attr('value');
alert(val);
});
});
View:
<table id="recover-table" class="table" >
<thead>
<tr class="bg-info">
<th>Teacher Name</th>
<th>Date</th>
<th>Action</th>
</tr>
</thead>
<tbody>
#foreach($trashs as $trash)
<tr id="thisr" value="{{$trash->id}}">
<td class="text-nowrap ">{{$trash->efirst}} {{$trash->esecond}}</td>
<td class="text-nowrap ">{{$trash->deleted_at}}</td>
<td class="text-nowrap "><button type="submit" class="" name="id"
value="{{$trash->id}}" id="restore-data">Delete</button></td>
</tr>
#endforeach </tbody></table>
Right now even alert is not working, but I want to achieve Refresh table after a record is deleted from Table.
Update: Now Alert is working fine, but when I delete a record by pressing a button, only one row is deleting. the function runs once.
Complete Js:
jQuery(document).ready(function(e) {
$('#restore-data').on('click', function(e) {
let teacher_id=$(this).attr('value');
console.log('Restore button clicked!')
e.preventDefault();
$.ajax(
{
url: "/teachers/recover/" + $('#restore-data').attr("value"),
type: 'GET', // Just delete Latter Capital Is Working Fine
headers: { 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') },
data: teacher_id,
success: function (data) {
console.log(data.msg);
console.log(teacher_id);
if(data.msg){
$('#thisr').remove();
$('#response').empty();
$(".toast").toast('show');
$('#response').append(data.msg);
}
},
error: function (xhr) {
console.log("Error Restoring Record");
//console.log(xhr.responseText);
},
});
});
});
You can try to use class 'restore-data'
$(document).ready(function(e) {
$(document).on('click', '.restore-data', function(e) {
var val = $('#thisr').val();
alert(val);
});
});
As id should be unique for each element.
You can try something like
#foreach($trashs as $trash)
<tr>
<td class="text-nowrap ">{{$trash->efirst}} {{$trash->esecond}}</td>
<td class="text-nowrap ">{{$trash->deleted_at}}</td>
<td class="text-nowrap ">
<button type="button" data-trash-id="{{$trash->id}}" class="restore-data">Delete</button>
</td>
</tr>
#endforeach
and JS as
$(document).on('click', '.restore-data', function(e) {
var trash_id = $(this).attr('data-trash-id');
alert(trash_id);
});
Change this line.
var val = $("#thisr").attr('value');
to (since you have value attribute in button):
var val = $(this).attr('value');
or (since you have value attribute td):
var val = $(this).parent('tr#thisr').attr('value')
To remove a row.
$('#restore-data').on('click', function(e) {
var _this = $(this);
...
if(data.msg){
_this.parent('tr#thisr').remove();
....
Also change button type to button.
<button type="button" class="" name="id"
value="{{$trash->id}}" id="restore-data">Delete</button></td>
You gave same id to all button and id must be unique of particular button so you can define unique id with key of array and pass it to Function
#foreach($trashs as $key=>$trash)
<tr id="thisr{{$key}}">
<td class="text-nowrap ">{{$trash->efirst}} {{$trash->esecond}}</td>
<td class="text-nowrap ">{{$trash->deleted_at}}</td>
<td class="text-nowrap ">
<button type="button" class="" name="id" value="{{$trash->id}}" id="restore-data{{$key}}" onclick="restoreData({{$key}})">Delete</button>
</td>
</tr>
#endforeach
function restoreData(key){
var val = $("#restore-data"+key).attr('value');
alert(val);
// you can use either
$("#restore-data"+key).closest('tr').remove();
// OR
$('#thisr'+key).remove();
}
I need to refresh the table to show newly added row after sending the data from $http method. Below is my working code for adding the form values to mysql table. Appreciate if anyone can help me out with the angular way to achieve this.
JS Code:
var myApp = angular.module('myApp', ['ngRoute']);
myApp.controller('bookmarkCtrl', function($scope, $http) {
$scope.addThis = function() {
$http({
url: "addbookmark.php",
method: "POST",
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
data: $.param({
bookmarktitle: $scope.bookmarktitle,
bookmarkurl: $scope.bookmarkurl
})
}).success(function(data, status, headers, config) {
//refresh the table after success
}).error(function(data, status, headers, config) {
});
}
});
HTML
<div class="panel-body" ng-app="myApp" ng-controller="bookmarkCtrl">
<input ng-model="bookmarktitle" type="text" class="form-control" required>
<input ng-model="bookmarkurl" type="text" class="form-control">
<button type="button" class="btn btn-default" ng-click="addThis();">Submit</button>
<table class="table table-responsive">
<thead>
<tr>
<th>...</th>
</tr>
</thead>
<tbody>
<!-- repeat row -->
<tr>
<td>
<?php echo $row['bookmark_title'] ?>
</td>
</tr>
<!-- repeat row -->
</tbody>
</table>
</div>
#ismailvtl, angular is a client-side library, so typically the data would be populated through an ajax call from the client. In order to dynamically add a row, the data has to be accessible to the controller.
$scope.bookmarks = [];
$scope.getBookmarks = function() {
$http.get('/bookmarks').then(function(response) {
// should do validation here
$scope.bookmarks = response.data
}
}
$scope.getBookmarks();
Then, in your html, it should look like
...
<tr ng-repeat="bookmark in bookmarks">
<td>{{bookmark.bookmarktitle}}</td>
<tr>
...
Then, lastly, in your addThis() function:
$scope.addThis = function() {
$http({
url: "addbookmark.php",
method: "POST",
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
data: $.param({
bookmarktitle: $scope.bookmarktitle,
bookmarkurl: $scope.bookmarkurl
})
}).success(function(data, status, headers, config) {
var bookmark = {
bookmarktitle: data.bookmarktitle,
bookmarkurl: data.bookmarkurl
}
$timeout(function() {
$scope.bookmarks.push(bookmark)
}
}).error(function(data, status, headers, config) {
// handle error here
});
}
Alternatively, you can assign the bookmarks array directly in the view from the php using ng-init (something like ng-init="bookmarks=[{bookmarktitle: 'titlea',bookmarkurl: 'urla'},...]" with the values being supplied by php.
On entering the customer name in textbox it searches for customer info. I have generated successfully using JQuery by passing the entire table through Json variable, as I dont want any page refresh. Now I want to select the customer id generated from mysql db (php) through radio button, but the radio button event is not working. For testing purpose I have put a static table having the same radio button properties in that particular div(place for dynamic record generation using JQuery) and working fine. Hence I found that the data received through JQuery got some problem. Hope I am clear. Please find a way. Thanks in advance.
below is the code
abc.php
<input type="text" placeholder="full name" id="fullName" name="fullName" class="txt" style="width: 250px" />
<input type="button" id="btSelect" value="Select" class="button-crystal" />
<div id="disp"></div>
script.js
$('#btSelect').click(function () {
var form_data = {
genCustDetails: $('#fullName').val(),
is_ajax: 1
};
$.ajax({
type: "POST",
url: "xyz.php",
data: form_data,
dataType: "json",
success: function (response)
{
$('#disp').html(response);
}
});
return false;
});
xyz.php
if (isset($_POST['genCustDetails'])) {
$out="";
$result = mysql_query("select * from dbcustdetails where name like '$_POST[genCustDetails]%'");
while ($row = mysql_fetch_assoc($result)) {
$out.='
<table style="background-color:#eee; margin-bottom:5px;">
<tr>
<th class="td3">Customer ID</th>
<td class="td4">
'.$row["custID"].' <input type="radio" id="cust_ID" name="cust_ID" value="'.$row["custID"].'" />
</td>
</tr>
<tr>
<th class="td3">Name</th>
<td class="td4">'.$row["name"].'</td>
</tr>
<tr>
<th class="td3">Phone No.</th>
<td class="td4">'.$row["phno"].'</td>
</tr>
<tr>
<th class="td3">Email</th>
<td class="td4">'.$row["email"].'</td>
</tr>
<tr>
<td colspan="2" style="padding:0;">
<b>Address</b><br/>'.$row["addr"].'
</td>
</tr>
</table>';
}
echo json_encode($out);
}
Maybe You should'nt bind the event properly for the dynamic elements in the DOM.
Try Like this
$('body').on('change','.radiobuttonClassorID',function(){
//actions
});
that is because your newly generated radio button is not having any event handler assigned to it.
you have to assign an event handler after the ajax call (on ajax success).
something like
$('input[type="radio"]').unbind('click').click(function(){
//Your handler code
})
I would like to sort a table with data row from MySQL then change the order and submit it.
I used jQueryUI.sortable to make those tr tag (row) draggable.
But when I submitting the form, some of them didn't changed order.
Why? I tried to figure it out, I var_dump the data I submitted and I found a problem:
The tr tag (row) I moved from the original order, won't pass to PHP so var_dump will not show the row ID.
To make it easier to understand, I post my code here:
HTML Code
<table>
<thead>
<tr>
<th>Subject</th>
<th>Content</th>
</tr>
</thead>
<tbody id="sortable">
<tr>
<td>
Hello World
<input name="displayorder[]" type="hidden" value="1" />
</td>
<td>I come from Mars!</td>
</tr>
<tr>
<td>
Hello Mars
<input name="displayorder[]" type="hidden" value="2" />
</td>
<td>I come from Jupiter!</td>
</tr>
<tr>
<td>
Hello StackOverflow
<input name="displayorder[]" type="hidden" value="3" />
</td>
<td>I come from North Korea ...</td>
</tr>
</tbody>
<tbody>
<tr>
<td colspan="2"><input type="submit" value="Submit!" />
</tr>
</tbody>
</table>
I omitted the form content cause it is not important
JavaScript (Sortable Library loaded)
$(document).ready(function() {
$('#sortable').sortable({
helper: fixHelper,
axis: 'y',
opacity: 0.6,
}).disableSelection();
});
var fixHelper = function(e, ui) {
ui.children().each(function() {
$(this).width($(this).width());
});
return ui;
};
PHP
$displayorder = $_POST["displayorder"];
if($displayorder != "") {
$order = 1;
foreach($displayorder as $value) {
mysql_query("UPDATE message SET displayorder=$order WHERE announcementid=$value");
$order++;
}
}
I will prefer not using Ajax to do this because I have dozens of similar page to do the same task.
Thanks in advance.
Well I decided to code it every page.
The code now:
JavaScript
$(document).ready(function() {
$('#sortable').sortable({
helper: fixHelper,
axis: 'y',
opacity: 0.4,
update: function(event, ui){
var data = $(this).sortable('serialize');
$.ajax({
data: data,
type: 'POST',
url: '/update.php?action=displayorder'
});
},
}).disableSelection();
});
var fixHelper = function(e, ui) {
ui.children().each(function() {
$(this).width($(this).width());
});
return ui;
};
PHP
foreach($_POST["displayorder"] as $i => $value) {
mysql_query("UPDATE message SET displayorder=$i WHERE announcementid=$value");
$i++;
}
Trying to display all users from a MySQL database in Knockout and CodeIgniter. I'm getting a json response back from the server but Knockout isn't displaying the Json data.
I keep getting:
Uncaught ReferenceError: Unable to parse bindings.
Bindings value: text: id
Message: id is not defined
Html:
<!-- Users -->
<table class="table table-condensed table-striped table-bordered table-hover">
<thead>
<tr><th>User Id</th><th>Name</th><th>Email</th><th>Role</th></tr>
</thead>
<tbody data-bind="foreach: users">
<tr>
<td data-bind="text: id"></td>
<td><input data-bind="value: name" /></td>
<td><input data-bind="value: email"/></td>
<td><select data-bind="options: $root.roles, value: role, optionsText: 'role', optionsValue: 'role'"></select></td>
<td><a href="#" data-bind="click: $root.removeUser" class='icon-remove'></a></td>
</tr>
</tr>
</tbody>
</table>
<pre data-bind="text: ko.toJSON($data, null, 2)"></pre>
Knockout:
<script type="text/javascript">
function User(data) {
this.name = ko.observable(data.name);
this.email = ko.observable(data.email);
this.id = ko.observable(data.id);
this.role = ko.observaveble(data.role);
}
function UserListViewModel(data) {
// Data
var self = this;
self.users = ko.observableArray([]);
// Operations
self.addTask = function() {
self.tasks.push(new Task({title: this.newTaskText()}));
self.newTaskText("");
};
self.removeTask = function(task) {
self.tasks.remove(task)
};
// Load initial state from server, convert it to Task instances, then populate self.tasks
$.get("/sws/users/index", function(data) {
var mappedUsers = ko.mapping.fromJSON(allData);
self.users(mappedUsers);
});
}
ko.applyBindings(new UserListViewModel());
</script>
Json:
{"users":[{"id":"1","email":"example#gmail.com","password":"tacos","permissions":null,"activated":"1","activation_code":null,"activated_at":"2013-09-23 20:19:42","last_login":"2013-09-23 20:19:42","persist_code":null,"reset_password_code":null,"name":"Chris","created_at":"2013-09-23 04:17:24","updated_at":"2013-09-23 07:16:23"}]}
You're passing allData as an argument to the mapping, but it isn't defined anywhere. You want data.users instead (not data because then ko.mapping.fromJSON will return a single object with one key, users whose value will be an observableArray; you'll confuse Knockout if you try to use that object as the value of another observableArray, namely self.users).
Switching to this .ajax call seemed to resolve the issue.
// Load initial state from server, convert it to User instances, then populate self.users
$.ajax({
url: '/sws/users/index',
dataType: 'json',
type: 'POST',
success: function (data) {
self.users(data['users']);
console.log(data['users']);
}
});