I want to change the city name to dropdown menu like in dropdown it shows specific cities name like NYC, Mumbai,HongKong,Karachi and etc how is it will be possible?
-
Check with this module-github.com/EaDesgin/Magento2-City-Dropdown– RanganathanCommented Oct 17, 2019 at 8:28
-
actuallly Sir I tried that extension before as well but there were a lot of errors in that extension.– Asad KhanCommented Oct 17, 2019 at 11:06
-
Ok....Explain about the process...Do you want all the cities for all the region,countries? render cities automatically or manually (can add cities for region from admin panel)?– RanganathanCommented Oct 17, 2019 at 11:14
-
Yeah I want to add the cities of Pakistan... It'll be good that the cities is selected in admin panel else if it'll be fine to set the cities in code– Asad KhanCommented Oct 17, 2019 at 11:18
-
Ok, I will update the answer.– RanganathanCommented Oct 17, 2019 at 11:34
1 Answer
app/code/Vendor/Checkout/etc/frontend/di.xml
Override layoutProcessor block for customize city field and change arguments of onepage block for render city options.
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<type name="Magento\Checkout\Block\Checkout\LayoutProcessor">
<plugin name="checkout_layout"
type="Vendor\Checkout\Plugin\LayoutProcessor" sortOrder="1"/>
</type>
<type name="Magento\Checkout\Block\Onepage">
<arguments>
<argument name="layoutProcessors" xsi:type="array">
<item name="cityData" xsi:type="object">Vendor\Checkout\Block\Checkout\CityDataProcessor</item>
</argument>
</arguments>
</type>
</config>
app/code/Vendor/Checkout/Plugin/LayoutProcessor.php
Initialize custom component and [import][initialoptions]
to get city array in city.js
<?php
namespace Vendor\Checkout\Plugin;
class LayoutProcessor
{
/**
* @param LayoutProcessor $subject
* @param array $result
* @return array
*/
public function afterProcess(
\Magento\Checkout\Block\Checkout\LayoutProcessor $subject,
array $result
) {
$result['components']['checkout']['children']['steps']['children']['shipping-step']['children']['shippingAddress']['children']['shipping-address-fieldset']['children']['city'] = $this->getConfig();
unset($result['components']['checkout']['children']['steps']['children']['shipping-step']['children']['shippingAddress']['children']['shipping-address-fieldset']['children']['region_id']);
unset($result['components']['checkout']['children']['steps']['children']['shipping-step']['children']['shippingAddress']['children']['shipping-address-fieldset']['children']['postcode']);
$result['components']['checkout']['children']['steps']['children']['shipping-step']['children']['shippingAddress']['children']['shipping-address-fieldset']['children']['telephone']['validation']['max_text_length'] = '11';
return $result;
}
/**
* @return $field
*/
private function getConfig()
{
$field = [
'component' => 'Vendor_Checkout/js/city',
'config' => [
'customScope' => 'shippingAddress',
'template' => 'ui/form/field',
'elementTmpl' => 'ui/form/element/select',
'id' => 'city'
],
'label' => 'City',
'value' => '',
'dataScope' => 'shippingAddress.city',
'provider' => 'checkoutProvider',
'sortOrder' => 80,
'customEntry' => null,
'visible' => true,
'options' => [ ],
'filterBy' => [
'target' => '${ $.provider }:${ $.parentScope }.country_id',
'field' => 'country_id'
],
'validation' => [
'required-entry' => true
],
'id' => 'city',
'imports' => [
'initialOptions' => 'index = checkoutProvider:dictionaries.city',
'setOptions' => 'index = checkoutProvider:dictionaries.city'
]
];
return $field;
}
}
app/code/Vendor/Checkout/Block/Checkout/CityDataProcessor.php
Add your city here, else better get cities from csv to avoid big array.
<?php
namespace Vendor\Checkout\Block\Checkout;
class CityDataProcessor implements \Magento\Checkout\Block\Checkout\LayoutProcessorInterface
{
/**
* Process js Layout of block
*
* @param array $jsLayout
* @return array
*/
public function process($jsLayout)
{
if (!isset($jsLayout['components']['checkoutProvider']['dictionaries']['city'])) {
$jsLayout['components']['checkoutProvider']['dictionaries']['city'] = $this->getCityOptions();
}
return $jsLayout;
}
/**
* Get country options list.
*
* @return array
*/
private function getCityOptions()
{
//Add your city list here
$options = [
'1' => [
'value'=>'city1',
'name'=>'city1',
'region_id'=>'1',//From database
],
'2' => [
'value'=>'city2',
'name'=>'city2',
'region_id'=>'2',//From databse
]
];
if (count($options) > 0) {
array_unshift(
$options,
['title' => '', 'value' => '', 'label' => __('Please select a city.')]
);
}
return $options;
}
}
app/code/Vendor/Checkout/view/frontend/web/js/city.js
Render city options from initialoptions and filter with region_id
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
/**
* @api
*/
define([
'underscore',
'uiRegistry',
'Magento_Ui/js/form/element/select',
'Magento_Checkout/js/model/default-post-code-resolver',
'jquery',
'mage/utils/wrapper',
'mage/template',
'mage/validation',
'underscore',
'Magento_Ui/js/form/element/abstract',
'jquery/ui'
], function (_, registry, Select, defaultPostCodeResolver, $) {
'use strict';
return Select.extend({
defaults: {
skipValidation: false,
imports: {
update: '${ $.parentName }.country_id:value'
}
},
/**
* @param {String} value
*/
update: function (value) {
var city = registry.get(this.parentName + '.' + 'city'),
options = city.initialOptions,
cityOptions = [];
$.each(options, function (index, cityOptionValue) {
//if(value == cityOptionValue.region_id){
var name = cityOptionValue.name;
var jsonObject = {
value: index,
title: name,
country_id: "",
label: name
};
cityOptions.push(jsonObject);
//}
});
this.setOptions(cityOptions);
}
});
});
app/code/Vendor/Checkout/view/frontend/requirejs-config.js
/**
* Copyright © 2018 EaDesign by Eco Active S.R.L. All rights reserved.
* See LICENSE for license details.
*/
var config = {
config: {
mixins: {
'Magento_Checkout/js/action/set-shipping-information': {
'Vendor_Checkout/js/action/set-shipping-information-mixin': true
}
}
}
};
app/code/Vendor/Checkout/view/frontend/web/js/action/set-shipping-information-mixin.js
Save city name instead of city value to database.
define([
'jquery',
'mage/utils/wrapper',
'Magento_Checkout/js/model/quote',
], function ($, wrapper, quote, shippingFields) {
'use strict';
return function (setShippingInformationAction) {
return wrapper.wrap(setShippingInformationAction, function (originalAction, container) {
var shippingAddress = quote.shippingAddress(),
shippingCity = $("#shipping-new-address-form [name = 'city'] option:selected"),
shippingCityValue = shippingCity.text();
shippingAddress.city = shippingCityValue;
return originalAction(container);
});
};
});
-
Sir I didn't get Initialize custom component and [import][initialoptions] to get city array in city.js this point Commented Oct 18, 2019 at 11:22
-
You can see the import array in initialOptions where i declared in layoutProcessor, This will set the city array in uiRegistry to get values in js file. city.js->
options = city.initialOptions,
Commented Oct 18, 2019 at 11:27 -
did I need to change something else except the vender name in that class?? Commented Oct 18, 2019 at 11:29
-
No....And
Checkout
is a module name..You can change as yours Commented Oct 18, 2019 at 11:39 -