CakePHP: Updating DIV content using AJAX - cakephp

I have a table where I load an external php file[name # settings_profile.php] inside settings.ctp file.
Code snippet from settings.ctp
<table>
<tr>
<td rowspan="2" id="upload-response-message">
<?php include("settings_profile.php"); ?>
</td>
</tr>
</table>
settings_profile.php
<?php
$image_path = $user['User']['image_path'];
if (!empty($image_path)) {
echo $this -> Image -> resize($image_path, 100, 200);
}else{
echo 'EMPTY' ;
}
?>
The output from settings_profile.php is generated as follows [copied from source code]
<table>
<tr>
<td rowspan="2" id="upload-response-message"> One
<img src="/dearmemoir/uploads/resized/image.jpg" alt="thumb" />
</td>
</tr>
</table>
The contents of $user['User']['image_path'] are updated by calling Controller using AJAX and I am trying to reload setting_profile.php file inside the table using -
function showUploadResponse(data) {
alert (data.status);
if( data.status == 1 ) {
$("#upload-response-message").load("settings_profile.php #upload-response-message");
}
}
But the content was never updated in the page. Any help?

You are breaking the MVC paradigm AND CakePHP conventions by doing this. If you are including an external php file in a view that is not a CakePHP helper, then you are doing something wrong.
If that is all there is to settings_profile.php, then delete it and move the functionality to either a controller or a component. Then assign the image to a variable that gets passed to the view.
If you are using Ajax to then make a call back to the server, then your page will never be reloaded in order for the included code in your view to be called again. Instead, pass the information about the resized image back to your javascript file and update the table through javascript.
//Pseudo Code
//Page is Loaded
//Ajax call made back to the server to resize the image
//Server resizes the image and sends the new image src back to the script
{Image:{name: "newImage", src: "/dearmemoir/uploads/resized/image1.jpg"}}
var returnedData = resultsFromAjax;
//Use javascript to update the image
var imgElement = document.getElementById('ProfileImageId').setAttribute("src", returnedData.Image.src);
That should update your image!

Related

Parsing json data and show in loop in a table

I'm developing a website with laravel where I've a json response from server with a blade.php view like below,
[{"id":1,"user_id":"1","patient_name":"kk","age":"44","sex":"Male"},
{"id":2,"user_id":"1","patient_name":"noor","age":"7","sex":"Male"},
{"id":3,"user_id":"1","patient_name":"noor","age":"44","sex":"Male"}]
How can I iterate through this json object so that I can show the data in a table with patient_name,age,sex column in blade.php?
First you would have to convert the JSON to an array with $array_data = json_decode($array, true), then you can pass the data to your view with return view('page', ["array_data"=>$array_data]);, next you would have to parse it in blade like:
<table>
<tr>
<td>id</td>
<td>User id</td>
<td>Patient name</td>
<td>Age</td>
<td>Sex</td>
</tr>
#foreach($array_data as $key=>$value){
<tr>
<td>{{$value["id"]}}</td>
<td>{{$value["user_id"]}}</td>
<td>{{$value["patient_name"]}}</td>
<td>{{$value["age"]}}</td>
<td>{{$value["sex"]}}</td>
</tr>
#endforeach
And so your code in your controller would be:
$array_data = json_decode($array, true);
return view('page', ["array_data"=>$array_data]);
Note that the string page must be the name of your blade template minus the .blade.php, i.e. if your template is called page.blade.php you would use the string page

getting the updated value of inputs in ng-repeat | Angular Js

I have a inputs in a table filled out with ng-repeat, i want to be able to get the updated values by one click for all inputs.
My View:
<tr ng-repeat="sf in selectedFacture">
// displaying default values in the input
<td><input class="facture_item_name" ng-model="sf.facture_item_name" value="{{sf.facture_item_name}}" type="text"/></td>
<td><input class="fcls_crt" ng-model="sf.fcls_crt" value="{{sf.fcls_crt}}" type="number"/></td>
<td><input class="fpiece" ng-model="sf.fpiece" value="{{sf.fpiece}}" type="number"/></td>
<td colspan="4"><input type="text" class="form-control note" ng-model="sf.note" value="{{sf.note}}"/></td>
<tr>
<td ng-click="updateFacture(sf.id,sf,sf.facture_type,sf.item_id)">SUBMIT</td>
</tr>
</tr>
JS:
// getting new values and send them to server side
$scope.updateFacture=function(id,sf,type,item_id){
var url = '../php/history.php';
var func = "updateFacture";
sf = sf || {};
var editedQuanCls= sf.fcls_crt,
editedQuan_piece= sf.fpiece,
editedQuan_cls_crt_gate= sf.fcls_crt_gate,
editedQuan_piece_gate= sf.fpiece_gate,
editedNote= sf.note;
var data = {"function": func,
"factureId":id,
"item_id":item_id,
"facture_type":facture_type,
"editedQuanCls":editedQuanCls,
"editedQuan_cls_crt_gate":editedQuan_cls_crt_gate,
"editedQuan_piece":editedQuan_piece,
"editedQuan_piece_gate":editedQuan_piece_gate,
"editedNote":editedNote};
var options = {
type : "get",
url : url,
data: data,
dataType: 'json',
async : false,
cache : false,
success : function(response,status) {
alert("success")
},
error:function(request,response,error){
alert("errro: " + error)
}
};
$.ajax(options);
}
I tried to put the updated button in a td aside to the inputs and it works fine, but this will update each row separately, but my need is to updated them all in one click.
I'll attach a screen shot of my view.
Many Thanks in advance
<input class="facture_item_name" ng-model="sf.facture_item_name" value="{{sf.facture_item_name}}" ng-change="updateValues(sf.facture_item_name)" type="text"/>
$scope.updateValues=function(value){
$scope.sf.facture_item_name=value;
}
What you need is a wrapper function.
First add a button on the page that covers the All option like:
<button ng-click="updateAllFacture()">SUBMIT ALL</button>
Then add the wrapper function. All this does is loop through each item in the list and call the update function.
The wrapper function would look like:
$scope.updateAllFacture=function(){
angular.forEach($scope.res, function(sf, index) {
$scope.updateFacture=function(sf.id,sf,sf.facture_type,sf.item_id );
});
};
If you have an awful lot of items then there will be a lot of calls back to your api. Consider submitting all the inputs in the form as a post instead - then there will be just one call back, but you will need to program your controller for that.

Replace all ↵ for a new line in angular loop

I have a loop currently in my application located here:
<tr ng-repeat="audit in audctrl.audits | orderBy:'-created_at'">
<td>
{{audit.objects}}
</td>
</tr>
The object's code shows a lot of text, but with a lot of the ↵ symbol.
How would I go about making these replaced?
I have tried
{{audit.object.replace(/\u21B5/g,'<br/>')}}
What would be the best method to make this work?
I would suggest you to write an angular filter. For example:
myApp.filter('multiline', function () {
return function(text) {
return text.replace(/\n/g, '<br>');
}
});
and then call it with pipe:
<tr ng-repeat="audit in audctrl.audits | orderBy:'-created_at'">
<td>
{{audit.objects | multiline}}
</td>
</tr>
#Edit
I'm not sure about your new line character code but you can easy change it. Angular filters are good because they are reusable in other parts of application.
#Edit2
To display html tags in Angular binding u have to use $sce service and ng-bind-html="audit.objects | multiline" instead of {{audit.objects | multiline}}
http://jsfiddle.net/c1qwg776/
Write this in your controller at initialisation:
for(var i=0;i<audctrl.length;i++){
for(var j=0;j<audctrl[i].objects.length;j++){
if(audctrl[i].objects.charCodeAt(j)===10){
var temp=audctrl[i].objects.substring(0,j);
temp+="<br/>";
audctrl[i].objects= temp+audctrl[i].objects.substring(j+5,audctrl[i].objects.length-1);
}
}
}

ng-change not working in Select

I don't know what happen but this function seems like not working at all.
Here is my view:
<tr>
<th>Category</th>
<td>
<select class="form-control" ng-model="masterlist.category_id" ng-options="c.category_id as c.category_name for c in category" required data-ng-change="getSubCategory(c.category_id)"></select>
</td>
</tr>
<tr>
<th>Sub Category</th>
<td>
<select class="form-control" ng-model="masterlist.sub_category_id" ng-options="c.sub_category_id as c.sub_category_name for c in subCategory" required></select>
</td>
</tr>
Angular JS
$scope.getSubCategory = function (category_id) {
$http.get('/MasterList/SubCategory' + category_id).then(function ($response) {
$scope.subCategory = $response.data;
});
}
Controller:
public ActionResult SubCategory(int id)
{
db.Configuration.ProxyCreationEnabled = false;
return Json(db.Sub_Category.Where(x => x.active_flag == true && x.category_id == id).ToList(), JsonRequestBehavior.AllowGet);
}
I check on the console but nothing's error and here is the inspect element view:
My main goal is to once category is selected, the display for sub category will be only those under the category.
Thanks in advance for the help.
Your select element's ng-model is set to masterlist.category_id. So you should pass that to your getSubCategory method.
<select class="form-control" ng-model="masterlist.category_id"
ng-options="c.category_id as c.category_name for c in vm.category"
required data-ng-change="vm.getSubCategory(masterlist.category_id)"></select>
Also you need to send a request with the url pattern SubCategory/3 where 3 is the category id value. With your current code it is going to make a request to SubCategory3 and you will see a 404 error if you inpsect your browser network tab.
You should add a / between the catetory_id variable and the action method name,
$http.get('Home/SubCategory/' + category_id)
I also recommend moving your http calls to a data service which can be injeccted to your controller. Als, you should not hard code the url's like that in your js file. Try to use the Url.Action helper method to generate the proper relative urls to your action method/api endpoints as explained in this post and this post.
Change the scope only when the value changes.
if($scope.subCategory != $response.data)
$scope.subCategory = $response.data;

how to fix ngtable pagination?

I have developed a ngtable with a filter. The pagination on the table does not work anymore though? When I select the show 10 rows on the bottom of the table it still shows 14 rows? How can i fix the pagination/indexing?
This is my table definition:
<table ng-table="tableParams" class="table">
<tr ng-repeat="account in $parent.filtered =(data | filter:search.accountName | filter:search.id)">
<td data-title="'id'">
{{account.account.accountId.id}}
</td>
<td data-title="'name'">
{{account.account.accountName}}
</td>
</tr>
</table>
plunkr:http://plnkr.co/edit/Rqt6px?p=preview
You need to figure pagination function by yourself. You may see ng-table's example in here.
var Api = $resource("/data");
this.tableParams = new NgTableParams({}, {
getData: function(params) {
// ajax request to api
return Api.get(params.url()).$promise.then(function(data) {
params.total(data.inlineCount); // recal. page nav controls
return data.results;
});
}
});
It first load all the data into Api. The params.url() contains current page and page count. It then use these two variable to return part of dataset. So you may need to figure out how to return this part of data.

Resources