Override a function in 'MultiSelect' component from PrimeNG - javascript

I'm new in JS. I have a small front-end task and I don't know how to solve it after few hours of googling.
I need to override this function in PrimeNG MultiSelect component: MultiSelect.prototype.updateLabel.
In project, I'm working on the label should be static, but alt text (when hovering) should be dynamic as in original realization.
It would be great if you point me to the right direction. I have found this page, but it didn't help me because I don't know how to implement it correctly.
Thanks in advance for any help.

I had to do the same thing in my project.
Here's what I did to get it to work:
In your component's .html file add something like:
<p-multiSelect #multiselect
[options]="someOptions"
[(ngModel)]="someModel.options"
[defaultLabel]="Did this work?"
(onChange)="onChange($event)"
>
</p-multiSelect>
Below the constructor in your component file, add:
#ViewChild('multiselect') multi: MultiSelect;
I put mine in a setter that is always called, but wherever you need to change the label - perhaps in a subscribe function - you can override using:
this.multi.updateLabel = function () {
var label = this.value.length.toString() + " Data Points Selected";
this.valuesAsString = label;
}
Hope that helps!

Related

Why "v-if" directive does not show hidden element when data is changed

i'm using Vue 2. With first render element is hidden, when i click on .mobile-trigger i can see in Vue-DevTools how variable "mobileMenuIsOpen" is changed to true, but .overlay is still not exist in DOM.
.mobile-trigger(#click='mobileMenuIsOpen = true')
.overlay(v-if='mobileMenuIsOpen')
...
data () {
return {
mobileMenuIsOpen: false
}
}
Thanks to everyone, who read this and leave comment in this question.
I'm forgot to explain, i'm using Pug(Jade)-preprocessor in this the code.
And i have not added enought code to give you help me.
So the problem was in the "v-once" directive which i put into component's root-element.

Trouble saving current state of css class in local storage

I am using two buttons to toggle css classes that either show or hide a background. I would like to save the current state of each class in local storage and display (or not display) them when the user returns. I have made an attempt with the wrapping class in this jsFiddle, but I don't have it working yet:
http://jsfiddle.net/eqrk6fak/1/
Setting it like so:
$("#switch2").click(function() {
wrap.fadeToggle(600);
if($('div').hasClass(wrap)){
localStorage.setItem('background', wrap);
}
});
And then trying to get it when the user returns:
$(document).ready(function(){
var background = localStorage.getItem('background');
if(background !== ''){
$('#wraping').addClass(background);
}
});
Any help would be appreciated. Thanks!
The problem is in the following line:
$('div').hasClass(wrap)
Reviewing your JSFiddle code, at that point wrap is a jQuery result:
var wrap = $(".wraping");
According to the documentation, jquery.hasClass receives a className which should be a String.

Polymer - Get data-bound attribute value in repeating template

I'm having a bit of an issue here. I had a small amount of success with event.target.templateInstance.model.thing syntax to get the value of attributes from within a repeating template but I keep getting back undefined from this bit of code I have here:
downloadFunction: function (e) {
console.log("dl function clicked");
//get particular id of thing
var fu = e.target.templateInstance.model.s.soundId;
console.log(fu);
//^ returns "TypeError: Cannot read property 'soundId' of undefined"
}
And my repeating template is here:
<div layout horizontal wrap center center-justified>
<template repeat="{{s in carddata}}">
<sound-card image="{{s.imgurl}}"
quotetext="{{s.quote}}"
soundsrc="{{s.soundurl}}"
soundref="{{s.soundId}}"
downloadfunction="{{downloadFunction}}">
</sound-card>
</template>
</div>
Where carddata is just an array with my data in it. All of the values are generated fine so I know it's not an issue with my array. I'm just confused how exactly I'm supposed to target someting from within the repeating template? Am I calling it at the wrong time? Or am I messing up the syntax of the templateInstance bit?
If it matters, I'm trying to get it to work in an Android 4.4 webView using Apache Cordova. 4.4 webView doesn't appear to enjoy the shadowDOM terribly much.
Thanks!
edit: After some jiggery pokery with console logs, it appears that the sender value is referring to the div that I apply the on-click="{{downloadFunction}} to. Here's the template that I am repeating, if this provides any insight.
<div class="soundcard-container" vertical layout>
//can't target this one either on WebView 4.4, works on ChromeOS
<img src="{{image}}" on-tap="{{playAudio}}">
<div class="soundcard-bottom-container" horizontal layout center justified>
<span>{{quotetext}}</span>
//I have an 'a' tag for desktop browsers and the div tag is targeting my Android/iOS
//apps that I am exporting as a webView to using Apache Cordova. Webonly is hidden
//at the point where I'm trying to get my downloadfunction to work.
//console.log(sender) in my downloadfunction returns this div v
<div on-tap="{{downloadfunction}}" class="mobileonly"></div>
</div>
//just a hidden audio thing for web
<div style="display: none">
<audio id="{{soundref}}" src="{{soundsrc}}" controls preload="auto"></audio>
</div>
</div>
edit2 some console logs..
console.log(sender) and console.log(event.target) are both the same div that has the on-click event for my downloadFunction.. not sure if this should be the case.
console.log(e.target.templateInstance.model) returns my <sound-card> object, I believe like it should(?)
It's just when I add the specific .s.soundId that it's undefined. I'm not sure why it's unable to find it.. Maybe there's another way to get the specific soundId (or s.soundId rather) of that particular <sound-card> object?
I'll bet you want to refer to the "sender" of the event—not e.target. See the part about inSender at https://www.polymer-project.org/0.5/docs/polymer/polymer.html#declarative-event-mapping:
inSender: A reference to the node that declared the handler. This is
often different from inEvent.target (the lowest node that received the
event) and inEvent.currentTarget (the component processing the event),
so Polymer provides it directly.
This might fix it:
downloadFunction: function (e, detail, sender) {
console.log("dl function clicked");
//get particular id of thing
var fu = sender.templateInstance.model.s.soundId;
console.log(fu);
}
Alright I was able to fit this in a different way. I wasn't able to get e.target.templateInstance.model.s.soundId bit to work, so instead on the div that I call the event on (event.target) I gave it an attribute called data-soundid and passed it {{soundref}} from my original template and then where I repeat that template I simply made a function like so:
downloady: function (e) {
console.log(e.target.getAttribute('data-soundurl'));
}
Ta da! Very nice solution. Thanks to Eyal who suggested this to me in a previous question. It works like a charm. :-)
Here is working example of using templateInstance, with included selecting by dynamic ID: Plunk .
As for your code, can't tell why it's not working.
handleEvent: function(e, detail, sender) {
console.log('handleEvent');
console.log(sender.id);
//How to catch full_obj here,
//..as if first item is clicked: full_obj = {"firstName":"John", "lastName":"Doe"}
//console.log(e);
console.log(e.target.templateInstance.model.item.firstName);
//console.log(detail);
//console.log(sender);
this.instance_firstName = e.target.templateInstance.model.item.firstName;
this.instance_lastName = e.target.templateInstance.model.item.lastName;
//Selecting by dynamic ID
var clicked_element = this.shadowRoot.querySelector('#'+this.instance_firstName);
console.log('Selecting');
console.log(clicked_element);
//var second_element = sender.templateInstance.model.querySelector('my-second-element');
//var second_element = this.$.second_element;
}
Edit:
Event handling and data binding Docs

