u/code-dispenser

▲ 0 r/Blazor

Read only if bored - TLDR - I hate f-ing spaces more than nulls.

I started my development path creating relational databases. Working with nulls was just part of the job, no complaints, I do not have an issue with them. Yes, I know that's a volatile topic, but I'm perfectly happy if you hate them; this isn't about nulls in databases.

I then became a general developer working with Microsoft technology. When I started it was relatively straightforward, VB desktop apps with a SQL Server backend or a distributed VB desktop apps with MTS or the odd intranet built with Classic ASP. I don't recall anyone moaning about nulls back then, although admittedly the internet wasn't what it is today and most developers were reading paper-based magazines or browsing MSDN CDs.

Around 2010, more and more articles began highlighting the problems nulls caused in applications. But here's the thing, in my career to date, I have spent considerably more time dealing with whitespace issues than I ever have with nulls.

I remember when SQL Server 2005 introduced, I started looking closer at user-defined functions. The very first thing I did with them was create a simple trim function I could use in table check constraints, so any varchar or nvarchar columns would have leading and trailing spaces removed, or be converted to null if the value was entirely whitespace on a nullable column. I still add trim to check constraints on every database I create. Some of you will think that's no big deal, but anyone who has spent serious time writing stored procedures and queries knows all too well how a field full of whitespace can completely destroy your report figures.

Right, enough history. On to my recent headache.

Some of you may know I am the author of the open source BlazorRamp project. What you may not know is that I also have a functional-style OSS validation library (Validated) with a companion project (Validated.Blazor) that integrates with Blazor's EditContext.

I'm currently working on the inputs for BlazorRamp and providing examples with validation, primarily using my own library but with at least one example using Data Annotations. Side note - I'm not a fan of data attributes, I tried them when they were first released but never warmed to them, so I've done my own thing ever since.

I am however a fan of regex, although you really do need to turn your brain upside down and inside out before working with them, especially once you start adding lookarounds.

In one of my examples I use a regex validator on a field, and on another I split validation so that one validator handles the allowed characters and a separate one handles length constraints. Anyway, during manual testing, which I do a lot of given my accessibility stuff, I noticed that a regex copied from another demo would correctly fail if a user typed "Paul " with a trailing space. The red error message would appear, but looking at the input control you can't see the issue unless you place the cursor in the field, and even then a single trailing space is easy to miss.

So what you may want is a regex that does what it needs to do, but doesn't fail on a trailing space, because your code can simply deal with that silently, right?.

Now some of you are thinking: "Noob, just add a normalise function in the property setter - it's even easier in C# 14 with the new field keyword, no backing field required."

set { field = NormaliseString(value); }

To those people I say: how's that going to work when you're using Blazor's oninput binding and you need to allow a space within the string value, just not after it?

This is one of those seemingly simple tasks that turns into an absolute cluster f*ck. No matter how you solve it, it's just more work, you either dirty your clean models or you end up re-validating them in your code to strip whitespace.

The solution I ended up with was adding an optional parameter to my BlazorValidationBuilder that, when set to true, mutates the string field on the model to remove leading and trailing whitespace but only during full model validation, i.e. when the form is submitted or you call validate explicitly.

For those who know my library, guessing that's approximately zero people, the BlazorValidationBuilder simply assigns validators to fields. There's no notion of mutation in the built-in validators; it's just a flag in the metadata that gets used when working with the EditContext. And just in case there is a dedicated user out there: yes, you could create a custom validator that trimmed the string, but when using the oninput option in BlazorRamp inputs or your own, it would be called on every keystroke, putting you right back to square one.

So, the point of this post: yet more days lost to whitespace. In this instance, updating, testing, and publishing a minor release of my OSS Blazor validation package just to trim a string. And I'm not done yet, I still need to update the documentation. People say nulls are bad. I say they've clearly have never spent a career at war with spaces.

