SwiftUI 4: Strange behaviour of TextField for URL? - swiftui

On iOS 16 beta with Xcode 14 beta 1+2, I experience an unexpected behaviour of a TextField if a URL shall be handled.
This is the code snippet:
struct Editor: View {
#State var data: ProfileItem // it has a property link: URL?
var body: some View {
Form {
TextField("Link",
value: $data.link,
format: .url)
.keyboardType(.URL)
.textInputAutocapitalization(.never)
.disableAutocorrection(true)
.onChange(of: data.link, perform: {
debugPrint("--- ", $0)
})
}
}
}
Observation 1:
When deleting a url like https://blablabla.com/home char-by-char with backspace from the end, then the debugPrint shows the remaining URL in sync with the device until the slash behind .com is erased. Then, on the device https://blablabla is presented, but the debugPrint still shows https://blablabla.com/.
"--- " https://blablabla.com/hom
"--- " https://blablabla.com/ho
"--- " https://blablabla.com/h
"--- " https://blablabla.com/ <<< from here on, the input field content and the debugPrint output diverge, until...
"--- " https://putput.com/ <<< this slash appears
Observation 2:
When deleting the url on the device down to https:// and entering then something else like https://putput.com, the debugPrint still shows the previous URL, until a slash is put behind the new value: https://putput.com/.
This is somehow strange, as I'd expect that a syntactically correct URL should be accepted and lead to a change even if the closing slash is not applied.
So:
(a) Is it correct that the TextField with the .url setup always requires a slash at the end to recognize a changed URL base value?
(b) Is there a possibility to accept a base URL like https://blabla.com even if the user does NOT apply the closing slash?
Thanks for any suggestions!

Related

D8: changing "login or register to post comments" text

