Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Jquery wrap an wrapall not working together correctly 1

Status
Not open for further replies.

tshad

Programmer
Jul 15, 2004
386
US
I am trying to wrap an input statement with a div and then wrap both of those with another div.

I am than trying to add some span code after the input.

All of this works fine separately but not together.

Code:
<!DOCTYPE html>
<html xmlns="[URL unfurl="true"]http://www.w3.org/1999/xhtml">[/URL]
<head>
    <title></title>
    <script src="Scripts/jquery-1.11.0.min.js" type="text/javascript"></script>
    <script src="Scripts/jquery-ui-1.11.2.js" type="text/javascript"></script>
    <script type="text/javascript">
    var PopupOn = "";

    $(document).ready(function () {
        $("input[name*='UserName']").wrap("<div class='input-group usergroup1'/>");
        //$("input[name*='UserName'], .usergroup1").wrapAll("<div class='form-group'/>");
        //$("input[name*='UserName']").after("<span class='input-group-addon'><i class='glyphicon glyphicon-user'></i></span>");
    })
    </script>
</head>
<body>
    <input class="form-control input-sm" id="UserName" name="UserName" type="text" value="" />
</body>
</html>

If I run this as written with the wrapAll and Span code commented out, the first div wraps the input statement correctly.

If I uncomment the 2nd line (wrapAll), the first line doesn't wrap the right way. It doesn't wrap the input statement. but the wrapAll statement did wrap both correctly.

I end up with the following:

Code:
...
<div class='form-group'>
   <div class='input-group usergroup1'><div>
   <input...></input>
</div>
...

instead of:


Code:
...
<div class='form-group'>
   <div class='input-group usergroup1'>
      <input...></input>
   <div>
</div>
...

Where the inner div doesn't wrap at all. If I uncomment the span, the span does work correctly but the 1st wrap is still wrong.

Why is that? And how do I get this to work.

I am working with a product that creates a bunch of html around my textbox so I need to use jquery to add in the extra code.

Thanks,

Tom
 
off the top of my head

Code:
$('input[name="UserName"]').wrapAll($('<div/>').addClass('form-group')).wrap($('<p>').addClass('input-group').addClass('userGroup1'));
 
Not quite sure what you are doing here.

I need to have an input element inside of a div and that div inside of another div.

Thanks,

Tom
 
It worked fine.

Then I used it to finish off my sample and was able to get it down to one statement.

I started out with the following (changing your <p> to a <div>):

Code:
$('input[name="UserName"]').wrapAll($('<div/>').addClass('form-group')).wrap($('<div>').addClass('input-group').addClass('userGroup1'));

Then I changed it to:

Code:
$('input[name="UserName"]').wrapAll($('<div class="form-group">')).wrap($('<div class="input-group">'));

I didn't need the UserGroup1 anymore as that was so I could do the wrapAll.

I then changed the wrapAll to just wrap as I didn't need it now.

I then finally changed it to:

Code:
$('input[name="UserName"]').wrap($('<div class="form-group">')).wrap($('<div class="input-group">')).after("<span class='input-group-addon'><i class='glyphicon glyphicon-user'></i></span>");

I added in the span element (which put the glyphicon after the input statement).

Not sure why that worked I would have thought it would put it outside of the two wraps, which it does if you put the span element before the wraps, like so:

Code:
$('input[name="UserName"]').after("<span class='input-group-addon'><i class='glyphicon glyphicon-user'></i></span>").wrap($('<div class="form-group">')).wrap($('<div class="input-group">'));

Not sure why.

It seems to go back to the selector for each ".wrap" or ".after" instead of applying it to the previous result.

I also found that if I took my original example and flipped the order of the wraps, it worked fine and I could then change the .wrapAll to .wrap.

Not sure why the original order caused the 1st wrap to not wrap.

Thanks,

Tom




 
because you are chaining off the first selector. you could write your statement like this to make the chaining more obvious.

