2

I have started using AngularJS with some code that was already written and need to get it to play nice together.

So I have

<html ng-app="MainPage">
<head>
...Some JS includes
</head>
<body>
    <div id="divDropDownMenu" class="DropDownMenu">
      ....AngularJS stuff in here
    </div>
</body>

I'm using this code to append a button at the end of "divDropDownMenu" and when the button is clicked slide the up and down to reveal the menu items.

var divPanel = $("<div class='slide-panel'>");
var divContent = $("<div class='content'>");
(function ($, $scope) {

$.fn.slideBox = function(params){

    var content = $(this).html();
    var defaults = {
        width: "100%",
        height: "500px",
        position: "top"         // Possible values : "top",     "bottom"
    }

    // extending the function
    if(params) $.extend(defaults, params);



    $(divContent).html(content);
    $(divPanel).addClass(defaults.position);
    $(divPanel).css("width", defaults.width);

    // centering the slide panel
    $(divPanel).css("left", (100 - parseInt(defaults.width))/2 + "%");

    // if position is top we're adding 
    if(defaults.position == "top")
        $(divPanel).append($(divContent));

    // adding buttons
    $(divPanel).append("<div class='slide-button'>Open Menu</div>");
    $(divPanel).append("<div style='display: none' id='close-button'     class='slide-button'>Close Menu</div>");

    if(defaults.position == "bottom")
        $(divPanel).append($(divContent));

    //$(this).replaceWith($(divPanel));

    // Buttons action
    $(".slide-button").click(function(){
        if($(this).attr("id") == "close-button")
            $(divContent).animate({height: "0px"}, 1000);
        else
            $(divContent).animate({height: defaults.height}, 1000);

        $(".slide-button").toggle();
    });
};

})(jQuery);
function SlidePanelExpandCollapse(ExpandCollapse)
{
if (ExpandCollapse == "Expand") {
    $(divContent).animate({ height: defaults.height }, 1000);
}
else {
    $(divContent).animate({ height: "0px" }, 1000);
}
$(".slide-button").toggle();

}

The problem is that any angular inside the targeted div does not fire when using the above code.


this is the CSS that goes with the above JS menu slider

/* @override 
http://samuelgarneau.com/slidebox.css
http://samuelgarneau.com/lab/validator/slidebox.css
http://samuelgarneau.com/lab/slidebox.css
http://samuelgarneau.com/lab/slidebox/style/slidebox.css
*/

body {
margin: 0;
padding: 75px 0 0;
}

.slide-panel {
z-index: 9999;
width: 5px;
position:absolute;
}

.bottom {
bottom: 0;
}

.right {
}

.left {
position: absolute;
left: 0;
}

.top {
top: 0;
}

.content {
margin-left: auto;
margin-right: auto;
z-index: 10;
overflow: hidden;
text-align: left;
background-color: #343434;
height: 0;
width: 100%;
color: #fff;
}

.slide-button {
background: none repeat scroll 0 0 gray;
margin-left: auto;
margin-right: auto;
position:relative;
width: 150px;
z-index: 20;
cursor: pointer;
height: 30px;
padding-top: 10px;
text-align: center;
}

.slide-button:hover {
color: #ffffff;
}
Daniel Daranas
  • 22,454
  • 9
  • 63
  • 116
TJunky
  • 49
  • 1
  • 7
  • 1
    What part of your Angular Code does not work? What is it supposed to do? Also, see: http://stackoverflow.com/questions/14994391/how-do-i-think-in-angularjs-if-i-have-a-jquery-background – Wottensprels Oct 15 '13 at 13:51

1 Answers1

3

I don't see any actual use of AngularJS in your example at all. The only thing which reminded me of AngularJS was the mention of $scope in your function definition. Now while AngularJS appears to work magically in some areas this still won't do anything.

Also it might appear tempting to keep existing code and just add some AngularJS parts. However seeing your example I would recommend that you rewrite this functionality using the means of AngularJS. Showing and Hiding stuff can be easily done with ng:hide or ng:show. The animation stuff you do can be done with ng:animate. And if you need to dynamically show data, put it into a model (in your scope) and use that with functions like ng:repeat.

