Create an ember component for input validation - javascript

I have a form in an Ember app which is starting to get a bit ugly after adding in server side validation feedback and I have tried to convert it into a component using This link as a base
My current input box looks like this:
<div class="form-group">
<label class="group-label">Message:</label>
{{textarea value=model.message classNames="group-control" placeholder="Message"}}
</div>
<div {{bind-attr class=":form-group model.errors.message:has-error"}}>
<label class="group-label">Message:</label>
{{input value=model.message classNames="group-control" placeholder="Message"}}
</div>
{{#if model.errors.message}}
<div class="group-errors">
{{#each error in model.errors.message}}
<div class="error">
{{error.message}}
</div>
{{/each}}
</div>
{{/if}}
I would like to convert that into a component, this is what I currently have:
form-input.hbs
<div {{bind-attr class=":form-group hasError:has-error"}}>
<label class="group-label" {{bind-attr for=label}}>{{label}}</label>
{{yield}}
</div>
{{#if errors.length}}
<p>Errors</p>
<span class="help-block">
{{errors}}
</span>
{{/if}}
form-input_component.coffee
App.FormInputComponent = Ember.Component.extend
label: Em.computed 'for', ->
#get('for').underscore().replace(/_/g, " ").capitalize()
hasError: (->
#get('object.errors')?.has #get('for')
).property 'object.errors.[]'
errors: (->
return Ember.A() unless #get('object.errors')
#get('object.errors').errorsFor(#get('for')).mapBy('message').join(', ')
).property 'object.errors.[]'
This displays the input field correctly but the errors do not display, I am missing something but I am not sure what it is.

Related

getValue not working on custom template

I've been able to make my own field, using a costum template. This field consist in a textField followed by button at the end, on the same line, but I'm confronted to an issue.
When I'm using form.getValue(), it does return the original values, I mean, if I modify 1 field and then do a getValue(), the modification won't be visible and I will still get the value I had when loading the form.
I'm pretty sure there is a problem with my template but I can't figure what to do ! :(
Here is my templates code :
{% raw %}
<script type="text/x-handlebars-template" id="input-group-addon-template">
<div class="input-group">
<input type="{{inputType}}" value="{{data}}" id="{{id}}" {{#if options.placeholder}}placeholder="{{options.placeholder}}"{{/if}} {{#if options.size}}size="{{options.size}}"{{/if}} {{#if options.readonly}}readonly="readonly"{{/if}} {{#if name}}name="{{name}}"{{/if}} {{#each options.data}}data-{{#key}}="{{this}}"{{/each}} {{#each options.attributes}}{{#key}}="{{this}}"{{/each}}/>
<div class="input-group-btn" id="{{id}}-basic-btn">
<button class="btn btn-default" id="{{id}}-button" onclick="test(event)" >
<i {{#if options.readonly}}class="fa fa-lock"{{else}}class="fa fa-unlock"{{/if}}></i>
</button>
</div>
</div>
</script>
{% endraw %}
<script>
With some help, I've been able to get it to work. So I just had to modify the template, new template :
<script type="text/x-handlebars-template" id="input-group-addon-template">
<div class="input-group">
{{#control}}{{/control}}
<div class="input-group-btn" id="{{id}}-basic-btn" >
<button class="btn btn-default" id="{{id}}-button" onclick="click_function(event)" >
<i {{#if options.readonly}}class="fa fa-lock"{{else}}class="fa fa-unlock"{{/if}}></i>
</button>
</div>
</div>
</script>
So the big difference is that we don't precise the "input-type" anymore so that we don't override all usefull function as getValue etc.
Feel free to add some explication ! :D

Bigcommerce - Display Certain Message/Image on a specific Category/Product

I'm fairly new to Big Commerce and had a question on how I'd be able to display an image / certain message on a specific category.
I currently have a free shipping image being displayed on all products but there's a certain category that I do not want that snippet of code being displayed.
How would I be able to achieve this?
The way I have the free shipping image being displayed is by modifying the card.html file
templates > components > products > card.html
Thanks!
You can consider inserting the image via banner on specific categories.
After this you can inject css via jQuery or override with plain css to display the banner wherever you like.
yourstore.xyz/manage/marketing/banners/create
Edit 1
Wrapping your div to if also should solve your issue on displaying that image in certain products.
{{#if product.shipping}}
{{#if product.shipping.price.value '===' 0}}
<img class="yourImgClass">{{imgURL}}
{{/if}}
{{/if}}
Edit 2
Here's the JS way to remove some elements from your specific categories:
var url = location.href;
if ( url.indexOf( 'your-url' ) !== -1 ) {
document.getElementById('your-free-shipping-image-id').remove();
console.log("yay, image bye");
}
else {
console.log("nay, image stays");
}
Edit 3
This is sort of a shift-make workaround with limited knowledge on jQuery. This would be much easier if you could place ID's on image wrapping span elements but I think you'll be alright with this.
Place this on footer, inside brackets.
$(document).ready(function() {
var s = $('img[src*="https://cdn7.bigcommerce.com/s-7iywz/product_images/uploaded_images/free-shipping-banner.jpg"]');
var url = location.href;
console.log(s.length);
if ( url.indexOf( 'framed' ) !== -1 ) {
s.remove();
}
});
You could try exempting that category (via ID or name) in particular with a conditional statement.
As an example, you might try:
{{#unless category.id '==' 5321}}
Free shipping!
{{/unless}}
Or for if/else:
{{#if category.id '==' 5321}}
No free shipping!
{{else}
Free shipping!
{{/if}}
Thanks for that but it still doesn't seem to be working.
Also there was a glitch with your code
You had {{/unless}} instead of {{/if}}
So this is what I used:
{{#if category.id '==' 70}}
No free shipping!
{{else}}
Free shipping!
{{/if}}
I've attached the Category ID which is 70
Everything on the store still shows the Free Shipping
If you want to remove "Free Shipping" from single category then use below code and get it fixed.
{{#if id '!=' 70 }} Free Shipping Message}} {{/if}}
If it doesn't work for you then i suggest you to post the "Card File" code here so that i can check what exactly you have written in the code.
<article class="card {{#if alternate}}card--alternate{{/if}}">
<figure class="card-figure">
{{#or price.non_sale_price_with_tax price.non_sale_price_without_tax}}
{{#if theme_settings.product_sale_badges '===' 'sash'}}
<div class="sale-flag-sash">
<span class="sale-text">On Sale!</span>
</div>
{{else if theme_settings.product_sale_badges '===' 'topleft'}}
<div class="sale-flag-side">
<span class="sale-text">On Sale!</span>
</div>
{{else if theme_settings.product_sale_badges '===' 'burst'}}
<div class="starwrap">
<div class="sale-text-burst">On Sale!</div>
<div class="sale-flag-star"></div>
</div>
{{/if}}
{{/or}}
{{#if demo}}
<img class="card-image lazyload" data-sizes="auto" src="{{cdn 'img/loading.svg'}}" data-src="{{getImage image 'productgallery_size' (cdn theme_settings.default_image_product)}}" alt="{{image.alt}}" title="{{image.alt}}">
{{else}}
<div class="card-image-container">
<a href="{{url}}">
<img class="card-image lazyload" data-sizes="auto" src="{{cdn 'img/loading.svg'}}" data-src="{{getImage image 'productgallery_size' (cdn theme_settings.default_image_product)}}" alt="{{image.alt}}" title="{{image.alt}}">
</a>
</div>
{{/if}}
</figure>
<div class="card-body">
<h4 class="card-title">
{{#if demo}}
{{name}}
{{else}}
{{name}}
{{/if}}
</h4>
<div class="card-text" data-test-info-type="price">
{{#or customer (if theme_settings.restrict_to_login '!==' true)}}
{{> components/products/price price=price customer=customer}}
{{else}}
{{> components/common/login-for-pricing}}
{{/or}}
</div>
<p class="card-text" data-test-info-type="productRating">
<span class="rating--small">
{{> components/products/ratings rating=rating}} <span style="color:gray;">{{#if num_reviews '>' 0}}</span>
({{num_reviews}}) Review{{#if num_reviews '>' 1}}s
{{/if}}{{/if}}
</span>
</p>
{{#if id '!=' 70 }}
<span><img src="https://cdn7.bigcommerce.com/s- 7iywz/product_images/uploaded_images/free-shipping-banner.jpg?t=1525811996&_ga=2.165904830.1847420277.1525706943-52562068.1494873040"></span>
{{/if}}
</div>
</article>
i have modified your code, just copy it and paste it in your theme.

I cant seem to find the error in Meteor

I am new at meteor and I am having some issues. I am creating a social network app and what it basically does is signs up user and the user can post and follow others. Thats the basic functionality it does right now. I want to add something that when a user clicks on other users profile it shows that users post. But the code isnt working and doesnt show any error at all
Template
<template name="profileArea">
{{#if currentUser}}
<div id="side-profile" class="side-box">
<a class="filter-user">{{currentUser.username}}</a>
</div>
{{/if}}
<div id="side-all" class="side-box">
<a class="community">Community</a>
</div>
{{#if currentUser}}
<div id="side-like" class="side-box">
<h3>Following</h3>
<div class="boxcontent">
{{#each username in following}}
<div>
<a class="filter-user">{{username}}</a>
</div>
{{/each}}
</div>
</div>
<div id="side-likeyou" class="side-box">
<h3>Follows You</h3>
<div class="boxcontent">
{{# each followers}}
<div>
<a class="filter-user">{{username}}</a>
</div>
{{/each}}
</div>
</div>
{{/if}}
</template>
Code:
Template.profileArea.events({
'click .filter-user': function(event){
event.preventDefault();
var selectedUser = event.target.text;
Session.set('username', selectedUser);
},
'click .community': function(event){
event.preventDefault();
Session.set('username', null);
}
});
Template.postsList.helpers({
posts: function() {
//Stuff should happen here but its not -_-
var result;
if(Session.get('username')){
result = Post.find({username: Session.get('username')}, {sort:{created: -1}});
}
else{
result = Post.find({}, {sort:{created: -1}});
}
return result;
}
});
The problem in this case is that you have never actually rendered your postsList template (you have only just defined it).
If you want to actually see postsList you need to call {{> postsList }} from somewhere in your profileArea's HTML. This will render that template and then your postsList.posts helper will execute (and change reactively when Session.get('username')) changes.
Maybe add this after the 'Follows You' section of the profile.
<div id="side-posts" class="side-box">
<h3>Posts</h3>
<div class="boxcontent"> {{> postsList }} <div>
</div>

Ember JS Enable dropdown only on element which was clicked

I am an Ember newbie and can't get my head around how to run events on specific elements populated via records on my ember model.
Here is my Template
{{#each user in model }}
{{#each activecredit in user.activecredits}}
<div class="col-lg-2 hive-credit-box active-credit">
<div class="credit-brandname">
{{activecredit.Brandname}}
</div>
<div class="credit-brand-image-container">
<img src="http://localhost:3000/{{activecredit.Imglocation}}" class="credit-image"/>
</div>
<div class="hive-credit-percent"><img class="hive-filled-container" src="imgs/hivefilled9.png"/></div>
<div class="hive-credit-dollars">$xx.xx</div>
<div {{bind-attr class=activecredit.Brandname}} {{action 'enableTrade'}}><img src="imgs/trade_button.png" class="credit-trade-button" /></div>
<div class="credit-brand-amount">
xx%
</div>
<!-- Trade button click dropdown -->
{{#if isSelected}}
<div class="hivetrade">
<div class="arrow_box">
Hi there
</div>
<div class=""></div>
</div>
{{/if}}
</div>
{{/each}}
{{/each}}
Now I want to show a drop down on each element on click of a button .
When I set the enableTrade action , all dropdowns of all the divs show up.
actions:{
enableTrade:function(){
this.set('isSelected',true);
}
}
How do I enable only the dropdown in the particular div that was created.
I suppose I need to bind certain attributes to each div,but how do I access which div was clicked in my controller?
Any help would be appreciated .
Thanks
You can pass params through the action helper, and use them to set isSelected on the appropriate item.
{{#each model as |user| }}
{{#each user.activeCredits as |activeCredit|}}
<button {{action 'enableTrade' activeCredit}}>Enable Trade</button>
{{#if activeCredit.isSelected}}
<div class="hivetrade">Hello World</div>
{{/if}}
{{/each}}
{{/each}}
To handle it:
actions:{
enableTrade:function(credit) {
credit.set('isSelected',true);
}
}
If you need to allow only one credit to be selected at a time, your controller and action could be modified like this:
selectedCredit: null,
actions:{
enableTrade:function(credit) {
// unselect the previously selected credit
if (this.get('selectedCredit')) {
this.set('selectedCredit.isSelected', false);
}
// select, and cache the selection choice
credit.set('isSelected',true);
this.set('selectedCredit', credit);
}
}

Using summernote with meteor (Discover Meteor)

So, I've been working with Discover Meteor, and I'm having problems.
I'm trying to insert what content inputted in summernote into mongo but I'm having a few problems.
post_submit.html
<div class="form-group {{errorClass 'content'}}">
<textarea class="form-control" name="content" id="summernote"></textarea>
</div>
post_submit.js
var post = {
url: checkURLPrefix( $(e.target).find('[name=url]').val() ),
title: $(e.target).find('[name=title]').val(),
content: $(e.target).find('[name=content]').val()
};
lib/posts.js (will say Match Failed error when submitting)
meteor.methods({
postInsert: function(postAttributes) {
check(this.userId, String);
check(postAttributes, {
title: String,
url: String,
content: function(content){$('[name=content]').html($('#summernote').code());}
});
I've tried content: String to input the data into mongo. It would work but when I tried to load {{content}} in the post_page.html file, it would just show the unrendered HTML codes. {{{content}}} would show to content properly rendered but would mess up the functionality of the sorting system based on votes.
I'm really lost here and I wish I could find a solution soon.
Thank you in advance!
EDIT1: Here is my post_page.html and what I see when I insert content: String and load with {{content}}
<template name="postPage">
{{> postItem}}
<div class="col-md-12" style="background:blue;">
{{content}}
</div>
<ul class="comments">
{{#each comments}}
{{> commentItem}}
{{/each}}
</ul>
{{#if currentUser}}
{{> commentSubmit}}
{{else}}
<p>Please log in to leave a comment.</p>
{{/if}}
</template>
http://i.imgur.com/Fm0CXAN.png
First: you should use summernote in a div, not a textarea.
And in post_submit.js you have to leave it like this:
var post = {
...
content: $(e.target).find('#summernote').code()
};
In your post_page.html use triple brackets, because its HTML.
<div class="col-md-12" style="background:blue;">
{{{content}}}
</div>

Categories