Snipcart: Switch off autocomplete in adress fields - snipcart

is it possible to switch off autocompletion in the adressfields? I can see there is
<template v-if="useAutocomplete">
in the template. But where can I set it to "false"?

I'm also interested in this. I'm sure the intention is to allow developers to turn off the auto-complete feature but I wasn't able to get this to work. As a workaround, you could override the template by overriding the address-fields component:
<div hidden id="snipcart" data-api-key="API_KEY">
<address-fields>
<div class="root">
<div class="snipcart-form__row">
<div class="snipcart-form__field snipcart-form__cell--large">
<snipcart-label class="snipcart__font--tiny" for="address1">
{{ $localize('address_form.address1') }}
</snipcart-label>
<snipcart-input name="address1"></snipcart-input>
<snipcart-error-message name="address1"></snipcart-error-message>
</div>
<div class="snipcart-form__field snipcart-form__cell--tidy">
<snipcart-label class="snipcart__font--tiny" for="address2">
{{ $localize('address_form.address2') }}
</snipcart-label>
<snipcart-input name="address2"></snipcart-input>
<snipcart-error-message name="address2"></snipcart-error-message>
</div>
</div>
<div class="snipcart-form__field">
<snipcart-label class="snipcart__font--tiny" for="city">{{ $localize('address_form.city') }}
</snipcart-label>
<snipcart-input name="city"></snipcart-input>
<snipcart-error-message name="city"></snipcart-error-message>
</div>
<div class="snipcart-form__field">
<snipcart-label class="snipcart__font--tiny" for="country">{{ $localize('address_form.country') }}
</snipcart-label>
<snipcart-typeahead type="dropdown" name="country" autocomplete="country"></snipcart-typeahead>
</div>
<div class="snipcart-form__row">
<div class="snipcart-form__field snipcart-form__cell--large">
<snipcart-label class="snipcart__font--tiny" for="province">
{{ $localize('address_form.province') }}
</snipcart-label>
<snipcart-typeahead type="dropdown" name="province" autocomplete="province state">
</snipcart-typeahead>
</div>
<div class="snipcart-form__field snipcart-form__cell--tidy">
<snipcart-label class="snipcart__font--tiny" for="postalCode">
{{ $localize('address_form.postalCode') }}
</snipcart-label>
<snipcart-input name="postalCode"></snipcart-input>
<snipcart-error-message name="postalCode"></snipcart-error-message>
</div>
</div>
</div>
</address-fields>
</div>
See: https://docs.snipcart.com/v3/setup/customization
I'm hoping someone chimes in with a better answer.

The accepted still appears to be the officially documented way to do this (April 2021, using Snipcart v3.0.31), but I’d also prefer not to overwrite templates for functionality already built into the checkout.
The autocomplete input also gives you a checkbox where you can opt-out and manually enter your address, which restores the default address templates.
Another option is to always check that box for the user, before they do anything else in the cart:
let disableAddressSearch = function () {
let fauxEvent = new MouseEvent('click', {
view: window,
bubbles: true,
cancelable: true
})
let input = document.querySelector('input[name=addressNotFound]')
if (!input) {
return null
}
let result = input.dispatchEvent(fauxEvent)
if (!result) {
// You probably don’t want this in production
console.warn('Couldn’t disable autocomplete checkbox')
}
}
You can try this out in the console on the Checkout page. Now, we want to do this each time the customer gets to the checkout.
// https://docs.snipcart.com/v3/sdk/events#themeroutechanged
Snipcart.events.on('theme.routechanged', function (routesChange) {
if (routesChange.to === '/checkout') {
console.log('cart opened');
// A timeout that should be long enough for the checkout
// to be rendered
window.setTimeout(disableAddressSearch, 100)
}
})
The timeout isn’t completely reliable, but it seemed like an acceptable tradeoff to me versus watching for the element to appear, ex. using MutationObserver.

