im using angularjs with select2 for application dropdowns, but i cannot figure how to get the change event or some other, inside my Controller.
is there some way to declare the eventhandler function via attribute?,
like ui-select2 data-on-somethinghappened="fnx"?
or instead on my configuration? like:
appXpto.value('ui.config', {
select2: {
placeholder: 'Please select a value..',
onsomethinghappened:function(e){ ... }
}
});
thanks in advance
yes, you can bind controller functions to directive scope object and call them when a select2 event happens on the directive. Use & to bind the function. then call scope.myBoundFunction() to call that function with or without parameters.
Related
I have a section of my view (html) that is generated programmatically by a viewmodel/class. This uses the Aurelia DOM (Aurelia Docs - pal :: Dom) functionality to generate and add the raw HTML elements to the view.
However, I am unable to get events within the generated html to call back to the viewmodel. An example:
let deleteButton = this.dom.createElement("button");
deleteButton.setAttribute("onclick", "cancelCreditNote(`${ row.creditNoteId }`)");
A click on the generated button won't call back to the viewmodel, which does have a cancelCreditNote function. Various other things like deleteButton.setAttribute("click.delegate", "cancelCreditNote('${ row.creditNoteId }')"); do not work either.
Does anyone know how to access a viewmodel class from essentiall 'raw' html in aurelia?
Unfortunately in this instance I cannot use the standard aurelia templating to generate the HTML.
The DOM property on PAL is just an abstraction for the browser's DOM object, create element is likely just calling document.createElement which doesn't afford any Aurelia binding to the created element.
You could try using aurelia.enhance(context, element) which takes an existing DOM element and runs it through the templating engine.
With this method you can also pass a binding context to apply to the element.
In my HTML I use this:
<div id="collapsesidebar" click.delegate="toggleSidebar()">
In my view-model I have this method:
toggleSidebar(){
alert('hi');
}
You could also do this from your view-model with JQuery like this:
attached() {
$('main').on('click', ()=> alert('hi'));
}
The last option is ONLY available áfter the attached() method is triggered: before that the binding needs to do its job and only after that the elements are located inside of the dom.
In other words: this will not work:
activate(){
$('main').on('click', ()=> alert('hi'));
}
because the constructor and the activate method both get fired before the attached method.
Just wondering if anyone knows a good/simple approach using Durandal to disposing of or re-initializing a viewmodel once it becomes invalid?
I have a registration form that I could 're-initialize' manually after a user has completed the form and registered successfully, but I'd prefer to just dispose of it so that Durandal creates a new registraion view/view model when that particular route is accessed again.
If your viewmodel module returns a function rather than an object, it will create a new one each time rather than reusing the 'singleton' object. See the Module Values section of Creating a Module.
Updated link for the Durandal Module constructor function information: Module Values
You can split the difference:
var cache;
var ctor = function () {
if (cache) return cache;
// init logic
cache = this;
}
Just replace the if(cache) check with whatever "do I need a new thing or not" logic you like.
If you're using routing, simply redirect the user to an instance-based module (one that returns a constructor function). The user will most likely click or touch a button that signifies that he is done with the registration form. That would be the redirect action.
If you're using composition, you would still create an instance-based module. Then, you would use dynamic composition to swap it in once the user signified he was done with the registration form.
Dynamic composition is where the view and/or model attributes on a Durandal composition are, themselves, observables, referencing something like the following in the viewModel:
this.currentView = ko.observable('');
this.currentModel = ko.observable('');
Then, in your HTML:
<div>
<div data-bind="compose: {view: currentView(), model: currentModel())"></div>
</div>
When the user clicks "Done", or something to that effect, functions on your viewModel might look something like:
ctor.prototype.done = function () {
this.setCurrentView('viewmodels/registrationForm.html');
this.setCurrentModel('viewmodels/registrationForm.js');
}
ctor.prototype.setCurrentView = function (view) {
this.currentView(view);
}
ctor.prototype.setCurrentModel = function (model) {
this.currentModel(model);
}
Either one of the approaches above will create the registrationForm only when it's needed.
With Durandal 2.0, you can use the deactivate callback within the composition lifecycle. Here is some documentation http://durandaljs.com/documentation/Hooking-Lifecycle-Callbacks
I have a form working with CSS selector binding and Scala-side validation. Now I want to add javascript validation either via my own jQuery code that I call or else the built-in commands like JsIf.
Here is my current code:
def create = {
"#description" #> SHtml.textarea(maintRV.is.description.get,
name => maintRV.is.description(name) ) &
"#submit" #> SHtml.onSubmitUnit(processSubmit)
}
How can I add onclick or onsubmit behavior to the SHtml.onSubmitUnit binding? I have already used Ajax forms in other parts of my code, but for this page that seems like overkill. I don't mind a regular form submit. I just want to add client-side validation.
I've combed SimplyLift, Exploring Lift and the groups and can't find it.
To allow to make validation of form before submit,
I want to make a simple HTTP POST submit from the Submit method i defined.
Code of the view :
<form data-bind="submit: BaseSubmit" id="FormId">
<!-- Some rows ... -->
<button type="submit">Create</button>
</form>
And of the JS behavior
this.viewModel.BaseSubmit =
function(formElements) {
//Here the code to make the submit redirection
};
Is this possible ?
Thanks by advance.
Upon successful validation, make sure and return true from your binding handler:
this.viewModel.BaseSubmit =
function(formElements) {
if (/* validation is successful */) {
return true;
} else {
/* handle validation errors */
}
};
Example: http://jsfiddle.net/CCNtR/22/
From the documentation:
By default, Knockout will prevent the event from taking any default action. For example if you use the event binding to capture the keypress event of an input tag, the browser will only call your handler function and will not add the value of the key to the input element’s value. A more common example is using the click binding, which internally uses this binding, where your handler function will be called, but the browser will not navigate to the link’s href. This is a useful default because when you use the click binding, it’s normally because you’re using the link as part of a UI that manipulates your view model, not as a regular hyperlink to another web page.
However, if you do want to let the default action proceed, just return true from your event handler function
I've seen heaps of questions about this, and all of them seem to be solved by either calling $scope.$apply(), $scope.$digest(), or by triggering the change() method on the input. But I can't seem to get it working with any of those methods. In this fiddle, I can type a name into the box and get the model value to update as I type. But when I click the link, to set the input name to a certain value, I want the model name to update. What do I need to do?
The reason I'm trying to do this is I want to be able to refresh my angular model when a user autofills the form, using the browser autofill or LastPass or similar. Surely there's some angular command to refresh the model from the DOM?
http://jsfiddle.net/PXCUq/
$(function () {
$('#setFirstName').click(function () {
$('input.firstname').val('Test Name');
angular.element($('input.firstname')[0]).scope().$apply();
// Model still not updated
});
});
Get the scope, then change the ng-model property:
$('#setFirstName').click(function() {
var scope = angular.element($('input').get(0)).scope()
scope.firstname = 'Test Name';
scope.$apply();
});
You can come up with a better jQuery selector. I was only focusing on the Angular part.
Fiddle.