AngularJS - Ng-repeat - Select2 JS - Issue setting default value - angularjs-select2

Having trouble in setting up the default value for the drop down when AngularJS/ng-repeat/custom directive + Select2 JS is used.
1. I avoided using ng-options as the directive priority is 0.
2. I tried setting the priority for the custom directive 'select2Directive' to a number less than 1000, but still no luck.
Plunker # http://plnkr.co/edit/Csy5FqDSQbErTm2fNPac. Appreciate any help. Thanks.

I noticed that you are calling the select2 using a small directive, but I found this library named angular-select2 which is easy to implement as well.
you can set the default values with your ng-model/$scope, take a lookt to this plunker to get the idea
http://plnkr.co/edit/pFkY5f?p=preview
EDIT:
I'd rather try to pass the data in other way seems like the select2 data and your the ng-repeat are not in sync
you could try a different approach something like creating a directive and insert the data from there.
directive('select2Dynamic', function ($timeout) {
return {
restrict: 'A',
priority: 1,
scope: {
ngModel: "="
},
require: 'ngModel',
link: function (scope, element, attr) {
var select2Inst = element.select2();
select2Inst.select2({data:scope.$parent.$eval(attr.ngModel)});
select2Inst.select2('val',attr['select2Dynamic']);
}
}
});
<select select2-dynamic='2' ng-model='addresses' id="address" name="address" style="width:200px;" >
</select>
if you want to stick to your approach you'll consider to set up the value and the end of the "model binding event"
look at this plunker
anyway I still stand my point that you should try angular-select2 library
hope that helps

Related

Twig function/filter with no input?

I'm using Slim 3 and Slim Twig-View. I want to add a Twig function (or filter, not sure what is the difference?) which generates a random string, and doesn't take any input.
I was able to add a filter like this:
$twig->getEnvironment()->addFilter(
new \Twig_Filter('guid', function(){ return generateGUID(); })
);
But I can't seem to use it without providing some dummy input:
{{ 0|guid }} This will work
{{ guid }} This will not work
How can I use my guid filter/function without providing any input?
A filter always apply on something, it filters something.
What you want is a function, indeed.
The extending Twig page of the documentation is an incredible source of information on that matter.
At first glance, I would even have said you should define a tag for this but the documentation on the tag, explicitly says:
If your tag generates some output, use a function instead.
Source: https://twig.symfony.com/doc/3.x/advanced.html#tags
So indeed, in order to define a function:
Functions are defined in the exact same way as filters, but you need to create an instance of \Twig\TwigFunction:
$twig = new \Twig\Environment($loader);
$function = new \Twig\Twig_Function('function_name', function () {
// ...
});
$twig->addFunction($function);
So more specifically for you:
$container->get('view')->getEnvironment()->addFunction(
new Twig_SimpleFunction('guid', function(){ return generateGUID(); })
);
Will be accessible via:
{{ guid() }}
Other worth reading:
extending twig, in Slim documentation
you can achieve the same with a macro

Rendering one of multiple pages with lit-element

The lit-element documentation describes conditional rendering via (condition ? a : b). I was wondering how to use that to render one of multiple pages, f.e. in combination with mwc-tab-bar from Googles material web components.
My current solution is something like this:
render() {
... other stuff ...
${this.selectedPage === 0 ? html`
<div>
...
</div>
` : html``}
${this.selectedPage === 1 ? html`
<div>
...
</div>
` : html``}
... further pages ...
}
I don't like the :html`` part but is that how it's meant to be?
Use more simple code like this.
constructor(){
super();
// don't forget add `prop` and `selectedPage` to `static get properties()`
this.prop = 1;
}
render() {
return this.getPage(this.selectedPage);
}
getPage(num){
switch(num){
default:
case 1:
return html`<div>P${this.prop}<div>`;
case 2:
return html`<div>P2<div>`;
}
}
There are multiple ways of achieving this, your solution is one, but as you mention, it's not the prettiest
One way you could modularize this somewhat is using an object/array and render functions, basically the idea is this:
First, define render functions for each page (this can be on the same file or on different files):
const page0Renderer = (context) => {
return html`<section>${context.someData}</section>`;
};
Then, you could define an object that has a match between the page identifiers and their respective functions, you are using numbers so the sample below uses numbers:
const pageRenderers = {
'0': page0Renderer,
'1': page1Renderer,
'2': page2Renderer,
// etc
};
And in your main render function you could use all these like this:
render() {
return html`
${pageRenderers[`${this.selectedPage}`](this)}
`;
}
This would basically call the render function that matches the selected page and send it a reference to the main web component so that you can access its properties.
Then again, this approach also has its flaws and I wouldn't really recommend it much if you need your child templates to be complex.
In that case, instead of rendering functions you probably would be better off creating other components for each view and that way you could also do some lazy loading and so on.
For that kind of approach, you might want to check out routers like vaadin router which help you both with routing and changing which component gets displayed accordingly

Vue Lifecycle: Object is undefined when binding attributes