This feature can be disabled by our team (I'm working at Snipcart) if you contact support. We have plans to make it configurable from the dashboard though.
It's possible to do it by overriding our components too, but a bit more complex.

Related

How to deal with a form that the button submit placed in parent component

I use react hook form, i have a form which my submit button placed in the parent component. my question is how i deal with the loading state of the button, when i try to call an api?. I have tried to use isSubmitting state, but again i dont know how to make that state visible for another component. i am glad to receive an answer. my real problem is how i can make state 'isSubmitting' able to read by my parent component, so i can do loading button after i call the api.
this for the parents
const ForceEditPassword = () => {
const childRef = useRef<any>();
return (
<>
<div className='force-edit-password d-flex flex-column justify-content-center align-items-center'>
<div className='inner d-flex justify-items-center align-items-center flex-column'>
<FormEditPassword ref={childRef} />
<button className='bg-primary rounded bottom-0 start-50 translate-middle-x'
onClick={() => { childRef.current?.onSubmit(); }}>
<p className='text-light m-0 p-2 text-capitalize rounded'>
Simpan
</p>
</button>
</div>
</div>
</>
);
};
export default ForceEditPassword;

Triggering A modal from within a countdown function

I am trying to get a bootstrap modal to be triggered when my jsonwebtoken is close to expiring.
I am able to get the modal to fire via a button on the nav bar, but I cannot get the modal to trigger from the function.
when i try to trigger the modal using this.openRenew(renew); i get an cannot find name renew error,
**** navbar.html
<!-- Renew Token -->
<ng-template #renew let-modal>
<div class="modal-header">
<h4 class="modal-title" id="renewModal">Renew Log In</h4>
<button type="button" class="close" aria-label="Close
(click)="modal.dismiss('Cross click')">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
Your Session In About To Expire.
For Security Please Confirm Your Password To Continue.
<form>
<div class="form-group">
<label for="password">Password</label>
<input id="password" class="form-control"
placeholder="Password" name="password">
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-outline-dark"
(click)="modal.close('Save click')">Log Back In</button>
</div>
</ng-template>
**** navbar.ts
constructor(
public _auth:AuthService,
public _router:Router,
public modalService: NgbModal) {
this._auth.time.subscribe((now: Date) => {
this.currentTime = now.valueOf();
if(!!this._auth.emToken){
if (!this.timeToRenew || this._auth.emExpTime==null){
console.log('Checking Time to renew',
this._auth.emExpTime*1000-this.currentTime );
if((this._auth.emExpTime*1000)-45000<this.currentTime){
this.timeToRenew = true;
console.log('Time to Log Back In');
/ * Need to trigger openRenew() here *
}
}
}
});
}
openRenew(renew) {
this.modalService.open(renew, {ariaLabelledBy:
'renewModal'}).result.then(
(result) => {
console.log(result);
// validate password
});
}
I've put together a StackBlitz demo to show this working. It should automatically display the modal after around 10 seconds.
There's a couple of changes you'll need to make to your code to get this to work:
i. Make sure you can get a reference to the modal template in your TS file by using the following code to declare the template as a class variable and using #ViewChild to get a reference to it in the HTML:
#ViewChild('renew')
private renew: TemplateRef<any>;
I've modified the logic to make it simpler for the demo - in this example the AuthService fires the time every 5 seconds. The component listens to this and if the timestamp emitted by the AuthService is greater than 10 seconds after the component was created, it displays the modal.
ii. You will need assign the subscription to a variable subscription so that you can then unsubscribe when you open the modal:
// 1. Maintain a reference to the subscription
const subscription: Subscription = this._auth.time.subscribe((now: Date) => {
...
if (/*should renew*/) {
this.openRenew(this.renew);
subscription.unsubscribe(); // 2. Unsubscribe here after opening modal
}
});
This prevents additional modals being displayed on top of the original one every time the AuthService emits a timestamp.

How do I to change the style of a tag using Razor?

I have a HTML tag which I want to only be visible when a condition is true, otherwise it will be hidden. To do this, I'm trying to change the style attribute using Razor, but still can't do this.
Note that: I don't want to use JQuery, I want to use only Razor.
How could I do this ?
Trying
<!--it will only visible if the conditional true-->
<div class="form-group" #(usuario.role == RoleType.Investidor) ? style="display:none;" : style="display:normal;">
<h1>Description</h1>
</div>
I would assume something like this works:
<div class="form-group" style="#(usuario.role == RoleType.Investidor ? "display: none" : string.Empty)">
<h1>Description</h1>
</div>
Move the ternary statement inside the attribute value for style. You may also be able to replace string.Empty with null - depending on context, that might enable the Razor engine to omit the attribute, rather than rendering an empty value.
You could try to do something like that:
#if (usuario.role != RoleType.Investidor)
{
<div class="form-group" style="display: normal">
<h1>Description</h1>
</div>
}
If RoleType equals Investidor, the div will not be shown at all.
If presence of this element is important to you, you can leave it like that:
#if (usuario.role != RoleType.Investidor)
{
<div class="form-group" style="display: normal">
<h1>Description</h1>
</div>
} else {
<div class="form-group" style="display: none">
<h1>Description</h1>
</div>
}

select2 4.0 - TypeError: $(...).select2(...).select2(...) is undefined

Trying to finally change over to the 4.0 version of select2 and running into a problem.
All of this works perfectly fine on 3.5. On button click I open a bootstrap modal and load a remote page into it. I have tested all everything on a normal page (not in a modal) and it works correctly. When loaded in a modal as below the modal opens and everything like it always had for 3.5, but select2 is returning an error. I believe the issue here is the select2 is being loaded from a remote page... thing is this same remote loading method always worked flawlessly with 3.5.
TypeError: $(...).select2(...).select2(...) is undefined
js:
// show edit modal
$('#datatable2').on('click', '.dtEdit', function () {
var data = {
'filter_id': $(this).parents('tr').attr('id').replace('dtrow_', '')
};
$('#modal-ajax').load(
'/modals/m_filtering_applications_filters.php',
data,
function() {
$(this).modal('show');
changeSettings();
hourSelection();
}
);
});
// change filter modal confirmation
var changeSettings = function() {
// get the default filter
var default_filter = $("#filter_default").val();
//app list
$("#vedit-filter").select2({
placeholder: {
id: default_filter, // or whatever the placeholder value is
text: default_filter // the text to display as the placeholder
},
allowClear: true,
multiple: false,
tags: true,
createTag: function (query) {
return {
id: query.term,
text: query.term,
tag: true
}
},
ajax: {
dataType: 'json',
delay: 500,
type: 'post',
url: '/process/get_application_list.php',
data: function (params) {
return {
term: params.term, // search term
page: params.page, //page number
page_limit: 25, // page size
};
},
results: function (data, page) {
var more = (page * 25) < data.total; // whether or not there are more results available
return {
results: data.results,
more: more
};
}
}
}).select2('val', [default_filter]).on('change', function() {
$(this).valid();
});
}
m_filtering_applications_filters.php :
Just the contents of the modal which is loaded in :
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true"></button>
<h3 class="modal-title">Change these settings?</h3>
</div>
<form id="application-filters-edit">
<div class="modal-body">
<div class="row">
<div class="col-md-12">
<div class="row">
<div class="col-md-12 margin-bottom-30 form-group">
<div class="input-modal-group">
<label for="vedit-filter" class="f-14"><b>Application to filter :</b></label>
<select id="vedit-filter" name="settings[filter]" class="form-control select2">
<option value="<?php echo htmlspecialchars($result['filter'], ENT_QUOTES, 'UTF-8'); ?>" selected=""><?php echo htmlspecialchars($result['filter'], ENT_QUOTES, 'UTF-8'); ?></option>
</select>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<input type="hidden" name="settings[users][]" value="<?php echo $result['user_id']; ?>"/>
<input id="filter_default" type="hidden" name="settings[original]" value="<?php echo htmlspecialchars($result['filter'], ENT_QUOTES, 'UTF-8'); ?>"/>
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
<?php
if (!$result)
{
//disable the button
echo '<button type="button" class="btn btn-primary disabled" data-dismiss="modal"><i class="fa fa-check-circle"></i> Save Settings</button>';
}
else
{
// show the button
echo '<button class="btn btn-primary" type="submit"><i class="fa fa-check-circle"></i> Save Settings</button>';
}
?>
</div>
</form>
</div>
</div>
UPDATE:
Okay, the error is coming from :
}).select2('val', [default_filter]).on('change', function() {
$(this).valid();
});
attached to the end... this is for using the jquery validation script (I did not include this in the jS here), and again, worked fine in 3.5. Can you not add on to the select2() anymore with 4.0 or something?
When removing this line the error goes away, but the display of the select2 is very small in width and I cannot gain focus on the search box to enter any values so it is still unusable within the modal.
UPDATE2:
Realized the events changed with 4.0 so this seems to work :
}).on("change", function (e) {
$(this).valid();
});
Still cannot enter anything into the search box though. Also, I notice if I click on anything other than the arrow in the input box to show the dropdown it acts as if the mouse is being held down - it highlights all the text/content within the modal.
Solution : All the issues I was having with the select2 in my bs3 modal were solved by adding the following in my js :
$.fn.modal.Constructor.prototype.enforceFocus = $.noop;
The highlighting of content/text is gone. The focus on the search box is gone. For now everything seems to work great. I do not have any information as to what this line actually does at the moment, but will be researching this to find out and will add it back here for future reference for anyone.

