Is there an easier way to get the (first) Parsley.js focusedField element after validation? - parsley.js

Is there an easier way to get the (first invalid) Parsley.js focusedField element after validation?
My code below works, but I am looking for an easier/better way to retrieve that element.
When form:error occurs, the Parsley formInstance._focusedField object contains this information, but console.log(formInstance._focusedField) always returns undefined.
My issue: I have some semantic ui dropdown (styled select boxes) which are not receiving focus() because they are hidden. (i.e. The form does not jump to the first error field if the select is hidden)
Each ui dropdown auto generates an input element for user searching, so if the element is('select:hidden'), I focus on the next closest input.
For this example i have data-parsley-focus="none" set on the form.
window.Parsley.on('form:error', function(formInstance) {
for (var i = 0; i < formInstance.fields.length; i++) {
var field = formInstance.fields[i];
if (true !== field.validationResult && field.validationResult.length > 0 && 'undefined' === typeof field.options.noFocus) {
var focusedField = field.$element;
if ($(focusedField).is('select:hidden')) {
$(focusedField).parent().find('input').focus();
} else {
$(focusedField).focus();
}
\\focus on first invalid element
break;
}
}
});

Direct answer:
You could listen to form:validate, and clear a variable firstField, and set that variable on field:error if it's not already set.
Better answer:
The actual problem is that focus() on the hidden field doesn't work. I'd suggest you fix that instead of hacking parsley... Find these hidden inputs, listen for focus on them and "redirect" the focus correctly.
Ultimate answer:
Fix the problem for everyone. Since Semantic UI replaces an input with a different UI element, it would make sense (in my mind at least), if it did the focus redirection itself... If you make a PR, let me know and I'll +1 it!

Related

AngularJS: invalid input is not styled as invalid until I click on the input field and click out of it

I am setting input field to invalid from javascript like this:
$scope.formName.fieldName.$setValidity("string", false);
This is working, but it affects the view only after clicking in a input field and then clicking out of it.
How can I change it in order to see the invalid field immediatelly?
You'll need to attach an ng-change="checker(model)" to your input field. Then just apply an ng-class to it to check for formName.fieldName.$error.string (since you put string as the error key) or you can also do formName.fieldName.$invalid && !formName.fieldName.$pristine
I've attached this codepen for you to play around with and see how to apply an invalid class on the field without having to lose focus on it.
Hope that helps!

How to make quill editor required?

How to make the quill editor field required? The editor gets rendered into a div, but it isn't clear if there is a way to make the field/editor required when the form submits.
As you wrote, Quill works with a div and not with a form element so it can't help you with form validation.
You'll need to check manually if the editor's content is empty, prevent the user from submitting the form and show a message that this field is required.
You can copy quill contents to a hidden input element before submitting the form as shown in this example.
A custom form control is also a good way to go. You can try to workaround with Quill's event handler and getting the value of the form.
Then a custom form validator is also possible.
Check : https://blog.thoughtram.io/angular/2016/07/27/custom-form-controls-in-angular-2.html
I've been trying to work around exactly this problem too today, using Python for back-end and a hidden form-field (name='editor') to get the value from the quill container to the back-end. Ended up with not actually really a validator but working about the same:
if request.form['editor'] == '\"<p><br></p>\"':
flash("You cannot send in empty posts!")
return redirect(CURRENT PAGE)
else:
CODE EXECUTED IF EDITOR IS NOT EMPTY
Not sure what you're doing with the input on the editor or whether you're even using Python for backend but I hope this helps. "<p><br></p>" is what the console told me the standard input on empty submission was when getting the information out of the editor.
Good luck!
const yourText = '<div><br></div>';
const htmlTagsToRemove = ['<div>', '</div>', '<br>'];
function removeHtmlTags(data) {
let text = data;
htmlTagsToRemove.forEach(it => {
text = text.replace(it, '');
});
return text;
}
const newText = removeHtmlTags(yourText);
console.log(newText);

Angular doesn't restore null-but-valid input value on model change when input is invalid