I seem to be having an issue with the vue lifecycle - the global objects that I'm retrieving data in the DOM using something like {{ family.plusOne }} is defined.
When I'm using it as an attribute such as :checked="family.plusOne" //expecting true as value, it's undefined.
I tried running the :check="callFunction()" and logging it to console.
I get two calls, one saying
family.plusOne is undefined
and another log to console saying
family.plusOne being true
which is the value I expected.
<label class="mdl-switch mdl-js-switch mdl-js-ripple-effect" for="switch">
<input type="checkbox" id="switch" #change="setPlusOne($event.target.checked)" class="mdl-switch__input" :checked="(family.plusOne == 1)"/>
<span class="mdl-switch__label" >{{family.plusOne == 1}}</span>
</label>
The {{family.plus ==1 }} within the span displays true but the :checked="(family.plusOne ==1)" is false
First, if you are passing just family.plusOne, what is the result in the child?, undefined?
Secondly, may you can use a computed property like
:checked="computedFamilyPlusOne"
computed: {
computedFamilyPlusOne: {
if(this.family.plusOne == 1){
return true
}else {
return false
}
}
}
My guess is that your family object does not exist as part of the default data binding in the data() {} method that is usually on a Vue.js component. That would mean that before the component is mounted, Vue doesn't know the value when it compiles the template, so it appears as though the value is undefined. Then, at some point, you are probably updating ONLY that property of the family object. This means that the reactive-state of the object has never changed, so Vue.js doesn't know that it needs to recompute the template (reactive "gotcha").
To verify that I am correct, make sure that you use the Vue.set() method, or re-bind a new object with the updated property value for the family object.
I played around with the lifecycle phases
created() {
this.populatePeople();
},
updated() {
componentHandler.upgradeDom();
},
This allowed me to update the data before the DOM was loaded and following some solutions, I call componentHandler.upgradeDom() to show the switches and radio buttons correctly.

Changing anyMatch default for Filter.JS in ExtJS for MultiSelect search

I have a multiselect bound to a store in which I implemented use of anyMatch: true to allow for True to allow any match - no regex start/end line anchors will be added (as per the comment in Filter.js). My problem is that I need to implement this as per the answer to multiselect-search-whole-string, in particular the solution provided in this fiddle https://fiddle.sencha.com/#fiddle/jf5
What I want to do is just set anyMatch: true, regardless, so I set it in Filter.js, but this has no effect on use of it. I searched the entire codebase for other instances of anyMatch: false and the only other one is in ext-all-debug.js. Why isn't setting these values having any effect? I don't see where else this default value could be set?
EDIT 1
I tried a different override, and while it is not exhibiting the right behavior, it is actually doing something this time. I figured that since the chunk of code that does work when embedded in the search attribute within the MultiSelector control was pretty much what was found in the MultiSelectorSearch's search method, that this was what I needed to focus on for the override. Any suggestions on tweaking this would be most welcome:
Ext.define('Ext.overrides.view.MultiSelectorSearch', {
override: 'Ext.view.MultiSelectorSearch',
search: function (text, me) {
var filter = me.searchFilter,
filters = me.getSearchStore().getFilters();
if (text) {
filters.beginUpdate();
if (filter) {
filter.setValue(text);
} else {
me.searchFilter = filter = new Ext.util.Filter({
id: 'search',
property: me.field,
value: text,
anyMatch: true
});
}
filters.add(filter);
filters.endUpdate();
} else if (filter) {
filters.remove(filter);
}
}
});
EDIT 2
Got it! The key was that originally, since this code was embedded in a singleton, I could reference the method by passing me from the calling form.panel. This did not work globally as an override, and required me to define the method as
search: function (text) {
var me = this,
I hope this helps someone out there!
Changing in ext-all-debug.js is not safe, when you do a production build this file will not get included.
Best way is to override the Filter class, here is how you can do it.
Ext.define('Ext.overrides.util.Filter', {
override: 'Ext.util.Filter',
anyMatch: true
});
And import this class in Application.js
Ext.require([
'Ext.overrides.util.Filter'
]);

using object.defineproperty with knockout observables

can i (and if yes how) create a ko.observable out of a object.defineproperty something like this
Strength: ko.observable(
Object.defineProperty(this, "strength", {
get: function () {
return this.level * 2;
},
enumerable: true
});
)
and
<span> str: <span data-bind="text: Strength"></span> / 100 </span>
what im trying to do is update the display of strength when its called after every level-up
i.e.
level up
(fight) request the current strength
update strength (+=2)
update strength display
using Object.defineProperty
i would probably just use ko.computable, but im wondering if there is a way to do it.
a bit unclear what you want to achive but I'd go with ko.computed. If you want the subscribers (namely your span) of your Strength property to be notified (when the level changes after the initial binding), you should also make level observable.
if you still want to use defineProperty, I hope this little example suits you (edit: added a button to level up)
function ViewModel() {
var self = this;
self.level=ko.observable(5);
self.really_use_computed = ko.computed(function() {
return self.level() * 2;
});
}
var MyViewModel=new ViewModel();
Object.defineProperty(MyViewModel, "Strength", {
get: function () {
return this.level() * 2;
},
enumerable: true
});
ko.applyBindings(MyViewModel);
please note that Internet Explorer 8 standards mode supports DOM objects but not user-defined objects for the first argument of Object.defineProperty() and that earlier versions of IE don't support Object.defineProperty() at all.
The Knockout ES5 plugin will do what you need. Although I had to also include the Weakmap shim to make it work.

Resources