Parsley.js - raising error so that multi-step interface NEXT button identifies that there's error - parsley.js

I am using parsley.js to control user input validity. If I define the rule via HTML tools such as required, pattern etc, everything works just fine. That is, if I do something not in line with the rules and press the NEXT button, parsley makes the fields render with red background (as expected).
BUT!
If I define the rule by this code:
$('#some_field').on('change', function()
if (something bad)
{
var elem = $('#id_kpp').parsley();
var error_name = 'multiple_inn_kpp';
elem.removeError(error_name);
elem.addError(error_name, {message:'My error message'});
}
});
rather than HTML tools, I am able to navigate to the next section by pressing the NEXT button as if parsley would not see the invalid input. Though the error raising itself works correctly in that after loosing focus the field renders with red background when loosing focus
Any ideas what am I doing wrong ?
I hope I put it clear. If something unclear, please ask for additional comments

Just to help you rule out anything simple, have you tried without dropping the braces?
if (something bad) {
var elem = $('#id_kpp').parsley();
var error_name = 'multiple_inn_kpp';
elem.removeError(error_name);
elem.addError(error_name, {message:'Такая пара ИНН/КПП уже существует.'});
}
Because of the way JavaScript inserts semicolons, it's possible that the if statement is being evaluated (and returning true), but that's the end of the statement. If you don't add a line break after the if statement, you might solve your problem.

Avoid as much as possible to manually add & remove errors. Instead, use a custom validator.
I would like to get rid of addError one day, it's nearly impossible to support it in a consistent way.

Related

