Quick Order module for Magento 2 - magento

I want to create a module of quickorder in magento 2. I have got an issues with the code path block, ajax etc. Please someone can help me on this. How can i generate the JS/Ajax autosearch file for work like search product by product name or SKU then i add that product to shopping cart page. I try to help one module like "MageWorx_SearchSuitAutoComplete" but it product an issues. Kindly help me on this.

Make A controller with front name like Quickorder/index/index,now execute a function on Quickorder.
<?php
namespace CompanyName\CustomApi\Controller\Index;
class Index extends \Magento\Framework\App\Action\Action
{
protected $resultPageFactory;
protected $httpClientFactory;
protected $productCollectionFactory;
public function __construct(
\Magento\Framework\App\Action\Context $context,
\Magento\Framework\View\Result\PageFactory $resultPageFactory,
\Magento\Framework\HTTP\ZendClientFactory $httpClientFactory,
\Magento\Catalog\Model\ResourceModel\Product\CollectionFactory $productCollectionFactory,
\Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory
) {
$this->resultPageFactory = $resultPageFactory;
$this->productCollectionFactory = $productCollectionFactory;
$this->_httpClientFactory = $httpClientFactory;
$this->resultJsonFactory = $resultJsonFactory;
parent::__construct($context);
}
public function execute(){
$search_text = $this->getRequest()->getPost('search_text');
$collection = $this->_productCollectionFactory->create();
$collection->addAttributeToSelect(array('name'))->addAttributeToFilter('name',
array('like' => $search_text.' %'),
array('like' => '% '.$search_text.' %'),
array('like' => '% '.$search_text)
));
echo "<pre>";
print_r($collection->getData());
die();
}
On input type make a jquery function and request a ajax call with keyup.
$('#quick-search').keyup(function(){
var search_text = jQuery("#quick-search").val();
try {
jQuery.ajax({
url : '<?php echo $block->getUrl('quickorder/index/index') ?>',
dataType : 'json',
data: { 'search_text' : search_text },
type : 'post',
success : function(data) {
jQuery('.main-search-results').html(data.products);
}
});
} catch (e) {
}
});
Or you can also used require js instead of this jquery.
Thanks

Related

laravel using jQuery Ajax | Ajax Cart

