I'm trying to build an example for processing creation of objects through a form with Ember Data to insert into database.
So far my store shows the results in client side, but as far as processing the data to server, seems like my data is always undefined and creates blank records.
For now, my php API is not polished (that's why it allows the blank inserts) but since I'm running tests I'm just concerned with the data making it to the database.
How should I process a form with Ember Data? (And why is it using the 'createRecords' method instead of 'createRecord'?)
All help will be incredibly appreciated, I'm really trying to pull things out with Ember and hoping I will not have to drop and switch to another framework.
Here's my code where I'm attempting to create a Person via form and directly via code.
Ember/JS:
App = Em.Application.create();
App.Person = DS.Model.extend({
id: DS.attr('string'),
name: DS.attr('string'),
lastname: DS.attr('string'),
didLoad: function() {
console.log(this.get('lastname') + " finished loading.");
}
}).reopenClass({
url: '../api/index.php?model=entity',
});
App.adapter = DS.Adapter.create({
findAll: function (store, type) {
var url = type.url+'&method=read';
$.getJSON(url, function(data) {
store.loadMany(type, data);
});
},
createRecord: function (store, type, model) {
console.log(id);
var url = type.url+'&method=create'
$.ajax({
url: url,
data: model.get('data'),
//data: id,
dataType: 'json',
type: 'POST',
success: function(data) {
console.log('didCreate');
}
})
},
createRecords: function (store, type, array) {
$.ajax({
url: type.url+'&method=create',
data: array.mapProperty('data'),
dataType: 'json',
success: function(data) {
store.didCreateRecords(type, array, data);
}
})
},
find: function(store, type, id) {
console.log('find one');
var url = type.url;
url = url.fmt(id);
$.getJSON(url, function(data) {
store.load(type, id, data);
});
}
});
App.store = DS.Store.create({
revision: 4,
adapter: App.adapter
});
App.personController = Ember.ArrayController.create({
content: [],
init: function(){
this._super();
this.set('content', App.store.findAll(App.Person));
},
loadCode: function() {
content: [];
var self = this;
var wycats = App.store.createRecord(App.Person, {"id":"", "name":"12", "lastname":"Steve"});
App.store.commit();
console.log('from file');
},
submitForm: function(event) {
console.log('Called Sumbit');
App.store.createRecord(App.Person, this.get("content"));
App.store.commit();
}
});
App.personView = Ember.View.extend({
templateName: 'text'
});
HTML:
<script type="text/x-handlebars">
<b>{{App.title}}</b><br>
{{view App.personView}}
Count: ({{App.personController.length }})
{{#each App.personController}}
<p>{{lastname}} {{name}}</p>
{{/each}}
</script>
<script type="text/x-handlebars" data-template-name="text">
<h2>Create from Code</h2>
<div class="send_form">
<button {{action "loadCode" target="App.personController"}}>Create</button>
<hr>
<h2>Create from Form</h2>
First name: {{view Ember.TextField valueBinding="lastname"}} <br/>
Last name: {{view Ember.TextField valueBinding="name"}} <br/>
<button {{action "submitForm" target="App.personController"}}>Create</button>
<h3>Current values: {{name}} {{lastname}}</h3>
</div>
</script>
And the back-end API (PHP):
<?php
require_once 'config.php';
if (!$errors) {
$method = mysql_real_escape_string($_GET['method']);
$model = mysql_real_escape_string($_GET['model']);
$format = mysql_real_escape_string($_GET['format']);
if($method === ''){
$method = mysql_real_escape_string($_POST['method']);
}
switch ($method) {
case 'create' :
$fieldlist=$vallist='';
foreach ($_POST as $key => $value) {
$fieldlist.=$key.',';
$vallist.='\''.urlencode($value).'\',';
}
$fieldlist=substr($fieldlist, 0, -1);
$vallist=substr($vallist, 0, -1);
$return.= $vallist.' (val)
';
$return.= $fieldlist .' (field)
';
$query='INSERT INTO `test_'.$model.'` ('.$fieldlist.') VALUES ('.$vallist.')';
$sql = mysql_query($query) or
die ('Error while getting data'.mysql_error());
$return= $sql;
break;
case 'read' :
$query = "SELECT * FROM `test_{$model}`";
$result = mysql_query($query);
$return = array();
while($row = mysql_fetch_assoc($result)) {
$return[] = $row;
}
$return= json_encode($return);
break;
case 'reads' :
$query = "SELECT * FROM `test_{$model}`";
$result = mysql_query($query);
$return='{ "'.$model.'" : ';
$resultados = array();
while($row = mysql_fetch_assoc($result)) {
$resultados[] = $row;
}
$return.= json_encode($resultados);
$return.=' }';
break;
}
mysql_close();
switch ($format) {
default :
echo $return;
break;
}
}
?>
Related
I have made a function of changing the Avatar. This works, but when I try to return a response in ajax, json content is displayed in my browser and do not get anything in ajax
My ajax
$('changeBlogLogoForm').submit(function (e) {
e.preventDefault();
var form = this;
$.ajax({
url: $(form).attr('action'),
method: $(form).attr('method'),
data: new FormData(form),
processData: false,
dataType: 'json',
contentType: 'application/json; charset=utf-8',
success: function (data) {
console.log(data);
}
// toastr.remove();
// console.log('+');
// if (data.status === 1) {
// toastr.success(data.msg);
// $(form)[0].reset();
// } else {
// toastr.error(data.msg);
// }
// }
});
My function in controller
public function changeBlogLogo(Request $request)
{
$settings = Setting::find(1);
$logo_path = 'back/dist/img/logo-favicon';
$old_logo = $settings->getAttributes()['blog_logo'];
$file = $request->file('blog_logo');
$filename = time() . '_' . rand(1, 100000) . '_sdblog_logo_png';
if ($request->hasFile('blog_logo')) {
if ($old_logo != null && File::exists(public_path($logo_path . $old_logo))) {
File::delete(public_path($logo_path . $old_logo));
}
$upload = $file->move(public_path($logo_path), $filename);
if ($upload) {
$settings->update([
'blog_logo' => $filename
]);
return response()->json(['status' => 1, 'msg' => 'Success']);
} else {
return response()->json(['status' => 0, 'msg' => 'Error']);
}
} else {
dd('No file');
}
}
I tried to display the data in the console, but nothing is displayed
try this one
let value = e.target.files[0]
let formData = new FormData();
formData.append('blog_logo', value)
and don't forget to add multipart form data in your jquery ajax
contentType: 'multipart/form-data',
hope this work
I have some code where I update multiple files using a package.
Add / Remove seems to work if I console.log, but if I do a POST request, on server I get all files, even if I delete them.
Example: I add 3 files, I delete 2 of them and I do a POST, on server I get 3 files. (But on console.log it shows me that I have only 1 which is correct).
Also, I find this article , but I am not sure what to do in my case.
This is a short version of my code.
<div id="upload-files-on-update">
<file-upload
:multiple="true"
v-model="certifications"
input-id="certifications"
name="certifications[]"
#input-filter="inputFilter"
ref="upload">
<span class="button">Select files</span>
</file-upload>
</div>
new Vue({
el: '#upload-files-on-update',
data: function () {
return {
certifications: [],
}
},
components: {
FileUpload: VueUploadComponent
},
methods: {
updateFiles(){
let formData = new FormData();
this.certifications.forEach((file, index) => {
if (!file.status && file.blob) {
formData.append("certifications[]",
{
types: this.accept,
certifications_ids: this.certifications_ids,
}
);
this.loadingButton = true;
}
});
axios
.post("<?php echo $link;?>", formData, {
headers: {
"Content-Type": "multipart/form-data"
},
params:{
types: this.accept,
certifications_ids: this.certifications_ids,
}
})
},
inputFilter(newFile, oldFile, prevent) {
if (newFile && !oldFile) {
if (/(\/|^)(Thumbs\.db|desktop\.ini|\..+)$/.test(newFile.name)) {
return prevent()
}
if (/\.(php5?|html?|jsx?)$/i.test(newFile.name)) {
return prevent()
}
}
if (newFile && (!oldFile || newFile.file !== oldFile.file)) {
newFile.blob = ''
let URL = window.URL || window.webkitURL
if (URL && URL.createObjectURL) {
newFile.blob = URL.createObjectURL(newFile.file)
}
newFile.pending = true;
newFile.thumb = ''
if (newFile.blob && newFile.type.substr(0, 6) === 'image/') {
newFile.thumb = newFile.blob
}
}
},
// Remove file from table
removeFile(index) {
this.certifications.splice(index, 1);
},
}
});
I found a solution for this problem.
//I catch ajax request and I make sure that is the request that I want it
var self = this;
$.ajaxSetup({
beforeSend: function (xhr,settings) {
if(settings.type != 'POST'){
return ;
}
if(settings.data.get('controller') != 'wcfm-memberships-registration'){
return ;
}
// Here I set file input as an empty array
settings.data.set('certifications[]',[]);
// Here I add my new files from a VueJS array
self.certifications.forEach((file, index) => {
settings.data.append("certifications[]", file.file);
});
}
});
});
I want to store Auth::user()->id on the default column user_id in the SQL query shown below.
I tried to set put like this but does not send any data to the database.
public function saveLoadingsData() {
//Validate for a valid Post Request
if (isset($_POST['orderNumber']) && isset($_POST['Truck']) && isset($_POST['receiptNumber']) && isset($_POST['items'])) {
// {"orderNumber":"CRS1104200001","agentId":"3","items":[{"itemId":"4","itemName":"Embe","quantity":"13"}]}
$orderNumber = $_POST['orderNumber'];
$items = $_POST['items'];
$receiptNumber = $_POST['receiptNumber'];
$Truck = $_POST['Truck'];
$driverName = $_POST['driverName'];
foreach ($items as $singleItem) {
$data = array('order_no' => $orderNumber,'user_id'=>Auth::user()->id,"receiptNumber" => $receiptNumber, "Truck" => $Truck, "driverName" => $driverName, "pid" => $singleItem['itemId'], "qty" => $singleItem['quantity']);
// print_r($data);
DB::table('loadings')->insert($data);
// return redirect()->back();
}
// return redirect()->back();
echo "Success";
}
My ajax function
$("#btnSaveOrder").on('click', function(e){
var orderNumber=$("#order_no").val();
var receiptNumber=$("#receiptNumber").val();
var Truck=$("#Truck").val();
var driverName=$("#driverName").val();
var jsonData=convertTableToJson();
$.ajax('/api/loading/saveLoadingsData', {
type: 'POST',
data: {
orderNumber:orderNumber,
receiptNumber:receiptNumber,
Truck:Truck,
driverName:driverName,
items:jsonData
},
success: function (data, status, xhr) {
alert("Data Saved");
document.location.reload(true);
},
error: function (jqXhr, textStatus, errorMessage) {
console.log(errorMessage);
}
});
});
var convertTableToJson = function(){
var rows = [];
$('table#tableSelectedItems tr').each(function(i, n){
if (i!=0) {
var $row = $(n);
rows.push({
itemId: $row.find('td:eq(0)').text(),
itemName: $row.find('td:eq(1)').text(),
quantity: $row.find('td:eq(2)').text(),
});
}
});
return rows;
};
My api route
Route::post('loading/saveLoadingsData', 'LoadingController#saveLoadingsData');
Can someone help me?
I recommend you the following
Pass the $request object in your method and log all object, maybe are missing data and for that reason it does not meet the condition:
saveLoadingsData(Request $request){
Log::info(json_encode($request->all()));`
}
Then check your logs files to see the result in /storage/logs/laravel.log
my view ProvaincePanel.js
Ext.define('MyApp.view.ProvaincePanel', {
extend: 'Ext.dataview.NestedList',
alias : 'widget.provaincePanel',
config: {
store : 'Provainces',
title: 'Select your Provaince',
displayField: 'text',
detailCard: {
html: 'You can see detail information here!'
}
}
});
my store Provainces.js
Ext.define('MyApp.store.Provainces', {
extend: 'Ext.data.TreeStore',
config: {
model: 'MyApp.model.Provaince',
proxy: {
type: 'ajax',
url: 'http://127.0.0.1/pbesse-test/list-provainces3.php',
}
}
});
my model Provaince.js
Ext.define('MyApp.model.Provaince', {
extend: 'Ext.data.Model',
config: {
fields: [{
name: 'text',
type: 'string'
}]
}
});
my controller TheWorld.js
Ext.define('MyApp.controller.TheWorld', {
extend : 'Ext.app.Controller',
config: {
profile: Ext.os.deviceType.toLowerCase(),
stores : ['Provainces'],
models : ['Provaince'],
refs: {
myContainer: 'provaincePanel'
},
control: {
'provaincePanel': {
activate: 'onActivate',
leafitemtap: 'onDetailDisplay'
}
}
},
onActivate: function() {
console.log('Main container is active');
},
onDetailDisplay: function(nestedList, list, index, target, record) {
var detailCard = nestedList.getDetailCard();
detailCard.setHtml('Here is the detail information for ' +
record.get('text'));
},
onItemTap: function(view, list, index, target, record, event) {
console.log('Item was tapped on the Data View');
console.log(view, list, index, target, record, event);
if(event.target.type == "button"){
Ext.Msg.alert('You clicked on the Button ...',
'The country code selected is: ' + event.target.name);
}
else {
Ext.Msg.alert('You clicked on the Row ...',
'The country code selected is: ' + record.get('code'));
}
//return false;
},
init: function() {
console.log('Controller initialized');
},
});
the list-provainces3.php file contain
<?php
#mysql_connect('127.0.0.1','root','') or die(mysql_error());
#mysql_select_db('pbesse_test');
$node = $_GET['node'];
$node = explode('%2F', $node);
if(count($node) == 1)
{
$sql = "SELECT * FROM provainces";
$req = mysql_query($sql) or die(mysql_error());
$data = array();
while($res = mysql_fetch_array($req)){
$tmp = array();
$tmp['id'] = "root/".$res['id'];
$tmp['text'] = utf8_encode($res['libelle']);
$tmp['leaf'] = false;
$tmp['cls'] = 'folder';
$data[] = $tmp;
}
}
if(count($node) == 2){
$sql = "SELECT * FROM chateaux where id_provaince = ". $node[1];
$req = mysql_query($sql) or die(mysql_error());
$data = array();
while($res = mysql_fetch_array($req)){
$tmp = array();
$tmp['id'] = "root/".$res['id_provaince']."/".$res['title'];
$tmp['text'] = utf8_encode($res['libelle']);
$tmp['leaf'] = false;
$tmp['cls'] = 'folder';
$data[] = $tmp;
}
}
header('Content-Type: application/json, charset=UTF-8');
echo str_replace('\\','' , json_encode($data));
exit;
?>
when i execute the application , i have a list of countries
but when i click on a country name, it show me a loading message and the application bugs
I'm trying to change the value of a dojo tree to display the correct icon. I was hopping that I could get the object with fetchItemByIdentity() and change the value there but the item is null
_target: null,
_treeModel: null,
constructor: function(target, uuid) {
this._target = target;
this._uuid = uuid;
// from somewhere else the value get's changed
topic.subscribe("questionChanged", lang.hitch(this, function(object, id) {
var item = this._treeModel.fetchItemByIdentity({
identifier: id,
onItem: function(item, request) { alert("item " + item); }
});
}));
},
buildTree: function() {
xhr.get({
// The URL to request
url: er.getAbsoluteUrl("/secure/staticquestion/tree?uuid=" + this._uuid),
handleAs: "json",
headers: {
"Content-Type": "application/json; charset=utf-8"
},
preventCache: 'true',
// The method that handles the request's successful result
load: lang.hitch(this, function(response) {
var rawdata = new Array();
rawdata.push(response);
var store = new ItemFileReadStore({
data: {
identifier: "uuid",
label: "name",
items: rawdata
}
});
this._loadtree(store);
}),
error: function(err, ioArgs) {
errorDialog.show(err.message);
}
});
},
_loadtree: function(store) {
this._treeModel = new TreeStoreModel({
store: store,
query: {
name: 'root'
},
childrenAttrs: [ "children" ],
mayHaveChildren: function(object) {
return object.children.length > 0;
}
});
var tree = new Tree({ // create a tree
model: this._treeModel, // give it the model
showRoot: false,
getIconClass: function(/* dojo.data.Item */item, /* Boolean */opened) {
if (!item || this.model.mayHaveChildren(item)) {
return opened ? "dijitFolderOpened" : "dijitFolderClosed";
} else if (item.comment == 'false') {
return (item.answer == 'YES') ? "dijitLeafNoCommentYes"
: ((item.answer == 'NO') ? "dijitLeafNoCommentNo" : "dijitLeafNoComment");
} else if (item.comment == 'true') {
return (item.answer == 'YES') ? "dijitLeafYes" : ((item.answer == 'NO') ? "dijitLeafNo"
: "dijitLeaf");
}
return "dijitLeaf";
},
}, this._target); // target HTML element's id
tree.on("click", function(object) {
topic.publish("staticQuestionSelected", object);
}, true);
tree.startup();
}
I'm glad for help, thanks!
Ok, I found my issue: I need to use a ItemFileWriteStore and there I can change values with store.setValue(item, attribute, value). The tree updates itself afterwards.