Symfony 5 ajax post form - ajax

I need to make dynamic form in symfony 5 with ajax.
I make post request with axios on input value change on main route "/".
This route call my controller and i call dump() function for debug my request but i don't have any params on my request.
I looked in my network and my data is posted well. But I don't receive params on my request controller :/
On my view
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.21.0/axios.min.js"></script>
<script>
cat = document.getElementById("article_category")
token = document.querySelector("#article__token");
title = document.querySelector("#article_title");
cat.addEventListener("change", function (e) {
let form = document.querySelector("form")
let data = {}
data[title.getAttribute("name")] = title.value
data[token.getAttribute("name")] = token.value
data[cat.getAttribute("name")] = cat.value
axios.post("https://127.0.0.1:8000/", data).then(res => {
str = res.data
var parser = new DOMParser();
var doc = parser.parseFromString(str, 'text/html')
console.log(doc);
}).catch(function (error) {
console.log(error);
});
})
</script>
My Controller
/**
* #Route("/", name="article")
*/
public function index(Request $request, EntityManagerInterface $em): Response
{
$article = new Article();
$form = $this->createForm(ArticleType::class, $article);
$form->handleRequest($request);
if ($request->getMethod() == 'POST') {
dump($request);
}
if ($form->isSubmitted() && $form->isValid()) {
$em->persist($article);
$em->flush();
}
return $this->render('article/index.html.twig', [
"form" => $form->createView(),
]);
}
FormType
$builder
->add('title')
->add('category')
->add('Submit', SubmitType::class);
$builder->get('category')->addEventListener(
FormEvents::POST_SUBMIT,
function (FormEvent $event) {
$form = $event->getForm();
if ($form->getData()->getName() == "Cat 0") {
$form->getParent()->add('tag', EntityType::class, [
'class' => Tag::class,
]);
}
}
);

Related

On vue how to make a Edit function

Im doing my first CRUD with Vue - Laravel, i did a Add function that works fine but my Edit button is doing another Add function.
(I get the alert from updateDespesa alert("Usuário Alterado!");)
My Frontend:
async updateDespesa(despesa) {
const response = await axios
.put("api/despesas/" + despesa, {
des: this.despesa.des,
valr: this.despesa.valr,
vencc: this.despesa.vencc,
stt: this.despesa.stt,
emiss: this.despesa.emiss,
})
.then((response) => {
this.despesa.id = "";
this.despesa.valr = "";
this.despesa.stt = "";
this.despesa.vencc = "";
this.despesa.emiss = "";
this.getDespesa();
if(despesa){
alert("Usuário Alterado!");
}
})
.catch((err) => {
console.log(err);
});
},
My Backend:
public function update(Request $request, $id) {
if ($id == 0) {
$despesa = new Despesa;
$despesa->create($request->all());
}
else {
$despesa = Despesa::findOrFail($id);
$despesa->fill($request->all())->save();
}
//$despesa->update($request->all());
return response()->json('Sucess');
}
In your backend, try update this and see
public function update(Request $request, $id) {
if ($id == 0) {
$despesa = new Despesa;
$despesa->create($request->all());
}
else {
$despesa = Despesa::findOrFail($id);
$despesa->fill($request->all())->save();
}
//$despesa->update($request->all());
return response()->json('Sucess');
}
and also please check the Despesa Model has declared the input fields in protected $fillable
async updateDespesa(despesa) {
const response = await axios
.put("api/despesas/" + despesa, {
...
})
.then((response) => {
// add this line, to check only alert when id is not null
// so that it only alert when update
if(despesa){
alert("Usuário Alterado!");
}
....
})
.catch((err) => {
console.log(err);
});
},

How to organize data to send a post request to a API? laravel + vue-cli project

i'm writing a code using laravel as backend and vue-cli as frontend.
i've got a problem with the data to send to an API laravel restful controller. I get back as answer the err 500.
That's my saveEvent code:
saveEvent() {
const staff = this.$store.getters.get_selected_staff.map(
raw_staff => {
return {
...raw_staff,
icon: "mdi-drama-masks" ? "actor" : "technician",
percent:
raw_staff.percent == "full"
? 1
: eval(raw_staff.percent),
allowance: parseInt(raw_staff.allowance),
daily: parseInt(raw_staff.daily)
};
}
);
const show = {
...this.$store.getters.get_tournee_show_detail
};
this.$http
.post(
"http://localhost:8080/api/tourneeDetail",
`show=${JSON.stringify(show)}&staff=${JSON.stringify(
staff
)}`
)
.then(response => {
this.closeEvent();
})
.catch(error => {
console.log("errore nella registrazione", error);
});
// );
}
The datas goest straight to the controller and get manages in this way:
public function store(Request $request)
{
//
dd($request->all());
$tournee = new TourneeDetail;
$show = json_decode($request->show, true);
$staff = json_decode($request->staff, true);
foreach ($show as $detail => $value){
if($detail == "stage_id"){
$tournee->stage_id = $value['id'];
}
else{
$tournee[$detail] = $value;
}
}
$tournee->save();
foreach ($staff as $row){
$staff = new Staff;
foreach ($row as $detail => $value){
if ($detail!="icon" && $detail!="names" ){
$staff[$detail] = $value;
}
}
$staff->type = $row["icon"];
$staff->tournee_detail_id = $tournee->id;
$staff->save();
foreach ($row["names"] as $id){
$staff_person = new StaffPerson;
$staff_person->person_id = $id;
$staff_person->staff_id = $staff->id;
$staff_person->save();
}
}
return $tournee;
}
The problem is that i get the 500 error on the 1rst foreach. I put a dd to check the $request->all() and i noticed that the payload sent is correct but the preview is an empty array!
I dunno how to fix this problem..any help would be appreciated!
Thank you
Valerio