I'm Trying to Save The Product into The Database By Clicking On Add To Cart
But It's Not Adding I Also Use Ajax `
I Want To Add The Cart To DataBase And It's Not Adding.
This is The Error That I cant Add Any Product To The Cart Because Of It
message: "Call to undefined method App\User\Cart::where()", exception: "Error",…
enter image description here
Model Page.
class Cart extends Model
{
use HasFactory; I
protected $table = 'carts';
protected $fillable = [
'user_id',
'prod_id',
'prod_qty',
];
}
Controller page.
public function addToCart(Request $request)
{
$product_qty = $request->input('product_qty');
$product_id = $request->input ('product_id');
if(Auth::check())
{
$prod_check = Product::where('id',$product_id)->first();
if($prod_check)
{
if(Cart::where('prod_id',$product_id)->where('user_id',Auth::id())->exists())
{
return response()->json(['status' => $prod_check->pname." Already Added to cart"]);
}
else
{
$cartItem - new Cart();
$cartItem->user_id = Auth::id();
$cartItem->prod_qty = $product_qty;
$cartItem->save();
return response()->json(['status' => $prod_check->pname." Added to cart"]);
}
}
}
else{
return response()->json(['status' => "Login to Continue"]);
}
}
javascript page.
This Is MY First Time To Use Ajax And Sure That Every Thing Is Correct I Want Know Why Its Not Add
$('.addToCartBtn').click(function (e) {
e.preventDefault();
var product_id = $(this).closest('.product_data').find('.prod_id').val();
var product_qty = $(this).closest('.product_data').find('.qty-input').val();
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$.ajax({
method: "POST",
url: "/add-to-cart",
data: {
'product_id': product_id,
'product_qty': product_qty,
},
success: function (response) {
alert(response.status);
}
});
// alert(product_id);
// alert(product_qty);
// // alert ("test ") ;
});
Route:
Route::middleware(['auth'])->group(function () {
Route::post('/add-to-cart', [App\Http\Controllers\User\indexController::class, 'addToCart' ]);});
So why this error occurs, how can I fix it?`
This look like an error in importation like App\Models\Cart not like this?
verify if you had added use App\Models\Cart;

Render Laravel Component via Ajax method

How can i render component that is sent from controller via an ajax request? For example i want to dynamically filter product using this method:
Load the index URL
Fetch the products based on the filter category or return all the products using ajax
My ajax Code:
$(document).ready(function () {
filterData();
// Filter data function
function filterData() {
// Initializing loader
$('#product-listing-row').html('<div id="loading" style="" ></div>');
var action = 'fetchData';
var subCategory = getFilter('sub-category');
/* LARAVEL META CSRF REQUIREMENT */
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
// Ajax Call
$.ajax({
url: "/shop/filter",
method: "POST",
data: {action: action, subCategory: subCategory},
success: function (data) {
$('#product-listing-row').html(data);
}
});
}
// Get Filter by class name function
function getFilter(className) {
var filter = [];
$('.' + className + ':checked').each(function () {
filter.push($(this).val());
});
//console.log(filter);
return filter;
}
$('.common-selector').click(function () {
filterData();
});
});
I am getting all the filters from ProductController
Instead of manually writing html in controller I want to return the specific component from the controller
ProductController:
public function productFilter() {
if (!request()->action) abort('500');
// Starting the query for products which are active
$products = Product::where('is_active', '1');
//dump(request()->subCategory);
/* Checking the filters */
// sub category exists
if (request()->subCategory) $products = $products->where('sub_category_id', request()->subCategory);
// Completing the query
$products = $products->orderBy('created_at', 'DESC')->paginate(15);
// Adding reviews and total review
$products = Product::setProductReviewTotalReviewsAttr($products);
foreach ($products as $product)
//view('components.shop-product', ['product' => $product])->render();
echo '<x-shop-product :product="$product"></x-shop-product>';
}
Instead of getting the components rendered, I am receiving the whole string echoed out. Is there any way i can just get the components rendered?
Thanks in advance
Actually now I found a way to do it myself
I applied the following to the ProductController
return View::make("components.shop-product")
->with("product", $product)
->render();
Updated Code:
public function productFilter() {
if (!request()->action) abort('500');
// Starting the query for products which are active
$products = Product::where('is_active', '1');
//dump(request()->subCategory);
/* Checking the filters */
// sub category exists
if (request()->subCategory) $products = $products->where('sub_category_id', request()->subCategory);
// Completing the query
$products = $products->orderBy('created_at', 'DESC')->paginate(15);
// Adding reviews and total review
$products = Product::setProductReviewTotalReviewsAttr($products);
$output = '';
foreach ($products as $product) {
$output .= View::make("components.shop-product")
->with("product", $product)
->render();
}
if (count($products) > 0)
echo $output;
else
echo '<div class="col">No Data</div>';
}
with laravel > 8 you can use \Blade::render directly in your controller to render even anonymouse components, here I'm rendering a table component with a lot of properties:
class componentController extends Controller {
public function index(){
$table = [
:tableid => "table"
:thead => ["id","name","job"]
:data => [
["1","marcoh","captain"],
["2","sanji","cook"]
],
tfoot => false
];
// Renders component table.blade.php
return \Blade::render('
<x-table
:tableid="$tableid"
:thead="$thead"
:data="$data"
tfoot
/>
', $table);
...

Ajax query works when adding new post but doesn't work when update an entity

I have two Select box one for the Countries and the second for the cities and the second one depends from the selected choice of the first one.
I the code is as the example Dynamic Generation for Submitted Forms in the documentation http://symfony.com/doc/current/cookbook/form/dynamic_form_modification.html#cookbook-form-events-submitted-data
All things work fine when adding a new post , but when trying do update a post, the Ajax query to display cities doesn't work .
This is the controller
// newAction
/**
* #ParamConverter("agence", options={"mapping": {"agence_slug":"slug"}})
*/
public function newAction(Agence $agence, Request $request)
{
$em = $this->getDoctrine()->getManager();
$travel = new Travel();
$form = $this->createForm(new TravelType($agence), $travel);
if ($request->getMethod() == 'POST')
{
//....
}
return $this->render('AppBundle:Dashboard/Travel:new.html.twig',
array(
'form' => $form->createView() ,
'agence' => $agence,
));
}
//editAction
/**
* #ParamConverter("agence", options={"mapping": {"agence_slug":"slug"}})
* #ParamConverter("travel", options={"mapping": {"travel_id":"id"}})
*/
public function editAction(Travel $travel, Agence $agence, Request $request)
{
$em = $this->getDoctrine()->getManager();
$form = $this->createForm(new TravelEditType($agence), $travel);
if ($request->getMethod() == 'POST'){
//....
}
return $this->render('AppBundle:Dashboard/Travel:edit.html.twig',
array(
'form' => $form->createView() ,
'travel' => $travel,
'agence' => $agence,
));
}
travelType and ti works good
namespace AppBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\FormEvent;
//........
use Symfony\Component\Form\FormInterface;
use AppBundle\Entity\Country;
class TravelType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
//....
$formModifier = function (FormInterface $form, Country $country = null) {
$cities = null === $country ? array() : $country->getCities();
$form->add('destination', 'entity', array(
'class' => 'AppBundle:CityWorld',
'choices' => $cities,
'multiple' => false,
'expanded' => false,
'property' => 'name',
'label' => 'Destination',
'attr' => array('class' => 'col-xs-10 col-sm-10', 'placeholder' => 'Destination'),
));
};
$builder->addEventListener(
FormEvents::PRE_SET_DATA,
function (FormEvent $event) use ($formModifier) {
// this would be your entity, i.e. SportMeetup
$data = $event->getData();
$formModifier($event->getForm(), $data->getCountry());
}
);
$builder->get('country')->addEventListener(
FormEvents::POST_SUBMIT,
function (FormEvent $event) use ($formModifier) {
// It's important here to fetch $event->getForm()->getData(), as
// $event->getData() will get you the client data (that is, the ID)
$country = $event->getForm()->getData();
// since we've added the listener to the child, we'll have to pass on
// the parent to the callback functions!
$formModifier($event->getForm()->getParent(), $country);
}
);
$builder->addEventListener(FormEvents::POST_SUBMIT, function ($event) {
$event->stopPropagation();
}, 90000000000000); // Always set a higher priority than ValidationListener
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\Travel'
));
}
public function getName()
{
return null;
}
}
This is TravelEditType
namespace AppBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\FormEvent;
//........
use Symfony\Component\Form\FormInterface;
use AppBundle\Entity\Country;
class TravelEditType extends TravelType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
parent::buildForm($builder, $options) ;
}
public function getName()
{
return null;
}
}
This is the form and javascript code
<form method="post" action="" class="form-horizontal" role="form" {{ form_enctype(form) }} >
//.............
</form>
<script type="text/javascript">
var $county = $('#country');
$county.change(function () {
// ... retrieve the corresponding form.
var $form = $(this).closest('form');
var data = {};
data[$county.attr('name')] = $county.val();
// Submit data via AJAX to the form's action path.
$.ajax({
url: $form.attr('action'),
type: $form.attr('method'),
data: data,
success: function (html) {
// Replace current position field ...
$('#city').replaceWith(
// ... with the returned one from the AJAX response.
$(html).find('#city')
);
// Position field now displays the appropriate positions.
}
});
});
Try it without parameter in URI:
dashboard_city_ajax:
path: /citiies/ajax
defaults: { _controller: AppBundle:TravelDashboard:ajaxCities }
And send data with POST:
$.ajax({
url: '{{ path('dashboard_city_ajax') }}',
type: 'POST',
data: { agence_slug: '{{ agenceSlug }}' },
You can receive it in controller:
$request->request->get('bar', 'default value if bar does not exist');
The problem is in your route matching. There is many way to solve problem. Try just include in your ajax route requirements for matching route or in $.ajax function use another route, for example
The simplest way for you (if you don't want rebuild your controller) is just rebuild your route and put in the first place your ajax route like :
dashboard_city_ajax:
path: /{ajax}/{agence_slug}/citiies
defaults: { _controller: AppBundle:TravelDashboard:ajaxCities }
requirements:
ajax: ajax
$.ajax({
url: '{{ path('dashboard_city_ajax', {'agence_slug': agence.slug, 'ajax': 'ajax' }) }}',
type: 'POST',
data: data,
But the right way IMHO is get your data from request. For example
vplanning_ajax:
path: /ajax
defaults: { _controller: VplanningPageBundle:Page:Ajax }
function getData(init) {
$.post(
{{ path('vplanning_ajax') }},
{
agence_slug: agence.slug,
yourdata2: 'yourdata2
} ,
function ( data ) {
handleData(data);
}
);
}
And in your Controller your just do
$agence_slug = $this->request->request->get('agence_slug');
$yourdata2 = $this->request->request->get('yourdata2);
...

Ajax changing the entire sql query

http://rimi-classified.com/ad-list/west-bengal/kolkata/electronics-and-technology
The above link has a filter in the left. I am trying to use ajax to get city from state. but as the ajax is triggered the entire query is changing.
SELECT * FROM (`ri_ad_post`)
WHERE `state_slug` = 'west-bengal'
AND `city_slug` = 'kolkata'
AND `cat_slug` = 'pages'
AND `expiry_date` > '2014-03-21'
ORDER BY `id` DESC
It is taking the controller name in the query (controller name is pages).
The actual query is:
SELECT *
FROM (`ri_ad_post`)
WHERE `state_slug` = 'west-bengal'
AND `city_slug` = 'kolkata'
AND `cat_slug` = 'electronics-and-technology'
AND `expiry_date` > '2014-03-21'
ORDER BY `id` DESC
// Controller
public function ad_list($state,$city,$category,$sub_cat=FALSE)
{
if($state===NULL || $city===NULL || $category===NULL)
{
redirect(base_url());
}
$data['ad_list'] = $this->home_model->get_adlist($state,$city,$category,$sub_cat);
$this->load->view('templates/header1', $data);
$this->load->view('templates/search', $data);
$this->load->view('ad-list', $data);
$this->load->view('templates/footer', $data);
}
public function get_cities()
{
$state_id = $this->input->post('state');
echo $this->city_model->get_cities($state_id);
}
// Model
public function get_adlist($state,$city,$category,$sub_cat=FALSE)
{
if ($sub_cat === FALSE)
{
$this->db->where('state_slug', $state);
$this->db->where('city_slug', $city);
$this->db->where('cat_slug', $category);
$this->db->where('expiry_date >', date("Y-m-d"));
$this->db->order_by('id', 'DESC');
$query = $this->db->get('ad_post');
}
$this->db->where('state_slug', $state);
$this->db->where('city_slug', $city);
$this->db->where('cat_slug', $category);
$this->db->where('sub_cat_slug', $sub_cat);
$this->db->where('expiry_date >', date("Y-m-d"));
$this->db->order_by('id', 'DESC');
$query = $this->db->get('ad_post');
return $query->result_array();
//echo $this->db->last_query();
}
//ajax
<script type="text/javascript">
$(document).ready(function () {
$('#state_id').change(function () {
var selState = $(this).val();
alert(selState);
console.log(selState);
$.ajax({
url: "pages/get_cities",
async: false,
type: "POST",
data : "state="+selState,
dataType: "html",
success: function(data) {
$('#city').html(data);
$("#location_id").html("<option value=''>--Select location--</option>");
}
})
});
});
</script>
Please help me how to solve this issue. Please check the url I have provided and try to select a state from the filter section the problem will be more clear.
In .js what is the value of selState ?
In your model, you should if() else() instead of just a if, because your query will get override.
Where is the get_cities function ? Can we see it ?
On your url, the problem is that your ajax url doesn't return a real ajax call but an entire HTML page which is "harder" to work with. Try to change it into json (for dataType's ajax()) You should only do in your php something like this :
in your controller :
public function get_cities()
{
$state = $this->input->post('state');
//Do the same for $cat
if (!$state) {
echo json_encode(array('error' => 'no state selected'));
return 0;
}
$get_cities = $this->model_something->getCitiesByStateName($state);
echo json_encode($get_cities);
}
You should definitely send with ajax the $cat info

Joomla component: controller not returning json

Why is my controller not returning my data in JSON format? Note that I am developing my component on Joomla 3.1.1.
/hmi.php
//Requries the joomla's base controller
jimport('joomla.application.component.controller');
//Create the controller
$controller = JControllerLegacy::getInstance('HMI');
//Perform the Request task
$controller ->execute(JRequest::setVar('view', 'hmimain'));
//Redirects if set by the controller
$controller->redirect();
/controller.php
class HMIController extends JControllerLegacy
{
function __construct()
{
//Registering Views
$this->registerTask('hmimain', 'hmiMain');
parent::__construct();
}
function hmiMain()
{
$view =& $this->getView('hmimain','html');
$view->setModel($this->getModel('hmimain'), true);
$view->display();
}
public function saveHMI()
{
echo 'Testing';
$this->display();
}
}//End of class HMIController
/controllers/properties.json.php
class HMIControllerProperties extends JController
{
function __construct()
{
$this->registerTask(' taskm', 'taskM');
parent::__construct();
}
function taskM()
{
$document =& JFactory::getDocument();
// Set the MIME type for JSON output.
$document->setMimeEncoding('application/json');
// Change the suggested filename.
JResponse::setHeader('Content-Disposition','attachment;filename="json.json"');
echo json_encode('Hello World');
// Exit the application.
Jexit();
}
}
JQuery function calling the joomla task
var request = $.ajax({
dataType:"json",
url:"index.php?option=com_hmi&task=properties.taskm&format=json",
type:"POST",
data:{propPage: "ABC"},
beforeSend: function (){
$("#loading_Bar").css("display","block");
}
});// dot ajax
When I use the above ajax settings the request fails. However if I change the datatype property to text, and remove the format=json from the url, I get html instead of json.
Can some one point out what I'm doing wrong?
Further investigation to my problem i concluded that the componenet was not triggering the desired task becuse of the following code in my /hmi.php
$controller ->execute(JRequest::setVar('view', 'hmimain'));
So I modified my /hmi.php as follows
//Requries the joomla's base controller
jimport('joomla.application.component.controller');
// Create the controller
$controller = JControllerLegacy::getInstance('HMI');
$selectedTask = JRequest::getVar( 'task');
if ($selectedTask == null)
{
//This will allow you to access the main view using index?option=com_hmi
//and load the "default" view
$controller->execute( JRequest::setVar( 'view', 'hmimain' ) );
}
else
{
//Will execute the assigned task
$controller->execute( JRequest::getVar( 'task' ) );
}
// Redirect if set by the controller
$controller->redirect();
then created the /controllers/properties.json.php file with the following code
class HMIControllerProperties extends JControllerLegacy
{
function myMethod()
{
$model = $this->getModel('hmimain');
$dataToolboxItems =& $model->getToolboxItems();
echo json_encode($dataToolboxItems);
//JExit();
}
}//End of class HMIController
then i'm calling the task from jquery as follows:
var request = $.ajax({
dataType:"json",
//task=properties.mymethod will access the subcontroller within the controllers folder
//format=json will by access the json version of the subcontroller
url:"index.php?option=com_hmi&task=properties.mymethod&format=json",
type:"POST",
data:{propPage: "ABC"},
beforeSend: function (){
$("#loading_Bar").css("display","block");
}
});
In your ajax request try changing to this format:
dataType:'json',
url: 'index.php',
data: {option: 'com_hmi', task: 'properties.task', format: 'jason', propPage: 'ABC' },
type:'POST',
.....
Another thing is in the controller file add the Legacy:
HMIControllerProperties extends JControllerLegacy
And I don't think you need this lines, for me it works without them
$document->setMimeEncoding('application/json');
JResponse::setHeader('Content-Disposition','attachment;filename="json.json"');

Resources