I want to completely disable shipping method while placing an order and add a custom shipping fee in magento 2. Can anyone tell me how to disable shipping method?
You can simply set all products with zero weight.
This will let all products into virtual product.
And system will auto skip the shipping step.
To disable any shipping method like flat rate: Goto Admin > Store > Configuration > Click on Shipping methods under Sales tab, it will show you all methods. Here you can disabled any method by setting "Enabled" option to No and click save config button.
I think you need to use flat shipping method and set the fee to zero. Then you need to create a script to autoselect flat rate as shipping method as magento does not select a shipping method.
Lastly, a front-end guy can hide the shipping part on the front end. A shipping method is crucial to an order in Magento. You would need one if you do not want to make core changes to magento.
The following should help to select a shipping method:
https://magento.stackexchange.com/a/161473
As you want to remove shipping method section completely but magento must need to assign one specific shipping method.
Please follow following steps to remove shipping method completely and assign automatically specific shipping method (magento 2.3.1)
Override these two files to your theme folder
/vendor/magento/module-checkout/view/frontend/web/template/shipping.html
/vendor/magento/module-checkout/view/frontend/web/js/model/checkout-data-resolver.js
On shipping.html file, remove entire code inside form except actions-toolbar div as it use for Next button.
So your shipping.html file will be
<li id="shipping" class="checkout-shipping-address" data-bind="fadeVisible: visible()">
<div class="step-title" translate="'Shipping Address'" data-role="title" />
<div id="checkout-step-shipping"
class="step-content"
data-role="content">
<each if="!quoteIsVirtual" args="getRegion('customer-email')" render="" />
<each args="getRegion('address-list')" render="" />
<each args="getRegion('address-list-additional-addresses')" render="" />
<!-- Address form pop up -->
<if args="!isFormInline">
<button type="button"
class="action action-show-popup"
click="showFormPopUp"
visible="!isNewAddressAdded()">
<span translate="'New Address'" />
</button>
<div id="opc-new-shipping-address"
visible="isFormPopUpVisible()"
render="shippingFormTemplate" />
</if>
<each args="getRegion('before-form')" render="" />
<!-- Inline address form -->
<render if="isFormInline" args="shippingFormTemplate" />
</div>
</li>
<!--Shipping method template-->
<li id="opc-shipping_method"
class="checkout-shipping-method"
data-bind="fadeVisible: visible(), blockLoader: isLoading"
role="presentation">
<div class="checkout-shipping-method">
<div id="checkout-step-shipping_method"
class="step-content"
data-role="content"
role="tabpanel"
aria-hidden="false">
<form id="co-shipping-method-form"
class="form methods-shipping"
if="rates().length"
submit="setShippingInformation"
novalidate="novalidate">
<div class="actions-toolbar" id="shipping-method-buttons-container">
<div class="primary">
<button data-role="opc-continue" type="submit" class="button action continue primary">
<span translate="'Next'" />
</button>
</div>
</div>
</form>
</div>
</div>
then, run s:s:d coomand and check checkout page, shipping method section should be removed.
Now, as magento must require shipping method, we can assign static shipping methods from checkout-data-resolver.js file
On checkout-data-resolver.js file, add following code on resolveShippingRates function
if (ratesData.length === 1) {
//set shipping rate if we have only one available shipping rate
selectShippingMethodAction(ratesData[0]);
return;
}
if (ratesData.length > 1) {
selectShippingMethodAction(ratesData[0]);
return;
}
You can auto assign shipping method like ratesData[0], ratesData[1],ratesData[2] as per requirement
Related
I want to use custom templates for the tree nodes as shown here on their website
https://angular2-tree.readme.io/docs/templates
But I also need the checkbox tri-state functionality as demonstrated here
https://angular2-tree.readme.io/docs/tri-state-checkboxes
In this custom treeNodeFullTemplate example they have a checkbox as part of the template but it doesn't have the tri-state relationship between the parents and children. Is there a way to have a custom checkbox and keep all the correct event listeners etc.? I can't seem to find any documentation on the checkboxes API if there is one.
<tree-root id="tree" [focused]="true" [nodes]="nodes">
<ng-template #treeNodeFullTemplate let-node let-index="index" let-templates="templates">
<div class="tree-node">
<input type="checkbox" [checked]="node.isActive" (change)="node.toggleActivated(true)" />
<tree-node-expander [node]="node"></tree-node-expander>
<div
class="node-content-wrapper"
[class.node-content-wrapper-active]="node.isActive"
[class.node-content-wrapper-focused]="node.isFocused"
(click)="node.toggleActivated(true)">
<span [class]="node.data.className + 'Index'">{{ index }}</span>
<span [class]="node.data.className" [class.title]="true">{{ node.data.title }}</span>
</div>
<tree-node-children [node]="node" [templates]="templates"></tree-node-children>
</div>
</ng-template>
</tree-root>
I can see that the (change) method on the checkbox is not right but do I need to write my own one to get the parent and children and determine state on click? It seems strange that I can't just tap into an existing API.
I'm trying to post data from an input and a button group in a component using Ember to my REST API using the actions up method, but the code is confusing me a bit and I haven't found a clear example of how to do it.
The site is a tracker for competitive games in Overwatch, so enter the rank after the game and see it in a list. There is one table, and one endpoint with no children in the API. Basically a simple to-do app, but i'm using components to keep everything modular. I also want to add edit and delete, but that is out of scope for this question.
app/templates/components/add-game.hbs
<form class="form-inline">
<div class="form-group">
<label class="control-label">
Rank <small>(After match)</small>
{{input value=rank type="number" min="4" class="form-control"}}
</label>
</div>
<div class="form-group">
<label class="control-label">
Outcome
{{#bs-button-group value=outcome type="radio" onChange=(action (mut outcome)) as |bg|}}
{{#bg.button type="default" value='W'}}Win{{/bg.button}}
{{#bg.button type="default" value='D'}}Draw{{/bg.button}}
{{#bg.button type="default" value='L'}}Loss{{/bg.button}}
{{/bs-button-group}}
</label>
</div>
<div class="spacer"></div>
<div class="form-group">
<button {{action 'saveGame'}} type="submit" class="btn btn-default btn-primary">Save</button>
</div>
</form>
app/components/add-game.js
import Ember from 'ember';
export default Ember.Component.extend({
actions: {
saveGame() {
const outcome = this.get('model.outcome');
const rank = this.get('model.rank');
console.log(outcome);
console.log(rank);
}
}
});
app/application.hb
{{nav-bar}}
<div class="container-fluid">
<div class="row">
<div class="col-md-offset-2 col-sm-8 col-md-8 main">
{{add-game}}
<br>
{{game-table model=model.games}}
</div>
</div>
</div>
{{outlet}}
I feel like I have most of it there, im just missing a few things with the Data Down, Actions Up approach that Ember uses, but haven't found a clear example to work off that is similar to my code. As you can probably tell I've got the code sending the data to the console, but im not sure of the best way to send it up to the route to then be sent to the server. I think I need to use the model, but the specific code
I am using ember-bootstrap for the styling and custom button group component.
The whole project is on Github
You can get an overview of DDAU architecture of Ember here. When you want to send the action up to the parent to handle, you have to notify the component of the action where you want to pass out any event. Here in your case, if you want to handle the action saveGame in the parent (application), then you have to pass the action to the component add-game while invoking the component as below:
**Application.hbs**
{{game-table model=model.games saveGameInParent=(action 'saveGameInParent')}}
where saveGameInParent is the action present in the application controller. In the component, you need to call out this action explicitly to pass out the control from the component to parent.
**component/add-game.js**
import Ember from 'ember';
export default Ember.Component.extend({
actions: {
saveGame() {
// do you really mean to access these props from model??
const outcome = this.get('model.outcome');
const rank = this.get('model.rank');
this.saveGameInParent(outcome, rank);
}
}
});
And finally, in you application controller, there should be action named, saveGameInParent to handle the bubbled up action from the component.
**controllers/application.js**
actions: {
saveGameInParent(outcome, rank) {
// post your result to the server using any network library.
}
}
PS: It looks like you have mentioned rank and outcome as your direct component property in the component's template file. but in the saveGame action, you tried to access those from model, which you cannot do.
Assuming that i have the following data in my params
params:[input:[1, 2, 3]]
And i have the following form in my Grails app
<div class="block1">
<label class="control-label">
<g:message code="input.label" default="Input"/>
</label>
<div class="controls">
<g:textField id="input1" name="input" value="${input}" readonly="${actionName != 'show' ? false : true}"/>
</div>
</div>
<div class="block2">
<label class="control-label">
<g:message code="input.label" default="Input"/>
</label>
<div class="controls">
<g:textField id="input2" name="input" value="${input}" readonly="${actionName != 'show' ? false : true}"/>
</div>
</div>
<div class="block3">
<label class="control-label">
<g:message code="input.label" default="Input"/>
</label>
<div class="controls">
<g:textField id="input3" name="input" value="${input}" readonly="${actionName != 'show' ? false : true}"/>
</div>
</div>
The form design above is correct, because in my form design, there will be several inputs of the same name (but each will be saved to the database under different primary keys) and it can be increases and decreases according to user selection.
Few questions using the above
How do i make it so that the value for input1 is params.input[0], input2 is params.input[1] and input3 is params.input[2] in the view? I can pass the model from controller without problem, but i couldn't distribute the value properly to each input on the form.
Is there any way to change the value ${input} dynamically? As in if i want to change the value to ${input[0]} or ${input[1]}
Can i automatically set the amount of block appended into the form using the g:each tag? Say like if from controller i want to set the rendering block amount to 3, so can i use the g:each tag to render the block 3 times in the form?
Thanks
The links are examples of how to use ajax/jquery to get values from a remote call and replace html element (divId) within a page - this divId could be the entire
<input type="text" name="input" value="newvalue"/>
upon triggering some form of call as above to get the new value.. in regards to
g:textField
yes it works like all other grails tags in the end they are transformed back to the correct HTML terminology...
The actual variable value is dynamic if you defined
<input name="existingvariable" value="${something}" ...
where something was a parameter from the given controller - and then you updated the call so
://YOURHOST:8080/yourapp/controller?existingvariable=newvalue
and refreshed or clicked this link which is what ajax would be doing for you doing a new call to either another controller to generate new values or same and passing new value to it and then grabbing data and pushing it back onto the divId ... (all in the background)
Groovy loading into divs
Grails - Select menu not rendering
I want my selects dropdowns to auto populate with Ajax in Grails website
The above are all related to using ajax to populate / update existing form elements
If you wish to update a live form with a new live value (non existant in DB) take a look at modaldynamix plugin. //github.com/vahidhedayati/modaldynamix
I have this very odd issue and I've picked my code apart and taken out any caching changes that I think would cause this but it still remains.
Here is whats happening:
I add an Address in my app, named "q", I save it and get id 1 for
example.
If I add another address names "q" (q isn't restricted to unique), then save it I get id 2.
If I repeat 2 I get a new item with id 3.
Here is the weird part, if I put the mouse over the Edit button for 2 or 3 it has a link to 1. If I look at the HTML generated I get this section for the form:
<form action="/CRM/address/delete/1" method="post" ><input type="hidden" name="_method" value="DELETE" id="_method" />
<fieldset class="buttons">
Edit
<input type="submit" name="_action_delete" value="Delete" class="delete" onclick="return confirm('Are you sure?');" />
</fieldset>
</form>
If I look at the show.gsp it's just the basic code from the generated scaffold:
<g:form url="[resource:addressInstance, action:'delete']" method="DELETE">
<fieldset class="buttons">
<g:link class="edit" action="edit" resource="${addressInstance}"><g:message code="default.button.edit.label" default="Edit" /></g:link>
<g:actionSubmit class="delete" action="delete" value="${message(code: 'default.button.delete.label', default: 'Delete')}" onclick="return confirm('${message(code: 'default.button.delete.confirm.message', default: 'Are you sure?')}');" />
</fieldset>
</g:form>
The controller has the following action:
def show(Address addressInstance) {
respond addressInstance
}
When i print the addressInstance it looks like the correct one.
Does anyone have any idea why I get ID 1 instead of the proper id in this form which is on the show screen of address 2 and 3???
I've tested it in H2 and PostgreSQL, Grails 2.3.3, locally and on Heroku.
Looks like a bug linkGenerator cache in Grails 2.3.0-2.3.4.
I've created a Jira: http://jira.grails.org/browse/GRAILS-10883
You can disable the cache in your config file:
grails.web.linkGenerator.useCache = false
I have this situation in which I show 1 form in two steps. So to proceed to the second part of the form you have to click on a button. But before moving on I would like to perform form validation (all required fields need to be filled in). But because this is a normal button, the whole submit magic is not triggered and the validation does not happen. So the question I'm interested in is how can I trigger form validation in my controller ? It would even be better to trigger validation for specific fields. Just to give an idea, the form looks like
<form name="form" submit="save()">
<section id="step1">
<label for="username" required>Username</label>
<input type="text" name="username" ng-model="user.username" required />
.....
<button ng-click="proceed()">Proceed</button>
</section>
<section id="step2">
<label ...></label>
<input...>
....
<button type="submit">Save</button>
</section>
</form>
Also, I don't want to opt for disabling the button until all required fields are valid.
Take a look at the ng-form directive. It allows nesting forms (actually not HTML <form>s, but Angular NgFormControllers). So you can split your one form, used for posting to the server, into two logical forms, used for independent validation:
<form submit="save()">
<div ng-form="form1">
...controls...
<button ng-click="proceed()"
ng-disabled="form1.$invalid">Proceed</button>
</div>
<div ng-form="form2">
...controls...
<button type="submit"
ng-disabled="form2.$invalid || form1.$invalid">Submit</button>
</div>
</form>
You can access the $valid property from your controller. Something like this could work.
$scope.proceed = function(){
if($scope.form.username.$valid){
//username is valid we may proceed to the next step
}
};
<button ng-click="proceed()">Proceed</button>
Replace To :
<button ng-click="proceed()" ng-disabled="form.$invalid">Proceed</button>
Button will not visible button until all required fields are valid.
DEMO