SitePoint Sponsor

User Tag List

Results 1 to 16 of 16
  1. #1
    SitePoint Evangelist
    Join Date
    Dec 2008
    Location
    Plymouth, United Kingdon
    Posts
    449
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    jquery: toggle an input value??

    Hi,

    this thread is related to the previous thread I have made on here,
    http://www.sitepoint.com/forums/show...43#post4523443

    I managed to add a new value to the existing value of the input,

    Code:
    function autofill() {
    		$('.items-form a').click(function(){
    			var currentValue = $("#inputString").val();
    			var newValue = $(this).attr('href') + " ";
    			var totalValue = currentValue + newValue;
    			$("#inputString").val(totalValue);
    			$(this).toggleClass('clicked');
    			return false;
    		});
    		
    	}
    now the problem is how I can 'toggle' the input like we have the toggleClass() in jquery?

    the idea is to remove the input value which I previously add in if I do a second click, but this value will be added again when I do a third click, and go on and on - it is like what toggleClass() does.

    Is it possible?

    here is the link to check the code above if I am not explaining it well...http://lauthiamkok.net/tmp/jquery/to...gle_input.html

    many thanks,
    Lau

  2. #2
    Utopia, Inc. silver trophy
    ScallioXTX's Avatar
    Join Date
    Aug 2008
    Location
    The Netherlands
    Posts
    9,077
    Mentioned
    153 Post(s)
    Tagged
    2 Thread(s)
    There is more simple method than the one you outlined.

    What you need to do when a user clicks a link is

    1) empty the input field
    2) toggleClass('clicked') on the clicked <a>
    3) walk through all <a> elements, if an element has class "clicked", add it's href (plus a space of course) to the input field

    I don't know if you need it, but the nice thing about this is that it preserves the order of the tags (the order in which tags appear in the input field is the same as the order in which the <a> tags are displayed on the website).

    Hint: to walk through all <a> elements use $.each()
    Rémon - Hosting Advisor

    SitePoint forums will switch to Discourse soon! Make sure you're ready for it!

    Minimal Bookmarks Tree
    My Google Chrome extension: browsing bookmarks made easy

  3. #3
    SitePoint Evangelist
    Join Date
    Dec 2008
    Location
    Plymouth, United Kingdon
    Posts
    449
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by ScallioXTX View Post
    There is more simple method than the one you outlined.

    What you need to do when a user clicks a link is

    1) empty the input field
    2) toggleClass('clicked') on the clicked <a>
    3) walk through all <a> elements, if an element has class "clicked", add it's href (plus a space of course) to the input field

    I don't know if you need it, but the nice thing about this is that it preserves the order of the tags (the order in which tags appear in the input field is the same as the order in which the <a> tags are displayed on the website).

    Hint: to walk through all <a> elements use $.each()
    hi, thanks for this idea.

    I have a problem with this idea though - bcos I might have some other tags that I type in myself which are not from the <a> tags.

    if I empty the input field on each click (step 1 above), then the other tags that I type in will be emptied too!

    as u can see it here...

    Code:
    $('.items-form a').click(function(){
    		var currentValue = $("#inputString").val();
    		var newValue = $(this).attr('href') + " ";
    		var totalValue = currentValue + foo;
    		$(this).toggleClass('clicked');
    		
    		var foo = [];
    		$('.items-form .clicked').each(function(i, val){
    			//alert($(this).attr('href'));
    			foo[i] = $(this).attr('href');
    		});
    		//alert(foo);
    		$("#inputString").val(foo);
    		return false;
    	});
    Im pulling my hair over this now! arggg

    thanks

  4. #4
    Utopia, Inc. silver trophy
    ScallioXTX's Avatar
    Join Date
    Aug 2008
    Location
    The Netherlands
    Posts
    9,077
    Mentioned
    153 Post(s)
    Tagged
    2 Thread(s)
    This works for me:

    Code Javascript:
    function autofill() {
    	$('.items-form a').click(function(){
    		var currentValue = $("#inputString").val();
    		var newValue = null;
    		$(this).toggleClass('clicked');
    		var tag = $(this).attr('href');
    		newValue = $(this).hasClass('clicked') ? currentValue + tag + ' ' : removeTag(currentValue, tag);
    		$("#inputString").val(newValue).focus();
     
    		return false;
    	});
    }
     
    function removeTag(str, tag) {
    	tag = String(tag);
    	str = String(str);
    	var idx = str.indexOf(tag);
    	if (idx === false) {
    		return;
    	}
    	var beforeTag = str.substring(0, idx);
    	var afterTag = str.substring(idx + tag.length);
    	return (beforeTag + afterTag).replace(/\s{2,}/,' ').replace(/^\s*/, '');
    }
    Rémon - Hosting Advisor

    SitePoint forums will switch to Discourse soon! Make sure you're ready for it!

    Minimal Bookmarks Tree
    My Google Chrome extension: browsing bookmarks made easy

  5. #5
    SitePoint Evangelist
    Join Date
    Dec 2008
    Location
    Plymouth, United Kingdon
    Posts
    449
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by ScallioXTX View Post
    This works for me:

    Code Javascript:
    function autofill() {
    	$('.items-form a').click(function(){
    		var currentValue = $("#inputString").val();
    		var newValue = null;
    		$(this).toggleClass('clicked');
    		var tag = $(this).attr('href');
    		newValue = $(this).hasClass('clicked') ? currentValue + tag + ' ' : removeTag(currentValue, tag);
    		$("#inputString").val(newValue).focus();
     
    		return false;
    	});
    }
     
    function removeTag(str, tag) {
    	tag = String(tag);
    	str = String(str);
    	var idx = str.indexOf(tag);
    	if (idx === false) {
    		return;
    	}
    	var beforeTag = str.substring(0, idx);
    	var afterTag = str.substring(idx + tag.length);
    	return (beforeTag + afterTag).replace(/\s{2,}/,' ').replace(/^\s*/, '');
    }
    yes it is perfect! thank you. im going to study this code in depth so that I will understand it. thank you so much!

  6. #6
    Utopia, Inc. silver trophy
    ScallioXTX's Avatar
    Join Date
    Aug 2008
    Location
    The Netherlands
    Posts
    9,077
    Mentioned
    153 Post(s)
    Tagged
    2 Thread(s)
    Quote Originally Posted by lauthiamkok View Post
    yes it is perfect! thank you. im going to study this code in depth so that I will understand it. thank you so much!
    Okay. If you have any questions about the code, just ask
    Rémon - Hosting Advisor

    SitePoint forums will switch to Discourse soon! Make sure you're ready for it!

    Minimal Bookmarks Tree
    My Google Chrome extension: browsing bookmarks made easy

  7. #7
    SitePoint Evangelist
    Join Date
    Dec 2008
    Location
    Plymouth, United Kingdon
    Posts
    449
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by ScallioXTX View Post
    Okay. If you have any questions about the code, just ask
    thank you. that's very kind of you!

  8. #8
    SitePoint Evangelist
    Join Date
    Dec 2008
    Location
    Plymouth, United Kingdon
    Posts
    449
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by ScallioXTX View Post
    Okay. If you have any questions about the code, just ask
    hi, I have looked very hard to understand this code, there are a few lines I am not quite get them...

    Code:
    tag = String(tag);
    str = String(str);
    i dont know why they have to be converted to string as they are already strings, arent they? does it make any different if I dont convert them to string?

    Code:
        if (idx === false) {
            return;
        }
    what does it mean if the idx is not found, then return? what does it do?

    Code:
     return (beforeTag + afterTag).replace(/\s{2,}/,' ').replace(/^\s*/, '');
    /\s{2,}/ and /^\s*/ - what do they stand for...?

    sorry for a long question. but i do understand this code in general that you use string to add or remove tag. brilliant!

    thanks!

    p.s. I also tried to use array to do the same thing, but it is quite complicated!

    Code:
    $('.items-form a').click(function(){
    
    	var currentValue = $("#inputString").val();
    	var intersect;
    	var tag = $(this).attr('href');
    	var arrA = currentValue.split(' ');
    	var arrB = [tag];
    	
    	for (i in arrA) {
    		for (j in arrB) {
            if (arrA[i] == arrB[j]) intersect = arrA[i];
    		var index = arrA.indexOf(intersect);
    		}
    	}
    
    	if(index >= 0){
    		arrA.splice(index,1);
    		$("#inputString").val(arrA.join(" "));
    		} 
    	else {
    		arrA.push(arrB);
    		$("#inputString").val(arrA.join(" "));
    	}
    		
    	$(this).toggleClass('clicked');
    	return false;
        });

  9. #9
    SitePoint Wizard Stomme poes's Avatar
    Join Date
    Aug 2007
    Location
    Netherlands
    Posts
    10,278
    Mentioned
    50 Post(s)
    Tagged
    2 Thread(s)
    I still can't read JS like this, but I can answer some of these:

    Code:
       
     if (idx === false) {
            return;
        }
    what does it mean if the idx is not found, then return? what does it do?
    When a function returns, it stops running. If you say "return x;" then it's also returning a value, but if I understand it correctly, if there is no value (just return) then it returns undefined. (notsure?) But anyway, in this case, the point is to stop the function, because something necessary for it to run has been checked for and found not to exist.

    Code:
    return (beforeTag + afterTag).replace(/\s{2,}/,' ').replace(/^\s*/, '');
    /\s{2,}/ and /^\s*/ - what do they stand for...?
    replace is a function that takes a regular expression as one of its arguments...
    the first argument of the first replace is inside /'s (/pattern here/)
    \s means "any whitespace" and {2,} means "at least two" (it's {minimum, maximum} and if you don't mention a maximum, then it's infinite).

    So it looks for anywhere where there's 2 or more whitespace characters (which can be spaces, tabs, and I think also newlines?), and replaces them literally with ' ' (one space).

    After that, another replace looks for any whitespace characters who start
    ^ means "the beginning" and is known as an "anchor" character in regexes.
    * is referring to how many whitespaces: none, one, or many.
    Any extra whitespace that ended up in the front of your tags is replaced with '' or nothing (no space between single quotes... looks like a double quote here but that's not what it is).

    http://www.regular-expressions.info/javascript.html The site as a whole is pretty good; I has it bookmarked.

  10. #10
    Utopia, Inc. silver trophy
    ScallioXTX's Avatar
    Join Date
    Aug 2008
    Location
    The Netherlands
    Posts
    9,077
    Mentioned
    153 Post(s)
    Tagged
    2 Thread(s)
    Quote Originally Posted by lauthiamkok View Post
    Code:
    tag = String(tag);
    str = String(str);
    i dont know why they have to be converted to string as they are already strings, arent they? does it make any different if I dont convert them to string?
    No you don't necessarily need to convert them to strings, but if you do you're sure they are strings and the javascript engine doesn't fail if you do a substr() or indexOf(); these functions are not defined for all objects.

    Quote Originally Posted by lauthiamkok View Post
    Code:
        if (idx === false) {
            return;
        }
    what does it mean if the idx is not found, then return? what does it do?
    [/CODE]
    If idx is not found, the substring is not found, i.e., the tag you want to remove is not currently in the input field (for example because I removed it manually, whithout using your links *evil grin*).
    If the substring is not found, i.e., if the tag is not found in the input, I won't waste any more time to remove it and can simply "return". That should be "return false" btw, my bad

    Quote Originally Posted by lauthiamkok View Post
    Code:
     return (beforeTag + afterTag).replace(/\s{2,}/,' ').replace(/^\s*/, '');
    /\s{2,}/ and /^\s*/ - what do they stand for...?
    That's a rather complicated one.
    They are known as regular expressions.

    Basically what this statement does is:
    .replace(/\s{2,}/,' ') - Replace every occurence of 2 or more spaces with one space
    .replace(/^\s*/, ''); - Remove any spaces at the start of the input

    This is just to make the input string look nicer.
    Regular Expression are a topic on their own, and should be viewed as such. If you're interested you could read this tutorial. If you have any questions about them I would advice you to start a new thread on that, since it would be rather offtopic in this thread
    Note that regular expressions are not only available in javascript, but in other programming languages as well.

    Quote Originally Posted by lauthiamkok View Post
    sorry for a long question. but i do understand this code in general that you use string to add or remove tag. brilliant!
    No worries, I'm just glad you're not "one of those guys" that just copy/paste the code and forget all about it
    It's good to see you're really making an effort!

    Quote Originally Posted by lauthiamkok View Post
    p.s. I also tried to use array to do the same thing, but it is quite complicated!

    Code:
    $('.items-form a').click(function(){
    
    	var currentValue = $("#inputString").val();
    	var intersect;
    	var tag = $(this).attr('href');
    	var arrA = currentValue.split(' ');
    	var arrB = [tag];
    	
    	for (i in arrA) {
    		for (j in arrB) {
            if (arrA[i] == arrB[j]) intersect = arrA[i];
    		var index = arrA.indexOf(intersect);
    		}
    	}
    
    	if(index >= 0){
    		arrA.splice(index,1);
    		$("#inputString").val(arrA.join(" "));
    		} 
    	else {
    		arrA.push(arrB);
    		$("#inputString").val(arrA.join(" "));
    	}
    		
    	$(this).toggleClass('clicked');
    	return false;
        });
    Now that isn't too bad, is it?
    You can however simplify it to:
    Code:
    $('.items-form a').click(function() {
      var tag = $(this).attr('href');
      var arrA = $("#inputString").val().split(' ');
    
      if((idx = arrA.indexOf(tag)) >= 0) {
        arrA.splice(idx,1);
      } else {
        arrA.push(tag);
      }
      $("#inputString").val( arrA.join(' ').replace(/\s{2,}/,' ').replace(/^\s*/, '') );
    		
      $(this).toggleClass('clicked');
      return false;
    });

  11. #11
    Utopia, Inc. silver trophy
    ScallioXTX's Avatar
    Join Date
    Aug 2008
    Location
    The Netherlands
    Posts
    9,077
    Mentioned
    153 Post(s)
    Tagged
    2 Thread(s)
    Quote Originally Posted by Stomme poes View Post
    * is referring to how many whitespaces: none, one, or many.
    To be more precise, * is "zero or more"

    To be complete:
    ? - zero or one
    * - zero or more
    + - 1 or more

    To top it off you also have:
    *? - zero or more, lazy
    +? - 1 or more, lazy

  12. #12
    SitePoint Wizard Stomme poes's Avatar
    Join Date
    Aug 2007
    Location
    Netherlands
    Posts
    10,278
    Mentioned
    50 Post(s)
    Tagged
    2 Thread(s)
    * is referring to how many whitespaces: none, one, or many.
    Me engrish most bestest na koffie : )

    btw I do love the way you've answered this thread... excellent posts. I don't do jQuery but it's something to keep bookmarked anyway.

  13. #13
    Utopia, Inc. silver trophy
    ScallioXTX's Avatar
    Join Date
    Aug 2008
    Location
    The Netherlands
    Posts
    9,077
    Mentioned
    153 Post(s)
    Tagged
    2 Thread(s)
    Quote Originally Posted by Stomme poes View Post
    btw I do love the way you've answered this thread... excellent posts.
    Thanks

    Off Topic:


    Quote Originally Posted by Stomme poes View Post
    I don't do jQuery ...
    Why not? Makes live soooo much easier
    Or do you use some other framework

  14. #14
    SitePoint Wizard Stomme poes's Avatar
    Join Date
    Aug 2007
    Location
    Netherlands
    Posts
    10,278
    Mentioned
    50 Post(s)
    Tagged
    2 Thread(s)
    Off Topic:

    No I'm a JS beginner and feel I should wait 'til I fully understand JS before using any frameworks.

  15. #15
    SitePoint Evangelist
    Join Date
    Dec 2008
    Location
    Plymouth, United Kingdon
    Posts
    449
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by ScallioXTX View Post
    Now that isn't too bad, is it?
    thank you very much for this thread! really appreciated.

    Code:
    $('.items-form a').click(function() {
      var tag = $(this).attr('href');
      var arrA = $("#inputString").val().split(' ');
    
      if((idx = arrA.indexOf(tag)) >= 0) {
        arrA.splice(idx,1);
      } else {
        arrA.push(tag);
      }
      $("#inputString").val( arrA.join(' ').replace(/\s{2,}/,' ').replace(/^\s*/, '') );
    		
      $(this).toggleClass('clicked');
      return false;
    });
    this is so much better than my version! thank you. I wish my coding brain can be that clever like yours!

  16. #16
    SitePoint Evangelist
    Join Date
    Dec 2008
    Location
    Plymouth, United Kingdon
    Posts
    449
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Stomme poes View Post
    I still can't read JS like this, but I can answer some of these:



    When a function returns, it stops running. If you say "return x;" then it's also returning a value, but if I understand it correctly, if there is no value (just return) then it returns undefined. (notsure?) But anyway, in this case, the point is to stop the function, because something necessary for it to run has been checked for and found not to exist.

    Code:
    return (beforeTag + afterTag).replace(/\s{2,}/,' ').replace(/^\s*/, '');
    replace is a function that takes a regular expression as one of its arguments...
    the first argument of the first replace is inside /'s (/pattern here/)
    \s means "any whitespace" and {2,} means "at least two" (it's {minimum, maximum} and if you don't mention a maximum, then it's infinite).

    So it looks for anywhere where there's 2 or more whitespace characters (which can be spaces, tabs, and I think also newlines?), and replaces them literally with ' ' (one space).

    After that, another replace looks for any whitespace characters who start
    ^ means "the beginning" and is known as an "anchor" character in regexes.
    * is referring to how many whitespaces: none, one, or many.
    Any extra whitespace that ended up in the front of your tags is replaced with '' or nothing (no space between single quotes... looks like a double quote here but that's not what it is).

    http://www.regular-expressions.info/javascript.html The site as a whole is pretty good; I has it bookmarked.
    hi, thank you for explaining this and the link. thanks!


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •