vendredi 29 juin 2018

Ember app use addon installed as transitive dependency

Can an Ember app use an addon that is installed as a transitive dependency? I have a local Ember addon that lists ember-angle-bracket-invocation-polyfill as a dependency in package.json. When I install the addon into an Ember app using ember install path/to/addon, I'm unable to use ember-angle-bracket-invocation-polyfill. Any help is appreciated!




Refreshing Semantic UI sticky with Ember does not work

Okay, so I have this Semantic UI sticky rails menu in an Ember application.

setTimeout(function(){
 $('.ui.sticky').sticky({
  offset: 60,
  observeChanges: true,
  silent: true
 });
},2000);

It is wrapped into a setTimeout() to wait for the document content to load, which seemed to be the only workaround at that time. Also it is supposed to refresh every time content is added to or removed from the column, for example when the document image loads after the timeout or one of the accordions is opened/closed by the user. To achieve this I tried

$('.document-content.column').attr('onresize', "$('.ui.sticky').sticky('refresh')");

to catch changes in the element size. Unfortunately this only works when the window is resized. As I already found out, there is no event that triggers after images load, so I tried listening to DOM element changes with DOMSubtreeModified.

$('.document-content.column').bind('DOMSubtreeModified', function() {
 $('.ui.sticky').sticky('refresh');
});

This works fine and also substitutes the dirty timeout solution, but it's very slow on the initial page load, as it is triggered a bunch of times. Also DOMSubtreeModified is said to be deprecated, which is why I tried MutationObservers like this:

var observer = new MutationObserver(function() {
  $('.ui.sticky').sticky('refresh');
});

var observerTarget = document.querySelector('.document-content.column');

var observerOptions = {
  attributes: true,
  childList: true,
  subtree: true
};

observer.observe(observerTarget, observerOptions);

But it seems that every refresh of the sticky just triggers the observer again, causing an endless loop. And now I don't know what else to do.

Short version of the hbs template:

<div class="ui stackable three column container relaxed grid">
 <div class="twothird wide document-content column">
  
  <div class="ui divider"></div>
  <h2 class="cap text"></h2>
  <div class="ui relaxed divided accordion">
   <div class="title"></div>
   <div class="content"></div>
  </div>
 </div>

 <div class="widescreen large screen computer only column">
  <div class="ui sticky rail-menu">
   
  </div>
 </div>
</div>

If there is anything else I should provide, please tell me. I am thankful for any help that I can get.




jeudi 28 juin 2018

Is it safe to remove `links.related` from JSON API response? (Ember.js)

Good day,

Does removing of links.related on my JSON response will affect any Ember-Data relationship fetching?

relationships": {
  "comments": {
    "links": {
      "related": "http://localhost:3099/api/v1/articles/1/comments"
    },
    "data": [
      {
        "type": "comments",
        "id": 1
      },
      {
        "type": "comments",
        "id": 2
      },
      { ... More comments here ... }
    ]
  }
}

I've read this article : https://thejsguy.com/2016/02/21/handling-nested-resources-in-ember-data.html and this points me to Ember data uses those links internally to fetch the related data so I won't have to access those URLs and make requests to them. I need more concrete opinion before we make any changes to our API.




Ember js params not passing properly

I have the routes defined in following way

this.route('league', {path: '/league'}, function () {
    this.route('matches', {path: '/'});
    this.route('create-team', {path: '/:matchId'}, function () {
        this.route('team',{path: '/team'});
    });
});

And i am trying to load all the players associated with a matchId inside team router as following

import Route from '@ember/routing/route';

export default Route.extend({
    model: function(params) {
        return this.store.query('player', {'match': params.matchId});
    }

});

The problem is that the params is empty. I tried to pass in hard values to the json query and it worked with get request but it doesn't work like this. Where am i going wrong with this ?




Firefox: Drag ghost image position not honoring transform

I made items in an ember-collection to be draggable with ember-drag-drop. See Twiddle for an example.

It works fine in Chrome. In Firefox the gohst image doesn't appear on the cursor when the list gets scrolled down.

ember-collection uses transforms to position the list items. It seems that Firefox doesn't honor these.




Ember change normalizeResponse based on queried model

I'm using a second datastore with my Ember app, so I can communicate with a separate external API. I have no control over this API.

With a serializer I can add some missing properties like id:

