AngularJS - Dynamically change class and load JSON - two things, really - html

I'm facing an issue (or probably two) that is frustrating the swearwords out of me; keep in mind, I'm a fairly beginner coder, so there's a good chance I'm missing something obvious.
One: I've got a page that has a sidebar that is hidden via a class containing margin-left: -90%. When the class is removed, the bar slides in to fill the whole screen. I can handle this really easily with jQuery, but I'd rather stick as much as possible in Angular - to this end, I've given it the following code:
<div id="detail_box" ng-class="{d_hide: dVis}">
<div tw-detail></div>
</div>
Which, as you can see, has a class that refers to a variable in a controller, and a link that has an ng-click connected to a function. The controller in question is stupidly simple, and relies on $rootScope variables. I'm only using rootScope because in total, over my whole page, I have two variables that will need to change dynamically, but be the same, for every controller and directive I've made. The connecting scope and controller are here:
app.run(function($rootScope) {
$rootScope.currentUrl = 'visual/design/1/';
$rootScope.detail_hide = true;
});
app.controller('navController', ['$scope', '$rootScope',
function ($scope, $rootScope) {
$scope.dVis = $rootScope.detail_hide;
$scope.hide = function(){
$rootScope.detail_hide = false;
}
}]);
Now, I've used console.log from my ng-click to see that it is picking up clicks, and I've used console.log to make sure that the detail_hide part of rootScope is changing. If I change true to false by hand in my app.js, the detail page hides itself just fine... but that ng-click doesn't actually do what I'm trying when I test it on the page. It's painful and I can't understand why changing the variable via a function (which I know changes the actual variable in rootScope, thanks to extensive testing) isn't telling my detail box to just go away.
Secondly, and it's connected to the first; dynamically changing the currentUrl in rootScope similarly doesn't change the actual AJAX content I've got stuck inside my twDetail directive, even though, again, the ng-click functions I've written do change the variable. Changing it manually works fine (although images in the second URL aren't loading but that's probably an entirely different problem) but just... what the heck am I doing wrong here?

The following code is only being run once, when the controller is being setup
$scope.dVis = $rootScope.detail_hide
Make sure you change the $scope.dVis in the hide function, like this
$scope.hide = function(){
$rootScope.detail_hide = false;
$scope.dVis = $rootScope.detail_hide;
}
I need more info on the twDetail directive to be able to solve that problem

Related

Basic DOJO 1.8: How to get a reference to a method?

I'm am pretty new to DOJO 1.8 and would like to know how I can call a function from outside a require-method? I try to implement a message-box which fades in and out.
I created the method:
require(["dojo/dom", "dojo/on", "dojo/domReady!" ], function(dom, on, ready) {
/*function which shows a msg-box on top of the page */
var showMsg = function(text) {
dom.byId("msgbox").innerHTML = text;
}
});
OK! IT works....but I no I would like to call it from somewhere else in my application:
showMsg("Item saved");
But that doesn't work: Uncaught ReferenceError: showMsg is not defined
How do I get that reference?
Thank you for your help!
AFX
As things stand you're declaring a local variable and so it's not visible elsewhere in the program.
You could make the variable global, for example
window.showMsg = function(text) {
dom.byId("msgbox").innerHTML = text;
}
The downside of this approach is that as you application gets bigger you end up with more and more global variables and that makes maintenance harder.
So Dojo offers ways to package chunks of reusable code and refer to them. You are already exploiting some of those capabilities when you use "require" - you're getting access to chunks of dojo. You can make your own code visible as reusable chunks in the same way.
This is quite a big topic, but you could start by reading this
Another thing you can do is to move the require inside the function.
Even if you have many such functions, while it's annoying to repeat, there is essentially no runtime penalty for requiring over and over. The only thing to watch for is that code inside the function becomes asynchronous, so instead of returning a value you have to use a callback or promise.
Alternatively, if you're only using this function from within some event handlers (I see dojo/on), you can set them up within the scope of this same require block.

create a link that opens a page and runs a function contained in the link

