Validation with parsley after re-enabling fields - html

I am working on a form that has two pages, technically 1 page, just hiding the second until first is finished. My first task was to be able to "validate" the first page with parsley.js, without including the elements from the second page. I did this by
disabling (via attr) the elements on the second page. Therefore only leaving the items on the first to be validated when the "Next" button is clicked.
This works great!, unfortunately on the second page, after I removeAttr('disabled') from the elements, parsley ignores them and still only validates the first page, thus returning "true" and submitting the page without checking any elements from the second.
Thanks for reading!

Ok so I figured this out just in case someone runs into this in the future.
After I loaded the second page, I destroyed the parsley and then re-added after the elements were re-enabled.
$('.new-account #page1 #next').on('click', function (e) {
e.preventDefault();
if ($('#new-account-form').parsley('isValid') == true) {
$('#new-account-form .hide input').removeAttr('disabled');
$('.new-account #page1').fadeOut(500, function() {
$('.new-account #page2').fadeIn(500);
});
// destroy
$('#new-account-form').parsley('destroy');
// Re-assign parsley to the form to include the second page now
$('#new-account-form').parsley();
} else {
$('#new-account-form').parsley('validate');
}
});

Related

Navigating to a page in a custom event doesn't work properly

When I navigate to a page using this event:
this.events.subscribe('liveTrackingEvent', (time, unit) => {
console.log("event triggered");
this.searchForm.controls['unitID'].setValue(this.unitSelected.unit.name);
this.GetLiveData();
});
everything gets called, also the function GetLiveData(). (I didn't post this function's code because it's irelevant)
However when I look at the page, not 1 element is updating. So this line:
this.searchForm.controls['unitID'].setValue(this.unitSelected.unit.name);
doesn't update the searchform control, however when I call this line of code from the page itself without the event getting triggered on another page, it works smoothly and updates the searchform control.
(It's like I'm on a separate thread for some reason), I'm putting this between brackets because it's just a thought.
So my question is: How do I force this page to update itself also when the event is triggered?
Thanks in advance and if you guys need more code just ask, but this is the most relevant code because everything is working just not when it gets called inside the event.
By using page life cycle events instead of custom events from the ionic framework I managed to make this work and even have a cleaner code.
example:
1st page:
GoToLiveTracking(unitID){
this.navCtrl.push(MapPage, {redirected: true, unitID: unitID});
}
2nd page:
ionViewDidEnter(){
if(this.navParams.get('redirected')){
let unit_id = this.navParams.get('unitID');
this.unitSelected = this.completeService.GetUnitByID(unit_id);
this.searchForm.controls['unitID'].setValue(this.unitSelected.unit.name);
this.GetLiveData();
}
}
I could think of only 1 reason for this behavior. You are updating your form outside of Angular Zone. That’s why the changes are not getting detected.
To fix the issue, wrapped the call of last 2 lines of event into “this.ngZone.run(() => { ... })”.
e.g
this.events.subscribe('liveTrackingEvent', (time, unit) => {
console.log("event triggered");
this.ngZone.run(()=>{
this.searchForm.controls['unitID'].setValue(this.unitSelected.unit.name);
this.GetLiveData();
});
});

reload only elements of the certain class on click - jquery

I have the function which reloads page on click:
$('#reload').click(function () {
location.reload();
});
What should I put instead of location.reload(); in order to reload only elements with aaa class?
tried $('.aaa').reload(); - doesn't work.
You can use .load to load the contents to an element, i.e provided you have a url that returns the html to be loaded into the element. You cannot just reload an element to an old state because HTML is stateless unless you manage the state manually.
$('#reload').click(function () {
$('.aaa').load(url); //url which returns you the content of the html.
});
or other way could be storing the previous state of the element in localstorage/cookie/data cache etc and populate it back on the click.
An example for second way is:
$('#reload').click(function () {
$('.aaa').replaceWith($('.aaa').data('cache')); //just replace itself with one in the data cache
});
$('.aaa').data('cache', $('.aaa').clone(true)); //on load of the page save the current element in data cache, for later use
Fiddle

TabIndex - hitting tab moves me to Address Bar - unable to work around this using Focus or +tab indexes

I read several threads that talk about how the Address Bar in IE is basically the first one to get focus when using TAB (MSDN's own docs talk about this).
Yet, I have seen situations where this doesn't always have to be the case....
I have a master page and inside my content area is a formView.
It defaults to INSERT view and can never leave it (they can only insert not edit and reading is handled elsewhere)
So on my page load for the page I have:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If fvwLogEntry.CurrentMode = FormViewMode.Insert = True Then
'Set the default field to position the cursor there...hopefully
Dim FCtxtHrEmployeeId As TextBox
FCtxtHrEmployeeId = CType(fvwLogEntry.FindControl("txtHrEmployeeId"), TextBox)
Page.SetFocus(FCtxtHrEmployeeId.ClientID.ToString)
End If
Now that works, when the page loads it sets the cursor to the employeeID text box inside the formview's INSERT template.
HOWEVER, when I hit TAB it takes me to the address bar and THEN if I hit tab again it takes me through the rest of the items on the page.
I set the tab index of the first item to 11 and then incrimented from there (I had read that IE's toolbars have tab indexes too so I thought perhaps using a higher number would bypass those, but again that doesn't REALLY make sense since it would still start at the lowest number, but I gave it a shot thinking it would move forward from where the focus was set.) If I click on the textbox and then hit TAB it DOES move through the page like I would expect.
It is just when the page loads and gets the focus set to the employeeID textbox that hitting tab moves it to the address bar.
I also tried setting the other controls to -1 (those I didn't want it to tab to), still no luck there.
So... what can I do to get around this?
There MUST be a simple way to set the focus to the employeeID textbox and ensure that pressing TAB after that moves to the next control in the formview's insert template and does NOT jump up to the address bar?
The following jquery code seems to be working fine for me..
$(window).load(function () {
$('.myClass :visible:input:enabled:first').focus();
});
$('body').on('keydown', '.myClass :visible:input:enabled:first', function (e) {
if ((e.which == 9) || (e.keyCode == 9)) {
$('.myClass :visible:input:enabled:first').focus();
}
});
I found another better option which is fastest as of what I tried.
Here's the code for that
function handleTabOrder() {
$('.myClass :visible:input:enabled').each(function (index) {
$(this).attr('tabindex', index + 10);
});
$('.myClass :visible:input:enabled:first').keydown(function (e) {
if (e.keyCode == 9 || e.which == 9) {
$("[tabindex=10]").focus();
}
});
}
What I have done here is to assign Tab order to all the visible controls on the page, then I have handled the key down event of only first control(that shifts the control to address bar) and now it shifts the control to next visible input item on the screen..
Its just a work around but works faster than any of the other things mentioned in the thread.
Just write the above function and all it in on-load event of page.
I was having this issue as well. For me, it was being caused by the use of the .select() method in order to bring focus automatically on a text field as soon as the page loaded. I changed my code to instead use JQuery's .focus() method and that resolved the issue.
I faced similar problem in IE. After some analysis I found that, this problem occurs if there is any HTML content outside form.
for example:
<html>
<div id="1">
</div>
<form>
//other code
</form>
</html>
It worked for me, after I moved all HTML inside form tag.
<html>
<form>
<div id="1">
</div>
//other code
</form>
</html>
Have a look at: http://www.w3schools.com/tags/att_global_tabindex.asp
Your txtHrEmployeeId element should have tabindex 1 and all other elements should have higher values.
-1 is not valid
Also verify that the tabindex are correct in the html that gets rendered (right-click in page and "view source").
I realize this is an old post, but an even simpler method is to add a "tab-stop" attribute to the form element with the last tabindex. Then bind a keydown listener and force focus to the first tabindex when the tab-stop is encountered.
Here's a simple example:
<input type="text" tab-stop />
$document.bind("keydown", function(event) {
var attrs = event.currentTarget.activeElement.attributes;
if (attrs['tab-stop']) {
angular.element.find('select')[0].focus();
event.preventDefault();
}
});
};
The answer mentioned in my other post works fine but it made the page take a huge performance hit because with every key press on the page the whole DOM was being searched for the elements.
So I found a new more optimized solution
var myNameSpace = function(){
this.selector = '.myClass :visible:input:enabled:first';
this.myElement = $(selector);
this._body = $('body');
var _self= this;
this._body.on('keydown',_self.selector,function(e){
if ((e.which == 9) || (e.keyCode == 9)) {
_self.myElement.focus();
}
});
};
The general idea being to 'cache' the node to be accessed. No need to traverse the DOM again and again for just selecting.
I had this same problem. It turns out mine was related to the ajax modal popup extenders. a modal popup was being shown, even though technically i could not see it because it was wrapped inside a parent div that was hidden. if you are using modal popup extenders, this could be causing an issue like this.
If you are using JSF or Primefaces, you can make use of:
<p:focus for"formname"></p:focus>

Is it possible to stop child click events propagating to parents when handled by .live()?

I have 'Back Board' on my images and content over here: http://syndex.me
So basically, you click on an image, it will overlay a info panel above the clicked content.
I want to do two things:
Click on the background of the site to fade out the currently opened info panel
Be able to click on a tag, link, or social icon within the info panel without triggering it's parent function, which is too fade out again.
I cannot use stopPropagation for the child click being superseded by the parent click as i need the click events to be handled by .live() (see documentation) This is due to the fact that posts are being dynamically loaded.
I cannot just say something like:
$("#Background").click(function(){//fade out the Info Board}
Because that is being covered by the entire post wrapper, and i can't put an event ont hat because then I'm even deeper in the dilemma of parents taking over children's events :-)
So far I'm at least able to have just one infoboard open (i.e I click on one image, then another, it will close the already opened one, and open the current one. So this part is all good:
$('.theContent:not(.clicked)').live("click", function () {
$(this).children('.postInfo').fadeIn(400);
$(".clicked").each(function() {
$(this).find('.postInfo').fadeOut(400);
$(this).removeClass('clicked');
});
$(this).addClass("clicked");
});
$('.clicked').live("click", function () {
$(".clicked").each(function() {
$(this).find('.postInfo').fadeOut(400);
$(this).removeClass('clicked');
});
});
Re .live(), .delegate() and .stopPropogation():
Since the .live() method handles events once they have propagated to the top of the document, it is not possible to stop propagation of live events. Similarly, events handled by .delegate() will propagate to the elements to which they are delegated; event handlers bound on any elements below it in the DOM tree will already have been executed by the time the delegated event handler is called. These handlers, therefore, may prevent the delegated handler from triggering by calling event.stopPropagation() or returning false.
How about simply checking whether the event actually took place on the specific element:
function activate(el) {
el.find('.postInfo').fadeIn(400);
el.addClass('clicked');
}
function deactivate(el) {
el.find('.postInfo').fadeOut(400);
el.removeClass('clicked');
}
$('.theContent:not(.clicked)').live('click', function(e) {
deactivate($('.clicked'));
activate($(this));
});
$('.clicked').live("click", function(e) {
if (! $(e.target).is('a')) {
// this should not trigger if a click occured on one of the links
deactivate($(this));
}
});
$('#ape').click(function(e) {
if ($(e.target).is('#ape')) {
deactivate($('.clicked'));
}
});
Have you thought about binding the click event when the post is dynamically loaded? This way you can use stopPropagation().
http://jsfiddle.net/rkw79/CzEj5/
If you bind the event to a parent element, it won't stop its propagation event to it's childrens.
You have two solutions, to bind an event to every children and put THERE the stop propagation call, or just test who ired the click event in the parent. I prsonaly find more elegant the second solution.
You can read something more about it here :
http://redfishmemories.blogspot.it/2014/08/jquery-prevent-event-propagation-and.html

mootools - using addEvent to element not working properly?

bangin' my head against this and it's starting to hurt.
I'm having trouble with adding an event to an element.
I'm able to add the event, and then call it immediately with element.fireEvent('click'), but once the element is attached to the DOM, it does not react to the click.
example code:
var el = new Element('strong').setStyle('cursor','pointer');
el.addEvent('click',function () { alert('hi!'); });
el.replaces(old_element); // you can assume old_element exists
el.fireEvent('click'); // alert fires
however, once I attach this to the DOM, the element is not reactive to the click. styles stick (cursor is pointer when I mouseover), but no event fires. tried mouseover as well, to no avail.
any clues here? am I missing something basic? I am doing this all over the place, but in this one instance it doesn't work.
EDIT----------------
ok here's some more code. unfortunately I can't expose the real code, as it's for a project that is still under tight wraps.
basically, the nodes all get picked up as "replaceable", then the json found in the rel="" attribute sets the stage for what it should be replaced by. In this particular instance, the replaced element is a user name that should pop up some info when clicked.
again, if I fire the event directly after attaching it, all is good, but the element does not react to the click once it's attached.
HTML-----------
<p>Example: <span class='_mootpl_' rel="{'text':'foo','tag':'strong','event':'click','action':'MyAction','params':{'var1': 'val1','var2': 'val2'}}"></span></p>
JAVASCRIPT-----
assumptions:
1. below two functions are part of a larger class
2. ROOTELEMENT is set at initialize()
3. MyAction is defined before any parsing takes place (and is properly handled on the .fireEvent() test)
parseTemplate: function() {
this.ROOTELEMENT.getElements('span._mootpl_').each(function(el) {
var _c = JSON.decode(el.get('rel'));
var new_el = this.get_replace_element(_c); // sets up the base element
if (_c.hasOwnProperty('event')) {
new_el = this.attach_event(new_el, _c);
}
});
},
attach_event: function(el, _c) {
el.store(_c.event+'-action',_c.action);
el.store('params',_c.params);
el.addEvent(_c.event, function() {
eval(this.retrieve('click-action') + '(this);');
}).setStyle('cursor','pointer');
return el;
},
Works just fine. Test case: http://jsfiddle.net/2GX66/
debugging this is not easy when you lack content / DOM.
first - do you use event delegation or have event handlers on a parent / the parent element that do event.stop()?
if so, replace with event.preventDefault()
second thing to do. do not replace an element but put it somewhere else in the DOM - like document.body's first node and see if it works there.
if it does work elsewhere, see #1
though I realsie you said 'example code', you should write this as:
new Element('strong', {
styles: {
cursor: "pointer"
},
events: {
click: function(event) {
console.log("hi");
}
}
}).replaces(old_element);
no point in doing 3 separate statements and saving a reference if you are not going to reuse it. you really ought to show the ACTUAL code if you need advice, though. in this snippet you don't even set content text so the element won't show if it's inline. could it be a styling issue, what is the display on the element, inline? inline-block?
can you assign it a class that changes it on a :hover pseudo and see it do it? mind you, you say the cursor sticks which means you can mouseover it - hence css works. this also eliminates the possibility of having any element shims above it / transparent els that can prevent the event from bubbling.
finally. assign it an id in the making. assign the event to a parent element via:
parentEl.addEvent("click:relay(strong#idhere)", fn);
and see if it works that way (you need Element.delegate from mootools-more)
good luck, gotta love the weird problems - makes our job worth doing. it wouldn't be the worst thing to post a url or JSFIDDLE too...