Import an excel and insert into database

How to import an excel file and add the data into the database? I have the logic in the controller (I think) but I'm unsure how to send it from the vue to the controller? I'm basing this code on another project I was working on and tutorials but I don't know how to adapt it to my project.
This is the controller store function
public function store(Request $request)
{
ini_set('max_execution_time', 300);
$users = $request->all();
try {
DB::beginTransaction();
foreach ($users as $user) {
$dbUser = $this->getUser($user['CARNET']);
Log::error($dbUser);
$dbUser->name = $user['NOMBRE'];
$dbUser->card = $user['CEDULA'];
$dbUser->scard = $user['CARNET'];
$dbUser->email = $user['CORREO'];
$dbUser->password = $user['PASSWORD'];
$this->isSet('TIPO-USUARIO', $user);
$user_type_id = $this->getUserId($user['TIPO-USUARIO']);
$dbUser->user_type_id = $user_type_id->id;
$dbUser->save();
foreach (explode(',', str_replace(' ', '', $user['CATEGORIA-USUARIO'])) as $c) {
$category = $this->getCategory($c);
$dbUser->userCategory()->save($category);
}
$dbUser->save();
}
DB::commit();
} catch (Exception $e) {
DB::rollBack();
throw new HttpException(500, 'Sucedio un error importando la información favor intentar de nuevo');
}
}
What I have in my vue
<input type="file" name="file" class="inputfile" id="fileUpload"/>
<label for="fileUpload">Select Excel</label>
<el-button
style="margin: 5px; margin-left: 20px"
type="primary"
class="mt-1"
:loading="loading"
#click="sendData()">Import
</el-button>
sendData(data) {
this.loading = true;
this.error = {};
this.$http.post(this.baseUrl, data, this.params)
.then(
() => {
this.successAction();
this.errorDis = false;
},
(res) => {
this.showErrors(res);
this.errorDis = true;
}
);
},
successAction() {
this.loading = false
},
showErrors(res) {
const [message, errors] = parseError(res);
this.error = {
message,
errors
};
this.loading = false;
this.processing = false;
},
I'm not sure how to send the actual data to the controller to be able to save it.
You could use Laravel-Excel to read the file, create an object or array and store the data on the table that you want. In the view (blade, vue, jQuery, whatever) you just must send the file as POST though a route like this:
Route::post('/importExcel', 'YourController#importExcelmethod');
In the controller you could make something like this:
public function importExcel(Request $request)
{
if($request->file('import_file')){
$path = $request->file('import_file')->getRealPath();
$data = Excel::selectSheetsByIndex(0)->load($path, function($reader) {
})->get()->toArray();
if(!empty($data) && (count($data)> 0)){
foreach ($data as $key => $value) {
DB::table('your_table')->insert(
[
"a_column" => $value[0],
"another_comun" => $value[1],
//etc
]
);
}
More info here and examples here: https://docs.laravel-excel.com/3.1/imports/
Actually there are some easier examples on how to store data to a Model from the xls like this:
public function import()
{
Excel::import(new UsersImport, 'users.xlsx');
return redirect('/')->with('success', 'All good!');
}

Laravel: Post Array of Objects

Im in trouble with this code, I cant store my dataP array objects into mysql.
Ajax request :
$.ajax({
url:'/register/addpostulantR',
method:'post',
dataType: "text",
data:JSON.stringify(dataP),
success(data){
console.log("succ "+data);
},
error:()=>{
console.log('error ');
}
})
Controller:intervenantController.php
public static function addPostulantR(Request $request)
{
return response()->json([
'dataP' => Intervenant::addPostulantR($request->all())
]);
//The dataP is my json
}
Model: Intervenant.php
public static function addPostulantR($data)
{
//$test = json_decode($data);
$id = 0;
foreach($data as $dataP) {
$id = DB::table('reponse')->insertGetId($dataP);
}
return $id;
}
Array: From my javascript
let dataP = [
{
fk_id_quest:1,
fk_id_post:id,
reponse : $("#descriptif_offre").val(),
created_at:date.getTime()/1000,
},
{
fk_id_quest:2,
fk_id_post:id,
reponse : $("#descriptif_offre").val(),
created_at:date.getTime()/1000,
}
];
Thanks a lot..

Timber - WordPress, Append data (json) to Timber\Post Object after ajax call

update 3
Please see answer below! Can provide further explanation there on request if needed
Update 2
js
$archiveLayout.on('click',loadMoreButtonID,function(){
let pageCount = $(this).attr('data-page'),
nextPage = parseInt( $(this).attr('data-page') ) + 1;
let getParams;
_.each($loadMoreButton, function(item) {
let thisData = window.$(item).data()
getParams = thisData;
});
console.log(getParams);
$.post(ajaxurl, getParams,function(response){
// var json_obj = JSON.parse(res);
console.log(response);
console.log(response.data);
}).done(function(){
$('#load-more').attr('data-page', nextPage);
});
});
php function
add_action('wp_ajax_more_all_posts', __NAMESPACE__ . '\\ajax_more_all_posts');
add_action('wp_ajax_nopriv_more_all_posts', __NAMESPACE__ . '\\ajax_more_all_posts');
function ajax_more_all_posts()
{
$response = array(
'data' => Timber::compile(array('templates/blocks/content.twig'), $context)
);
wp_send_json($response);
}
HTML is retunred, but it's only 1 post and the data isn't populating the twig markup.
old****
So on my blog page, I want to load more posts, and I'm wondering if I can just append the response data to the posts array aleady on the page. Or if need to build it out a certain way to allow for that.
Any tips/help etc would be greatly appreciated.
code samples below
I have the following set up in in my twig file:
{% for post in posts %}
{% set postCount = loop.index %}
{% set postImage = TimberImage(post.get_field('preview_image_post'))|resize('medium_large') %}
{% include "blocks/content.twig" with {post: post} %}
{% endfor %}
Outputs the posts onto the page just fine.
I then make an ajax request doing the following:
window.axios.get(fancySquaresRestUrl + 'wp/v2/posts', {
params: getParams
})
.then(function (response) {
// append the entire repsonese? wasn't working, could be doing it wrong
_.each( response.data, function( post, index ) {
//append each object on its own maybe???
});
})
.catch(function (error) {
console.log(error);
});
The full answer is as follows: (this is not appending anything to the Timber/Post Object, this is appending HTML from the data that get's passed to the twig file)
Any questions or comments you have about the below code feel free to ask.
The js used:
$archiveLayout.on('click',loadMoreButtonID,function(){
var $this = $(this);
var pageCount = $(this).attr('data-pageCount');
var nextPage = parseInt($(this).attr('data-page')) + 1;
var getParams = void 0;
_.each($loadMoreButton, function (item) {
var thisData = window.$(item).data();
getParams = thisData;
});
getParams.pagecount = pageCount;
// console.log(getParams);
$loader.fadeIn();
$loadMoreButton.fadeOut();
$.post(ajaxurl, getParams, function (response) {
// var json_obj = JSON.parse(res);
// console.log(response);
//console.log(response.data);
if(response === 'nomore'){
$loadMoreButton.fadeOut();
} else {
for(var hp = 0; hp < response.length; hp++){
$('[data-js="append-content"]').append(response[hp].data);
$this.attr('data-pageCount', Number(pageCount)+1);
}
$loadMoreButton.fadeIn();
}
}).done(function () {
$loader.fadeOut();
// $('#load-more').attr('data-page', nextPage);
});
});
the function being called:
add_action('wp_ajax_more_all_posts', __NAMESPACE__ . '\\ajax_more_all_posts');
add_action('wp_ajax_nopriv_more_all_posts', __NAMESPACE__ . '\\ajax_more_all_posts');
function ajax_more_all_posts()
{
$cat_id = $_REQUEST[ 'cat' ] or $_GET[ 'cat' ];
$paged = $_REQUEST['pagecount'];
$cat = $_REQUEST['dataCat'];
$args = [
'cat' => $cat_id,
'posts_per_page' => 9,
'post_status' => 'publish'
];
if($paged != ""){
$args['paged'] = $paged;
}
$posts = Timber::get_posts($args);
$message = [];
if($posts){
foreach($posts as $post){
$response = array(
'data' => Timber::compile('templates/blocks/content.twig', ['post' => $post])
);
$message[] = $response;
}
} else {
$message = "nomore";
}
wp_reset_query();
wp_reset_postdata();
wp_send_json($message);
die();
}
I already did something close. My solution was to render at the ajax and send the html.
So my Ajax calls a php and at the php I do this:
For this example my ajax call the get_php_logic action.
At the php action I do my logic to render the twig, at the final i return as Json response.
$response = array(
'data' => Timber::compile(array('template.twig'), $context)
);
wp_send_json($response);
So this way my response.data will be html ready to append or replace.

Resources