I have the following knockout bindings...
<ul class="list-group" data-bind="foreach: $parent.levels">
<li class="list-group-item">
<img alt="level" class="pic" data-bind="attr:{src: '../../Content/images/levels/' + $index() + '.png'}" />
<button class="btn btn-default piclabels" data-bind="click:$parent.startingLevel.bind($parent,$index()),text:$data,css:{active:$parent.startingLevel() == $index()}"></button>
</li>
</ul>
I want to remove the img tag and instead apply background images to the button. I have tried multiple examples all over the web, including from knockout, but I haven't been able to get it to work.
data-bind="style: {background: 'url('../../Content/images/levels/' + $index() + '.png')' repeat-none left}"
What am I doing wrong?
When using the style binding, each style needs to return a string for the whole value. So if you are using single quotes such as in a url you need to escape them using backslash \. Instead of repeat-none, I think you meant to use no-repeat.
data-bind="style: {background: 'url(\'../../Content/images/levels/' + $index() + '.png\') no-repeat left' }"
JsFiddle
Related
I am new in VUE JS.
I have a form where I want to add multiple media.
So on click of "Add media" button i want to add "li" tag with respective html content in which i have on remove button too.
On click on remove button i want to delete the respective li.
What will be the best way to do this?
Here is what i have done so far
HTML:
<div class="col-md-10">
<button #click="addMediaRow()" class="btn btn-primary" :disabled="mediaRowCount >= 3" type="button">Add Media</button>
<br>
<br>
<ul style="list-style-type: none; padding: 0;" id="project_media_ul">
<li v-for="(row, index) in mediaRowArr">
<span v-html="row.template"></span>
</li>
</ul>
</div>
JS
In data i have declared variable
mediaRowLI: '<a v-on:click="openMediaFileInput"><i class="fa fa-camera fa-2x"></i> \n' +
' <span class="photospan">Add Photo </span></a>\n' +
' or Input Video URL here : <input type="text" class="form-control"\n' +
' placeholder="use embed URL, e.g. www.youtube.com/embed/EXa9ZeqRKl8"\n' +
' name="media_video_url" style=" width: 50%">\n' +
' \n' +
' <i class="fa fa-close"></i>\n' +
'\n' +
' <input multiple type="file" accept=\'image/x-png,image/jpeg\' name="media_images"\n' +
' style="visibility: hidden;">\n' +
''
Methods :
addMediaRow () {
this.mediaRowArr.push({
template: this.mediaRowLI
})
},
removeMediaRow (key) {
this.mediaRowArr.splice(key, 1)
},
Thanks in advance
Note that:
you cannot use v-html to compose template partials, because Vue is
not a string-based templating engine. Instead, components are
preferred as the fundamental unit for UI reuse and composition.
(source)
meaning html raw with v-on:click="removeMediaRow" doesn't work.
As the documentation says, you should create a component instead.
(jsfiddle example here)
I know that there are some associated questions about it, I tried all solutions and read all documentation, but w/o result.
I am initializing a Owl carousel :
HTML
In HTML, I have 2 items :
<div class="owl-carousel owl-theme all_diplomas">
<div class="item diploma-0">
<div class="content_diplomas">
<a data-fancybox="gallery" href="images/6.jpg"><i
class="material-icons">search</i></a>
<figure><img src="images/6.jpg" alt=""></figure>
</div>
<button class="waves-effect delete-diploma waves-blue diploma-0" type="button"><span>x</span> </button>
</div>
<div class="item">
<div class="add_diplomas">
<div class="item_add_diplomas">
<span class="plus_add">+</span>
<span class="txt_btn">Add diploma<br></span>
<input id="generateInputsForDiplomas">
</div>
</div>
</div>
</div>
JS :
$(".all_diplomas").owlCarousel({
loop: true,
margin: 15,
responsive: {
1000: {
items: 4
},
1200: {
items: 2
}
},
});
Next, after my script initialization :
$('input#generateInputsForDiplomas').on('click',function() {
var template = '<div class="item diploma-' + index + '"> <div class="content_diplomas"> <a class="diploma-' + index + '" data-fancybox="gallery" href="images/3.jpg"><i class="material-icons">search</i></a>' +
'<figure><img src="images/3.jpg" class="addedDiplomaInput diploma-' + index + '"alt=""></figure> </div> </div>'
+ '<button class="waves-effect delete-diploma waves-blue ' + classes + '" type="button"><span>x</span> </button>';
var newEl= $('.all_diplomas').trigger('add.owl.carousel', [template, 33]).trigger('refresh.owl.carousel');
});
Code above just adds a block of owl-item with one image and some id-s
and classes.
Then, it appends this template to position 33 and refreshes the
carousel
Them, each element has a delete button associated to owl-item class
$(document).on('click', 'button.delete-diploma',function() {
$(".all_diplomas").trigger('remove.owl.carousel', 33).trigger('refresh.owl.carousel');
});
That's the thing. When adding an element, from documentation, I am setting the position for this element explicitly - like 33. But when I am calling the button that is responsable to remove item with position 33, it deletes entire slider, or sometimes unexpected behavior.
The reason why I'm calling position explicitly, because I need to know each item's index, because when calling delete button, to know item with which position to delete. Documentation offers callbacks that has this information, but not for "add" event.
How can I lifehack that problem? I want to add n-items to carousel, and each this block with image to has it's own delete button. So, when calling this button, it will delete that element and refresh the Owl. I tried with pure jQuery to delete parents and so on... but Owl generates some other classes, and because of it, item is deleted, but empty spaces in slider remains.
Am new to Angularjs, any one can help me about this
infact my array is like this
array = [{"loc_name":"pronto network office","address":"3rd floor, kalyani motors","ap":[]}],
but when i use at dynamically its converted like this
[" {\"loc_name\":\"pronto="" network="" office\",\"address\":\"3rd="" floor,="" kalyani="" motors\",\"ap\":[]}"]
finally i want like this
<ul ng-repeat="loc in [" {\"loc_name\":\"pronto=" " network=" " office\",\"address\":\"3rd=" " floor,=" " kalyani=" " motors\",\"ap\":[]} "]"="">
<li class="clearfix">
<div class="list-icon">
<i class="fa fa-user"></i>
</div>
<div class="location-info">
<h4 class="location-name">{{ loc.loc_name }}</h4>
<p class="location-address">{{ loc.address }}</p>
</div>
</li>
<li ng-if="loc.aps != '' ">
<ul ng-repeat="ap in loc.aps">
<li class="clearfix">
<div class="list-icon">
<i class="fa fa-user"></i>
</div>
<div class="location-info">
<h4 class="location-name">{{ ap.mac_id }}</h4>
<p class="location-address"></p>
</div>
</li>
</ul>
</li>
</ul>
Your response should not contain " at starting of object inside array right after [ and just before ] need to remove " like it should be like [{\"loc_name\":\"pronto="" network="" office\",\"address\":\"3rd="" floor,="" kalyani="" motors\",\"ap\":[]}]
Then place it in your scope variable $scope.locations = [{\"loc_name\":\"pronto="" network="" office\",\"address\":\"3rd="" floor,="" kalyani="" motors\",\"ap\":[]}] & refer that scope variable on html then you need to worry about to convert it to double quote" to '`' single quote.
<ul ng-repeat="loc in locations">
...
<ul>
You can just use single quotes instead of ":
<ul ng-repeat="loc in [{loc_name: 'pronto network office', address: '3rd floor, kalyani motors', ap: []}]">
<!-- ... -->
</ul>
You can also omit quotes around keys: string inside ngRepeat doesn't have to comply string JSON notation with quoted keys. Of course you can still use ' for keys as well.
Do you really want your array inside your html? Otherwise to make it simple and recommended way of doing is to move it to your controller in the JS. I have created a sample in http://jsbin.com/tayege/2/edit?html,js,output for you
I am generating the following in a for loop (ignore the jade template syntax for now):
ul.nav.nav-tabs(data-bind="foreach: channels", id="galery_tabs")
li
a(data-toggle='tab', data-bind="attr: {href: '#tab_section_' + __kb.object.cid},html: name() + ' <i class=\"icon-remove close\" data-binding=\"click: removeChannel\"></i>'")
When I call .applyBindings it will correctly render my A element with the Icon that has a binding inside.
Question: How do I make second pass apply to ensure the dynamically generated binding is now applied to all Icon elements as well?
You don't need to use the html binding for the scenario.
You can just put your <i> inside the <a> and you can use the KO container-less syntax to add the name property before the icon:
ul.nav.nav-tabs(data-bind="foreach: channels", id="galery_tabs")
li
a(data-toggle='tab', data-bind="attr: {href: '#tab_section_' + __kb.object.cid}")
// ko text: name
// /ko
i.icon-remove.close(data-binding="click: removeChannel")
And the generated HTML will look like this:
<ul data-bind="foreach: channels" id="galery_tabs" class="nav nav-tabs">
<li><a data-toggle="tab" data-bind="attr: {href: '#tab_section_' + __kb.object.cid}">
<!-- ko text: name -->
<!-- /ko--><i data-binding="click: removeChannel" class="icon-remove close"></i></a></li>
</ul>
I'm trying to apply a background image to a div by using the angular ng-style ( I tried a custom directive before with the same behaviour ), but it doesn't seem to be working.
<nav
class="navigation-grid-container"
data-ng-class="{ bigger: isNavActive == true }"
data-ng-controller="NavigationCtrl"
data-ng-mouseenter="isNavActive = true; $parent.isNavActive = true"
data-ng-mouseleave="isNavActive = false; $parent.isNavActive = false"
data-ng-show="$parent.navInvisible == false"
data-ng-animate="'fade'"
ng-cloak>
<ul class="navigation-container unstyled clearfix">
<li
class="navigation-item-container"
data-ng-repeat="(key, item) in navigation"
data-ng-class="{ small: $parent.isNavActive, big: isActive == true }"
data-ng-mouseenter="isActive = true; isInactive= false"
data-ng-mouseleave="isActive = false; isInactive= true">
<div data-ng-switch on="item.id">
<div class="navigation-item-default" data-ng-switch-when="scandinavia">
<a class="navigation-item-overlay" data-ng-href="{{item.id}}">
<div class="navigation-item-teaser">
<span class="navigation-item-teaser-text" data-ng-class="{ small: isScandinavia }">{{item.teaser}}</span>
</div>
</a>
<span class="navigation-item-background" data-ng-style="{ 'background-image': 'public/img/products/{{item.id}}/detail/wide/{{item.images.detail.wide[0]}}' }"></span>
</div>
<div class="navigation-item-last" data-ng-switch-when="static">
<div class="navigation-item-overlay">
<div class="navigation-item-teaser">
<span class="navigation-item-teaser-text">
<img data-ng-src="{{item.teaser}}">
</span>
</div>
</div>
<span class="navigation-item-background">
<img class="logo" data-ng-src="{{item.images.logo}}">
</span>
</div>
<div class="navigation-item-default" data-ng-switch-default>
<a class="navigation-item-overlay" data-ng-href="{{item.id}}">
<div class="navigation-item-teaser">
<span class="navigation-item-teaser-text">{{item.teaser}}</span>
</div>
</a>
<span class="navigation-item-background" data-ng-style="{ 'background-image': 'public/img/products/{{item.id}}/detail/wide/{{item.images.detail.wide[0]}}' }"></span>
</div>
</div>
</li>
</ul>
</nav>
Though, if I do try a background color, it seems to be working fine. I tried a remote source and a local source too http://lorempixel.com/g/400/200/sports/, neither worked.
It is possible to parse dynamic values in a couple of way.
Interpolation with double-curly braces:
ng-style="{'background-image':'url({{myBackgroundUrl}})'}"
String concatenation:
ng-style="{'background-image': 'url(' + myBackgroundUrl + ')'}"
ES6 template literals:
ng-style="{'background-image': `url(${myBackgroundUrl})`}"
Correct syntax for background-image is:
background-image: url("path_to_image");
Correct syntax for ng-style is:
ng-style="{'background-image':'url(https://www.google.com/images/srpr/logo4w.png)'}">
IF you have data you're waiting for the server to return (item.id) and have a construct like this:
ng-style="{'background-image':'url(https://www.myImageplusitsid/{{item.id}})'}"
Make sure you add something like ng-if="item.id"
Otherwise you'll either have two requests or one faulty.
For those who are struggling to get this working with IE11
HTML
<div ng-style="getBackgroundStyle(imagepath)"></div>
JS
$scope.getBackgroundStyle = function(imagepath){
return {
'background-image':'url(' + imagepath + ')'
}
}
This worked for me, curly braces are not required.
ng-style="{'background-image':'url(../../../app/img/notification/'+notification.icon+'.png)'}"
notification.icon here is scope variable.
If we have a dynamic value that needs to go in a css background or
background-image attribute, it can be just a bit more tricky to
specify.
Let’s say we have a getImage() function in our controller. This
function returns a string formatted similar to this:
url(icons/pen.png). If we do, the ngStyle declaration is specified the
exact same way as before:
ng-style="{ 'background-image': getImage() }"
Make sure to put quotes around the background-image key name.
Remember, this must be formatted as a valid Javascript object key.
Just for the records you can also define your object in the controller like this:
this.styleDiv = {color: '', backgroundColor:'', backgroundImage : '' };
and then you can define a function to change the property of the object directly:
this.changeBackgroundImage = function (){
this.styleDiv.backgroundImage = 'url('+this.backgroundImage+')';
}
Doing it in that way you can modify dinamicaly your style.
The syntax is changed for Angular 2 and above:
[ngStyle]="{'background-image': 'url(path)'}"