i called a controllerAction in symfony2 from jquery script in twig template for form validation and verification. After a successful response i called another controller from jquery script using $.post() for rendering a template for user-dashboard. but all i am getting is a template displayed in console but not in the user browser window. How to achieve this in the above stated way. ??
Thanks for help (in advance)
AKSHAT.
<script>
// my jquery code
$(document).ready(function()
{
$('.sign_in_box').click(function()
{
var data = new Object();
data.email=$('.email_txt').val();
data.password=$('.pwd_txt').val();
$.ajax('{{ path('login_login_validation') }}', {
type : 'POST',
data : data,
success : function(response){
var json = JSON.parse(response);
var flag = json.success;
if(flag)
{
$('#pwd_login_error').css('opacity' , '0');
$('#email_login_error').css('opacity' , '0' );
$.ajax('{{ path('login_login_verification') }}',{
type : 'POST',
data : data,
success : function(response){
var login = JSON.parse(response);
if(login.login)
{
alert("login success");
$.post('{{ path('login_dashboard') }}', data);
}
else
{
$('#pwd_login_error').css('opacity' , '0.5' );
}
}});
}
else
{
$('#pwd_login_error').css('opacity' , '0' );
$('#email_login_error').css('opacity' , '0.5' );
}
}
});
});
});
</script>
//////////////////////////////////////////////////////////////////////////////////////////////////////////
// controller
<?php
namespace Login\Bundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class DashboardController extends Controller
{
public function indexAction()
{
$email = $this->get('request')->get('email');
return $this->render('LoginBundle:Dashboard:index.html.twig', array('email'=> $email));
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// routing file
login_homepage:
pattern: /
defaults: { _controller: LoginBundle:Homepage:index }
login_login_validation:
pattern: /ajax_validate
defaults: { _controller: LoginBundle:Login:validation }
login_login_verification:
pattern: /ajax_verify
defaults: { _controller: LoginBundle:Login:verification }
login_dashboard:
pattern: /dashboard
defaults: { _controller: LoginBundle:Dashboard:index }
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// twig file
{% block message %}
hello ! {{ email | json_encode | raw }}
welcome to dashboard .
{% endblock%}
The only wrong thing is this your are rendering the index page . after successfull login you have to redirect you page by
window.location = "http://somewhereelse.com";
Or You can also append data in any div , Its on to you which way you want to follow .
Related
Hi I am beginner with Ajax at the Laravel. I wanted to fetch data with Laravel Eagerload function to my blade modal.
This is my Expenses Model
protected $fillable = [
'name',
'surname',
'email',
'password',
'status',
'role',
];
protected $hidden = [
'password',
'remember_token',
];
public function Expense () {
return $this->hasMany(ExpensesModel::class);
}
This is my Expenses Model
`
{
use HasFactory;
protected $table = 'expenses';
protected $fillable = [
'id',
'emp_id',
'expense_input_date',
'expense_type',
'expense_category',
'reason',
'status'
];
public function UserExpense () {
return $this->belongsTo(User::class, 'emp_id' );
}
My controller
This is My controller function
public function edit (Request $request) {
$req_id = array('id' => $request->id);
if($request->ajax()) {
$employee = ExpensesModel::with('UserExpense')->where('id' ,$req_id)->first();
return response()->json($employee);
}
}
This is my blade script
`
function editFunc(id){
$.ajax({
type:"POST",
url: "{{ url('/expenses/advancedtable/edit') }}",
data: { id: id },
dataType: 'json',
success: function(res){
$('#EmployeeModal').html("Edit Employee");
$('#employee-modal').modal('show');
$('#id').val(res.id);
$('#emp_id').val(res.name);
$('#expense_input_date').val(res.expense_input_date);
$('#expense_type').val(res.expense_type);
$('#expense_category').val(res.expense_category);
$('#expense_slip_no').val(res.expense_slip_no);
$('#expense_amount').val(res.expense_amount);
$('#currency').val(res.currency);
$('#description').val(res.description);
}
});
}
I tried everyting but it does not work. I wanted to retrive user name from User Model by using foreign key on the Expenses model emp_id.
is there something I missed somewhere can you help me with this.
Thank you.
Here how its work.
First of all change relationship in your User and Expenses model like this.
// User Model
public function userExpense() {
return $this->hasMany(ExpensesModel::class,'emp_id','id');
}
// ExpensesModel
public function user() {
return $this->hasOne(User::class,'id','emp_id');
}
Then change your controller function.
// controller function
public function edit (Request $request) {
$req_id = $request->id;
$employeeExpense = ExpensesModel::with('user')->where('id' ,$req_id)->first();
return response()->json($employeeExpense);
}
Then change your ajax sucess function.
// ajax sucsess function
success: function(res) {
console.log(res); // to view your response from controller in webbrowser's console
$('#EmployeeModal').html("Edit Employee");
$('#employee-modal').modal('show');
$('#id').val(res.id);
$('#emp_id').val(res.user.name); // it will print user name
$('#expense_input_date').val(res.expense_input_date);
$('#expense_type').val(res.expense_type);
$('#expense_category').val(res.expense_category);
$('#expense_slip_no').val(res.expense_slip_no);
$('#expense_amount').val(res.expense_amount);
$('#currency').val(res.currency);
$('#description').val(res.description);
}
when you use 'with' eloqunt method it will add relationship function name to your query result, so you want to get user details then you should be do like res.user.userfield this is applicable for hasOne only.
For other relationship you will refer to this https://laravel.com/docs/9.x/eloquent-relationships
i am actually using graphs in my project for which i am passing dynamic data from controller to blade and then in the js script. The js function in the blade accept the array of objects and i dont know how to assign the data from the controller to that js function.
$data['typesBasedProperties'] = DB::table('properties')
->join('property_types', 'properties.property_type', 'property_types.id')
->select('property_types.types as label', DB::Raw('COUNT(properties.id) as value'))
->whereIn('properties.id', $property_ids)
->groupBy('label')
->get()
->toJson();
and this is the js function
var donutChart = function(){
Morris.Donut({
element: 'morris_donught',
data: [
{
label: " Download Sales ",
value: 12,
}, {
label: " In-Store Sales ",
value: 30
}, {
label: " Mail-Order Sales ",
value: 20
}
],
resize: true,
redraw: true,
colors: ['#2b98d6', 'rgb(59, 76, 184)', '#37d159'],
//responsive:true,
});
}
I think you need to do something like this:
<script>
var typesBasedProperties = {!! $typesBasedProperties !!}
</script>
After this you have typesBasedProperties object available in all your js code.
Check out laravel documentation for more info.
You can use ajax request to fetch data from laravel controller to javascript or JQuery.
here's some example
controller
function bbq(Request $r){
$data = DB::select('CALL bukubesar('.$r->no.')');
$node = DB::select('CALL infonode('.$r->no.')');
return array(
'data' => $data,
'node' => $node
);
}
route (I'm using Group)
Route::controller(CPembukuan::class)->group(function () {
Route::get ('/pembukuan-besar', 'bukubesar');
Route::get ('/pembukuan-besar/query', 'bbq' );
Route::get ('/pembukuan-labarugi', 'labarugi' );
Route::get ('/pembukuan-labarugi/query', 'lrq' );
});
ajax (JQuery) on html or blade file
//a variable to pass to controller (optional)
val = $('#kode').val();
$.ajax({
type: "get",
url: "/pembukuan-besar/query",
data: {
'no': val // the data represented as 'no'
},
success: function(data) {
console.log(data); // to view the data in console
//do anything you want here
}
});
I am having some difficulties with trying to add to cart with custom data from the front end.
My current PHP from the backend is as follows - this is placed in my functions.php for my child-theme (This code is from the following post: Adding a product to cart with custom info and price - considering I am indeed a PHP-noobie):
<?php // This captures additional posted information (all sent in one array)
add_filter('woocommerce_add_cart_item_data','wdm_add_item_data',1,10);
function wdm_add_item_data($cart_item_data, $product_id) {
global $woocommerce;
$new_value = array();
$new_value['_custom_options'] = $_POST['custom_options'];
if(empty($cart_item_data)) {
return $new_value;
} else {
return array_merge($cart_item_data, $new_value);
}
}
// This captures the information from the previous function and attaches it to the item.
add_filter('woocommerce_get_cart_item_from_session', 'wdm_get_cart_items_from_session', 1, 3 );
function wdm_get_cart_items_from_session($item,$values,$key) {
if (array_key_exists( '_custom_options', $values ) ) {
$item['_custom_options'] = $values['_custom_options'];
}
return $item;
}
// This displays extra information on basket & checkout from within the added info that was attached to the item.
add_filter('woocommerce_cart_item_name','add_usr_custom_session',1,3);
function add_usr_custom_session($product_name, $values, $cart_item_key ) {
$return_string = $product_name . "<br />" . $values['_custom_options']['description'];// . "<br />" . print_r($values['_custom_options']);
return $return_string;
}
//This adds the information as meta data so that it can be seen as part of the order (to hide any meta data from the customer just start it with an underscore)
add_action('woocommerce_add_order_item_meta','wdm_add_values_to_order_item_meta',1,2);
function wdm_add_values_to_order_item_meta($item_id, $values) {
global $woocommerce,$wpdb;
wc_add_order_item_meta($item_id,'item_details',$values['_custom_options']['description']);
wc_add_order_item_meta($item_id,'customer_image',$values['_custom_options']['another_example_field']);
wc_add_order_item_meta($item_id,'_hidden_field',$values['_custom_options']['hidden_info']);
}
and then I have a button on the frontend that runs the following script when pressed - this runs on a custom wordpress post where I have scripted have done some scripting in the background that collects information based on the users actions on the post:
function cartData() {
var metaData = {
description: 'My test Description'
another_example_field: 'test'
};
var activeVariationId = 10335;
var data = {
action: 'wdm_add_item_data',
product_id: 10324,
"add-to-cart": 10324,
quantity: 1,
variation_id: activeVariationId,
cart_item_data: metaData
};
$.ajax({
type: 'post',
url: wc_add_to_cart_params.wc_ajax_url.toString().replace( '%%endpoint%%', 'add-to-cart' ),
data: data,
beforeSend: function (response) {
//$thisbutton.removeClass('added').addClass('loading');
},
complete: function (response) {
//$thisbutton.addClass('added').removeClass('loading');
},
success: function (response) {
if (response.error & response.product_url) {
window.location = response.product_url;
return;
} else {
alert('ajax response recieved');
jQuery( document.body ).trigger( 'added_to_cart', [ response.fragments, response.cart_hash ] );
}
},
});
}
Unfortunately this only seems to add my current variation of the product to the to cart without any more custom information. Any help with nesting in this issue would be highly appreciated. If you need any more information and/or code examples I'd be happy to supply it :)
I think that I might have solved it, or at least parts of it with this PHP (this is really just a small modification of this code - adding $cart_item_data https://quadmenu.com/add-to-cart-with-woocommerce-and-ajax-step-by-step/):
add_action('wp_ajax_woocommerce_ajax_add_to_cart', 'woocommerce_ajax_add_to_cart');
add_action('wp_ajax_nopriv_woocommerce_ajax_add_to_cart', 'woocommerce_ajax_add_to_cart');
function woocommerce_ajax_add_to_cart() {
$product_id = apply_filters('woocommerce_add_to_cart_product_id', absint($_POST['product_id']));
$quantity = empty($_POST['quantity']) ? 1 : wc_stock_amount($_POST['quantity']);
$variation_id = absint($_POST['variation_id']);
// This is where you extra meta-data goes in
$cart_item_data = $_POST['meta'];
$passed_validation = apply_filters('woocommerce_add_to_cart_validation', true, $product_id, $quantity);
$product_status = get_post_status($product_id);
// Remember to add $cart_item_data to WC->cart->add_to_cart
if ($passed_validation && WC()->cart->add_to_cart($product_id, $quantity, $variation_id, $cart_item_data) && 'publish' === $product_status) {
do_action('woocommerce_ajax_added_to_cart', $product_id);
if ('yes' === get_option('woocommerce_cart_redirect_after_add')) {
wc_add_to_cart_message(array($product_id => $quantity), true);
}
WC_AJAX :: get_refreshed_fragments();
} else {
$data = array(
'error' => true,
'product_url' => apply_filters('woocommerce_cart_redirect_after_error', get_permalink($product_id), $product_id));
echo wp_send_json($data);
}
wp_die();
}
Where this is part of the JS-function:
var data = {
action: 'woocommerce_ajax_add_to_cart',
product_id: 10324,
quantity: 1,
variation_id: activeVariationId,
meta: metaData
};
$.ajax({
type: 'post',
url: wc_add_to_cart_params.ajax_url,
data: data, ...........
I am going to have to test it some more, as it seems now that all the data-fields also gets posted in the cart, email etc - I probably have to rewrite something so that some parts of it is hidden for the "non-admin", but available for me later on + adding custom product thumbnail on add to cart.
Hey having a issue with the rendering of a .erb file, in my AJAX call I make a call to my create action on rails where I validate and process the form data and sent back the completed order data as render: json which works fine.
I have a conditional that checks to see if parameter exists, it if does then the completed order data is passed back as a response via render: json
It if doesn't exists it will render a receipt page.
The problem is when I render the receipt page, the full HTML receipt page comes back as a response instead of rendering the page. Please Help!
$scope.placeOrder = function() {
var body = composeOrderBody();
var isValid = validateForm(body.order);
if(isValid) {
var orderComplete = '<%= #orderComplete %>';
var baseUrl = '<%= request.base_url %>';
console.log('Passing order object: ', body.order);
$http({
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
url: checkout_url,
data: {
order: body.order,
xhr_request: true
},
}).then((function(_this) {
return function(response) {
if(typeof response.data == 'undefined' || response.data == null || !response.data) {
console.log('Error: missing Order Number from Order Confirmation data.', response.data);
}
console.log('Order Confirmation response data object:' , response.data);
if(orderComplete) {
var redirectUrl = 'http://' + orderComplete
var order_params = `?oid=${response.data.oid}?cart=${response.data.cart}?total=${response.data.total}`
window.location.href = redirectUrl + order_params;
} else {
console.log('Base Url: ', baseUrl);
// window.location.href = `${baseUrl}/receipt`;
}
};
})(this));
} else {
console.log('Form Validation or Stripe Validation Failed');
}
} // end placeOrder
Rails Code
# Redirect to orderComplete URL if it's set
if !#orderComplete.blank?
puts 'orderComplete parameter is not blank'
# Sum up all the line item quantities
qty = #order.line_items.inject(0) {|sum, line_item| sum + line_item.quantity}
# Get all of the coupons (and values) into a string
coupons = #order.applied_coupons.map { |coupon| coupon.coupon }.join(',')
coupon_values = #order.applied_coupons.map { |coupon| '%.2f' % coupon.applied_value.to_f }.join(',')
order_params = {
"oid" => URI::escape(#order.number),
"cart" => URI::escape(#cart),
"total" => URI::escape('%.2f' % #order.total),
}
#redirectUrl = URI.parse(URI.escape(#orderComplete))
#redirectUrl.query = [#redirectUrl.query, order_params.to_query].compact.join('&')
#redirectUrl = #redirectUrl.to_s
if params[:xhr_request]
render json: order_params.to_json
return
end
render 'receipt_redirect', :layout => 'receipt_redirect'
else
puts 'OrderComplete Parameter is blank'
render 'receipt', :layout => 'receipt', :campaign => #campaign
end
I'm trying to create a dynamic 2-step form using Jquery where in "step 1", I want to submit the form data without refreshing my page so that I can hide my html division containing my form and show the other representing my step 2 using Jquery.
The problem is that I'm using a collection of forms in my controller action like this:
public function indexAction(Request $request)
{
$user = $this->getUser();
$em = $this->getDoctrine()->getManager();
$repository = $em->getRepository('ATPlatformBundle:NoteDeFrais');
$form = $this->get('form.factory')->createBuilder(FormType::class)
->add('ndf', CollectionType::class,array(
'entry_type' => NoteDeFraisType::class,
'label' => false,
'allow_add' => true,
'allow_delete' => true,
))
->getForm();
And I'm getting the forms data submitted from like this:
if ($request->isMethod('POST') && $form->handleRequest($request)->isValid()
&& isset($_POST['next_button'])) {
$notesDeFrais = $form['ndf']->getData();
foreach ($notesDeFrais as $ndf) {
$ndf->setUser($user);
$em->persist($ndf);
}
$em->flush();
}
elseif (isset($_POST['validate_button'])) {
foreach ($listNdf as $ndf) {
$ndf->setSubmitted(true);
}
$em->flush();
}
So what I wanted to know is how to send my data via an ajax request and how to get them from my action. So far I tried to proceed like this but it (logically) doesn't work.
$("div#bloc_validation").css("display", "none");
$("#next_button").click(function(){
$(".form_ndf").each(function(){
$.post("{{ path('platform_homepage') }}",
{ndf: $(this).serialize()}, //My issue is here
function(){
alert('SUCCESS!');
}
);
});
$("div#form_bloc ").css("display", "none");
$("div#bloc_validation").css("display", "block");
});
Do you have any ideas ? Thanks in advance
The most basic approach is this:
add a javascripts block in your twig file with the content as below.
Change appbundle_blog in the first line inside the .ready() function in the name of your form. (Inspect your html to find it).
{% extends 'base.html.twig' %}
{% block body %}
{{ form_start(edit_form) }}
{{ form_widget(edit_form) }}
<input type="submit" value="Save Changes" />
{{ form_end(edit_form) }}
{% endblock %}
{% block javascripts %}
<script
src="https://code.jquery.com/jquery-3.3.1.min.js"
integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
crossorigin="anonymous">
</script>
<script>
$(document).ready( function() {
var form = $('form[name=appbundle_blog]');
form.submit( function(e) {
e.preventDefault();
$.ajax( {
type: "POST",
url: form.attr( 'action' ),
data: form.serialize(),
success: function( response ) {
console.log( response );
}
});
});
});
</script>
{% endblock %}
If the form has been submitted you have to answer to an AJAX request. Therefore you could render another template..
/**
* Displays a form to edit an existing blog entity.
*
* #Route("/{id}/edit", name="blog_edit")
* #Method({"GET", "POST"})
*/
public function editAction(Request $request, Blog $blog)
{
$editForm = $this->createForm('AppBundle\Form\BlogType', $blog);
$editForm->handleRequest($request);
if ($editForm->isSubmitted() && $editForm->isValid()) {
$this->getDoctrine()->getManager()->flush();
/* render some new content */
return $this->render('blog/ajax.html.twig', array(
'blog' => $blog,
));
}
return $this->render('blog/edit.html.twig', array(
'blog' => $blog,
'edit_form' => $editForm->createView(),
));
Or answer in JSON:
use Symfony\Component\HttpFoundation\JsonResponse;
/**
* Displays a form to edit an existing blog entity.
*
* #Route("/{id}/edit", name="blog_edit")
* #Method({"GET", "POST"})
*/
public function editAction(Request $request, Blog $blog)
{
$editForm = $this->createForm('AppBundle\Form\BlogType', $blog);
$editForm->handleRequest($request);
if ($editForm->isSubmitted() && $editForm->isValid()) {
$this->getDoctrine()->getManager()->flush();
return new JsonResponse(array(
'status' => 'success',
// ...
));
}
return $this->render('blog/edit.html.twig', array(
'blog' => $blog,
'edit_form' => $editForm->createView(),
));
}
If you want you can even test if the request is an AJAX request or not:
if($request->isXmlHttpRequest()) {
// yes it is AJAX
}