I have run across a weird/confusing behavior with <input> and form validation.
Essentially, if input has an invalid numeric value (which sets form.$valid to false), if a model value is changed to null, it sets the $valid flag back to true, but doesn't change the value displayed in the input field.
I have created a plunker to illustrate. Follow these steps to reproduce:
Modify value of a cell to empty.
Click on save link (which saves null into model)
Input a non-numeric character.
Click on reset link (which restores null from model)
Observe that the input field is no longer invalid, but the invalid character is still there.
Is this a bug or am I doing something wrong?
EDIT:
I'm starting to believe that it is a bug. I "fixed" it by introducing another directive that forces "" value for null.
Here's a fork of the plunker above with the "fix".
EDIT2:
This was fixed in v1.3+
You code is working fine but you forgot to add a validation check at app.js
this.save = function(){
if($scope.mainForm.$valid && !this.get() == ""){
old_num = num;
}
};
You should only save the value when the form is valid.
However that is not a full prove solution as the entire form has to be valid in order for save to work. To further improve the algorithm, i suggest that you mark the validity of individual model and you check validity to the individual model.
Hope it helps
Had a similar problem, I solved it by first doing:
form.$rollbackViewValue() or form.field.$rollbackViewValue if it was .$invalid before doing any of my other reset code.
In your example, you could change to something like:
<button class="btn btn-link" ng-click="cellForm.$rollbackViewValue(); item[prop].reset()">reset</button>

Selenium wait until textbox value change

I came across a situation, on selecting combobox value textbox value changes. I need to wait until textbox change to a particular value. I have tried wait.Until, please help me in solving this issue.
If you already knows the value, which going to reflect in the text box after the combo box change. Then you could create a xPath like.
//*[contains(text(),'Expectedvalue']
Then create a method for checking whether that xPath is available or not.
public boolean isElementPresent(String xPath)`
{
try
{
this.driver.findElement(By.xpath(xPath);
return true;
}
catch()
{
return false;
}
}
Then you can check using while loop
`//Do the code for changing combo box value
while(isElementPresent("//*[contains(text(),'Expectedvalue']")
{//do the necessary actions}`
//Assume the Combo box is edited also the Text box is visible
while(! driver.findElement(By.xpath("textboxXpath")).getText().equalsIgnoreCase("expected value"))
{
System.out.println("waiting for text to be loaded");
}
end of this loop, the text box must be loaded with expected value
Caution:
This may lead you to infinite execution. implement with a limitation.
while(! driver.findElement(By.id("id_of_combo_box")).getAttribute("value").equals("Expected Value"))
{/*Loops till value is written*/}
Here we loops till the value of the combo box equals expected value.

Stellar.js in RWD

I've been messing around with stellar.js. In my design, the navigation needs to become a select in order to save horizontal space.
I imagine the html would be similar to this :
<select>
<option data-slide="1">Accueil</option>
<option data-slide="2">Services</option>
<option data-slide="3">RĂ©alisations</option>
<option data-slide="4">Contact</option>
</select>
However, I am not sure as to how the .js file should be changed in order to do this. I believe this is where the magic happens, but I am not 100% on this :
slide.waypoint(function (d, e) {
dataslide = c(this).attr("data-slide");
if (e === "down") {
c('.navigation li[data-slide="' + dataslide + '"]').addClass("active").prev().removeClass("active")
} else {
c('.navigation li[data-slide="' + dataslide + '"]').addClass("active").next().removeClass("active")
}
});
Has anyone ever done this ? Thanks !
I can tell by the code you posted that you're following the tutorial published a while a go in Tutsplus, right?
Well, that piece of Javascript code leverages the waypoint plugin to mark as selected the link corresponding to the slide in the viewport (and hence visually enhance it). But since you're going to be using a dropdown list the approach above is useless. To get things done you will need first to ensure that the user is properly scrolled upon changing the selectbox value. This will make the trick (you'd better change the jQuery selector below to ensure this handler does not affect any other input control in the page but the main dropdown nav widget):
$('select').on('change', function() {
var slide = $(this).find(':selected').data('slide');
goToByScroll(dataslide);
});
Ok, and now we need to ensure that the listbox changes its default value as the user performs the scrolling. We will leverage some bits of the code you posted. Something like this will be enough:
slide.waypoint(function (d, e) {
var dataslide = c(this).attr("data-slide");
$('select').prop('selectedIndex', parseInt(dataslide)-1);
});
AS a word of caution, the code above assumes that all aslides have a numeric data-slide value that goes from 1 to n and each listbox index refer to a matching slide with the same index in the page, plus 1, being its sorting order the same as the dataslide it represents.

Resources