Expression in ng-init not working with ng-repeat - javascript

So I am trying to have many divs with background images and disable the background image when I hover over any particular div.
<div id="interest" class="col-md-4 col-sm-6" ng-repeat="interest in vm.interestList"
ng-init="myStyle={'background-image': 'url(interest.src)'}"
ng-style="myStyle" ng-mouseenter="myStyle={}"
ng-mouseleave="myStyle={'background-image': 'url(interest.src)'}">
<button id="interestButton" class="btn btn-default btn-lg" >{{interest.interestName}}</button>
</div>
For some reason the myStyle in ng-init never gets the actual value in interest.src rather just gets 'interest.src'. I also tried {{interest.src}} but that does not work.
Any help is appreciated!!

Try this
var jimApp = angular.module("mainApp", []);
jimApp.controller('mainCtrl', function($scope){
$scope.interestList = [{interestName:"One", src:"img/one.png"}];
$scope.url = function(url){
return 'url('+url+')';
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="mainApp" ng-controller="mainCtrl">
<div id="interest" class="col-md-4 col-sm-6" ng-repeat="interest in interestList"
ng-init="myStyle = {'background-image': url(interest.src)}"
ng-style="myStyle" ng-mouseenter="myStyle={}"
ng-mouseleave="myStyle={'background-image': url(interest.src)}">
<button id="interestButton" class="btn btn-default btn-lg" >{{interest.interestName}}</button>
</div>
</div>

You will have to interpolate the string literal of your evaluated angular expressions for interest.src
Instead of
ng-init="myStyle={'background-image': 'url(interest.src)'}" change it to ng-init="myStyle={'background-image': 'url(' + interest.src + ')'}"
Note the string concantenation via +
Here is the plnkr

try like this
<div id="interest" class="col-md-4 col-sm-6" ng-repeat="interest in vm.interestList"
ng-style="{'background-image': 'url('+interest.src+')'}" ng-mouseenter="{}"
ng-mouseleave="{'background-image': 'url('+interest.src+')'}">
<button id="interestButton" class="btn btn-default btn-lg" >{{interest.interestName}}</button>
</div>

Related

Why when trying to use JQuery on a previously initialized html element variable it returns undefined?

I read on the JQuery docs ( https://learn.jquery.com/using-jquery-core/faq/how-do-i-select-elements-when-i-already-have-a-dom-element/ ) that you could use a previously initialized element by writing the variable name like you do with selectors:
$(element)
but whenever i try to do so from a function that i call at the press of a button it returns 'undefined'.
This is an example code i did to test this out in a more controlled environment:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container-fluid">
<div class="row">
<div class="col-md-6">
<button class="btn btn-block btn-primary" onclick="jquery(this)">JQuery</button>
</div>
<div class="col-md-6">
<button class="btn btn-block btn-info" onclick="normaljs(this)">normalJs</button>
</div>
</div>
<div class="row">
<div class="col-md-6">
<button class="btn btn-block btn-danger" onclick="basicTest()">basicTest</button>
</div>
<div class="col-md-6">
<button class="btn btn-block btn-info" id="empty">dynamicTest</button>
</div>
</div>
</div>
<script>
function jquery(caller){
var element = $(caller).parent();
alert("Tag name: " + element.tagName);
}
function normaljs(caller){
var element = caller.parentElement;
alert("Tag name: "+ element.tagName);
}
function basicTest(){
alert("This is a basic test");
}
$("#empty").click(function(){
alert("Tag name: " + $(this).tagName);
alert("Tag name: " + this.tagName);
});
</script>
Am i doing something wrong?
By $(caller), you just "converted" the DOM element into a jQuery object, therefore, DOM properties and methods won't work in the normal way on it anymore, but if you want to get the tagName using jQuery, then prop() would do :
function jquery(caller){
var element = $(caller).parent();
alert("Tag name: " + element.prop("tagName"));
}
$(caller).parent() returns a jQuery object, but tagName is a DOM property, not a jQuery property (jQuery makes very little use of data properties, almost everything is a function). To get the DOM elements contained in a jQuery object, you can use the get() function or an array index,.
function jquery(caller) {
var element = $(caller).parent()[0];
alert("Tag name: " + element.tagName);
}
function normaljs(caller) {
var element = caller.parentElement;
alert("Tag name: " + element.tagName);
}
function basicTest() {
alert("This is a basic test");
}
$("#empty").click(function() {
alert("Tag name: " + $(this).get(0).tagName);
alert("Tag name: " + this.tagName);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container-fluid">
<div class="row">
<div class="col-md-6">
<button class="btn btn-block btn-primary" onclick="jquery(this)">JQuery</button>
</div>
<div class="col-md-6">
<button class="btn btn-block btn-info" onclick="normaljs(this)">normalJs</button>
</div>
</div>
<div class="row">
<div class="col-md-6">
<button class="btn btn-block btn-danger" onclick="basicTest()">basicTest</button>
</div>
<div class="col-md-6">
<button class="btn btn-block btn-info" id="empty">dynamicTest</button>
</div>
</div>
</div>

Modal window comment editing module (editable text)

I want to make, that during the ediditing comment action, I have modal window with comment text written inside textarea, and it is editable without deleting all text with clicking. I tried just to put value inside textarea or placing it in placeholder. But both options are wrong and doesnt work.
Can someone take a look on this code and give me an advice, how should I take for it.
editComment.html
<div class="modal-header">
<h3 class="modal-title" id="modal-title">Edytuj komentarz</h3>
</div>
<div class="modal-body" id="modal-body">
<div class="row">
<div class="col-sm-12">
<div class="row">
<div class="col-sm-12 form-group">
<label>Treść</label>
<textarea class="form-control input-sm"
name="description"
ng-maxlength="512"
ng-model="$ctrl.selected"
rows="6">{{comment.value()}}</textarea>
</div>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-raised btn-primary"
type="button"
ng-disabled="!$ctrl.selected"
ng-click="$ctrl.ok()">Zapisz
</button>
<button class="btn btn-raised btn-warning"
type="button"
ng-click="$ctrl.cancel()">Anuluj
</button>
</div>
editComment.js
(function() {
'use strict';
angular.module('settlerApplication').controller('EditCommentCtrl', function($uibModalInstance) {
var $ctrl = this;
$ctrl.ok = function() {
$uibModalInstance.close($ctrl.selected);
};
$ctrl.cancel = function() {
$uibModalInstance.dismiss('cancel');
};
});
})();
I'm not sure to understand what you are trying to achieve. But anyway : if you want to init your textarea's ng-model with $ctrl.foo (comment.value() in your case, from what I understood), you should either :
In the controller, init your $ctrl.selected variable with this value :
$ctrl.selected = $ctrl.foo;
Or, in your template, use ng-init :
<textarea class="form-control input-sm"
ng-init="$ctrl.selected = $ctrl.foo"
name="description"
ng-maxlength="512"
ng-model="$ctrl.selected"
rows="6"></textarea>
Ok, so I am going to explain that a little.
I have modal window like that:
I want to edit existing comments in this window. And so I want my comment appears instead of text: "Komentarz" (under: "Treść" after clicking in there). And I want that comment text to be editable, so I dont have to write it down again (put the whole text to that area). Is it make it a little better explained about my goal?

HTML Template (Jquery)

I am looking for a small javascript / jquery plugin that can better structure HTML injected content. For example, In my current plugin I need to create templates and it just feels "hacky" injecting this way:
var sticker_src = $('<div class="storefront-sticker" style="max-width:'+feature_width+';"><div class="storefront-feature" data-sticker><div class="inner"><span class="flag-icon" style="background-image: url('+iso_flag+');"></span><div class="logo"></div></div><div class="tint"><img src="'+storefront+'" class="bg"></div></div><div class="row pt-1"><div class="col-xs-12 col-sm-12 col-md-6 pr-0"><button class="btn btn-secondary btn-sm pull-left" type="button">Find Directions</button></div><div class="col-xs-12 col-sm-12 col-md-6"><a class="btn btn-secondary btn-sm pull-right" href="#">View Retailer</button></div></div></div>');
I am aware of Handlebars / moustache / underscore but there is a lot of bloat with them, things I do not need. How do I better structure these aspects with js applications?
If you are going to create you're own templates and you want to clean up your main script, move the code to a funciton, define that function in another JS file if you really don't want to see it.
var createStickerTemplate = function( feature_width, iso_flag, storefront )
{
return $('<div class="storefront-sticker" style="max-width:'+feature_width+';"><div class="storefront-feature" data-sticker><div class="inner"><span class="flag-icon" style="background-image: url('+iso_flag+');"></span><div class="logo"></div></div><div class="tint"><img src="'+storefront+'" class="bg"></div></div><div class="row pt-1"><div class="col-xs-12 col-sm-12 col-md-6 pr-0"><button class="btn btn-secondary btn-sm pull-left" type="button">Find Directions</button></div><div class="col-xs-12 col-sm-12 col-md-6"><a class="btn btn-secondary btn-sm pull-right" href="#">View Retailer</button></div></div></div>');
}
var sticker_src = createStickerTemplate( feature_width, iso_flag, storefront );
I assume you are just looking for a way to make the code look a bit more clear right ?
var a = 'string from variable ...',
b = [
'<div>',
a,
'</div>'
],
c = b.join('');
console.log(c);

Trying to generate a button-group with Bootsrap and AngularJS to redirect to different URLs

I am trying to create a button group of two (using bootstrap and angularjs) that, when clicking on them, each would redirect to a different URL. I currently have the following code (copied only the relevant pieces):
app.controller('LinkController',function(link, $scope, $location){
$scope.go = function(){
$location.url(link);
};
});
<div class="btn-group btn-group-lg" data-ng-controller = "LinkController">
<button type="button" class="btn btn-primary" data-ng-click = "go('test1.html')">Click1</button>
<button type="button" class="btn btn-primary" data-ng-click = "go('test2.html')">Click2</button>
</div>
However, this doesn't work, and I am not sure why. I might not be passing the arguments correctly, but I tried it even without passing the link itself and it still didn't work. Would appreciate any help!
Are you trying to pass the url ?,
if so, then i would be like this :
app.controller('LinkController',function(link, $scope, $location){
$scope.go = function(link){
$location.url(link);
};
});
<div class="btn-group btn-group-lg" data-ng-controller = "LinkController">
<button type="button" class="btn btn-primary" data-ng-click = "go('test1.html')">Click1</button>
<button type="button" class="btn btn-primary" data-ng-click = "go('test2.html')">Click2</button>
</div>
Ok so after many many attempts, and with some inspiration from the answers above, I was able to solve it in the following way:
app.controller('LinkController',function($scope){
$scope.go = function(link){
window.location = link;
};
});
<div class="btn-group btn-group-lg" data-ng-controller = "LinkController">
<button id = Image type="button" class="btn btn-primary"
data-ng-click = "go('Test1.html')">Click1</button>
<button id = Text type="button" class="btn btn-primary"
data-ng-click = "go('Test2.html')">Click2</button>
</div>
Thanks for your help guys.
I don't know much of Angular js, but there are other alternative ways to achieve the same purpose. This works with simple html
<div class="btn-group btn-group-lg">
<input type="button" class="btn btn-primary">Click1</input>
<input type="button" class="btn btn-primary">Click2</input>
</div>
Notice I changed the button element to input, this because a button element can not be placed inside an anchor tag <a>.
I hope this helps

Meteor template not updating on changed data

I'm currently building a nifty little 'talent point distributor' view, similar to what popular RPG games offer. I didn't want a huge wall of HTML code for all the buttons and textboxes, so I created a template to which I pass two parameters:
the name of the stat I want to alter
the initial value of the stat
The template renders correctly, and I notice that when I log the results to the console, the variable seems to be changed correctly. However, the displayed value does not change and will always stay at 0.
Here is the template itself:
<template name="attributeStepper">
<div class="row" style="margin: 1em;">
<div class="col-sm-3 col-md-2">
<h4>{{toUpper attribute}}</h4>
</div>
<div class="col-sm-6 col-md-4">
<div class="btn-group" role="group">
<button type="button" class="btn btn-default btn-value-dec">
<span class="glyphicon glyphicon-chevron-down"></span>
</button>
<button type="button" class="btn btn-default disabled">{{attributeValue}}</button>
<button type="button" class="btn btn-default btn-value-inc">
<span class="glyphicon glyphicon-chevron-up"></span>
</button>
</div>
</div>
</div>
</template>
Here is the helper I defined for the template:
Template.attributeStepper.helpers({
toUpper : function(str) {
return str.substring(0, 1).toUpperCase() + str.substring(1);
}
})
Template.attributeStepper.events({
'click .btn-value-inc' : function(event, tmpl) {
tmpl.data.attributeValue ++;
},
'click .btn-value-dec' : function(event, tmpl) {
tmpl.data.attributeValue --;
}
});
And this is how I call the templates from the actual view:
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Attributes</h3>
</div>
{{ >attributeStepper attribute="strength" attributeValue="0"}}
{{ >attributeStepper attribute="courage" attributeValue="0"}}
{{ >attributeStepper attribute="intelligence" attributeValue="0"}}
{{ >attributeStepper attribute="agility" attributeValue="0"}}
{{ >attributeStepper attribute="dexterity" attributeValue="0"}}
{{ >attributeStepper attribute="intuition" attributeValue="0"}}
{{ >attributeStepper attribute="charisma" attributeValue="0"}}
</div>
I hope you can make any sense out of this and tell me what I'm doing wrong, because I feel like I'm not following the mindset behind Meteor correctly yet.
Cheers!
There is nothing wrong but also nothing reactive in your code. For the attributeValue you should use a template based ReactiveVar which is created at the onCreate Event
Template.attributeStepper.onCreated(function() {
if (! _.isUndefined(this.data.startingValue))
this.attributeValue = new ReactiveVar(Number(this.data.startingValue));
else
this.attributeValue = new ReactiveVar(0);
})
You can use some initialValue from Template as you like
See complete example at the MeteorPad I created for you.
http://meteorpad.com/pad/Zw7YnnW57uuGKcu3Q/MultipleTemplateUsage
This should solve your question
Cheers
Tom
Do you have idea about reactive-var in meteor (Meteor Doc) or you can also use Session instead of reactive-var (ReactiveVar is similar to a Session variable)
Have a look at changes as per your code.
Here is the template(.html)
<template name="attributeStepper">
<div class="row" style="margin: 1em;">
<div class="col-sm-3 col-md-2">
<h4>{{toUpper attribute}}</h4>
</div>
<div class="col-sm-6 col-md-4">
<div class="btn-group" role="group">
<button type="button" class="btn btn-default btn-value-dec">
<span class="glyphicon glyphicon-chevron-down"></span>
</button>
<button type="button" class="btn btn-default disabled">{{getAttributeValue}}</button>
<button type="button" class="btn btn-default btn-value-inc">
<span class="glyphicon glyphicon-chevron-up"></span>
</button>
</div>
</div>
</div>
</template>
Here is helpers for your template(.js)
Template.attributeStepper.created = function(){
this.attributeValue = new ReactiveVar(parseInt(this.data.attributeValue));
}
Template.attributeStepper.helpers({
toUpper : function(str) {
return str.substring(0, 1).toUpperCase() + str.substring(1);
},
getAttributeValue : function(){
return Template.instance().attributeValue.get();
}
});
Template.attributeStepper.events({
'click .btn-value-inc' : function(event, tmpl) {
tmpl.attributeValue.set(tmpl.attributeValue.get()+1)
},
'click .btn-value-dec' : function(event, tmpl) {
tmpl.attributeValue.set(tmpl.attributeValue.get()-1)
}
});
Template.attributeStepper.created = function(){...} method called before your template's logic is evaluated for the first time.

Categories

Resources