normalizeResponse(store, primaryModelClass, payload, id, requestType) {
    if (requestType == 'query') {
        payload.forEach(function(el, index) {
            payload[index].id = index
        })
    }

Now I can do some different tricks for each different requestType. But every response is parsed. Now sometimes a response from one request needs to be parsed differently.

So what I am trying to do is change the normalizeResponse functionality for each different request path (mapped to a fake model using pathForType in an adapter for this store). But the argument store is always the same (obviously) and the argument promaryModelClass is always "unknown mixin" - not sure if this can be any help.

How can I find what model was requested? With this information I could do a switch() in normalizeResponse.




Add mouse over capability like a thumbnail

Hi I need to see a thumbnail preview of an item (image, pdf, html etc) by hovering my mouse over it so I can easily see what the item is without having to load it fully. It should show preview in a pop-up window when I’m mouses over for 1 second and should disappear when I’m mouses off the item. If the preview cannot be shown in a browser window, then show a message like “Cannot display”.

For here I have provided pdf preview of html code (Icon) is below:

<div id="ember8734" class="ember-view managed-object-tools-icon managed-object-icon-view container-view clickable" style="font-size: 20px">
<rs-icon id="ember8737" class="ember-view primary-icon managed-object-primary-icon icon" style="font-size: 20px">
<icon glyph="type_pdf" class="type_pdf" set="types" style="font-size: 20px;">
</icon>
</rs-icon>
<rs-icon id="ember8743" class="ember-view version-icon icon" style="width: 1em; height: 1em; font-size: 20px">
</rs-icon>
</div>
<managed-object-label id="ember8749" class="ember-view content-data managed-object-label-view managed-object-label-view managed-object-label data-view managed-object-label-view-core_component_data-view-mixin managed-object-label-core_component_data-view-mixin data-view-core_component_data-view-mixin">
<div core-role="primaryLabel" class="" data-bindattr-49="49">story.​pdf</div>

For all the item(html, pdf, image etc) Thumbnail-preview.js code is here:

    ScalerMixin = {
        imageWidth: null,
        imageHeight: null,
        containerWidth: null,
        containerHeight: null,
        width: null,
        height: null,
        top: null,
        left: null, 
        attributeBindings: [ 'style', 'src' ],
        style: function () {
            if (!this.get('width') || !this.get('height') || isNaN(this.get('top')) || isNaN(this.get('left'))) {
                return '';
            }
            return 'width: ' + this.get('width') + 'px; height: ' + this.get('height') + 'px; margin-top: ' + this.get('top') + 'px; margin-left: ' + this.get('left') + 'px;';
        }.property('width', 'height', 'top', 'left'),
        captureImageSize: function () {
            if (this.isDestroying || this.isDestroyed) { return; }
            var i = new window.Image();
            i.src = this.get('src');
            this.set('imageWidth', i.width);
            this.set('imageHeight', i.height);
            this.updateSize();
        },
        updateSize: function () {
            if (this.isDestroying || this.isDestroyed) { return; }
            if (!this.imageWidth || !this.imageHeight || !this.containerWidth || !this.containerHeight) {
                return;
            }
            var iar = this.imageWidth / this.imageHeight,
                car = this.containerWidth / this.containerHeight;
            var width, height;
            if (car > iar) {
                height = this.containerHeight;
                width = iar * this.containerHeight;
            } else {
                height = this.containerWidth / iar;
                width = this.containerWidth;
            }
            if (this.width !== width) {
                this.set('width', width);
            }
            if (this.height !== height) {
                this.set('height', height);
            }
            this.set('top', (this.containerHeight - height) / 2);
            this.set('left', (this.containerWidth - width) / 2);
        }.observes('imageWidth', 'imageHeight', 'containerWidth', 'containerHeight'),
        containerWidthBinding: 'parentView.width',
        containerHeightBinding: 'parentView.height',
        _attachLoadHandler: function () {
            this.get('element').onload = this.captureImageSize.bind(this);
        }.on('didInsertElement')
    },

    ThumbnailImage = Ember.View.extend(ScalerMixin, {
        tagName: 'img',         
        isVisible: function () {
            return !!this.get('src');
        }.property('src'),  
        objectBinding: 'parentView.object',
        click: function () {
            alert('thumb1');
            var i = new window.Image(),
                src = this.get('object').uri();
            i.onload = function () {
                Core.openWindow(src, {
                    width: i.width,
                    height: i.height
                });
            };
            i.src = src;
        },
        classNames: [ 'clickable' ]
    }),
    Thumbnail = ThumbnailImage.extend({
        src: function () {
            var object = this.get('object');
            if (!object) { return; }
            var thumb = object.get('keyedVariants.core:thumbnail');
            if (thumb) {
                return object.uri({ variantName: thumb.variantName });
            }
            return null;
        }.property('object', 'object.keyedVariants.core:thumbnail', 'object.variants.length')
    }),
    Image = ThumbnailImage.extend({
        src: function () {
            var object = this.get('object');
            if (!object) { return; }
            var type = object.get('contentType');
            if (/^image\/(?:jpeg|gif|png|svg)/.test(type)) {
                return object.uri();
            }
            return null;
        }.property('object')
    }),             
    Playable = Ember.ContainerView.extend({
        object: null,
        playableSources: function () {
            var playerTag = document.createElement(this.get('playerTagName')),
                sources = this.get('sources') || [];
            return sources.filter(function (source) {
                if (!playerTag.canPlayType) { return false; }
                return !!playerTag.canPlayType(source.type + ';').replace(/no/, '');
            }, this);
        }.property('sources.@each.type'),
        updateSizes: function () {
            var w = Math.min(this.get('parentView.width') | 0),
                h = Math.min(this.get('parentView.height') | 0),
                s = Math.min(128, Math.min(this.get('parentView.width'), this.get('parentView.height')) * 0.75) | 0,
                l = Math.floor((w - s) / 2),
                t = Math.floor((h - s) / 2),
                m = 'margin: ' + t + 'px 0 0 ' + l + 'px';
            this.set('margin', m);
            this.set('iconSize', s);
        }.on('didInsertElement').observes('parentView.width', 'parentView.height'),
        iconSize: 128,
        marginLeft: 0,
        marginTop: 0, 
        PlayView: Ember.ContainerView.extend({
            tagName: null,
            ThumbnailView: ThumbnailImage,
            thumbnailView: childView('ThumbnailView'),
            objectBinding: 'parentView.object',
            attributeBindings: [ 'controls', 'preload', 'style' ],
            style: function () {
                var w = this.get('parentView.parentView.width'),
                    h = this.get('parentView.parentView.height');
                return "max-width: " + w + "px; max-height: " + h + "px;";
            }.property('parentView.parentView.width', 'parentView.parentView.height'),
            controls: "true",
            preload: 'metadata',
            poster: 'thumbnailView.src',
            SourceView: Ember.View.extend({
                tagName: 'source',
                attributeBindings: ['src', 'type'],
                src: null,
                type: null
            }),
            PlayButton: Core.view.Icon.extend({
                classNames: ['play-button'],
                sizeBinding: 'parentView.parentView.iconSize',
                marginBinding: 'parentView.parentView.margin',
                model: 'play',
                click: function () {
                    alert('thumb2');
                    var el = this.get('parentView.element');
                    if (el) {
                        this.get('parentView.element').play();
                    }
                }
            }),
            playButton: childView('PlayButton'),
            sourceViews: function () {
                return this.get('parentView.sources').map(function (source) {
                    return this.createChildView(this.SourceView, source);
                }, this);
            }.property(),
            setupView: function () {
                if (this.isDestroying || this.isDestroyed) { return; }
                this.set('tagName', this.get('parentView.playerTagName'));
                this.replace(0, this.get('length'), []);
                this.get('sourceViews').forEach(function (sourceView) {
                    this.pushObject(sourceView);
                }, this);
                this.pushObject(this.get('thumbnailView'));
                this.pushObject(this.get('playButton'));
            }.on('init').observes('parentView.sources')
        }),
        playView: childView('PlayView'),
        PremediaView: Ember.ContainerView.extend({
            ThumbnailView: ThumbnailImage,
            thumbnailView: childView('ThumbnailView'),
            PlayButton: Core.view.Icon.extend({
                classNames: ['play-button'],
                sizeBinding: 'parentView.parentView.iconSize',
                marginBinding: 'parentView.parentView.margin',
                model: 'play',
                click: function () {
                    alert('thumb3');
                    this.get('parentView.parentView').play();
                }
            }),
            playButton: childView('PlayButton'),
            setupView: function () {
                this.replace(0, this.get('length'), []);
                this.pushObject(this.get('thumbnailView'));
                this.pushObject(this.get('playButton'));
            }.on('init').observes('thumbnailView.src')
        }),
        premediaView: childView('PremediaView'),
        PlaceholderView: Ember.ContainerView.extend({
            ThumbnailView: ThumbnailImage,
            thumbnailView: childView('ThumbnailView'),
            CantPlayButton: Core.view.Icon.extend({
                classNames: ['play-button', 'cant-play'],
                sizeBinding: 'parentView.parentView.iconSize',
                marginBinding: 'parentView.parentView.margin',                  
                model: 'play_not_available',
                titleBinding: 'Core.messageTable.content/icon/preview/cant-play'
            }),
            cantPlayButton: childView('CantPlayButton'),
            setupView: function () {
                this.replace(0, this.get('length'), []);
                this.pushObject(this.get('thumbnailView'));
                this.pushObject(this.get('cantPlayButton'));
            }.on('init').observes('thumbnailView.src')
        }),
        placeholderView: childView('PlaceholderView'),
        media: false,
        play: function () {
            this.set('media', true);
            Ember.run.schedule('render', this, function () {
                var go = function () {
                    var el = this.get('playView.element');
                    if (!el) {
                        Ember.run.later(this, go);
                    } else {
                        $(el).on('canplay', function () {
                            el.play();
                        });
                    }
                }.bind(this);
                go();                   
            });
        },
        setupView: function () {
            this.replace(0, this.get('length'), []);
            if (!this.media) {
                this.pushObject(this.get('premediaView'));
            } else {
                if (this.get('playableSources.length') === 0) {
                    this.pushObject(this.get('placeholderView'));
                } else {
                    this.pushObject(this.get('playView'));
                }
            }
        }.on('init').observes('playableSources.length', 'media')
    });
Core.component.ManagedObjectPreview.MediaPreview = Ember.ContainerView.extend({
    classNames: [ 'thumbnail-preview' ],
    height: 250,
    width: 292,
    captureSizeForRealsies: function () {
        if (this.isDestroying || this.isDestroyed) { return; }
        var el = this.get('element');
        if (!el) {
            Ember.run.later(this, 'captureSizeForRealsies', 125);
            return;
        }
        var rect = el.getBoundingClientRect();
        if (!rect.width || !rect.height) {
            Ember.run.later(this, 'captureSizeForRealsies', 125);
            return; 
        }
        // Find first scrollable containment
        var scrollX = scrollY = el;
        while (scrollX && scrollX.nodeType !== Node.DOCUMENT_NODE && $(scrollX).css('overflow-x') !== 'auto') {
            scrollX = scrollX.parentNode;
        }
        while (scrollY && scrollY.nodeType !== Node.DOCUMENT_NODE && $(scrollY).css('overflow-y') !== 'auto') {
            scrollY = scrollY.parentNode;
        }
        if (scrollY) {
            rect.height = Math.min(rect.height, scrollY.clientHeight);
        }
        if (scrollX) {
            rect.width = Math.min(rect.width, scrollX.clientWidth);
        }
        this.beginPropertyChanges();
        if (rect.width !== this.width) {
            this.set('width', rect.width);
        }
        if (rect.height !== this.height) {
            this.set('height', rect.height);
        }
        this.endPropertyChanges();
    },
    captureSize: function () {
        Ember.run.later(this, 'captureSizeForRealsies', 125);
    }.on('didInsertElement').observes('Core.document.width'),
    classNameBindings: [ 'isImage:ui-clickable' ],
    objectBinding: 'model.finalManagedObject',
    thumb: Ember.computed(function () {
        var uri, mo = this.get('object');
        if (!mo) { return; }
        if (mo.getVariant('core:thumbnail')) {
            uri = Core.restUrl(2, 'content/binary/id/' + this.get('object.id') + '?variant=core:thumbnail');
            if (mo.get('revision')) {
                uri += '&revision=' + mo.get('revision');
            }
            return uri;
        }
        return null;
    }).property(
        'object.variants.@each.variantName',
        'object.id',
        'object.revision'
    ),
    isImage: function () {
        var contentType = this.get('object.contentType'),
            isImage = (/^image\/(?:jpeg|gif|png|svg)/).test(contentType);
        return isImage;
    }.property('object.contentType'),
    urlsFor: function (type) {
        var obj = this.get('object') || this.get('model');
        URL = obj.streamingUri;
        var parentId = $('.preview-and-information-view').attr('id');
        var childId = $('#' + parentId).find('div').attr('id');
        if (obj.contentType == 'application/vnd.openxmlformats-officedocument.presentationml.presentation') {
            $('#'+childId).html('<a href="'+URL+'" target=_blank><span style=cursor:pointer><img src=/core-cms/plugin/core-cms-theme/images/core/content-type/24/office-powerpoint.png  alt=power-point style=width: 20px; cursor:pointer;></span></a>');
            return false;
        }
        else if(obj.contentType == 'text/plain' || obj.contentType == 'application/vnd.ms-xpsdocument'){
            $('#'+childId).html('<a href="'+URL+'" target=_blank><span style=cursor:pointer><img src=/core-cms/plugin/core-cms-theme/images/core/content-type/24/file-generic.png style=width: 20px;cursor:pointer;></span></a>');
            return false;
        }
        else if(obj.contentType == 'application/pdf'){
            $('#'+childId).html('<a href="'+URL+'" target=_blank ><span style=cursor:pointer><icon glyph=type_pdf class=type_pdf set=types style=font-size:20px;cursor:pointer;></icon></span></a>');
            return false;
        }
        else if(obj.contentType == 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'){
            $('#'+childId).html('<a href="'+URL+'" target=_blank ><span style=cursor:pointer><img src=/core-cms/plugin/core-cms-theme/images/core/content-type/24/office-word.png alt=office-word style=width: 20px;cursor:pointer;></span></a>');
            return false;
        }
        else if(obj.contentType == 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'){
            $('#'+childId).html('<a href="'+URL+'" target=_blank ><span style=cursor:pointer><img src=/core-cms/plugin/core-cms-theme/images/core/content-type/24/office-excel.png style=width: 20px;cursor:pointer;></span></a>');
            return false;
        }
        else if(obj.contentType == 'application/x-shockwave-flash'){
            $('#'+childId).html('<a href="'+URL+'" target=_blank ><span style=cursor:pointer><icon glyph=type_adobe_flash_ class=type_adobe_flash set=types style=font-size: 20px;cursor:pointer;></icon></span></a>');
            return false;
        }
        else {
            $('#'+childId).html('');
        }
        if (!obj) { return; }
        var items = [obj].concat(obj.get('variants') || []);
        items = items.map(function (variant) {
            var ret = {};
            if (Ember.get(variant, 'variantName')) {
                ret.src = obj.uri({ variantName: Ember.get(variant, 'variantName') });
            } else {
                ret.src = obj.uri();
            }
            ret.type = Ember.get(variant, 'contentType');
            return ret;
        });
        items = items.filter(function (item) {
            if (!item.src || !item.type) { return false; }
            return item.type.substr(0, type.length + 1) === (type + '/');
        });
        return items;
    },
    videoUrls: function () {
        return this.urlsFor('video');
    }.property('object.contentType', 'object.variants.@each.contentType'),
    isVideo: function () {
        return !!this.get('videoUrls.length');
    }.property('videoUrls.length'),
    audioUrls: function () {
        return this.urlsFor('audio');
    }.property('object.contentType', 'object.variants.@each.contentType'),
    isAudio: function () {
        return !!this.get('audioUrls.length');
    }.property('audioUrls.length'),
    objectChanged: function () {
        console.log(this);
        if (this.get('length')) {
            this.replace(0, this.get('length'), []);
        }
        if (this.get('isVideo')) {
            this.pushObject(this.get('videoView'));
        } else if (this.get('isAudio')) {
            this.pushObject(this.get('audioView'));
        } else {
            this.pushObject(this.get('imageView'));
        }
    }.on('init').observes('object', 'media'),
    VideoView: Playable.extend({
        classNames: [ 'video-preview' ],
        playerTagName: 'video',
        objectBinding: 'parentView.object',
        sourcesBinding: 'parentView.videoUrls'
    }),
    videoView: childView('VideoView'),
    AudioView: Playable.extend({
        classNames: [ 'audio-preview' ],
        playerTagName: 'audio',
        objectBinding: 'parentView.object',
        sourcesBinding: 'parentView.audioUrls'
    }),
    audioView: childView('AudioView'),
    ImageView: Image.extend({
        classNames: [ 'image-preview' ]
    }),
    imageView: childView('ImageView'),
    ThumbView: Thumbnail.extend({
        classNames: [ 'thumbnail-preview' ]
    }),
    thumbView: childView('ThumbView')
});
Core.component.ManagedObjectPreview.ThumbPreview = Core.component.ManagedObjectPreview.MediaPreview.extend({
    objectChanged: function () {
        if (this.get('length')) {
            this.replace(0, this.get('length'), []);
        }
        if (this.get('thumb')) {
            this.pushObject(this.get('thumbView'));
        }       
    }.on('init').observes('object')
});
var LocalNavigator = Core.component.NavigableSection.Navigator.extend({
    objectBinding: 'sectionView.model.finalManagedObject',
    tooltipBinding: "Core.messageTable.content/preview/thumbnail",
    enabled:function () {
        return !!this.get('types.length');
    }.property('types', 'types.length')
});
Core.component.ManagedObjectPreview.proto().navigators.pushObjects([
    LocalNavigator.extend({
        enabled: function () {
            return !!this.get('types.length');
        }.property('types.length'),
        icon: function () {
            if (this.get('thumb')) {
                return 'thumbnail_missing';
            }
            var types = this.get('types'),
                isAudio = false,
                isVideo = false;
            types.forEach(function (type) {
                if (/^video\//.test(type)) {
                    isVideo = true;
                }
                if (/^audio\//.test(type)) {
                    isAudio = true;
                }
                if (/^application\//.test(type)) {
                    isDocument = true;
                }
            });
            if (isVideo) {
                return 'types:type_video';
            }
            if (isAudio) {
                return 'types:type_audio';
            }
            return types.find(function (type) {
                return /^image\//.test(type);
            }) ? 'types:type_image' : 'thumbnail_missing';
        }.property('thumb', 'object'),
        thumb: function () {
            var obj = this.get('object'),
                variants = obj && obj.get('variants'),
                types;
            if (!variants) { return null; }
            return obj && obj.get('keyedVariants.core:thumbnail');
        }.property('object.keyedVariants.core:thumbnail'),
        types: function () {
            var thumb = this.get('thumb');
            if (thumb) {
                return [ thumb.contentType ];
            }
            var obj = this.get('object'),
                variants = (obj && obj.get('variants')) || [],
                types;
            if (!obj) { return []; }
            types = [ obj.get('contentType') ];
            variants.forEach(function (variant) {
                if (variant.variantName !== 'core:thumbnail') {
                    types.push(variant.contentType);
                }
            });
            types = types.filter(function (type) {
                return (/^(image|audio|video|application)\//).test(type);
            });
            return types;       
        }.property('object', 'object.keyedVariants', 'object.variants.length'),
    }).create()
]);

for that corresponding icon having code in managedObjecttool.js :

ObjectIconView: Ember.ContainerView.extend(childMOMixin, {
                classNames: ['managed-object-tools-icon'],
                classNameBindings: [ 'clickable' ],
                attributeBindings: [ 'style' ],
                style: function () {
                    return 'font-size: ' + this.get('size') + 'px';
                }.property('size'),
                mouseDown: function () { return false; },
                click: function () {
                    var actionMenuContext = this.get('actionMenuContext'),
                        element = this.$(),
                        row = element.parents('tr:first'),
                        ctl = this.get('controller');
                    if (ctl && ctl.send) {
                        ctl.send('contentItemActionMenu', row.length ? row : element, element, actionMenuContext);
                    }
                    return false;
                },
                clickable: function () {
                    return !!this.get('controller._actions.contentItemActionMenu');
                }.property(''),
                childViews: [
                    'PrimaryIcon',
                    'TypeOverlay',
                    'VersionStatus',
                    'DraftStatus'
                ],
                size: 20,
                PrimaryIcon: Core.component.ManagedObjectPrimaryIcon.extend(childMOMixin, {
                    sizeBinding: 'parentView.size',
                    loadStateBinding: 'parentView.loadState',
                    suggestedIconsBinding: 'parentView.suggestedIcons'
                }),
                VersionStatus: Core.view.Icon.extend(childMOMixin, {
                    sizeBinding: 'parentView.size',
                    classNames: ['version-icon'],
                    classNameBindings: [ 'model' ],
                    model: function () {
                        if (this.get('isFrozen')) { return 'status_pinned'; }
                        if (this.get('isOwned')) { return 'status_checked_out'; }
                        if (this.get('isLocked')) { return 'status_locked'; }
                    }.property('isFrozen', 'isOwned', 'isLocked')
                }),
                DraftStatus: Core.view.Icon.extend(childMOMixin, {
                    sizeBinding: 'parentView.size',
                    classNames: ['version-icon'],
                    classNameBindings: [ 'model' ],
                    model: function () {
                        if (this.get('hasDraft')) { return 'status_draft'; }
                        return "$blank";
                    }.property('hasDraft')
                }),
                TypeOverlay: Core.view.Icon.extend(childMOMixin, {
                    sizeBinding: 'parentView.size',
                    classNames: ['type-icon'],
                    classNameBindings: [ 'model' ],
                    model: function () {
                        var type = this.get('finalObjectType');
                        if (type === 'canode') {
                            return 'status_ca_node';
                        }
                        if (type === 'mo') {
                            return 'status_is_xml';
                        }
                        //if (type === 'mononxml' && this.get('variants.length') > 0) {
                        //  return 'status_has_variants';
                        //}
                        return '$blank';
                    }.property('parentView.finalMO.objectType', 'finalObjectType')
                })
            }).named("ManagedObjectIconView")

I have tried by using "mouseMove" option. But the image is not showing. Please provide me the suggestion for this. I’m new to the ember. If you need the further detail ask me in the comment. Your help will be more appreciate. Thanks in advance.




Thumbnail preview of an item by hovering my mouse over

Hi I need to see a thumbnail preview of an item (image, pdf, html etc) by hovering my mouse over it so I can easily see what the item is without having to load it fully. It should show preview in a pop-up window when I'm mouses over for 1 second and should disappear when I'm mouses off the item. If the preview cannot be shown in a browser window, then show a message like "Cannot display".

For the pdf preview of html code (Icon with the label) is below:

<div id="ember8734" class="ember-view managed-object-tools-icon managed-object-icon-view container-view clickable" style="font-size: 20px">
<rs-icon id="ember8737" class="ember-view primary-icon managed-object-primary-icon icon" style="font-size: 20px">
<icon glyph="type_pdf" class="type_pdf" set="types" style="font-size: 20px;">
</icon>
</rs-icon>
<rs-icon id="ember8743" class="ember-view version-icon icon" style="width: 1em; height: 1em; font-size: 20px">
</rs-icon>
</div>
<managed-object-label id="ember8749" class="ember-view content-data managed-object-label-view managed-object-label-view managed-object-label data-view managed-object-label-view-core_component_data-view-mixin managed-object-label-core_component_data-view-mixin data-view-core_component_data-view-mixin">
<div core-role="primaryLabel" class="" data-bindattr-49="49">BAB ​7-​Badai.​pdf</div>

For all the item(html, pdf, image etc) Thumbnail-preview.js code is here:

(function () {
    var childView = function (name, ext) {
            return function () {
                return this.createChildView(this.get(name), ext);
            }.property();
        },
        ScalerMixin = {
            imageWidth: null,
            imageHeight: null,
            containerWidth: null,
            containerHeight: null,
            width: null,
            height: null,
            top: null,
            left: null, 
            attributeBindings: [ 'style', 'src' ],
            style: function () {
                if (!this.get('width') || !this.get('height') || isNaN(this.get('top')) || isNaN(this.get('left'))) {
                    return '';
                }
                return 'width: ' + this.get('width') + 'px; height: ' + this.get('height') + 'px; margin-top: ' + this.get('top') + 'px; margin-left: ' + this.get('left') + 'px;';
            }.property('width', 'height', 'top', 'left'),
            captureImageSize: function () {
                if (this.isDestroying || this.isDestroyed) { return; }
                var i = new window.Image();
                i.src = this.get('src');
                this.set('imageWidth', i.width);
                this.set('imageHeight', i.height);
                this.updateSize();
            },
            updateSize: function () {
                if (this.isDestroying || this.isDestroyed) { return; }
                if (!this.imageWidth || !this.imageHeight || !this.containerWidth || !this.containerHeight) {
                    return;
                }
                var iar = this.imageWidth / this.imageHeight,
                    car = this.containerWidth / this.containerHeight;
                var width, height;
                if (car > iar) {
                    height = this.containerHeight;
                    width = iar * this.containerHeight;
                } else {
                    height = this.containerWidth / iar;
                    width = this.containerWidth;
                }
                if (this.width !== width) {
                    this.set('width', width);
                }
                if (this.height !== height) {
                    this.set('height', height);
                }
                this.set('top', (this.containerHeight - height) / 2);
                this.set('left', (this.containerWidth - width) / 2);
            }.observes('imageWidth', 'imageHeight', 'containerWidth', 'containerHeight'),
            containerWidthBinding: 'parentView.width',
            containerHeightBinding: 'parentView.height',
            _attachLoadHandler: function () {
                this.get('element').onload = this.captureImageSize.bind(this);
            }.on('didInsertElement')
        },


        ThumbnailImage = Ember.View.extend(ScalerMixin, {
            tagName: 'img',         
            isVisible: function () {
                return !!this.get('src');
            }.property('src'),  
            objectBinding: 'parentView.object',
            click: function () {
                alert('thumb1');
                var i = new window.Image(),
                    src = this.get('object').uri();
                i.onload = function () {
                    Core.openWindow(src, {
                        width: i.width,
                        height: i.height
                    });
                };
                i.src = src;
            },
            classNames: [ 'clickable' ]
        }),
        Thumbnail = ThumbnailImage.extend({
            src: function () {
                var object = this.get('object');
                if (!object) { return; }
                var thumb = object.get('keyedVariants.core:thumbnail');
                if (thumb) {
                    return object.uri({ variantName: thumb.variantName });
                }
                return null;
            }.property('object', 'object.keyedVariants.core:thumbnail', 'object.variants.length')
        }),
        Image = ThumbnailImage.extend({
            src: function () {
                var object = this.get('object');
                if (!object) { return; }
                var type = object.get('contentType');
                if (/^image\/(?:jpeg|gif|png|svg)/.test(type)) {
                    return object.uri();
                }
                return null;
            }.property('object')
        }),             
        Playable = Ember.ContainerView.extend({
            object: null,
            playableSources: function () {
                var playerTag = document.createElement(this.get('playerTagName')),
                    sources = this.get('sources') || [];
                return sources.filter(function (source) {
                    if (!playerTag.canPlayType) { return false; }
                    return !!playerTag.canPlayType(source.type + ';').replace(/no/, '');
                }, this);
            }.property('sources.@each.type'),
            updateSizes: function () {
                var w = Math.min(this.get('parentView.width') | 0),
                    h = Math.min(this.get('parentView.height') | 0),
                    s = Math.min(128, Math.min(this.get('parentView.width'), this.get('parentView.height')) * 0.75) | 0,
                    l = Math.floor((w - s) / 2),
                    t = Math.floor((h - s) / 2),
                    m = 'margin: ' + t + 'px 0 0 ' + l + 'px';
                this.set('margin', m);
                this.set('iconSize', s);
            }.on('didInsertElement').observes('parentView.width', 'parentView.height'),
            iconSize: 128,
            marginLeft: 0,
            marginTop: 0, 
            PlayView: Ember.ContainerView.extend({
                tagName: null,
                ThumbnailView: ThumbnailImage,
                thumbnailView: childView('ThumbnailView'),
                objectBinding: 'parentView.object',
                attributeBindings: [ 'controls', 'preload', 'style' ],
                style: function () {
                    var w = this.get('parentView.parentView.width'),
                        h = this.get('parentView.parentView.height');
                    return "max-width: " + w + "px; max-height: " + h + "px;";
                }.property('parentView.parentView.width', 'parentView.parentView.height'),
                controls: "true",
                preload: 'metadata',
                poster: 'thumbnailView.src',
                SourceView: Ember.View.extend({
                    tagName: 'source',
                    attributeBindings: ['src', 'type'],
                    src: null,
                    type: null
                }),
                PlayButton: Core.view.Icon.extend({
                    classNames: ['play-button'],
                    sizeBinding: 'parentView.parentView.iconSize',
                    marginBinding: 'parentView.parentView.margin',
                    model: 'play',
                    click: function () {
                        alert('thumb2');
                        var el = this.get('parentView.element');
                        if (el) {
                            this.get('parentView.element').play();
                        }
                    }
                }),
                playButton: childView('PlayButton'),
                sourceViews: function () {
                    return this.get('parentView.sources').map(function (source) {
                        return this.createChildView(this.SourceView, source);
                    }, this);
                }.property(),
                setupView: function () {
                    if (this.isDestroying || this.isDestroyed) { return; }
                    this.set('tagName', this.get('parentView.playerTagName'));
                    this.replace(0, this.get('length'), []);
                    this.get('sourceViews').forEach(function (sourceView) {
                        this.pushObject(sourceView);
                    }, this);
                    this.pushObject(this.get('thumbnailView'));
                    this.pushObject(this.get('playButton'));
                }.on('init').observes('parentView.sources')
            }),
            playView: childView('PlayView'),
            PremediaView: Ember.ContainerView.extend({
                ThumbnailView: ThumbnailImage,
                thumbnailView: childView('ThumbnailView'),
                PlayButton: Core.view.Icon.extend({
                    classNames: ['play-button'],
                    sizeBinding: 'parentView.parentView.iconSize',
                    marginBinding: 'parentView.parentView.margin',
                    model: 'play',
                    click: function () {
                        alert('thumb3');
                        this.get('parentView.parentView').play();
                    }
                }),
                playButton: childView('PlayButton'),
                setupView: function () {
                    this.replace(0, this.get('length'), []);
                    this.pushObject(this.get('thumbnailView'));
                    this.pushObject(this.get('playButton'));
                }.on('init').observes('thumbnailView.src')
            }),
            premediaView: childView('PremediaView'),
            PlaceholderView: Ember.ContainerView.extend({
                ThumbnailView: ThumbnailImage,
                thumbnailView: childView('ThumbnailView'),
                CantPlayButton: Core.view.Icon.extend({
                    classNames: ['play-button', 'cant-play'],
                    sizeBinding: 'parentView.parentView.iconSize',
                    marginBinding: 'parentView.parentView.margin',                  
                    model: 'play_not_available',
                    titleBinding: 'Core.messageTable.content/icon/preview/cant-play'
                }),
                cantPlayButton: childView('CantPlayButton'),
                setupView: function () {
                    this.replace(0, this.get('length'), []);
                    this.pushObject(this.get('thumbnailView'));
                    this.pushObject(this.get('cantPlayButton'));
                }.on('init').observes('thumbnailView.src')
            }),
            placeholderView: childView('PlaceholderView'),
            media: false,
            play: function () {
                this.set('media', true);
                Ember.run.schedule('render', this, function () {
                    var go = function () {
                        var el = this.get('playView.element');
                        if (!el) {
                            Ember.run.later(this, go);
                        } else {
                            $(el).on('canplay', function () {
                                el.play();
                            });
                        }
                    }.bind(this);
                    go();                   
                });
            },
            setupView: function () {
                this.replace(0, this.get('length'), []);
                if (!this.media) {
                    this.pushObject(this.get('premediaView'));
                } else {
                    if (this.get('playableSources.length') === 0) {
                        this.pushObject(this.get('placeholderView'));
                    } else {
                        this.pushObject(this.get('playView'));
                    }
                }
            }.on('init').observes('playableSources.length', 'media')
        });
    Core.component.ManagedObjectPreview.MediaPreview = Ember.ContainerView.extend({
        classNames: [ 'thumbnail-preview' ],
        height: 250,
        width: 292,
        captureSizeForRealsies: function () {
            if (this.isDestroying || this.isDestroyed) { return; }
            var el = this.get('element');
            if (!el) {
                Ember.run.later(this, 'captureSizeForRealsies', 125);
                return;
            }
            var rect = el.getBoundingClientRect();
            if (!rect.width || !rect.height) {
                Ember.run.later(this, 'captureSizeForRealsies', 125);
                return; 
            }
            // Find first scrollable containment
            var scrollX = scrollY = el;
            while (scrollX && scrollX.nodeType !== Node.DOCUMENT_NODE && $(scrollX).css('overflow-x') !== 'auto') {
                scrollX = scrollX.parentNode;
            }
            while (scrollY && scrollY.nodeType !== Node.DOCUMENT_NODE && $(scrollY).css('overflow-y') !== 'auto') {
                scrollY = scrollY.parentNode;
            }
            if (scrollY) {
                rect.height = Math.min(rect.height, scrollY.clientHeight);
            }
            if (scrollX) {
                rect.width = Math.min(rect.width, scrollX.clientWidth);
            }
            this.beginPropertyChanges();
            if (rect.width !== this.width) {
                this.set('width', rect.width);
            }
            if (rect.height !== this.height) {
                this.set('height', rect.height);
            }
            this.endPropertyChanges();
        },
        captureSize: function () {
            Ember.run.later(this, 'captureSizeForRealsies', 125);
        }.on('didInsertElement').observes('Core.document.width'),
        classNameBindings: [ 'isImage:ui-clickable' ],
        objectBinding: 'model.finalManagedObject',
        thumb: Ember.computed(function () {
            var uri, mo = this.get('object');
            if (!mo) { return; }
            if (mo.getVariant('core:thumbnail')) {
                uri = Core.restUrl(2, 'content/binary/id/' + this.get('object.id') + '?variant=core:thumbnail');
                if (mo.get('revision')) {
                    uri += '&revision=' + mo.get('revision');
                }
                return uri;
            }
            return null;
        }).property(
            'object.variants.@each.variantName',
            'object.id',
            'object.revision'
        ),
        isImage: function () {
            var contentType = this.get('object.contentType'),
                isImage = (/^image\/(?:jpeg|gif|png|svg)/).test(contentType);
            return isImage;
        }.property('object.contentType'),
        urlsFor: function (type) {
            var obj = this.get('object') || this.get('model');
            URL = obj.streamingUri;
            var parentId = $('.preview-and-information-view').attr('id');
            var childId = $('#' + parentId).find('div').attr('id');
            if (obj.contentType == 'application/vnd.openxmlformats-officedocument.presentationml.presentation') {
                $('#'+childId).html('<a href="'+URL+'" target=_blank><span style=cursor:pointer><img src=/core-cms/plugin/core-cms-theme/images/core/content-type/24/office-powerpoint.png  alt=power-point style=width: 20px; cursor:pointer;></span></a>');
                return false;
            }
            else if(obj.contentType == 'text/plain' || obj.contentType == 'application/vnd.ms-xpsdocument'){
                $('#'+childId).html('<a href="'+URL+'" target=_blank><span style=cursor:pointer><img src=/core-cms/plugin/core-cms-theme/images/core/content-type/24/file-generic.png style=width: 20px;cursor:pointer;></span></a>');
                return false;
            }
            else if(obj.contentType == 'application/pdf'){
                $('#'+childId).html('<a href="'+URL+'" target=_blank ><span style=cursor:pointer><icon glyph=type_pdf class=type_pdf set=types style=font-size:20px;cursor:pointer;></icon></span></a>');
                return false;
            }
            else if(obj.contentType == 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'){
                $('#'+childId).html('<a href="'+URL+'" target=_blank ><span style=cursor:pointer><img src=/core-cms/plugin/core-cms-theme/images/core/content-type/24/office-word.png alt=office-word style=width: 20px;cursor:pointer;></span></a>');
                return false;
            }
            else if(obj.contentType == 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'){
                $('#'+childId).html('<a href="'+URL+'" target=_blank ><span style=cursor:pointer><img src=/core-cms/plugin/core-cms-theme/images/core/content-type/24/office-excel.png style=width: 20px;cursor:pointer;></span></a>');
                return false;
            }
            else if(obj.contentType == 'application/x-shockwave-flash'){
                $('#'+childId).html('<a href="'+URL+'" target=_blank ><span style=cursor:pointer><icon glyph=type_adobe_flash_ class=type_adobe_flash set=types style=font-size: 20px;cursor:pointer;></icon></span></a>');
                return false;
            }
            else {
                $('#'+childId).html('');
            }
            if (!obj) { return; }
            var items = [obj].concat(obj.get('variants') || []);
            items = items.map(function (variant) {
                var ret = {};
                if (Ember.get(variant, 'variantName')) {
                    ret.src = obj.uri({ variantName: Ember.get(variant, 'variantName') });
                } else {
                    ret.src = obj.uri();
                }
                ret.type = Ember.get(variant, 'contentType');
                return ret;
            });
            items = items.filter(function (item) {
                if (!item.src || !item.type) { return false; }
                return item.type.substr(0, type.length + 1) === (type + '/');
            });
            return items;
        },
        videoUrls: function () {
            return this.urlsFor('video');
        }.property('object.contentType', 'object.variants.@each.contentType'),
        isVideo: function () {
            return !!this.get('videoUrls.length');
        }.property('videoUrls.length'),
        audioUrls: function () {
            return this.urlsFor('audio');
        }.property('object.contentType', 'object.variants.@each.contentType'),
        isAudio: function () {
            return !!this.get('audioUrls.length');
        }.property('audioUrls.length'),
        objectChanged: function () {
            console.log(this);
            if (this.get('length')) {
                this.replace(0, this.get('length'), []);
            }
            if (this.get('isVideo')) {
                this.pushObject(this.get('videoView'));
            } else if (this.get('isAudio')) {
                this.pushObject(this.get('audioView'));
            } else {
                this.pushObject(this.get('imageView'));
            }
        }.on('init').observes('object', 'media'),
        VideoView: Playable.extend({
            classNames: [ 'video-preview' ],
            playerTagName: 'video',
            objectBinding: 'parentView.object',
            sourcesBinding: 'parentView.videoUrls'
        }),
        videoView: childView('VideoView'),
        AudioView: Playable.extend({
            classNames: [ 'audio-preview' ],
            playerTagName: 'audio',
            objectBinding: 'parentView.object',
            sourcesBinding: 'parentView.audioUrls'
        }),
        audioView: childView('AudioView'),
        ImageView: Image.extend({
            classNames: [ 'image-preview' ]
        }),
        imageView: childView('ImageView'),
        ThumbView: Thumbnail.extend({
            classNames: [ 'thumbnail-preview' ]
        }),
        thumbView: childView('ThumbView')
    });
    Core.component.ManagedObjectPreview.ThumbPreview = Core.component.ManagedObjectPreview.MediaPreview.extend({
        objectChanged: function () {
            if (this.get('length')) {
                this.replace(0, this.get('length'), []);
            }
            if (this.get('thumb')) {
                this.pushObject(this.get('thumbView'));
            }       
        }.on('init').observes('object')
    });
    var LocalNavigator = Core.component.NavigableSection.Navigator.extend({
        objectBinding: 'sectionView.model.finalManagedObject',
        tooltipBinding: "Core.messageTable.content/preview/thumbnail",
        enabled:function () {
            return !!this.get('types.length');
        }.property('types', 'types.length')
    });
    Core.component.ManagedObjectPreview.proto().navigators.pushObjects([
        LocalNavigator.extend({
            enabled: function () {
                return !!this.get('types.length');
            }.property('types.length'),
            icon: function () {
                if (this.get('thumb')) {
                    return 'thumbnail_missing';
                }
                var types = this.get('types'),
                    isAudio = false,
                    isVideo = false;
                types.forEach(function (type) {
                    if (/^video\//.test(type)) {
                        isVideo = true;
                    }
                    if (/^audio\//.test(type)) {
                        isAudio = true;
                    }
                    if (/^application\//.test(type)) {
                        isDocument = true;
                    }
                });
                if (isVideo) {
                    return 'types:type_video';
                }
                if (isAudio) {
                    return 'types:type_audio';
                }
                return types.find(function (type) {
                    return /^image\//.test(type);
                }) ? 'types:type_image' : 'thumbnail_missing';
            }.property('thumb', 'object'),
            thumb: function () {
                var obj = this.get('object'),
                    variants = obj && obj.get('variants'),
                    types;
                if (!variants) { return null; }
                return obj && obj.get('keyedVariants.core:thumbnail');
            }.property('object.keyedVariants.core:thumbnail'),
            types: function () {
                var thumb = this.get('thumb');
                if (thumb) {
                    return [ thumb.contentType ];
                }
                var obj = this.get('object'),
                    variants = (obj && obj.get('variants')) || [],
                    types;
                if (!obj) { return []; }
                types = [ obj.get('contentType') ];
                variants.forEach(function (variant) {
                    if (variant.variantName !== 'core:thumbnail') {
                        types.push(variant.contentType);
                    }
                });
                types = types.filter(function (type) {
                    return (/^(image|audio|video|application)\//).test(type);
                });
                return types;       
            }.property('object', 'object.keyedVariants', 'object.variants.length'),
            bodyView: function () {
                if (this.get('thumb')) {
                    return Core.component.PrimaryTile.extend({
                        contains: Core.component.ManagedObjectPreview.ThumbPreview.extend({
                            modelBinding: 'parentView.model'
                        }),
                        scrollable: false,
                        style: function () {
                            return 'overflow: hidden';
                        }.property(),
                        attributeBindings: ['style']
                    });
                } else {
                    return Core.component.PrimaryTile.extend({
                        contains: Core.component.ManagedObjectPreview.MediaPreview.extend({
                            modelBinding: 'parentView.model'
                        }),
                        scrollable: false,
                        style: function () {
                            return 'overflow: hidden';
                        }.property(),
                        attributeBindings: ['style']
                    });                 
                }
            }.property('thumb', 'object')
        }).create()
    ]);
}());

Please provide me the suggestion for this. If you need the further detail as k me in the comment. Your help will be more appreciate. Thanks in advance.




mercredi 27 juin 2018

Ember and Node.js Nginx Configuration amazon EC2 Ubuntu Server

Hello i am getting this error when i try and load my site:

enter image description here

Reading into it I think there is an issue with my front end not being able to contact my backend. Ive done a CURL to my backend inside the server and outside and everything works. Also deploying with Ember-Cli-mirage works fine as well, Leading me to belive there is an issue with my NGINX config files. I have two config files one for the front end and one for the backend:

Front end Ember config:

 server {
 listen 80 default_server;
 listen [::]:80 default_server ipv6only=on;
 root /usr/local/t;
 index index.html;
  location / {
 try_files $uri $uri/ /index.html;
 }
 }

My backend Node.js Express config:

 server {
   listen 80;
   server_name default_server;

    root /usr/local/cloudBackend;
   index index.html index.htm;

   access_log /var/log/nginx/cpe.access.log;
   error_log /var/log/nginx/cpe.error.log notice;

   #  auth_basic "Restricted";
   #  auth_basic_user_file /etc/nginx/.htpasswd;

  location / {
    proxy_pass http://localhost:3001;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection 'upgrade';
    proxy_set_header Host $host;
    proxy_cache_bypass $http_upgrade;
}
}

Any help would be much appreciated.




ember waiting for user to complete the form

In ember, I have a form which ask the user their username and password for our remote server and then I want to verify the credentials by making an ajax call. Currently, I am using a custom made component which allows me to bind any action on clicking next or submit where I can verify the credentials and throw errors if needed. But once an error will occur, user cant click the next button (the way component is implemented) and hence second time validation is not happening. So, I thought to make a computed property which will look for username and password (and hence make ajax call when entered). But the problem with this approach is: every time something is entered in these boxes, computed property gets triggered which makes an ajax call (i dont want to make so many network calls for no purpose). Is there a way in ember where we can wait for user to finish the input and then invoke any kind of action?




Options working well in Chrome But not in IE and firefox

I have worked in the right click option for the Bodyrow.js and its working fine with the google chrome as I am expected. But its not working in the IE 11 and Firefox.

Below is the ember code I have worked for the right click option:

click: function (event) {
        var originalEvent = event.originalEvent.path[0];
        var bufferHtml = this.buffer.buffer;
        var isClicked = false;
        if(event){
            var isClicked = true;
        }
        if(isClicked == true) {
            var actionContextObject = this.get('object');
            var ctl = this.get('controller');
                $('.content-data').contextmenu(function(e){
                    var eMenupath = e.originalEvent.path[0];
                    var eCurrentTarget = $(e.currentTarget).attr('id');
                    var eSelect = $(bufferHtml).find(eCurrentTarget);
                    if(e.which === 3 && eSelect.selector!='' && originalEvent === eMenupath ) {
                        var parentId = $(e.currentTarget).closest('tr').prop('id');
                        var rowInspCheck = $('#'+parentId).hasClass('inspected');
                        if(rowInspCheck == true) {
                            var actionMenuContext = actionContextObject;
                            var element = e.currentTarget;
                            var row = e.currentTarget.parentNode;
                            ctl.send('contentItemActionMenu', row.length ? row : row, element, actionMenuContext);
                            isClicked = false;
                            return false;
                        }    
                    }
                });
      }
},

Can You please provide me the suggestion for this. I'm using ember 1.4.0. Your help will be appreciate. Thanks in advance.




mardi 26 juin 2018

Use variable for array key naming inside Ember class

I have an Ember component class as below;

import Ember from 'ember';
import myappconstants from '../utils/constants';

export default Ember.Component.extend({
    constants: myappconstants.FIELD_CONSTANTS.SECTION_1,
    myConfigs: {
        [myappconstants.FIELD_CONSTANTS.SECTION_1.FIELD_1] : {fieldName:"my__label__1", type:"text"},
        [myappconstants.FIELD_CONSTANTS.SECTION_1.FIELD_2] : {fieldName:"my__label__2", type:"text"}        
    }
})

My question is in my component class, I want to have the "myConfigs" keys defined in a slightly different way. This is because the definition can grow to around as many as 20 items & any name change in future would have to be done in multiple places.

So I want it to be defined as

myConfigs: {
        [this.constants.FIELD_1] : {fieldName:"my__label__1", type:"text"},
        [this.constants.FIELD_2] : {fieldName:"my__label__2", type:"text"}      
    }

With the above code, I get an error; Cannot read property 'constants' of undefined

Is it possible to achieve the above naming ?




How to get a javascript (emberjs) rendered HTML source in javascript

Problem: I am working on an extension in javascript which needs to be able to view the source HTML of a page after everything is rendered. The problem is that no matter what method I use, I can only seem to retrieve the pre-rendered source. The website is using emberjs for generating the content of the page.

Example: Site: https://www.playstation.com/en-us/explore/games/ps4-games/?console=ps4

When I right click and view source, I get the page before the content is loaded.When I right click and inspect element, I want to get the source after the content has loaded.

What I've tried:

background.js

var acceptedURLPattern = "playstation.com";

tabUpdatedCallback = function(tabID, changeInfo, tab) {
    if(tab.url.indexOf(acceptedURLPattern) == -1)   return;

    var eventJsonScript = {
        code: "console.log(\"Script Injected\"); window.addEventListener(\"load\", (event) => { " + browserString + ".runtime.sendMessage({ \"html\": document.documentElement.outerHTML });});"
    };


    browser.tabs.executeScript(tabID, eventJsonScript);
}

handleHTMLMessage = function(request, sender, sendResponse) {
    console.log(request);
}

browser.tabs.onUpdated.addListener(tabUpdatedCallback);
browser.runtime.onMessage.addListener(handleHTMLMessage);

The above script is injecting an eventListener onto the page I want to grab the source of after it fires the "load" event which will then send a message back to background.js containing that source.

I've tried changing the documentElement to innerHTML/outerHTML as well as changing the eventListener to document.addEventListener(\"DOMContentLoaded\"), but none of these changes seemed to have any effect.

I've also tried using these: Get javascript rendered html source using phantomjs and get a browser rendered html+javascript but they are using phantomjs to load and execute the page, then return the html. In my solution, I need to be able to grab the already rendered page.

Thanks for the help in advance!




lundi 25 juin 2018

Ember JS - routing from resourse to route

i'm trying to update and ember project from version 2.x to version 3.x, and one of my first issue is that in the route file i get this.resouce is not defined. i belive this was deprecated. the code looks like this :

  this.route('objects', function () {
    this.route('search', { path: '/' }, function () {
      this.resource('objects.items', { path: '/:search_id' }, function () {
        this.resource('objects.item', { path: '/item/:item_id'}, function () {
          this.route('general', { path: '/' });
          this.route('tab', { path: '/tab/:tab' });
          this.route('relations');
          this.route('diagram');
          this.route('comments');
          this.route('sources');
          this.route('views');
        });
      });
    });
  });

i've tried to simply change the resource to route and give resetNameSpace: true attribute, but didn't help. also i've tried various combinations, but without luck. anyone with experience can help me redo this routing to be compatible with the latest ember?

thanks!




Storing emberjs hasMany model on server?

So here is the model structure that i currently have in place

// match.js
import DS from 'ember-data';

export default DS.Model.extend({
    name: DS.attr('string'),
    match: DS.attr('number'),
    players: DS.hasMany('player')
});
//player.js
import DS from 'ember-data';

export default DS.Model.extend({
    pid: DS.attr('number'),
    match: DS.attr('number'),
    name: DS.attr('string'),
    point: DS.attr('number'),
    home: DS.attr('boolean'),
    squard: DS.belongsTo('squard'),
    selected: DS.attr('boolean', {default: false})
});

I create a new squad on client side and use push playerss using the following code

let player - this.store.peekRecord('player', id);
let squard = this.store.peekRecord('squard', 1);
squard.get('players').pushObject(player);

I tried using squard.save() but that doesn't send the array of players with it. How can i push those changes to server ?




ember js error before page loads

I am trying to upgrade ember application to 3.1.3. On main page load I am getting an error:

Could not find module `ember` imported from `ember-truth-helpers/utils/register-helper`

I upgraded the version to "ember-truth-helpers": "2.0.0" and ran npm install, but it still shows the same error.

Here are the package.json depdendencies.

 "devDependencies": {
    "broccoli-asset-rev": "^2.4.5",
    "ember-ajax": "^3.0.0",
    "ember-cli": "~3.1.3",
    "ember-cli-app-version": "^3.0.0",
    "ember-cli-babel": "^6.6.0",
    "ember-cli-dependency-checker": "^2.0.0",
    "ember-cli-eslint": "^4.2.1",
    "ember-cli-htmlbars": "^2.0.1",
    "ember-cli-htmlbars-inline-precompile": "^1.0.0",
    "ember-cli-inject-live-reload": "^1.4.1",
    "ember-cli-qunit": "4.3.2",
    "ember-cli-sri": "^2.1.0",
    "ember-cli-uglify": "^2.0.0",
    "ember-data": "3.1",
    "ember-export-application-global": "^2.0.0",
    "ember-load-initializers": "^1.0.0",
    "ember-maybe-import-regenerator": "^0.1.6",
    "ember-resolver": "^4.0.0",
    "ember-source": "3.2.0",
    "ember-welcome-page": "^3.0.0",
    "loader.js": "^4.2.3",
    "animateplus": "1.4.0",
    "body-parser": "1.15.2",
    "connect-restreamer": "1.0.3",
    "crossfilter": "1.3.12",
    "d3": "3.5.11",
    "dc": "2.0.0-beta.20",
    "ember-animatable": "0.1.6",
    "ember-api-actions": "0.0.11",
    "ember-autoresize": "1.3.0",
    "ember-bootstrap-datetimepicker": "1.1.0",
    "ember-browserify": "1.2.2",
    "ember-browsery-stats": "0.1.1",
    "ember-cli-autoprefixer": "0.5.0",
    "ember-cli-chart": "3.3.2",
    "ember-cli-content-security-policy": "1.0.0",
    "ember-cli-copyable": "0.9.6",
    "ember-cli-flash": "1.3.16",
    "ember-cli-mirage": "^0.4.7",
    "ember-cli-moment-shim": "3.7.1",
    "ember-cli-nouislider": "^0.13.0",
    "ember-cli-page-object": "^1.8.0",
    "ember-cli-release": "1.0.0-beta.2",
    "ember-cli-sass": "5.5.1",
    "ember-cli-selectize": "0.5.12",
    "ember-cli-test-loader": "^1.1.1",
    "ember-cli-test-recorder": "0.2.0",
    "node-sass": "^4.9.0",
    "ember-cookie-monster": "0.0.2",
    "ember-django-adapter": "1.1.2",
    "ember-href-to": "0.0.11",
    "ember-in-viewport": "2.0.8",
    "ember-light-table": "^1.12.1",
    "ember-modal-dialog": "^2.3.0",
    "ember-moment": "7.7.0",
    "ember-network": "0.1.0",
    "ember-polyfill-for-tests": "0.2.0",
    "ember-power-select": "^1.8.5",
    "ember-responsive": "^2.0.5",
    "ember-route-action-helper": "2.0.6",
    "ember-shepherd": "2.1.3",
    "ember-simple-auth": "1.3.0",
    "ember-slack-search-input": "^1.0.6",
    "ember-sortable": "1.8.2",
    "ember-tag-search-input": "0.6.0",
    "ember-tether": "0.3.1",
    "ember-tooltip": "0.1.0",
    "ember-truth-helpers": "1.3.0",
    "eslint-plugin-ember": "5.2.0",
    "eslint": "^3.14.1",
    "express": "4.14.0",
    "glob": "5.0.15",
    "http-proxy": "^1.16.2",
    "jison": "0.4.17",
    "morgan": "1.7.0",
    "multer": "1.2.0",
    "phantomjs-prebuilt": "^2.1.14"
  },
  "ember-addon": {
    "paths": [
      "lib/e-genesys"
    ]
  },
  "engines": {
    "node": ">=6.9.4"
  },
  "private": true,
  "dependencies": {
    "chart.js-rangeslider": "^1.2.1",
    "ember-cli-babel": "6.7",
    "node-sass": "^4.9.0",
    "npm": "^6.0.1"
  }




Ember js error on index page

I am trying to upgrade ember application to 3.1.3. On main page load I am getting an error:

Could not find module `ember` imported from `ember-simple-auth/configuration`

Here are the package.json depdendencies.

  "devDependencies": {
    "broccoli-asset-rev": "^2.4.5",
    "ember-ajax": "^3.0.0",
    "ember-cli": "~3.1.3",
    "ember-cli-app-version": "^3.0.0",
    "ember-cli-babel": "^6.6.0",
    "ember-cli-dependency-checker": "^2.0.0",
    "ember-cli-eslint": "^4.2.1",
    "ember-cli-htmlbars": "^2.0.1",
    "ember-cli-htmlbars-inline-precompile": "^1.0.0",
    "ember-cli-inject-live-reload": "^1.4.1",
    "ember-cli-qunit": "4.3.2",
    "ember-cli-sri": "^2.1.0",
    "ember-cli-uglify": "^2.0.0",
    "ember-data": "3.1",
    "ember-export-application-global": "^2.0.0",
    "ember-load-initializers": "^1.0.0",
    "ember-maybe-import-regenerator": "^0.1.6",
    "ember-resolver": "^4.0.0",
    "ember-source": "3.2.0",
    "ember-welcome-page": "^3.0.0",
    "loader.js": "^4.2.3",
    "animateplus": "1.4.0",
    "body-parser": "1.15.2",
    "connect-restreamer": "1.0.3",
    "crossfilter": "1.3.12",
    "d3": "3.5.11",
    "dc": "2.0.0-beta.20",
    "ember-animatable": "0.1.6",
    "ember-api-actions": "0.0.11",
    "ember-autoresize": "1.3.0",
    "ember-bootstrap-datetimepicker": "1.1.0",
    "ember-browserify": "1.2.2",
    "ember-browsery-stats": "0.1.1",
    "ember-cli-autoprefixer": "0.5.0",
    "ember-cli-chart": "3.3.2",
    "ember-cli-content-security-policy": "1.0.0",
    "ember-cli-copyable": "0.9.6",
    "ember-cli-flash": "1.3.16",
    "ember-cli-mirage": "^0.4.7",
    "ember-cli-moment-shim": "3.7.1",
    "ember-cli-nouislider": "^0.13.0",
    "ember-cli-page-object": "^1.8.0",
    "ember-cli-release": "1.0.0-beta.2",
    "ember-cli-sass": "5.5.1",
    "ember-cli-selectize": "0.5.12",
    "ember-cli-test-loader": "^1.1.1",
    "ember-cli-test-recorder": "0.2.0",
    "node-sass": "^4.9.0",
    "ember-cookie-monster": "0.0.2",
    "ember-django-adapter": "1.1.2",
    "ember-href-to": "0.0.11",
    "ember-in-viewport": "2.0.8",
    "ember-light-table": "^1.12.1",
    "ember-modal-dialog": "^2.3.0",
    "ember-moment": "7.7.0",
    "ember-network": "0.1.0",
    "ember-polyfill-for-tests": "0.2.0",
    "ember-power-select": "^1.8.5",
    "ember-responsive": "^2.0.5",
    "ember-route-action-helper": "2.0.6",
    "ember-shepherd": "2.1.3",
    "ember-simple-auth": "1.1.0",
    "ember-slack-search-input": "^1.0.6",
    "ember-sortable": "1.8.2",
    "ember-tag-search-input": "0.6.0",
    "ember-tether": "0.3.1",
    "ember-tooltip": "0.1.0",
    "ember-truth-helpers": "1.3.0",
    "eslint-plugin-ember": "5.2.0",
    "eslint": "^3.14.1",
    "express": "4.14.0",
    "glob": "5.0.15",
    "http-proxy": "^1.16.2",
    "jison": "0.4.17",
    "morgan": "1.7.0",
    "multer": "1.2.0",
    "phantomjs-prebuilt": "^2.1.14"
  },
  "ember-addon": {
    "paths": [
      "lib/e-genesys"
    ]
  },
  "engines": {
    "node": ">=6.9.4"
  },
  "private": true,
  "dependencies": {
    "chart.js-rangeslider": "^1.2.1",
    "ember-cli-babel": "6.7",
    "node-sass": "^4.9.0",
    "npm": "^6.0.1"
  }




dimanche 24 juin 2018

Ember Mirage Fake API test with Postman

I have my mirage setup which returns data on my defined models, for example if I call /api/users: it returns me all the fake users I need. If I take the same call and test it on Postman, it returns nothing? I thought mirage is acting like a fake API end point server and testing it with Postman will work. Am I missing anything here?




import materializecss javascript in ember

I would like to use materializecss framework in my ember app, but without using external ember-cli addons since many times I've tried them and always got problems; It has been easy to add materialize's css fonts and icons, but can't figure out how to import and use materialize.js from the official package;




Write an Or filter in Ember

I want to write an Or filter in Ember. The filter that I want to implement is as follows:

(end_date <= filter_end_date && end_date >= filter_start_date) || (start_date >= filter_start_date && start_date <= filter_end_date)

I am collecting all the filters together and then passing it while sending the query:

filterOptions: [
    {
      name : 'state',
      op   : 'eq',
      val  : 'published'
    }
  ]

Query is as follows:

return this.get('store').query('event', {
      sort   : 'starts-at',
      filter : filterOptions
    });

I went through the docs but didn't find anything. What is best way to model this filter?




samedi 23 juin 2018

Emberjs getJSON data from an url

I am a bit confused. Components, controllers, routes, helpers and whatsoever. I simply want to grab a value from a JSON file and calculate it with a value on Ember.Helper. Which way should i use, i cannot know anymore, brain burned. Would someone please help me to grab the "sell" part of the "market_name" which equals to "BTC_USDT" on "https://stocks.exchange/api2/prices" and put that into helper?




vendredi 22 juin 2018

How to specify compression for custom build environment in Ember

How do I specify compression, bundling and adding invalidation hashes to filenames for a custom environment?

The production environment will automatically compress and consolidate files and add invalidation hashes to the file names. I.e. whenever I use ember build --environment=production to trigger the if (environment === 'production'){} case in config/environment.js

But I want to create and build for a QA environment that also compresses files and adds invalidation hashes to file names. I.e. the following should also produce compressed files named with invalidation hashes:

config/environment.js

if (environment === `qa`){
    ENV.somevar = 'qa-value'
}

command

ember build --environment=qa




Best practice to organize list, view, create and update routes in Ember.js

Working for a few years with ember.js now, it's still not quite clear to me, what should be considered as best practice for structuring list, view, create and update routes.

The projects I've worked with so far mostly used to routing trees per entity. The pluralized entity name for listing with a subroute for create and the singular entity name for detail view with a subroute for editing. As an example a post model would have these for routes: /posts for listing posts, /posts/new for the create functionality, /post/:post_id for showing a single post and /post/:post_id/edit for editing that one. The corresponding router would look like this one:

Router.map(function() {
  this.route('post', { path: '/post/:post_id' }, function() {
    this.route('edit');
  });
  this.route('posts', function() {
    this.route('new');
  });
});

This approach is working quite nicely for detail and edit view cause they are sharing the same model. So the model hook of the edit route could just reuse the model of the detail view route. In ember code this looks like the following:

// app/routes/post.js
import Route from '@ember/routing/route';

export default Route.extend({
  model({ post_id }) {
    return this.get('store').findRecord('post', post_id);
  }
});

// app/routes/post/edit.js
import Route from '@ember/routing/route';

export default Route.extend({
  model() {
    return this.modelFor('post');
  }
});

Normally we would return a collection of posts from posts route model hook and not implementing the model hook of posts.new route (or returning a POJO / Changeset there depending on architecture but that's not the question here). Assuming we are not implementing the model hook of posts.new the routes would look like:

// app/routes/posts.js
import Route from '@ember/routing/route';

export default Route.extend({
  model({ post_id }) {
    return this.get('store').findAll('post');
  }
});

// app/routes/posts/new.js
import Route from '@ember/routing/route';

export default Route.extend({
});

But now this approach is not working well anymore cause a transition to posts.new route is blocked until the collection of posts are loaded. Since we don't need this collection to create a list of posts (at least if we only show them in posts.index route and not on all subroutes) this doesn't feel right.

Side note for those ones not that familiar with ember: Nested routes model hooks are executed in order. So in our case first the model hook of application route, afterwards posts route and then posts.new route waiting for any promise executed by one of them.

So what should then be considered as best practice?

  • Should the fetching of posts live in posts.index route if we are not showing them on nested routes?
  • Shouldn't the create route be a nested under the list route? So should we have posts, post-new, post and post.edit routes? Feels confusing since the post related code is splited over three route trees. Also it would go against the goal of the improved file layout being developed currently since the code would be splitted over three directories.
  • Should we just take the tradeoff of unnecessarily fetching the collection of posts since mostly the user flow comes from this route before the creation route and therefore the model hook is in most cases already loaded anyway?

Would appreciate any thoughts on that one. Decided to not ask that question in the community slack to better document the answer.




jeudi 21 juin 2018

Ember.js slow response from server, error `The adapter operation timed out`

There is an ember application with quite slow server-side app. One of the server api endpoints returns response in ~2 minutes by some circumstances.

In such cases I see an error in my browser console: The adapter operation timed out.

Is it possible to tweak ember.js api adapter timeout or somehow make ember app to interact with such slow endpoints?




Repeated options coming while clicking table rows

I’m having the table row, for that I have wrote right click option method by using below code and it working fine,

click: function (event) {        
        var isConnected = false;
        if(event){
            var isConnected = true;
        }
        if(isConnected == true) {
        var eventResult = this.get('tableView').clickRow(event, this.get('object'));
        console.log(eventResult);
        if (eventResult !== false) {
            this.get('element').focus();
            $('.content-data, .action-menu, .managed-object-tools-icon.clickable').bind('contextmenu', function(e) {
                e.preventDefault();
                var k = $(e.currentTarget).closest('tr').prop('id');
                var l = $('#'+k).hasClass('inspected');
                if(l == true) {
                    var actionMenuContext = this.get('object');
                    var element = e.currentTarget;
                    this.get('controller').send('contentItemActionMenu', row.length ? row : element, element, actionMenuContext);
                    isConnected = false;
                    return false;
                }
            }.bind(this))
        }
        return eventResult;
      }
    }

But while right clicking on the multiple rows continuously, the same options coming repeatedly on the backside. It have to disappear while clicking new table row and appear as single newly option. I’m using ember 1.4.0. Your help will be appreciate. Thanks in advance.




How to create right click option using ember

I am having table row, in that action icon only able to show left click options. Now I need to create right click option for action icon as well as to the total row.

Here is the picture for the row,

In that gear icon only we can able to left click to get options

For this html file having:

<tbody id="ember52450" class="ember-view body-view container-view">
<tr id="ember52672" class="ember-view content-row body-row-view container-view" tabindex="0" aria-label="">
<td id="ember52822" class="ember-view content-data item-number item-number-view container-view item-number-view-core_component_data-view-mixin container-view-core_component_data-view-mixin itemNumber">
<div id="ember52825" class="ember-view view">
<div>1</div>
</div>
</td>
<td id="ember52831" class="ember-view lmdd-menu actions container-view">
<rs-icon id="ember52834" class="ember-view action-menu icon clickable-icon" title="Actions and transitions" style="width: 1em; height: 1em; font-size: 20px">
<icon glyph="action" class="action" style="font-size: 20px;">
</icon>
</rs-icon>
</td>
<td id="ember52840" class="ember-view content-data view view-core_component_data-view-mixin name">
<div class="container">
<div class="content">autocomplete</div>
</div>
</td>
<td id="ember52846" class="ember-view content-data view view-core_component_data-view-mixin label">
<div class="container">
<div class="content">autodf</div>
</div>
</td>
</tr>
</tbody>

For this having corresponding ember file, In that of table part is below:

Core.component.ObjectTable.extend()
                .named("Admin.LMDView")
                .reopen({
                    controllerBinding: 'parentView.pagination',
                    modelBinding: 'controller.resultSet',
                    displayStartBinding: 'controller.contentPageStart',
                    displayLengthBinding: 'controller.contentPageLength',
                    noContentIcon: 'metadata',
                    noContentMessage: 'admin/navigators/administration/lmd/no-content',
                    hasHeader: true,
                    paginated: true,
                    trailingColumns: [],
                    columns: [
                        // TODO: Move labels into messageTable
                        { type: "actions", label: " " },
                        { name: "name", label: "Name" },
                        { name: "label", label: "Label" },
                    ],
                    getColumnView: function (column) {
                        if (column.type === 'itemNumber') {
                            return Core.view.Activity.ItemNumberView;
                        }
                        if (column.type === 'actions') {
                            return this.constructor.ActionsColumn;
                        }
                        if (column.type === 'boolean') {
                            return Core.component.ObjectTable.BooleanColumn;
                        }
                        if (column.name === 'description') {
                            return Core.component.ObjectTable.NullableColumn;
                        }
                        if (column.name === 'elementCriteria') {
                            return Admin.ElementCriteriaColumn;
                        }
                        if (column.type === 'icon') {
                            return Core.component.ObjectTable.IconColumn.extend({ withName: true });
                        }
                        return Core.view.Activity.GenericDataView;
                    },
                    getHeaderView: function (column) {
                        if (column.icon && column.type === 'boolean') {
                            return Core.component.ObjectTable.IconHeader;
                        }
                        if (column.type === 'itemNumber') {
                            return Core.component.ObjectTable.ItemNumberHeader;
                        }
                        if (column.type === 'selection') {
                            return Core.view.Activity.SelectionCheckmarkView;
                        }                       
                        return Core.component.ObjectTable.DefaultHeaderView;
                    }
                }).reopenClass({
                    ActionsColumn: Ember.ContainerView.extend()
                        .named("Admin.navigators.Administration.LMD.Actions")
                        .reopen({
                            tagName: 'td',
                            classNames: [ 'lmdd-menu' ],
                            childViews: [
                                Core.view.Icon.extend({
                                    model: 'action',
                                    classNames: [ 'action-menu' ],
                                    size: 20,
                                    titleBinding: 'Core.messageTable.workflow/chrome/action-menu',
                                    click: function () {
                                        var lmdd = this.get('parentView.rowView.object');
                                        var lmdds = this.get('parentView.rowView.tableView.model');
                                        var model = Core.model.Menu.create({
                                            loadState: 'done',
                                            content: [
                                                Core.model.Menu.Item.create({
                                                    label: 'Delete LMD Definition',
                                                    icon: 'delete',
                                                    invoke: function () {
                                                        var fmtLabel = lmdd.label ? (lmdd.label + " ("+lmdd.name+")") : lmdd.name;
                                                            Core.confirm(
                                                                "Delete LMD Definition",
                                                                "Are you sure you want to delete the LMD Definition for " + fmtLabel + "?",
                                                                "Delete",
                                                                "Cancel"
                                                            ).then(function () {
                                                                Core.services({
                                                                    service: 'lmdd',
                                                                    type: 'delete',
                                                                    data: {
                                                                        name: lmdd.name
                                                                    }
                                                                }).done(function () {
                                                                    lmdds.reload();
                                                                    Core.notify({
                                                                        title:"Delete LMD Definition",
                                                                        message: "LMD Definition " + fmtLabel + " deleted"
                                                                    });
                                                                });
                                                            });
                                                    }
                                                })
                                            ]
                                        });
                                        var view = Core.view.Menu.create({
                                            model: model,
                                            menuContext: { lmdd: lmdd },
                                            anchor: this.$(),
                                            highlight: this.$().parent('tr:first')
                                        });
                                        view.show();
                                        return false;
                                    }
                                })
                            ]
                        })
                })

I need the right click options come for whole table row(every "td"). I'm using ember 1.4.0 version. I'm new to the Ember. Please ask me if you need further details also. Your help will be appreciate. Thanks in advance.




mercredi 20 juin 2018

Add auth token in request header in ember-file-upload

I am using ember vesrion 2.15.1 for my application. I am using ember-file-upload node module to support file upload and that is successful. Challenge is I am not able to add auth token to the request header. My request header looks like this:

enter image description here I am not able to add userAuthToken in request header of file upload like below which I am able to add for other api calls:

enter image description here

I have tried uploading the file via

set(file, 'headers.userAuthToken', localStorage.getItem("userToken")); // this line is creating problems
let response = yield file.upload(url);

But unable to add userAuthToken in request header. Any fix or workaround will be appreciated.




OPTIONS HTTP method instead of GET

I am new to ember js. From a route I am using this line this.get('store').findAll('users'); Instead of setting HTTP method GET, it is setting HTTP method OPTIONS.

Because of server is getting OPTIONS HTTP method, server side i am getting error.

io.katharsis.errorhandling.exception.MethodNotFoundException: OPTIONS: /users/

and in browser I am getting this error Request header field Access-Control-Allow-Origin is not allowed by Access-Control-Allow-Headers in preflight response. I am having the below code in application adapter and @CrossOrigin(origins="*") on Spring Rest API side.

import DS from 'ember-data';

export default DS.JSONAPIAdapter.extend({

init() {
    this._super(...arguments);

    this.set('headers', {
      'Access-Control-Allow-Origin': '*'
    });
  },

  host: 'http://localhost:8082',
  namespace: 'spring-katharsis'
});

If the request contain HTTP method GET, I think it may solve the issue.

Please help on this.




How to dynamically form a Table column based on JSON Values in Ember 1.10

I am using Ember 1.10 version

[{
        "name": "John",
        "city": "New York",
        "status": false
    },
    {
        "name": "SAAA",
        "city": "California",
        "status": true
    },
    {
        "name": "Vignesh",
        "city": "India",
        "status": false
    }
]

Based on the above JSON i am forming a table . Incase the status is false , i need to show a different column and vice versa

But irrespective of status , its displaying a same Value .

<script type="text/x-handlebars">
   
</script>
<script type="text/x-handlebars" data-template-name="index">
   <table class="table table-striped table-condensed">
    <thead>
        <tr>
            <th>Participant</th>
        </tr>
    </thead>
    <tbody id="ParticipantList">
        
            <tr>
                <td> </td>
                <td> </td>
                     
                <td>  True</td>
                    
                <td>  False</td>
               
            </tr>
        
    </tbody>
   </table>
</script>

http://jsfiddle.net/mnvqd1jk/86/




regular expression for (000)000-0000 not working?

Regular expresson not working properly but it works for other regex like /.*/

if(value == 'phone'){
     if(this.get('user.phone').length>0){
      if (( /^\(\d{3}\)\s\d{3}-\d{4}$/.test(this.get('user.phone'))) ){
        const user_obj = {
            phone: this.get('user.phone'),
            sessionid: localStorage.getItem('session_id'),
        }
        set(this, 'pass_user', user_obj);
        this.set('invalidPhone', false);
      }
      else{
        this.set('invalidPhone', true);
      }     
    }
    else{
      this.set('invalidPhone', false);
    }
  }




mardi 19 juin 2018

Javascript Facebook Login Flow PWA

I'm using EmberJS to build a PWA that implements Facebook Login. When it's used as a "installed" PWA Facebook SDK is not working and gives a blank page after permissions are given. So I had to implement Facebook Login Flow and everything was working until lst week.

var permissionUrl = "https://www.facebook.com/v2.8/dialog/oauth?client_id=CLIENTID&redirect_uri="+window.location.href+"&scope=email,public_profile";
window.location = permissionUrl;

This code only runs after checking if it's in "Standalone". Now when I run the same thing in my Android phone it opens Facebook App, asks for permission and goes to de redirect but in a webview inside Facebook App.

The code was not changed from when it was working.

Any help would be much appreciated.




Rest Adapter set dynamic host and headers depending on route

I have an existing ember application whose APIs are being updated and shifted on different server. So, currently some routes need old API and some need new API. I don't want to create separate adapters for these routes. I want to manage both new and old APIs with application.js adapter and serializer.

On serializer end, i have made a transformer mixin which is fine. But on adapter (adapters/application.js) i cannot set host and headers dynamically based on route. For pathForType i have used a method in mixin which returns new/old API path based o route name. Cannot set header and host this way.

Can someone suggest a way to handle this ??




lundi 18 juin 2018

Ember - multi-sort table

Is there a multi-sort table in Ember? Something like what you can do in excell?

I've only seen a simple sort and filter. http://crodriguez1a.github.io/ember-sort-filter-table/




How to run an action on every route transition in ember?

I have an Ember application with several routes and I want to scroll the page to top every time the user makes a transition. The problem is that I don't want to duplicate the same code on every route's didTransitionmethod.

So, Is there a way that I can observe all routes transitions and execute (declare) an action in just one place ?

Another way to put put this: If I have a parent route, can I fire the same action to all of its children ?

My current solution is to fire the action on every route's didTransition method like this:

//router.js
Router.map(function() {
  this.route('login');
   this.route('portal',{ path:'/'}, function() {
      this.route('clientes');
      this.route('convite');
      this.route('usuario', function() {
      this.route('view', { path: '/:id' });
  });
 });

 //everyChildren.route.js
 didTransition(){
   this.super(...arguments);
   Ember.$("html, body").animate({ scrollTop: 0 }, "slow");
 }

Is there a way to do this ?

PS:. I am using Ember version 2.14.0




How to set Ember model default value when no data type specified?

How can I add a default value to an Ember model that does not have a data type specified.

import DS from 'ember-data'

export default DS.Model.extend({

  // with data type specified
  propertyString: DS.attr('string'),
  propertyWithDefault: DS.attr('number', {default: 0}),
  propertyWithFunctionDfault: DS.attr('date', {
      defaultValue() { return new Date() }
  }),

  // How to set default when no type defined
  propertyNoType: DS.attr(),
  propertyNoTypeWithDefault: DS.attr(null, {default: 0}) // does not work

})

https://guides.emberjs.com/release/models/defining-models/#toc_options