I am still learning PHP so my question may seem a little obvious but...
My question relates to opencart but is probably quite a common practice on many websites. I am creating a opencart module and in that module i have several buttons that complete different tasks. Now I have assigned the button the correct 'href' with the path and appropriate action. eg
$this->data['dosomething'] = $this->url->link('module/modulename/dosomething', 'token=' . $this->session->data['token'], 'SSL');
Note: I have called the module and action a general name for the purposes of my question.
In the controller I then have a private function called 'index', followed by a private function called 'dosomething' like below
public function index() {
* insert code *
}
public function dosomething() {
*insert code*
$this->redirect($this->url->link('module/modulename', 'token=' . $this->session->data['token'], 'SSL'));
}
Now, I would like to know how do I get the button to direct to the module controller and then run the 'dosomething' function. I could put something information in the link, ie action=dosomething and do it this way but most of opencart simply uses the text of the last / as the action. If I use the href stated above I get a error as it is trying to find the controller and template located in 'module/modulename/dosomething' rather than the controller and template located in 'module/modulename' USING the function 'dosomething'.
I hope this makes sense. I see that many other scripts in opencart successfully use this method but I just cant figure out how? I am sure I missing something obvious.
What you are doing is correct. OpenCart's framework will use the third piece of the route if specified as the method. If you try
public function dosomething() {
die('OK');
}
Then go to the url you've got, it should just show a blank white page with OK written on it. My guess is the error doesn't actually relate to the controller being an issue, and more to do with something else you've done. Either that, or the method and the third part of the route aren't a match, or the dosomething method isn't public

Why is e.parameter.source undefined?

I am trying to find out where a callback function came from, but e.parameter.source has been undefined.
The code I'me using to create the callback event is:
var temp_handler = app.createServerHandler("do_things");
container.add(app.createButton(s_list[i][2]).setId("goto_"+s_list[i][1]).addClickHandler(temp_handler));
container.add(app.createLabel("goto_"+s_list[i][1]));
where container is later added to the app.
The first part of the function that gets called is:
function do_things (e)
{
var app = UiApp.getActiveApplication();
Logger.log(e.parameter);
var src = e.parameter.source;
From this, I have been able to tell that e.parameter is:
{clientY=61, clientX=38, button=1, alt=false, eventType=click, screenY=278, ctrl=false, screenX=493, y=11, shift=false, meta=false, x=34}
This does not include source. I find this peculiar because as far as I can tell, other callback functions in the same file have been able to access and use e.parameter.source without issue.
Does anyone know what I am doing wrong in this callback such that the source parameter is inaccessible?
The other answers do not make much sense to me.
First, because the source parameter is filled by the element id that generated the event, not its name.
Also it's filled automatically, there's no need to addCallbackElement, which is required for accessing widgets contents by their name. And last, set a name for a label is only useful when you're setting a tag on it, as there's no "content" for a label.
All that said, the only problem I can imagine is if you're setting the same id on another widget and it's messing with your original one (the button). But I haven't tested that to be sure.
You simply forgot to give a name to your Label widget. The value returned by the e.parameter is assigned to a widget by its name.
The ID is used to access the widget from outside the UiApp creation function when you need to modify it.
In addition to what Serge answered, you might want to supply a callback element on the handler using
ServerHandler.addCallbackElement()

How to extend a native mootools method

Is it possible to extend the addEvent function in mootools to do something and also calls the normal addEvent method? Or if someone has a better way to do what I need I'm all years.
I have different 'click' handlers depending on which page I'm on the site. Also, there might be more than one on each page. I want to have every click on the page execute a piece of code, besides doing whatever that click listener will do. Adding that two lines on each of the handlers, would be a PITA to say the least, so I thought about overriding the addEvent that every time I add a 'click' listener it will create a new function executing the code and then calling the function.
Any idea how I could do it?
Whereas this is not impossible, it's a questionable practice--changing mootools internal apis. Unless you are well versed with mootools and follow dev direction on github and know your change won't break future compatibility, I would recommend against it.
The way I see it, you have two routes:
make a new Element method via implement that does your logic. eg: Element.addMyEvent that does your thing, then calls the normal element.addEvent after. this is preferable and has no real adverse effects (see above)
change the prototype directly. means you don't get to refactor any code and it will just work. this can mean others that get to work with your code will have difficulties following it as well as difficulties tracing/troubleshooting- think, somebody who knows mootools and the standard addEvent behaviour won't even think to check the prototypes if they get problems.
mootools 2.0 coming will likely INVALIDATE method 2 above if mootools moves away from Element.prototype modification in favour of a wrapper (for compatibility with other frameworks). Go back to method 1 :)
I think solution 1 is better and obvious.
as for 2: http://jsfiddle.net/dimitar/aTukP/
(function() {
// setup a proxy via the Element prototype.
var oldProto = Element.prototype.addEvent;
// you really need [Element, Document, Window] but this is fine.
Element.prototype.addEvent = function(type, fn, internal){
console.log("added " + type, this); // add new logic here. 'this' == element.
oldProto.apply(this, arguments);
};
})();
document.id("foo").addEvent("click", function(e) {
e.stop();
console.log("clicked");
console.log(e);
});
it is that simple. keep in mind Element.events also should go to document and window. also, this won't change the Events class mixin, for that you need to refactor Events.addEvent instead.