Just in case you want to see what I was talking about go type stuff in the two inputs example on my BlazorRamp doc site: https://docs.blazorramp.uk/components/inputs/text-input/usage

The First name input is just a single regex that does job lot and fails with a trialing space, the Surname input will allow a single trailing space (could be more) which then gets stripped off on model validation. You can see this just be clicking the button and putting the cursor back in the input.

Break over. Back to work and then documentation, and then hopefully (please) a start on the next BlazorRamp input without whitespace issues.

Paul

reddit.com
u/code-dispenser — 4 days ago
▲ 40 r/Blazor

What's happened to professionalism and due diligence in Blazor / .NET development - another rant from the old git.

I've been a developer for some time now. I am not a fancy front-end, back-end, or full-stack titled guy; I am just a developer that builds stuff, be it web, desktop or mobile, whatever needs building. Now, given almost 30 years, that's a lot of different tech, a lot of which devs will never have heard of.

Now, despite the saying "you are only as good as your last project", which has a lot of truth to it, there are some things that I have carried with me over the years, such as pride in my work, due diligence, and when a problem arises, the ability to work the problem, build environments if need be, and fix it.

When I started, at the start of each project it was the devs who built stuff; if you needed a network you built one, you installed and configured all the servers, everything, it was just what you did.

Later, when virtual machines became available such as VMware and Virtual PC (my first VM), you could then set up a VM if you needed a server on your PC instead of fighting with accounting to give you some cash for a new server, etc. In tandem with that, a lot of us also set up dual booting on our dev boxes. All of this was normal; I did not know any developer back then that did not dual boot or have at least one VM on their PC.

Why have I mentioned all of this? Because since my last rant, devs just seem to be getting worse. I am sorry, but devs now seem to be missing basic skills, or what I class as basic skills, such as being able to work through a problem outside of Visual Studio.

So since my last rant: https://www.reddit.com/r/Blazor/comments/1qxb6n8/whatever_happened_to_craftsmanship_in_blazor_oss/ there have been a few devs post their new commercial Blazor projects, some on this subreddit, some in the dotnet subreddit. You know how it goes: look at my super duper new Blazor thingamajig and here's the link to the live demo.

So you think, why not, let's take a look, only to find the site does not load, with the dev asking you if you have the latest browser installed. WTF, shall I reboot my PC as well?

You then mention that you have the latest versions of Chrome, Firefox, Edge on your Windows PC, and use the latest version of Safari on macOS, iOS, and the latest mobile Chrome browser on Android, and just for good measure you mention that you've also tried to access the site from both Europe and the US. Admittedly, I kind of switched off after the browser comment so was unwilling to help further.

Now some of you will flame me for not being more helpful/patient (did I not mention I tried a gazillion browsers and opened VPNs?), which is fair, but I am just sick of it; it's happening more and more.

As a developer reading this, you have just built something and you want to showcase it; do you not make sure it's all working OK before you do so?

And then, if there is a problem, rather than work the problem, do you just make comments about it probably being the user's browser?

On more than one occasion, the OP just continuously says it's working on their machine so it's probably your browser, and does not take note until about six hours have gone by and dozens of other Redditors across multiple threads and subreddits are all saying the same.

Bear in mind these are devs that are trying to sell you stuff; not open source, purely commercial.

If I were the OP and some dev (not some typical end user) just told me the site was not loading, before asking for more information I would be double-checking various things so I do not look like a complete idiot. And I would assume that if it's not loading, I have done something wrong, maybe a deployment issue or a server configuration issue, etc.

Does it work on my box if I clear my browser cache, in case there was a missing asset? Can I ping the server? tracert, netstat, DNS propagation checks, etc.

Can I access it from one of my VMs? I always have a couple on my dev box along with free VPNs for things like trying different geographical regions.

Now, in all the years I have been a developer, I have never not been able to figure out something like a site not loading problem. Yes, at some stage you may have to ask the user for more details, but not before you do your due diligence, especially if you are trying to sell me something.