jquery mobile multiple page, tinyscrollbar missing bar

I try to implement tinyscrollbar (tinyscrollbar.js) into jquery mobile with data-role=page. On the first page it works perfectly fine. but on the second page, the bar is missing. until i clicked on inspect element. I tried tinyscrollbar_update(), update(0), slideToggle().promise()... non works. They all give me different kind of errors.
looks like this
<div class="scrollbar1">
<div class="scrollbar" style="height: 200px;">
<div class="track" style="height: 200px;">
<div class="thumb" style="top: 0px; height: 32.6530612244898px;">
<div class="end"></div>
</div>
</div>
</div>
<div class="viewport">
<div class="overview">//text</div>
</div>
<div id="footerNavigation">
Back
Next
</div>
i copied the exact same code as above to my second page code:
<div id="theNextPage" data-role="page"><!--scrollbar code--></div>
and my javascript file:
$(document).ready(function() {
$('.scrollbar1').tinyscrollbar();
});
anybody has any idea how is that so? Any way to solve it?
I have found out away!
change the class into id.
class="scrollbar1" >> id="scrollbar1"
next page:
class="scrollbar2" >> id="scrollbar2"
$(document).ready(function() {
$('#scrollbar1').tinyscrollbar();
$('#scrollbar2').tinyscrollbar();
});
$(document).on("pageshow", "#theNextPage", function () {
var $scrollbar2 = $('#scrollbar2');
$scrollbar2.tinyscrollbar();
var scrollbar1 = $scrollbar2.data("plugin_tinyscrollbar")
$scrollbar2.update(0);
});
like this would be better

Resources