JsRender if-else renders nothing - javascript

I have a simple model:
var model = [{
content: "",
type: "photo",
src: "xxx"
}, {
content: "",
type: "quote",
text: "blah"
}];
and a simple template:
{{if type eq='photo'}}
<img src="{{:src}}" />
<div class="photo-caption">
{{:caption}}
</div>
{{else type eq='quote'}}
<div class="quote-text">
{{:text}}
</div>
{{/if}}
The problem is that the template renders nothing at all when the type is "quote". If I change it slightly to two ifs instead of an if-else, it renders the quote, but also renders the div class="photo-caption">. I need it to only render one or the other. I have a feeling it's a simple matter of syntax, but can't seem to find sufficient docs on how this is done correctly on the JsRender site.
Here's a fiddle. The two templates should behave exactly alike. Instead one renders both, the other renders only the image.

I got it:
{{if type == 'quote' }}
<div>
{{: text }}
</div>
{{else type == 'photo'}}
<div>
{{: src }}
</div>
{{/if}}
http://jsfiddle.net/4QzZX/2/

When you tried the version with two if statements, did you remember to add a {{/if}} in addition to changing the {{else}} into an {{if}}?
{{if type eq='photo'}}
<img src="{{:src}}" />
<div class="photo-caption">
{{:caption}}
</div>
{{/if}}
{{if type eq='quote'}}
<div class="quote-text">
{{:text}}
</div>
{{/if}}

Related

Accessing nested objects VueJS during for loop

I am trying to dynamically create a form (why? It's 200+ fields long and I am not permitted to modify it). The entire app is in the VueJs environment.
The problem I'm having is that each field requires different things (obviously). I'm trying to add attributes dynamically to each field, which would allow me to render the entire form dynamically, rather than hard coding a 200+ field form. So in my stupidity I'm taking more time trying to solve this problem than it would take to just hard code the form. Oh well...
Here's a specific (simplified) example of what I want to do...
data() {
return {
form: {
input1: {value: "", classIWantToDynamicallyAdd: "FieldSizeSmallAF"},
input2: {value: "", classIWantToDynamicallyAdd: "FieldSizeBigAF"},
//Repeat 200 times
}
}
}
Now ultimately I want to get the value of "classIWantToDynamicallyAdd" and :class="put it here"
The HTML looks like this:
<template>
<div>
<div v-for="(field, index)" in form" :key="index">
<div class="labelAndInput" :class="**I don't know what to do here**">
<label>index</label> // Successfully outputs: "input1", "input2", etc...
<input>
</div>
</div>
</div>
</template>
Hopefully that's somewhat clear. I expected form.index.classIWantToDynamicallyAdd to work, but it did not, i got the following error:
TypeError: "_vm.form.index is undefined".
Thanks in advance!
You could do :class="[field.classIWantToDynamicallyAdd]" :
<div v-for="(field, index)" in form" :key="index">
<div class="labelAndInput" :class="[field.classIWantToDynamicallyAdd]">
....
<input>
</div>
</div>
You could define those class names on data() and just bind it to :class
Example:
https://jsfiddle.net/pguti19/hL2vamnw/
More help:
https://michaelnthiessen.com/dynamically-add-class-name/
<div id="app">
<h1>
Forms:
</h1>
<div v-for="(field, index) in form" :key="index">
<span :class="field.class">
Using {{field.class}} class
</span>
</div>
</div>
<script>
new Vue({
el: "#app",
data: {
form: {
input1: {value: "", class: "red-theme"},
input2: {value: "", class: "blue-theme"},
input3: {value: "", class: "green-theme"}
},
theme1: 'blue-theme',
theme2: 'red-theme',
theme3: 'green-theme'
},
methods: {
toggle: function(todo){
todo.done = !todo.done
}
}
})
</script>

Vue: Setting initial data string with link

I have an array of objects as boxData in my initial data. How would I go about making the word "here" a hyperlink that I can use whenever referencing boxData?
data() {
return {
boxData: [
{
body: "This is the link here."
},
{
body: "Normal text."
}
]
}
}
Child component
<div v-for="(box, index) in boxData" class="box">
<div>
{{ box.body }}
</div>
</div>
Ideally, the objects with a link would have a property like url. Then, assuming all of the links should say "This is the link here", you could do:
<div v-for="(box, index) in boxData" class="box">
<div>
<template v-if="box.url">
This is the link <a :href="box.url">here</a>.
</template>
<template v-else>
{{ box.body }}
</template>
</div>
</div>
Then you don't need "This is the link here" in any of the objects.
You just have to put the data into the hyperlink like so:
<a :href="boxData.body">Here</a>
Much better
<router-link :to="boxData.body">Here</router-link>

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.

Create an ember component for input validation

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.

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