how to make cookies and remember answer for iphone/android devices? - javascript

I have this code in my index.html
if((navigator.userAgent.match(/iPhone/i)) ) {
if (document.cookie.indexOf('iphone_redirect=false') == -1) {
if (confirm('for your device exist iphone app')) {
window.location = 'https://itunes.apple.com/us/app/....';
}
}
}
var ua = navigator.userAgent.toLowerCase();
var isAndroid = ua.indexOf('android') > -1;
if(isAndroid) {
if (confirm('for your device exist iphone app')) {
window.location = 'https://play.google.com/store/apps/details?id=...';
}
}
But i don't know how to make cookie to remember my answer. If user click "cancel" or "OK" to remember "cancel" or "OK" until user clean cache.
Do you have idea how to make cookie to remember answer?

Using localStorage (phrase it so the default is falsey)
// save a flag
window.localStorage.setItem('iphone_no_redirect', 'true'); // any truthy string
// check a flag
if (window.localStorage.getItem('iphone_no_redirect')) {
// this has a truthy value
} else {
// this has a falsey value ("" or null)
}
// remove a flag
window.localStorage.removeItem('iphone_no_redirect');
// make flag falsy without removing it, set to ""
window.localStorage.setItem('iphone_no_redirect', '');
You can check against null if you want to know if a flag is set and falsey
// flag set but falsey
var x = window.localStorage.getItem('iphone_no_redirect');
if (!x && x !== null) { // x is falsey, x is not null
// ...
}
Combining this with a confirm,
function ask(question, key, overwrite) {
var response;
if (!overwrite) { // if not overwriting, check first
response = window.localStorage.getItem(key);
if (response !== null) { // has been asked before
if (['', 'false', 'no', '0', 'null', 'undefined'].indexOf(response) !== -1)
return false; // negative answers
return true; // anything else is a positive answer
}
}
if (overwrite === 2) { // easy cleanup
window.localStorage.removeItem(key);
return; // die
}
// not been asked before or we are overwriting previous answer
response = confirm(question);
window.localStorage.setItem(key, response.toString()); // "true" or "false"
return response;
}
In action
console.log(ask('Are you human?', 'is_human')); // this causes confirm dialog
console.log(ask('Are you human?', 'is_human')); // this doesn't need to ask
// changing a previous answer
console.log(ask('Are you human?', 'is_human', 1)); // this causes confirm dialog again
// cleanup
ask(null, 'is_human', 2); // (don't need question for this)

Related

How to use quills setSelection?

I am writing a custom module for quilljs. It is a simple text macro replacement tool.
ie type ".hi", it will replace it with "hello".
Originally I was calling quill.setSelection(...) within the text-change event. It wasn't working Codepen Original. Eventually I found this in the docs
Changes to text may cause changes to the selection (ex. typing advances the cursor), however during the text-change handler, the selection is not yet updated, and native browser behavior may place it in an inconsistent state. Use selection-change or editor-change for reliable selection updates." Quill setSelection API docs
So I reworked the code Codepen Revised. It works, but it sure is ugly and cursor updating after the text insertion looks weird. I cannot believe there isn't a better/idiomatic way to do this.
Quill.register("modules/quicktext", function (quill, options) {
let cache = "";
let finalcaret = null;
quill.on("editor-change", (eventName, ...args) => {
if (eventName === "text-change" && args[2] === "user") {
let [delta, oldDelta, source] = args;
console.log(source, delta);
let lastkey = delta.ops[delta.ops.length - 1]?.insert || "";
if (delta.ops[delta.ops.length - 1]?.delete) {
// handle delete key
cache = cache.slice(0, -1);
return;
}
if (lastkey && lastkey !== " ") {
cache += lastkey;
console.log("cache", cache, "lastkey", lastkey);
} else if (cache) {
// avoid initial call
console.log("cache", cache, "lastkey", lastkey);
reps.forEach((rep) => {
console.log("rep check", cache, rep[cache]);
if (rep[cache]) {
console.log("triggered");
let caret = quill.getSelection().index;
let start = caret - cache.length - 1;
quill.deleteText(start, cache.length, "api");
quill.insertText(start, rep[cache], "api");
//quill.update("api");
finalcaret = caret + rep[cache].length - cache.length;
console.log(
`caret at ${caret}, moving forward ${
rep[cache].length - cache.length
} spaces, to position ${
caret + rep[cache].length - cache.length
}.`
);
console.log("done trigger");
}
});
cache = "";
}
} else if (eventName === "selection-change") {
if (finalcaret) {
quill.setSelection(finalcaret);
finalcaret = "";
}
}
});
});
let reps = [
{ ".hi": "hello" },
{ ".bye": "goodbye" },
{ ".brb": "be right back" }
];
// We can now initialize Quill with something like this:
var quill = new Quill("#editor", {
modules: {
quicktext: {
reps: reps
}
}
});
I was able to figure out a solution based upon this issue. Not sure why this is necessary, but works but it does.
// quill.setSelection(finalcaret, 0) // this fails
setTimeout(() => quill.setSelection(finalcaret, 0), 1); // this works
Codepen FINAL