How to better toggle between view and edit mode in reactjs

I am developing a user profile page, which has many boxes with two modes each - view and edit. Each box is defined as a react class <ProfileBox> ... </ProfileBox>.
For the view and edit mode of each box I defined classes <EditMode> ... </EditMode> and <ViewMode>...</ViewMode>. Eventually I want to render e.g. an address like
<ProfileBox editMode={true}>
<EditMode>
...
</EditMode>
<ViewMode>
...
</ViewMode>
</ProfileBox>
I want the logic to be in the ProfileBox. My current approach is to iterate all children and filter them if they are of type ViewMode or EditMode. Too late, I realized that this breaks down as soon as I do something like:
<ProfileBox editMode={true}>
<EditMode>
...
</EditMode>
<div>
<ViewMode>
...
</ViewMode>
</div>
</ProfileBox>
How could I do it better? What is the standard approach? I don't want to have to manually care about passing an id or a status to the Edit and ViewMode in the definition of the address.
Thank you!
You can continue to render ViewMode and EditMode as children rather than pass them as props by using logic in the render function of ProfileBox similar to this:
render: function() {
var child = this.props.editMode ?
<EditMode>
...
</EditMode> :
<ViewMode>
...
</ViewMode>;
return child;
}
You can do:
<ProfileBox editMode={this.state.editingWhatever} onModeChange={this.updateEditingWhatever}
editView={ <EditMode>...</EditMode> }
viewView={ <div><ViewMode>...</ViewMode></div> }
/>
Or you can conditionally render the EditMode/ViewMode in this code. To make it less ugly, a well designed mixin would do wonders. It's hard to tell what the exact requirements are from your question, but take a look at what all of your <ProfileBox/> uses have in common, and where they differ.
In the simpler case shown above, you probably just want to dynamically create the onModeChange handler, and the onChange handler for any inputs children in edit mode.

Dojo: TabContainer - how to place menu button in the header?

is it possible to place a button in TabContainer header on the left side ?
I want to place it next to First Tab.
Thanks for help :)
You are going to have to create your own tab controller widget. The steps would be as follows:
Create MyTabController that extends dijit.layout.TabController
Create a template for MyTabController that has a place for the button
Update MyTabController javascript to create the button
You can use your new controller widget in one of two ways. If it were me, I'd also create my own tab container widget that extends dijit.layout.TabContainer and overrides the _makeController function to instantiate the new controller.
Alternatively, you could pass in the _makeController function when instantiating the TabContianer widget
var tc = new dijit.layout.TabContainer({
_makeController: function(srcNode) {
...
}
}, node);
You can look at the dijit.layout.TabContainer source to see what needs to be done in the _makeController function.

Categories

Resources