jimfog Posted August 11, 2013 Share Posted August 11, 2013 I am trying to append content on an input element on keyup but my code does not work: Here is the fiddle link: http://jsfiddle.net/fiddlehunt/bpAAS/15/ What is wrong with the above code? Link to comment Share on other sites More sharing options...
dsonesuk Posted August 11, 2013 Share Posted August 11, 2013 you can't use appending to input VALUE, you could retrieve current value, and add new text, THEN apply it to the input value using .val() <label class="label" for="current">Tωρινό</label><input id="current" > note no 'for' attribute in input $('input#current').keyup(function () { var appendword=" BRAVOOO "; $(this).val($(this).val().replace(appendword,'')+appendword); //replace appendword with '' and add appendword to end on every keyup}); Link to comment Share on other sites More sharing options...
dsonesuk Posted August 11, 2013 Share Posted August 11, 2013 If you meant to label then try $('input#current').keyup(function () { var appendword=" BRAVOOO "; $(this).prev('label').find('span').remove(); $('<span>'+appendword+'</span>').appendTo($(this).prev('label'));}); Link to comment Share on other sites More sharing options...
jimfog Posted August 11, 2013 Author Share Posted August 11, 2013 (edited) Neither of the above achieve what I want...for clarity take a look at the the picture https://skydrive.live.com/redir?resid=BE27434B2AAC8130!256&authkey=!AAC_RLgOGejY7s0&v=3 Copy And paste the whole link. Edited August 11, 2013 by jimfog Link to comment Share on other sites More sharing options...
dsonesuk Posted August 11, 2013 Share Posted August 11, 2013 Then you either need to wrap label and input in a containing element such as div, OR place input within label <label class="label" for="current">Tωρινό <input id="current" ></label> then target the inputs parent (the label) to append span after child elements already present ie in this case the input. $('input#current').keyup(function () { $(this).parent().find('span').remove(); $("<span>BRAVOOO</span>").appendTo($(this).parent());}); Link to comment Share on other sites More sharing options...
jimfog Posted August 11, 2013 Author Share Posted August 11, 2013 (edited) Now your code works. But lets's for a moment that I do not want to put the input element inside the label. Is there another method that can do what I want-achieving the same effect WITHOUT as I said putting the input inside the label. I just want to avoid changing the markup as the form has many fields. I USED After instead of appendTo Edited August 11, 2013 by jimfog Link to comment Share on other sites More sharing options...
dsonesuk Posted August 11, 2013 Share Posted August 11, 2013 insertAfter() Link to comment Share on other sites More sharing options...
jimfog Posted August 13, 2013 Author Share Posted August 13, 2013 here is the code that does what i want...almost finished. $('input#name').keyup(function(){ var remove=$('.OK').remove(); if($('#formall #name').valid()) { $(this).after('<span class="OK">OK</span>'); }}); My problem now is that the OK does not stay there after I go to another an input element-that is reasonable because I am using the keyup event, I want the OK though to stay besides the input element even after I go to another input... Tale a look the code at fiddle to see the issue now. http://jsfiddle.net/fiddlehunt/bpAAS/34/ Link to comment Share on other sites More sharing options...
davej Posted August 13, 2013 Share Posted August 13, 2013 (edited) It seems suspicious that you need a selector with two id's when id's are unique. id="name" is unique to the entire document, but I guess it doesn't matter. Looking at your code I could tell you what to do in Javascript, but I don't know jQuery. I can only fudge. To me it seems odd that you add "OK" on a keyup. What if they just hit the spacebar? Try this... $('#name').keyup(function(){ if ($(this).val().trim() != ''){ if(!$('#nok').length){ $(this).after('<span id="nok">OK</span>'); } }else{ $('#nok').remove(); }});$('#lastname').keyup(function(){ if ($(this).val().trim() != ''){ if($(this).next('span').length==0){ $(this).after('<span>OK</span>'); } }else{ $(this).next('span').remove(); }}); Two variations. Edited August 13, 2013 by davej Link to comment Share on other sites More sharing options...
jimfog Posted August 13, 2013 Author Share Posted August 13, 2013 WHERE DID YOU SEE THAT? Link to comment Share on other sites More sharing options...
dsonesuk Posted August 13, 2013 Share Posted August 13, 2013 You have to trigger the event and process to the specific element related using $(this) <label class="label" for="name">name</label><input id="name" value="" ><br><label class="label" for="lastname">lastname</label><input id="lastname" value="" > $('.label + input#name, .label + input#lastname').keyup(function(){ // var remove=$('.OK').remove(); if($(this).val()=="" || $(this).val()== this.defaultValue) { $(this).next('.OK').remove() } else { $(this).next('.OK').remove() // next element following the element $(this) that triggered the event $(this).after('<span class="OK">OK</span>'); } }); Link to comment Share on other sites More sharing options...
davej Posted August 13, 2013 Share Posted August 13, 2013 (edited) Oh, tricky! $('#name,#lastname').keyup(function(){ if ($(this).val().trim() != ''){ if($(this).next('span.ok').length==0){ $(this).after('<span class="ok">OK</span>'); } }else{ $(this).next('span.ok').remove(); }}); Can't get away from needing the .ok class. Edited August 13, 2013 by davej Link to comment Share on other sites More sharing options...
dsonesuk Posted August 13, 2013 Share Posted August 13, 2013 you can just use $('#name,#lastname').keyup(function(){ // var remove=$('.OK').remove(); if($(this).val()=="" || $(this).val()== this.defaultValue) { $(this).next('span').remove() // next element following the element $(this) that triggered the event } else { $(this).next('span').remove() // next element following the element $(this) that triggered the event $(this).after('<span>OK</span>'); } }); without ref to class, you can style the span with input+span {color:red;} or #name+span, #lastname+span {color:red;} Link to comment Share on other sites More sharing options...
davej Posted August 14, 2013 Share Posted August 14, 2013 (edited) Well, I wanted to trim and to protect innocent spans. Oh, I see in your version you were going to add .trim() but forgot it. <!DOCTYPE html><html lang="en"><head><meta charset="utf-8"/><title>jQuery add OK</title><style></style><script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script><script>$(document).ready(function(){$('#name,#lastname').keyup(function(){ if ($(this).val().trim() != ''){ if($(this).next('span.ok').length==0){ $(this).after('<span class="ok">OK</span>'); } }else{ $(this).next('span.ok').remove(); }});}); </script></head><body><label class="label" for="name">name</label><input id="name" /><span>Don't delete this</span><br/><label class="label" for="lastname">lastname</label><input id="lastname" /><span>Don't delete this</span></body></html> Edited August 14, 2013 by davej Link to comment Share on other sites More sharing options...
dsonesuk Posted August 14, 2013 Share Posted August 14, 2013 I was never going to use trim, the next() will only target the next sibling element it won't target any other following it so simply using if($(this).next('span.ok')) will do the job without .length==0 Link to comment Share on other sites More sharing options...
jimfog Posted August 14, 2013 Author Share Posted August 14, 2013 You have to trigger the event and process to the specific element related using $(this) <label class="label" for="name">name</label><input id="name" value="" ><br><label class="label" for="lastname">lastname</label><input id="lastname" value="" > $('.label + input#name, .label + input#lastname').keyup(function(){ // var remove=$('.OK').remove(); if($(this).val()=="" || $(this).val()== this.defaultValue) { $(this).next('.OK').remove() } else { $(this).next('.OK').remove() // next element following the element $(this) that triggered the event $(this).after('<span class="OK">OK</span>'); } }); I do not want to comment on the whole code mentioned in the whole topic but I just want to focus in the above segment and say some things: Why do you persist on using (this) and not using the selector itself...I know you are right but I want to here some explanation on it. I do not use code to look for empty string as shown above as this is taken care from the jquery validation plugin...http://jqueryvalidation.org/ Here is the code using the plugins methods: $('input#name').keyup(function(){ var remove=$('.OK').remove(); if($('#formall #name').valid()) { $(this).after('<span class="OK">OK</span>'); }}); Link to comment Share on other sites More sharing options...
dsonesuk Posted August 14, 2013 Share Posted August 14, 2013 Why do you persist on using (this) and not using the selector itself...I know you are right but I want to here some explanation on it. Because you have multiple class of 'OK', previously inputting of any text would trigger keyup event and it would target ALL classes of 'OK', you only want to target span with class 'OK' to remove() and append (using after()) directly following the element that triggers the event. #name input trigger event = use this input that triggered event to move through DOM hierarchy using next() to only target very next span with class 'OK' and stop. DON'T move to next span with class and remove()/after(), OR if from #lastname input, remove()/after() previous span. Link to comment Share on other sites More sharing options...
davej Posted August 14, 2013 Share Posted August 14, 2013 You had #name and #lastname. What if you had 100 such text fields? How would you handle that? Link to comment Share on other sites More sharing options...
dsonesuk Posted August 14, 2013 Share Posted August 14, 2013 give them a class name Link to comment Share on other sites More sharing options...
dsonesuk Posted August 14, 2013 Share Posted August 14, 2013 you need some method as identify them as using the span placed after the input. IF its all text inputs you could just use $('input[type=text]').keyup(function(){ // var remove=$('.OK').remove(); if($(this).val()=="" || $(this).val()== this.defaultValue) { $(this).next('span').remove() // next element following the element $(this) that triggered the event } else { $(this).next('span').remove() // next element following the element $(this) that triggered the event $(this).after('<span>OK</span>'); } }); of cycle those specific with a specific class container <div class="required"><label class="label" for="name">name</label><input id="name" value="" ><br><label class="label" for="lastname">lastname</label><input id="lastname" value="" ></div> $('.required input').keyup(function(){ .... }); or again if you wish to target a specific type $('.required input[type=text]').keyup(function(){ .... }); or as mentioned give class name to those specific inputs $('input.reqiired').keyup(function(){ .... }); in each case you would use exactly the same function code Link to comment Share on other sites More sharing options...
davej Posted August 15, 2013 Share Posted August 15, 2013 (edited) <!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><title>Validate by Class</title><style></style><script>window.onload = init;function init(){assignHandlerToClass(checkIt,'ok','form1','onkeyup');}function assignHandlerToClass(handler,sclass,formId,event1){var form = document.getElementById(formId);var list = form.getElementsByTagName('input');var iclass, idx;for( var i=0 ; i<list.length ; i++ ){iclass = list[i].getAttribute('class');if (iclass!=undefined && iclass.length!=0){idx = iclass.indexOf(sclass);if (idx>=0){eval( 'list[i].' + event1 + '=' + handler);}}}}//end of funcfunction checkIt(){form = this.parentNode;var nexte = this.nextSibling;if (this.value!=null && this.value.trim() != ''){ if (nexte.nodeName != 'SPAN' || nexte.getAttribute('class') != 'ok'){ //add ok-span var e = document.createElement('span'); e.setAttribute('class','ok'); e.innerHTML = ' OK'; form.insertBefore(e, nexte); }}else{ if (nexte.nodeName == 'SPAN' && nexte.getAttribute('class') == 'ok'){ //remove ok-span form.removeChild(nexte); }}}</script></head><body><form id="form1"><label class="label" for="name">name</label><input id="name" class="ok" placeholder="Name"/><span>Don't delete this</span><br/><label class="label" for="lastname">lastname</label><input id="lastname" class="blue font1 ok" placeholder="Last name"/><span>Don't delete this</span></form></body></html> Edited August 15, 2013 by davej Link to comment Share on other sites More sharing options...
davej Posted August 16, 2013 Share Posted August 16, 2013 (edited) I was thinking you could also change the class and use that after: content css thing... http://www.w3schools.com/cssref/pr_gen_content.asp ...but it won't work with input or br. I guess that was in the earlier part of this discussion where there was the question of wrapping the input in the label. Edited August 16, 2013 by davej Link to comment Share on other sites More sharing options...
jimfog Posted August 19, 2013 Author Share Posted August 19, 2013 It seems suspicious that you need a selector with two id's when id's are unique. Yes you are right...no need for both Id's Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now