Angular2/Rxjs nested maps with conditions in guard

I'd stuck with Rxjs operators.
This is a part of Angular's guard canActivate
const ifNoPatientCondition$ = this.dataService.getList().map(pl => {
console.log('im here'); // <<< this message not showing
const found = findOnlyAvailablePatients(pl);
if (found[0] === 1) {
this.stateService.patient.setCurrent(found[1]);
this.dataService.getPatientData(pid);
// return Observable.of(true);
return true;
} else {
if (found[0] === 0) {
this.stateService.app.message.send('Wrong patient status');
} else if (found[0] === -1) {
this.stateService.app.message.send('Wrong patient ID');
}
this.subscribes.forEach(subscribe => subscribe.unsubscribe());
this.stateService.navigate('/patients');
// return Observable.of(false);
// return false;
}
});
const warnOkCondition$ = this.stateService.patient.getCurrent().pipe(mergeMap(pat => {
if (!pat || pat.patient_id !== pid) { // <<< i'm interested with this condition
console.log('there is no patient!', pat); // <<< i see this message
return ifNoPatientCondition$; // <<< but cannot reach this line
} else {
if (pat.status === 'TREATMENT_COMPLETE') {
return Observable.of(false);
}
return Observable.of(true);
}
}));
return warningDialog().pipe(concatMap(warningResult => {
if (!warningResult) { // <<< if clicked No
this.stateService.navigate('/patients');
return Observable.of(false);
} else { // <<< 'Yes'
console.log('you are the best');
return warnOkCondition$;
}
}));
warningDialog() shows a dialog and returns observable of result.
If i clicked No, code works right: guard returns false and router navigate to /patients.
else if i clicked Yes, warnOkCondition$ works partially right (i'm interesting with first condition (with console.log)): i see message in console, but cannot reach next line - ifNoPatientCondition$ code.
Thanks!
Please use Types if you are working with Typescript. It is not clear what is an array and what is an Observable. Since warnOkCondition$ returns Observable.of(true/false) on some conditions, I assume this.dataService.getList() returns an Observable as well, and not a list, even though pl has no $-suffix at the end. In this case you need to subscribe to ifNoPatientCondition$ if you want it to be executed.
You might want to use switchMap or mergeMap here. https://netbasal.com/understanding-mergemap-and-switchmap-in-rxjs-13cf9c57c885

eventOverlap is supposed to allow another event into a day that has a different tag

Here's the code:
eventOverlap: function(stillEvent, movingEvent) {
console.log("I am overlapping something");
if (stillEvent.tags == ""|| movingEvent.tags == "") {
console.log("One of the events have no tag");
return true;
} else {
console.log("SE = " + stillEvent.tags + " ME = " + movingEvent.tags);
$.each( stillEvent.tags.split(','), function( key, value ) {
var index = $.inArray( value, movingEvent.tags.split(',') );
var result = "";
if( index == -1 ) {
console.log("Found no similar tags");
result =true;
} else {
console.log("Similar tags at index:"+index);
result =false;
}
return result;
});
}
}
What I'm trying to do, is when I drag an event above another day that contains an event as well, this function will compare the tags string they have (by splitting them) and looking at each individually.
If one or both of the events have no tags, it is allowed into the day.
Else, each of these are supposed to be compared per element
say X=["1","2","3"] and Y=["3","4","5"] both of these has 3, therefore it should return false. But if it finds no similar elements, like X = ["1"] and Y = ["2"] it should return true. False will disable eventOverlap, and true otherwise.
So I checked with the console. What's happening here is that even if it knows that there are no similar tags, eventOverlap is still not enabled. Only when the other event has no tag.
Might it be a flaw on my logic? Thanks!
What about something like this?
...
eventOverlap: function(stillEvent, movingEvent) {
if (stillEvent.tags == ""|| movingEvent.tags == "") {
console.log("One of the events have no tag");
return true;
} else {
for (i = 0; i<stillEvents.tags.length; i++){
for(j = 0;j<movingEvent.tags.length,j++) {
if (movingEvent.tags[j] == stillEvents.tags[i]){
return false;
}
}
}
return true;
}
}
...

how to catch the event and distinguish close and refresh event

In my project I need to use close event in browser through web, server and database deal with the information when user log out.
I do not know how to catch the event and distinguish close and refresh event.
I tried these code:
window.onbeforeunload = function() {
var n = window.event.screenX - window.screenLeft;
var b = n > document.documentElement.scrollWidth-20;
if(b && window.event.clientY < 0 || window.event.altKey) {
alert("close event");
}else{
alert("refresh event");
}
}
But it only catches the refresh event.
Is there a better way to solve the problem?
Besides,I have read the How to differentiate browser close and refresh events in Chrome?,but it doesn't give me the answer.
An idea: Judge by cookie to get the information if it is log in.
And the browser usually doesn't disable cookies.
If the cookie is disable, you may ask user to enable it.
Here is an example for cookie:
function setCookie(name, value) //cookies setting
{
var argv = setCookie.arguments;
var argc = setCookie.arguments.length;
var expires = (argc > 2) ? argv[2] : null;
if(expires!=null)
{
var LargeExpDate = new Date ();
LargeExpDate.setTime(LargeExpDate.getTime() + (expires*1000*3600*24));
}
document.cookie = name +value }
//In Js
setCookie("a","34234523542");
//read cookie:
function WM_readCookie(name)
{
//if there is no cookie,return false;or get value and return value
if(document.cookie == '')
return false;
else
return
unescape(WM_getCookieValue(name));
}
function WM_getCookieValue(name)
{
// Declare variables.
var firstChar,lastChar;
// Get the entire cookie string.
// (This may have other
name=value pairs in it.)
var theBigCookie = document.cookie;
// Grab
just this cookie from theBigCookie string.
// Find the start of
'name'.
firstChar = theBigCookie.indexOf(name);
// If you found it,
if(firstChar != -1)
{
// skip 'name' and '='.
firstChar +=
name.length + 1;
// Find the end of the value string (i.e. the next
';').
lastChar = theBigCookie.indexOf(';', firstChar);
if(lastChar == -1) lastChar = theBigCookie.length;
// Return the
value.
return theBigCookie.substring(firstChar, lastChar);
} else
{
// If there was no cookie, return false.
return false;
}
}

Why isn't this working javascript?

I am using this to detect errors on my form...
var error = false;
if (val === '') {
error = true;
}
if (error = true) {
$('#joinForm .submit').click(function(event) {
event.preventDefault();
});
}
Simple really but not working, am I missing something stupid? variable error is default false.
If an error is found it is true.
If error is found to be true it prevents the form being submitted?
var error = false;
if (val === '') { // <<< This checks type first, then value
// An empty '' variable is not type-equivalent
// to a (boolean) false value
error = true;
}
if (error = true) { // <<< You're setting a variable here, which means
// means that you're testing if the variable
// assignment itself is successful, you'll get
// a true result in most cases, and except with
// things like while loops, you shouldn't use this
// form.
// Maybe you want == (falsy)? Or === (type-checked)?
$('#joinForm .submit').click(function(event) {
event.preventDefault();
});
}
You should do the checking in the submit event handler:
$('#joinForm').submit(function(event) {
var error = false;
if (val === '') {
error = true;
}
if (error) {
event.preventDefault();
}
});

Categories