Losing my mind from jquery validate and knockout

I have been trying to do this for months, and months, and months, and
months. And I am literally at the point of tears from trying to get Knockout to work for me.
I have posts dating back way last year trying to do this. I
just simply cannot get validation to work with knockout and asp.net
mvc.
If I put the $.validator.unobtrusive.parse("#__frmAspect"); line in, I
get the validation, but then it does not obey the submit handler. If I
take that out, it obeys the submit handler, but it does not get any
validation.
This is my code - all of it. (I think)
Main View
http://pastie.org/2016031
Editor View
http://pastie.org/2016043
View Model
http://pastie.org/2016045
Controller and Model Binder
http://pastie.org/2016052
Html Output
http://pastie.org/2016100
HtmlTags class
http://pastie.org/2016107
Helpers
http://pastie.org/2016111
I have been stuck on this for literally going on 8 months. Can anyone
please help me? All I want is to submit the data back to the server. I
don't want ajax, I don't want a callback. I don't want anything fancy.
I just want to send my JSON model back to the server after proper
client validation, and have it get the data. That is all I want. I do
not want to use the $.ajax method. I have reasons for why I want to do
it this way, and they are not relevant to the question.
Response to RP Niemeyer
Yes, that worked!!!!!!!! oh my god. I owe you like ,the last 8 months
of my life. I want to send you a cheesecake smothered in raw calories
of taste and internets.
I feel like I could punch the screen from how frustrated this problem
made me. I'm sorry if the question sounded rude, but no where on the
internet have I seen this kind of thing. I'm sure any other developer
can understand the frustration of a problem that just does not seem to
have an answer.
I have no idea how you came to this conclusion and I don't understand
exactly why it worked.
I tried the same thing with an object-instanced view model (where the
view model was not its own object, but an instance of another object)
and it didn't work. In other words, if I do ..
var aspect = function () {
this.Id = ko.observable();
// other variables, using ';' and 'this' keyword
this.Save = function() {
alert('We got to the save function');
}
}
var viewModel = new aspect();
ko.applyBindings(viewModel, $("#__frmAspect")[0]);
// attach the jquery unobtrusive validator
$.validator.unobtrusive.parse("#__frmAspect");
// bind the submit handler to unobtrusive validation.
$("#__frmAspect").data("validator").settings.submitHandler =
viewModel.Save;
This approach did not work.
Can I bother you to explain to me what is different, and why? I am
completely lost.
I think that the issue is that the unobtrusive library will have already setup validation on the form, so you would actually need to go in and set the submitHandler like:
// attach the jquery unobtrusive validator
$.validator.unobtrusive.parse("#__frmAspect");
// bind the submit handler to unobtrusive validation.
$("#__frmAspect").data("validator").settings.submitHandler = viewModel.Save;
http://jsfiddle.net/rniemeyer/V8MhG/