why useState`s value does not change in this code?

enter image description here
height value change by setHeight() but
page value does not change by setPage()
when i use annotation code, page value change...
Rather than assuming react's useState() hook is not updating its value when you call the setter function, it's probably safer to assume your surrounding logic is keeping setPage() from being called. I would start by adding a console.log statement above each setPage call to verify whether that part of the code is being reached or not.
If the code is not being reached, then you need to revisit your logic. It looks like page increase will not be reached if:
$html.is(":animated")
e.originalEvent.deltaY <= 0
page == 6
Is that your intended logic? Based on your indentation after the line if($html.is(":animated")) return; I'm a little concerned you meant to do if($html.is(":animated")) { there instead. I would also suggest you might want to get out of the habit of omitting the brackets on single line if statements, this can really bite you sometimes, and may be what is causing your logic to not work as intended here.

Implementing "tab completion" in RichEdit Winapi

This is a feature you see in a lot of IRC clients. Basically, if you type a string "Ad" and then hit tab the client will fill in the first matching nick (in the case of an IRC client) mathcing 'Ad' - so let's say it fills in Adam. But, like bash, if you keep hitting tab it should cycle through all the names containing "Ad" as a prefix.
I'm not quite sure how to implement this in the Wndproc for a RichEdit though. Specifically, when a user hits tab I need to get the current 'token', save it, and get all the prefixes and fill in the first. If he hits tab again I need to get the next prefix, and so on, but I need to empty the prefix list once I get a WM_CHAR that's not tab -- I think?
I'm wondering if there's some easier, less hacky way though, or if anybody has seen code that does this?
Thanks.
Useful though Remy's comments are, it seems to me that this question is more about what the logic should be to implement kind-of-bash-style auto-completion than anything else. On that basis, and based on what you posted, which I found slightly confusing, I think it should be something like this (pseudo-code);
int autocomplete_index = 0;
string autocomplete_prefix;
on_tab:
if (autocomplete_prefix == "")
{
autocomplete_prefix = current_contents_of_edit_field ();
autocomplete_index = 0;
}
auto autocomplete_result = get_autocomplete_string (autocomplete_prefix, autocomplete_index++);
if (autocomplete_result != "")
replace_contents_of_edit_field_and_move_caret_to_end (autocomplete_result);
else
beep (); // or cycle round
done;
on_any_other_char:
autocomplete_prefix = "";
If the rich edit control is embedded in a dialog, you also need to ensure that the dialog manager does not speak in and snaffle VK_TAB before you do. That normally doesn't happen for rich edit controls (although it does for regular edit controls - go figure) but if it does you can handle WM_GETDLGCODE appropriately in your WndProc (details on request).
And 'hacky'? Why? I don't think so. Sounds like a good idea to me.

Coded UI - How do we find if something exists when IsVisible, Exists, TryGetClickablePoint etc all return true when I can't see the control?

I am testing a WPF application and am not privy to it's exact workings but I am finding many instances where I need to find if a control is shown. All the traditional answers on this on Stack Overflow and MS forums etc say to use one of the following ...
IsVisible,
Exists,
TryGetClickablePoint,
State (e.g. OffScreen
The problem is that for this system, many controls return true for all of those even when the control cannot be seen! They also return a point with co-ordinates (-1, -1, -1, -1) whether the control is visible or not.
The only thing I have had any success with is using a try catch finally. I try to click on the control and if that fails, I go in to the catch block. That takes 60 seconds to time out though and I am getting intermittent issues with tests that run 9 times out of 10. Maybe the constant use of try catch is causing performance issues.
Is there an approach that actually works when all the standard approaches fail? I have noticed lots of other people asking these question are also testing WPF. Is there something WPF developers are doing to hide controls that makes CodedUI think they are still present and visible etc. Are they just behind something?
Many thanks in advance.
The solution was two-fold. Firstly I had to find the element and this was not working properly with my recorded steps. The element was buried too deeply in the system under test which is WPF (XAML). Secondly I had to prove I had found the element and for this I can't use TryGetClickablePoint, Exists, Top or Width. None of them seemed to work properly at all for my element. I had to use State.
public void Assert_MyElementShown()
{
#region Variable Declarations
WpfCustom uISurfaceCustom = this.UISysUnderTestClientShWindow.UIItemCustom1.UISurfaceCustom;
WpfCustom uIYAxisLabelsCustom = new WpfCustom();
#endregion
//Find the Element using it's Container and SearchProperties
uIYAxisLabelsCustom.Container = uISurfaceCustom;
uIYAxisLabelsCustom.SearchProperties[WpfControl.PropertyNames.ClassName] = "Uia.AxisLabelControl";
uIYAxisLabelsCustom.SearchProperties[WpfControl.PropertyNames.AutomationId] = "YAxisLabels";
//Use the State to find if it's on screen or not
var state = uIYAxisLabelsCustom.State;
if (state == Microsoft.VisualStudio.TestTools.UITest.Extension.ControlStates.Default)
{
//Element is visible, do stuff here!
}
else if (state == Microsoft.VisualStudio.TestTools.UITest.Extension.ControlStates.Offscreen)
{
//The control may exist, it may have location on screen and may even
//appear to be clickable according to coded ui framework but is is NOT
//shown on the screen.
}
}
You can try this approach for your application..if control properties are showing true for viable than we can go for height and width.Means if control is not visible in UI and but still all properties are showing true than check control height and width must be in -ve number.Than we can keep a assertion like
If control.height<0
Not visible in UI

RxJS DOM pause observable while another "is dragging"?

UPDATE
I've tried to make a standalone version here: https://codepen.io/neezer/pen/pPRJar
It doesn't work quite like my local copy, but I'm hoping it similar enough that you can see where I'm trying to go.
I'm not getting quite the same behavior as well because I changed the listener target to document, which seemed to help some.
Also, I'm using RxJS v5 and the latest version of React.
Still getting the hang of RxJS...
I have two Observables: one subscribed to mouseover x coordinates on a table to show a resize column, and the other to allow the user to drag on that column.
Roughly speaking, the first one looks like this (all of the below defined in a componentDidUpdate lifecycle method in a React component):
Rx.DOM.mouseover(tableEl)
.map(/* some complicated x coordinate checking */)
.distinctUntilChanged()
.subscribe(/* setState call */)
That works great, and gives me this:
So now I want to provide the actual "drag" behavior, and I tried setting up a new Observable like so
// `resizerEl` is the black element that appears on hover
// from the previous observable; it's just a div that gets
// repositioned and conditionally created
Rx.DOM.mousedown(resizerEl)
.flatMap(md => {
md.preventDefault()
return Rx.DOM.mousemove(tableEl)
.map(mm => mm.x - md.x)
.takeUntil(Rx.DOM.mouseup(document))
})
.subscribe(/* do column resizing stuff */)
There are three problems with that:
Once I've done my first "drag", I can't do any more. My understanding is that takeUntil completes the Observable, and I'm not sure how I can "restart" it.
The mousemove from the first observable is still active while I'm dragging, so my black div will disappear once my x position changes enough to trigger that behavior.
The binding on the second Observable doesn't always seem to trigger (it's unreliable). I think there might be a race condition or something happening here because sometimes I'll refresh the page and I'll get the drag once (from #1), and other times I won't get it at all.
Note at first after a clean refresh I can't drag the handle (#3), then I refresh, and I can't drag the handle past the bounds setup from the first Observable--and the black resizer bar disappears and reappears as my mouse's x coordinate enters and leaves that envelope (#2).
I've been head-banging on this for quite some time now and would really appreciate any insight as to what I'm doing wrong here. In short, I want
the first Observable to "pause" when I'm dragging, then resume when I'm done dragging
the second Observable to not "complete" (or "restart") once a drag is done
the second Observable to reliably work
As I mentioned earlier, I currently have this logic setup in a React component's componentDidUpdate lifecycle method, the shape of which looks roughly like this:
componentWillUpdate() {
// bail if we don't have the ref to our table
if (!tableEl) {
return;
}
// try not to have a new Observable defined on each component update
if (!this.resizerDrag$ && this.resizer) {
this.resizerDrag$ = // second Observable from above
}
// try not to have a new Observable defined on each component update
if (!this.resizerPos$) {
this.resizerPos$ = // first Observable from above
}
}
I've played around with this a bit now, I don't think this answer will be complete, but I'd like to share my insights. Hopefully a more advanced RxJS mind will chime in, and we can all work together to figure it out :).
I recreated a "lite-er" version of this in CodePen, using some light jQuery manipulation as opposed to React. Here's what I have so far:
"the first Observable to "pause" when I'm dragging, then resume when I'm done dragging"
Solving the first point helps with the other two. Based on what I had to do to get my resizerEl, I get the feeling it is rendered in the render method of the component based on something in this.state. If this is true, that means that when the first observable still has the ability to create and destroy resizerEl even while the second observable is listening. This means that resizerEl will no longer be able to generate any events, even though the observable doesn't complete until you've moused up.
In my case, I noticed that if you moved the mouse fast enough to go outside of width of what you were trying to drag, it would eliminate resizerEl, which is of what we want, but not while we're trying to drag something!
My solution: I introduced another variable to the "state" of the "component". This would set to true when we moused down on resizerEl, and then false when we moused up again.
Then we use switchMap.
Rx.DOM.mousemove(tableEl)
.switchMap(function(event) {
return this.state.mouseIsDown ? Rx.Observable.never() : Rx.Observable.of(event);
})
.map(...
There's probably a better way to do it rather than just sticking event back in an Observable, but this was the last part of it I worked on and my brain is kind of fried hehe. The key here is switching to Observable.never while the mouse is down, that way we don't go any further down the operator chain.
Actually, one nice thing is that this may not even need to be put in this.state, since that would cause a re-render. You can probably just use an instance variable, since the variable is only essential to the Observables functionality, and not any rendering. So, using this.mouseIsDown would be just as good.
How do we handle the mouse being down or up?
Part 1:
...
Rx.DOM.mousedown(resizerEl)
.do(() => this.mouseIsDown = true)
Better to abstract this to a function of course, but this is the gist of what it does.
Part 2:
...
return Rx.DOM.mousemove(tableEl)
.map(mm => mm.x - md.x)
.takeUntil(Rx.DOM.mouseup(document))
.doOnCompleted(() => this.mouseIsDown = false)
Here we take advantage of doOnComplete to perform this side-effect once the observable has completed, which in this case, would be on mouseup.
"the second Observable to not "complete" (or "restart") once a drag is done"
Now here's the tricky one, I never ran into this problem. You see, every time Rx.DOM.mousedown(resizerEl) emits an event, inside of flatMap, a new Observable is created each time with return Rx.DOM.mousemove(tableEl).... I used RxJS 4.1 when making this, so it's possible that there could be behavioral differences, but I found that just because the inner observable completed didn't mean the outer one would complete as well.
So what could be happening? Well, I'm thinking that since you're using React, that resizerEl is being created/destroyed respectively when the component is rendering. I haven't seen the rest of your code of course, but please correct me if I'm wrong about this assumption.
This wasn't a problem for me because, for the sake of simplicity, I simply re-used the same element as a dragger, only hiding it when I wasn't hovering over a draggable element.
So the important question is: how is resizerEl being defined and used in your component? I'm assuming the actual reference to it is made using, well, a ref. But if it that DOM element is ever destroyed or recreated, then the Rx.Dom binding needs to be repeated all over again.
I see you're doing this with componentDidUpdate. However, the Rx.Dom.mousedown event may still be bound to an old copy of the ref to resizerEl. Even if the component destroys the resizer in the DOM, and sets the ref (I assume that is this.resizer) to null or undefined, that does not destroy the Observable that is bound to that element. In fact, I don't even think it removes it from memory, even if it's removed from the DOM! That means that this.resizerDrag$ will never evaluate to false/null, and it will still be listening to an element that is no longer in the DOM.
If that is the case, something like this in componentWillUpdate might help:
if (!this.resizerDrag$ && this.resizer) {
this.resizerDrag$ = // second Observable from above
}
else if (!this.resizer && this.resizerDrag$) {
this.resizerDrag$ = null;
}
This will remove the Observable if the resizer object ceases to exist, that way we can properly reinitialise it upon it's return. There's a better to way to do with Subjects, keeping the subscription to one subject and just subscribing the subject to different mousedown streams once they become available, but let's keep this simple :).
This is something where we'd have to see the rest of your code (for this component) tell what's going on, and figure how to address it. But, my hypothesis is that you'd need to intentionally destroy the Observable if this.resizer is ever removed.
the second Observable to reliably work
Pretty sure that once the above two issues work, this one goes away. Nice and easy!
The CodePen
Here is the very naive mockup I made of this problem:
https://codepen.io/anon/pen/KmapYZ
Drag the blue circles back and forth along the X axis. (Has some little problems and bugs unrelated to the scope of this question, so I'm not worried about them.)
I made some slight changes of course just to keep it in-step with the more dumb downed approach I used. But all the concepts are there, as well as most of the code you wrote, modified to match this approach.
As I mentioned before, I didn't encounter the problem of the dragging only working once, so this better demonstrates the solution to pausing the first Observable. I re-use the dragging element, which I assume is why I didn't run into the 'drag-only-once' problem.
I hope that you or anyone else can comment with some improvements to this approach, or just show us a better (potentially more idiomatic) approach.

Add scope variable to array and then stop data bind

For reference, here is the fiddle: http://jsfiddle.net/6u3Gn/1/
I am playing around with angular and ran into a behavior that I can understand, but am not sure how to stop. I created a simple form for places and things, where you define a place, and then you can add things at that place. When the button to add a thing is clicked, it successfully adds the thing to the place:
$scope.addThing = function() {
if ('things' in $scope.place) {
$scope.place.things.push($scope.thing);
} else {
var things = [$scope.thing]
$scope.place['things'] = thing;
}
};
However, when I try to add another thing, the first one is still bound to $scope.thing, so the first one updates to be the exact same as the second thing I add.
How can I stop the 2 way data binding once the object in the array has been added? Is there a way to do so, or am I going about adding it to the array all wrong?
Well that was easy. Not exactly sure how I missed it but the right way to do this is to use angular.copy($scope.variable). Whoops!

Resources