And to top it all off, I mentioned that their commercial NuGet package had health issues, only to be told that they would check for missing metadata, as if I was just some moaning old fart (OK, I am), but they did not know that.

But I was not moaning about missing metadata; I was telling them their so-called professional product had NuGet/build issues, i.e. it was not deterministic and there was no Source Link. For starters, I am not going to install it without them. These are the things that tell you: this was built against this specific commit, it will build the same way every time, and if you do have a problem, you can step into the source code for that commit to find the issue; you know, the stuff that actually helps you solve problems.

If you are a commercial entity, a so-called professional developer trying to sell me something, and you do not even know how to ensure NuGet package health, give up your day job, because all you are doing is making the rest of us look bad with your incompetence. And if you can't figure out how to tick a couple of boxes and run a local NuGet feed to verify your package before release, then what on earth is your code going to be like?

Sorry folks I aint sugar coating for you.

Paul

reddit.com
u/code-dispenser — 12 days ago
▲ 2 r/Blazor

Blazor Ramp – Input Errors Summary

Yes, it's not the most inspired name, but "Validation Summary" was already taken by Blazor, so it is what it is, and it does exactly what it says on the tin.

Whilst working on the inputs for Blazor Ramp I thought I had best get this one out of the way early, given that each input needs to register itself with the summary component.

But why do that, you ask?

By doing so, each input can provide the summary component with its unique ID, and with that ID the summary can, as well as displaying error messages as the built-in Blazor one does, also provide a link directly to the erroneous input and, using a small amount of JavaScript, move focus to that input for the user.

OK, but why bother at all?

It's all about making things easier for the user. When they click the form's submit button, if there are any validation errors the summary component is displayed and focus moves directly to it.

Screen reader users are informed via the heading that there are problems with their entries, and on reviewing them in the summary they can activate a link to jump directly to the relevant field.

Screen reader users also have a wealth of keyboard shortcuts available to them, such as navigating by headings or landmarks. The summary section has been elevated to a landmark via role="region", so rather than scanning through headings they can navigate straight to it using the landmarks shortcut.

Given all the shortcuts available to screen reader users, I may need to create some sort of dialog component for sighted keyboard-only users, so they too can jump around busy pages without endless tabbing - but my to-do list is currently long enough, so that will have to wait.

I have said on numerous occasions that with inputs and forms, if you are going to use ARIA live regions to make announcements to the user, the submit button is the place to do it - not individual fields. That said, depending on how you structure things you can negate the need for a live region entirely, which is exactly what I have done here with the summary component.

When focus moves to the summary component a <section> element with both role="region" and an aria-labelledby attribute pointing to its heading - the screen reader announces to the user that they are now on a landmark region and reads the heading, such as "There is a problem with your entries", thus eliminating the need for a live region altogether.

Currently the summary only supports Blazor Ramp inputs, as getting the information needed to build links and set focus dynamically from the EditContext alone would require jumping through considerable hoops. By having the inputs register themselves with the summary, it has everything it needs and as the developer consuming the component, you do nothing other than add it alongside your inputs.

I may in the future add the ability to manually register inputs, or even do the necessary gymnastics to keep things fully dynamic, but I suspect most developers won't be mixing inputs from different libraries or rolling their own alongside Blazor Ramp's, so that may be something for the very distant future, if it is ever requested.

I will leave it there for now, for anyone interested in the details, everything is covered on my test and documentation sites. Any questions, fire away.

Docs/example: https://docs.blazorramp.uk/components/inputs/input-errors-summary/usage
Test site: https://blazorramp.uk/
Repo: https://github.com/BlazorRamp/Components

Regards

Paul

u/code-dispenser — 14 days ago
▲ 5 r/Blazor

https://preview.redd.it/gtpsapa5bwyg1.png?width=1834&format=png&auto=webp&s=0f16f9279b788be67be5e35b313a610226a71f92