Code:
$('input[name="UserName"]')
    .wrap($('<div class="form-group">'))
    .wrap($('<div class="input-group">'))
    .after("<span class='input-group-addon'><i class='glyphicon glyphicon-user'></i></span>");

so each command relates to the first selector (with an implicit .each) and not to the result of each preceding command.

note that your code will wrap EACH input (with a name of UserName) with the form-group; whereas you suggested before that you wanted all inputs to be wrapped with a single div.form-group and EACH to be wrapped with a div.input-group. that is the difference between wrapAll and wrap

stylistically I prefer the addClass method to specifying the class (and arbitrary attributes) in the constructor. This is mainly for readability. If you do it my waay then you need to use brackets sensitively to ensure that you are chaining off the right selector

Code:
$('input[name="UserName"]')
    .wrap( $('<div/>').addClass("form-group") )           //relates to the input selector
    .wrap(                                                 // relates to the input selector
           $('<div/>')
               .addClass("input-group")                    //relates to the new div element
               .append(                                    //relates to the new div element
                   $("<span/>")
                       .addClass('input-group-addon')      //relates to the new span element
                       .append(                            //relates to the new span element
                           $('<i/>')
                              .addClass('glyphicon')       // relates to the new i element
                              .addClass('glyphicon-user')  //relates to the new i element
                      )));

[/code]
 
Makes sense.

Suppose I wanted to chain off the preceding result. Could this be done?

Thanks,

Tom
 
yes; depending where you are in the chain you can alter the bracketing. the second code snip in my last post shows how you chain off intermediate selectors.

if you can be more specific then an example can be given.

 
Ok.

A good example would be part of the initial question, which was why the .wrapAll didn't work correctly. Why the 1st jquery (.wrap) worked fine if that was all you did, it worked fine. But when you added the .wrapAll, it changed the result of the first wrap.

Let us suppose I wanted to do the above, starting with:

Code:
<!DOCTYPE html>
<html xmlns="[URL unfurl="true"]http://www.w3.org/1999/xhtml">[/URL]
<head>
    <title></title>
    <script src="Scripts/jquery-1.11.0.min.js" type="text/javascript"></script>
    <script src="Scripts/jquery-ui-1.11.2.js" type="text/javascript"></script>
    <script type="text/javascript">
    var PopupOn = "";

    $(document).ready(function () {
        $("input[name*='UserName']").wrap("<div class='input-group usergroup1'/>");
        $("input[name*='UserName'], .usergroup1").wrapAll("<div class='form-group'/>");
        $("input[name*='UserName']").after("<span class='input-group-addon'><i class='glyphicon glyphicon-user'></i></span>");
    })
    </script>
</head>
<body>
    <input class="form-control input-sm" id="UserName" name="UserName" type="text" value="" />
</body>
</html>

First why does this not work.

But then change the jquery to do the following:

Code:
        $("input[name*='UserName']").after("<span class='input-group-addon'><i class='glyphicon glyphicon-user'></i></span>");
        $("input[name*='UserName']").wrap("<div class='input-group usergroup1'/>");
        $("input[name*='UserName'], .usergroup1").wrapAll("<div class='form-group'/>");

So that the span is added first, then the input group is added after that so that it surrounds those two and then the form-group is added last and surrounds all three elements.

I know the way you had which actually keeps pushing the elements out from the input statement works fine.

But I would like to see how you would do the wrapping in one statement that uses the previous result. Mainly, I am trying to understand the two ways.

Thanks,

Tom
 
because of the wrapAll line being second.

it only works the way you want if there are no intervening child nodes within the set of matched elements. ie. that they are all siblings. this is clear in the manual.

because the first line puts divs around each element, they are no longer direct siblings but children of siblings.

solutions:
1. change the wrapAll to be first
2. change the wrapAll to refer to the outer divs
Code:
$('.input-group').wrapAll($('<div class="form-group"/>'));

 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top