I need to change the text "login or register to post comments" but for one specific node.
The answers I found so far do not work for me: 1) I couldnt get it to change via twig 2) I do not want to use translation tool or the string module since it would change the text everywhere.
I found this https://api.drupal.org/api/drupal/modules%21comment%21comment.module/function/theme_comment_post_forbidden/7.x but it appears to be only for D7.
For the "add comment" text, I managed to change the theme.theme:
function milu2_preprocess_links(&$variables) {
$node = \Drupal::routeMatch()->getParameter('node');
if ($node) {
if ($node->id() == 36) {
if (isset($variables['links']['comment-add'])) {
$variables['links']['comment-add']['link']['#title'] = t('NEW');
}
}
However, if I replace "comment-add" with "forbidden-comment" it does not work. Any ideas?
Another problem above is, it works perfectly on the node 36 page until I hit the button. Then it shows the form to input a comment, but the text "add comment" reverts to the default. Why is that? The URL still states its the node 36 "/comment/reply/node/34/field_xyz#comment-form"

Returning a Hash as an 'else branch' dependant on Regex match

The below is a challenge assignment so may not reflect 'real-world' code. I am trying to setup my method in a way that uses the properties of one hash to return a new hash. In this case, my method is taking an email as a string, uses regex to extrapolate the tld of the email and then outputs a hash-based message based of the tld. In this example, it generates an email in the language of the tld it registers.
The code works as it should but is failing one test:
"should return a Hash with the message informations in english for any other ccTlD mail"
I cannot work out how to just set up a default value of 'en' when the tld is not in the original translation hash i.e. bob#gmail.pl should just return the English-based translation.
BONUS: I also note that my Rubocop doesn't like my styling because my compose_translated_email method has too many lines. I couldn't work out how to put the translation in another method without making that method too long too.
Any help would be greatly appreciated - rather than just the answer, I would love if you could explain what the code is doing too. Thank you.
LOCALES = {
en: {
subject: "Our website is online",
body: "Come and visit us!",
closing: "See you soon",
signature: "The Team"
},
fr: {
subject: "Notre site est en ligne",
body: "Venez nous rendre visite !",
closing: "A bientot",
signature: "L'équipe"
},
de: {
subject: "Unsere Website ist jetzt online",
body: "Komm und besuche uns!",
closing: "Bis bald",
signature: "Das Team"
}
}
def compose_translated_email(email)
username = email.match(/^(\w*)/)[1]
domain = email.match(/[^#]+(?=\.)/)[0]
tld = email.match(/.*\.(\w+)$/)[1]
tldsym = tld.to_sym
new_hash = {
username: username,
domain: domain,
tld: tld,
subject: LOCALES[tldsym][:subject],
body: LOCALES[tldsym][:body],
closing: LOCALES[tldsym][:closing],
signature: LOCALES[tldsym][:signature]
}
return new_hash
end
Wouldn't it be enough to default the value of tld to en before creating the hash? As in:
(...)
# default to english language
tldsym = tld.to_sym
# i.e. if the key does not exist in LOCALES, use "en" as key
tldsym = LOCALES.key?(tldsym) ? tldsym : "en".to_sym
(...)
Considering your bonus question, you might fill the translated values via loop to save a few lines:
(...)
new_hash = {
username: username,
domain: domain,
tld: tld,
}
%i(subject body closing signature).each { |k| new_hash[k] = LOCALES[tldsym][k] }
(...)
Explanation: We're iterating over an array of key names (subject, body, closing, signature) that will be filled in from the LOCALES hash. That %i notation (requires Ruby 2.0.0 or newer) gives us an array with symbols to these keys right away, so no to_sym is needed inside the each block - we can just use the current symbols (named k in this case) in both the source and the target hash.
Save additional lines by filling the other hash slots iteratively, too:
(...)
new_hash = {}
%W(username domain tld).each { |k| new_hash[k.to_sym] = eval(k) }
%i(subject body closing signature).each { |k| new_hash[k] = LOCALES[tldsym][k] }
(...)
Explanation: Here we're using %W to get an array of strings, so we need to_sym for the key in the target. The target value is then resolved using evaluation, which is probably not considered the cleanest style, I guess.
Please forgive any stupid mistakes, I'm a Ruby beginner myself :)
I would do something like this:
LOCALES = Hash.new({
subject: "Our website is online",
body: "Come and visit us!",
closing: "See you soon",
signature: "The Team"
}).merge({
'fr' => {
subject: "Notre site est en ligne",
body: "Venez nous rendre visite !",
closing: "A bientot",
signature: "L'équipe"
},
'de' => {
subject: "Unsere Website ist jetzt online",
body: "Komm und besuche uns!",
closing: "Bis bald",
signature: "Das Team"
}
}).freeze
def compose_translated_email(email)
email.scan(/([^#]+)#(.*\.([^.]+))/) => [[username, domain, tld]]
{
username:,
domain:,
tld:,
**LOCALES[tld]
}
end
It's not the most beautiful code in the world, but it'll do.

Flutter/Dart - Regex for removing hashtag and spaces?

The user is asked to fill in a field with a tag containing no hashtags and no spaces. But some will no doubt do it anyway. How do I strip the hashtags and spaces before sending it off to the database? Here's the code I used to try and simply remove the hashtag. But although it prints the correct removal in the console in realtime as I type into the field, I get the following error when I try to post it off to the server:
[ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: Invalid argument(s) (input): Must not be null
So here's the code;
child: TextField(
keyboardType: TextInputType.text,
autocorrect: false,
onChanged: (tag1text){
nohash1 = tag1text.replaceAll('#', '');
print("This is nohash1 " + nohash1);
setState(() {
this.tag1 = nohash1;
});
},
),
You can try .replaceAll(RegExp('[# ]'),'') . Your original code only removed matching #. Using RegExp('[# ]') we can specify the regex pattern to use for removal.
void main() {
String inputText = '#big dog sled';
print(inputText.replaceAll(RegExp('[# ]'),''));
}
Output :
bigdogsled

Minify JSON with regex

Problem Description
I want to minify a JSON. Meaning:
Desired Result
Before
{
"keyOne": "First Value",
"keyTwo": "Second Value"
}
After
{"keyOne": "First Value", "keyTwo": "Second Value"}
I want to achieve this using RegEx.
What I tried is to replace \s with an empty string. But this leads to the unwanted result that whitespaces also gets removed from values:
Result of Solution attempt
Before
{
"keyOne": "First Value",
"keyTwo": "Second Value"
}
After
{"keyOne": "FirstValue", "keyTwo": "SecondValue"}
Research done / Solution attempts
Searching Google and Stack Overflow, without success since all found questions target other use cases
Honestly just fooling around with basic RegEx knowledge
To clarify the question: I do not want to do this in JavaScript. I know I can go to the console and run something like copy(JSON.stringify(<the-json>)).
I want to quickly do this in an editor, in this case Webstorm using the Replace Tool – without installing any plugins or switching tools.
Final solution
To steps are needed:
Replace \n with an empty string. This removes linebreaks
Replace \s+" with " to remove whitespances.
You need two steps to achieve that in webstrom:
first replace \n with (nothing!) to remove line breaks;
then \s{2}" with " to remove two whitespaces before each key;
The way object is shown in JS isn't related to the way you can handle it;
{\n
"keyOne": "First Value",\n
"keyTwo": "Second Value"\n
}
the \n characters here are shown to make it more human readable, they don't actually exist in the object itself;
const data = {
"keyOne": "First Value",
"keyTwo": "Second Value"
};
console.log(JSON.stringify(data))
thus you can't apply regex to a regular JavaScript object;
however (very unlikely) if you have a string representation of an object (from somewhere?)
you can apply regex to achieve the result you want like shown in the snippet below:
const strObj = `{
"keyOne": "First Value",
"keyTwo": "Second Value"
}`;
//since it is string we can't access it like normal js objects
console.log(strObj["keyOne"]);
console.log(typeof strObj, strObj);
//replacing the new line with nothing to make it linear
let result = strObj.replace(/\n/g,"")
console.log(typeof result, result);
//casting result to a valid json to an actual js object
let castedResult = JSON.parse(result);
// it will be shown as human readable since its normal object :)
console.log(typeof castedResult,castedResult);
//accessing one its attributes since its normal object now
console.log(castedResult.keyOne);

mongo shell search for value like "/"fubak#drooop.com"/"

I may have let a bug loose on our code that essentially ruined some of our db data.
Every now and again we come across a username that has " " in his email so we need to fix this.
How can I search for a value like "/"fubak#drooop.com"/" in one field using my mongo shell?
I have been trying all the combinations I can think of like:
db.users.find(username: /"/" .* /)
and
db.users.find(username: //.*//)
or
db.users.find(username: /"".*/)
But nothing seems to work.
new RegExp('^".*')
This finds all the records that start with ".
Thanks.
Try this:
db.users.find({ email: "(?:[^\\"]+|\\.)* })
This will match all documents which contains quotes in the email
Not to sure which one is you problem, so the solutions to both possible scenarios with data in MongoDB like this:
{ "email" : "\"/\"fubak#drooop.com\"/\"" }
{ "email" : "/fubak#drooop.com/" }
{ "email": "\"blablabla#blip.ca\"" }
First document match:
db.problem.find({ email: /^\"/ })
Second document match:
db.problem.find({ email: /^\// })
Third document match
db.problem.find({ email: /^\"/ })
Do not know what you mean otherwise by "having quotes" as that is not valid JSON and by extension is also invalid BSON.