It appears that what you are doing in your example would boil down to only a couple of lines using the AngularJS functionality, so the result would be better and easier to read and maintain. Do yourself a favor and get familiar with what AngularJS can provide you with and stop bothering with direct DOM manipulation. It is a bad pattern. DOM manipulation is pesky, complicated and prone to break. It is also usually an unmaintable mess. And the best: If you are using AngularJS anyway, it is complete superflous because everything can be achieved much easier by having a model triggering conditional logic in your HTML.

Some impressive fact from the talk of the AngularJS creator at Google I/O 2013: He used AngularJS in its beginning to rewrite a internal project of Google. The result was that 14000 lines of code were reduced to 1500.

I recognize that this does not really count as an answer to your problem but I really believe that you would be better off stopping this approach right here and now and instead of wasting time to get this working rewrite it in AngularJS. This seriously should not take longer than half an hour even if you have to read up all the details still.

Edit/Addendum: The talk I mentioned is "Google I/O 2013 - Design Decisions in AngularJS" at http://www.youtube.com/watch?v=HCR7i5F5L8c I highly recommend watching this video even to people who have already experience with AngularJS. It gives good insight to the AngularJS way and its points come handy when trying to convince someone else in trying AngularJS :)

Edit/Addendum2: As Sprottenwels helpfully mentioned above, there is another question here on stackoverflow which gives a much more thorough explanation of what I boiled down above, so please give it a read: "Thinking in AngularJS" if I have a jQuery background?

Edit/Addendum3: As again Sprottenwels helpfully mentioned: The videos at http://www.egghead.io/lessons are a great resource. I personally found them sometime a little hard to understand (you might need to stop the video and read up in the documentation of AngularJS which thankfully is nowadays much better than it used to be).

Oh and on a personal note: While I did web development since about 1997, I was never a friend of doing application like stuff in JavaScript because all those frameworks are so complicated with lots of boilerplate and you are doing stuff which feels like a waste of time. AngularJS really did wonders to my motivation doing such stuff because it finally is totally logical and its magically like inner workings totally freed me from doing stuff I hated like synchronisation of data and view.

I am totally thankful to the AngularJS people and I absolutely believe that this is the only real future of doing web application programming. Right now AngularJS can be a problem performance-wise because of doing "bad" stuff like dirty-checking but this is going to change with new browser features like Object.observe. So I really think that choosing to use AngularJS to its full extent is a wise and future-safe move.

Community
  • 1
  • 1
Juliane Holzt
  • 2,135
  • 15
  • 14
  • Full ACK I found it easy to strictly remove all jQuery code of my project, then do everything with Angular. Once you are familiar with the framework, you can still add jQuery again, if you still need it – Wottensprels Oct 15 '13 at 13:53
  • This expertly answers the actual problem. – Mike Robinson Oct 15 '13 at 13:55
  • Thanks...I didn't include all the Angular code, I don't think it really mattered for the question since when I include the Jquery Angular doesn't work and when I don't include it Angular does work. I started to go down the road of rewriting and wondered if there was just an easy way to pass the $scope around. I think you're right though, in the long run I'll be better off just rewriting it. Thanks. I with there were some better examples out there of how to do stuff like this. – TJunky Oct 15 '13 at 14:05
  • 1
    @TJunky I greatly recommend www.egghead.io/lessons as a learning resource :) – Wottensprels Oct 15 '13 at 14:07
  • Well, it really is not that hard. Identify what the jQuery-Code is actually doing/intending and then look how you can do that in AngularJS. For example showing/hiding stuff would boil down to binding something like ``$scope.flag`` to ``ng:view`` and then just setting $scope.flag to true when you want to show the content. Setting a class in jQuery? Use ``ng:class`` with another scope variable. Animations? Comes basically free (in Angular 1.2 that is), you might need to only set some CSS. XHR? Use $http or Restangular. Again: Bind it to a scope variable. Use that in your HTML. – Juliane Holzt Oct 15 '13 at 14:10