For those interested in the open source project, earlier this week I released the NuGet package BlazorRamp.Inputs.

This package will eventually contain a full set of basic input components - though "basic" might be doing them a disservice. Think text inputs, checkboxes, dropdowns and so on. The initial release contains a Text Input, Numeric Input and Password Input, with all future inputs following the same layout and accessibility patterns.

For anyone who missed my previous post on inputs - https://www.reddit.com/r/Blazor/comments/1sn4dci/blazor_ramp_wazzup/ - I'd suggest reading that first as it provides useful context.

These inputs have been designed to work with the Blazor EditForm and EditContext and as such will work with your chosen validation framework that you normally use with these components.

Structure

All inputs follow a consistent layout and are self-contained units comprising a label, optional hint text, the input itself (with an optional leading icon and a fixed validity state icon), and an area for one or more validation error messages rendered as an unordered list.

Both the hint text and validation error messages are associated with the input via aria-describedby. In practical terms, this means that when a screen reader user lands on the input, in addition to the field name, required state, and validity, the screen reader will also announce the text content of any elements linked via aria-describedby - in the order they appear.

The "in the order they appear" detail cost me a couple of days down various rabbit holes. VoiceOver was ignoring the text content when the referenced id was on a div containing the unordered list rather than on the list itself. Given the long history of VoiceOver quirks with aria-describedby, it took longer than I'd like to admit to pinpoint.

Validation Display Options

There are several options for how validation errors are communicated to screen reader users.

The first is whether to suppress the hint text id from aria-describedby when errors are present, useful when the error message alone contains sufficient information and you want to reduce the verbosity for screen reader users who would otherwise hear the hint text on every focus.

The second, and more significant option, is whether to use aria-describedby for error messages at all.

As covered in the previous post, ARIA live regions for field-level validation are generally a bad idea - either due to repeatedly interrupting the user or by confusing them with out of order messages.

With aria-describedby, the behaviour is consistent across screen readers: the user types, validation occurs (via oninput or onchange), and they are not immediately interrupted. If they tab to the next field they will skip over the error area entirely; if they use the arrow keys the errors become apparent; and when they tab back and refocus the input they will hear the full announcement - field name, validity state, and the associated error messages.

The alternative is a tabbable landmark region. In plain English, this option adds a tabindex to the error area and promotes it to a transient landmark region with an accessible name. This does two things. First, when the user tabs away from an invalid field assuming oninputfor immediate validation, they land on the error region before moving on, and are informed of the errors. With onchange, validation hasn't yet occurred at that point so they will move straight to the next field as normal. Second, the landmark itself becomes discoverable, screen reader users can pull up a list of landmarks on a page and navigate directly to them. So for a field labelled "First name" with the region named "errors", a landmark named "First name errors" will appear in that list, allowing the user to navigate directly to it at any time.

Navigating in the reverse direction, the user will encounter the tabbable error region before the input itself, allowing them to read the errors before landing on the input and hearing the hint text. For this reason, when using the tabbable region option the hint text association is retained rather than suppressed.

A Final Note on Field-Level Validation

Everything discussed above relates to field-level validation, which, whilst now widely expected, should be considered a complement to, not a replacement for, a solid form submission experience. The correct starting point is ensuring that when a user submits a form with errors, they are clearly and accessibly informed. An ARIA live region announcement directing the user to review an error summary is entirely appropriate at that point. Field-level validation should then enhance that experience, not substitute for it.

I will continue to work on the Inputs package as well as to build some sort of Form Errors Summary component along the way. I have not yet added the Inputs to the test site, but there are working examples on the doc stie

Doc site: https://docs.blazorramp.uk/components/inputs/overview
Test site: https://blazorramp.uk/
Repo: https://github.com/BlazorRamp/Components.

Any questions on inputs whilst this is fresh in my mind fire away.

Regards

Paul

reddit.com
u/code-dispenser — 20 days ago