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);
Related
This drive me crazy, i've this simple html bootstrap-gentelella template that works almost in every page of the site that im developing, the html is so simple:
(this code make the part in the class "x_content" visible or not visible by clicking the "collapse-link" class in the "a" tag)
<div class="x_panel">
<ul class="nav navbar-right panel_toolbox">
<li>
<a class="collapse-link freccia_feed">Replies
<i class="fa fa-chevron-up"></i>
</a>
</li>
</ul>
<div class="x_content" style="display: none;">
<div class="input-group col-md-12 col-sm-12 col-xs-12">
<input data-role="tagsinput" id="risposta_'+j+'_D_'+element+'" class="form-control risposta_domanda_'+element+'" name="reply" value="" placeholder="Insert one solution" type="text">
<span class="input-group-btn">
<button id="elimina_risp_'+j+'_D_'+element+'" class="btn btn-danger glyphicon glyphicon-trash" > </button>
</span>
</div>
</div>
</div>
be carefull that the part like id="risposta_'+j+'_D_'+element+'" have no sense in this static part, and rendered as is it, just for example, I use that in the jQuery function that fail to make it works!
here:
$("#domanda_"+element).append(
'<div class="x_panel">'+
'<ul class="nav navbar-right panel_toolbox">'+
'<li>'+
'<a class="collapse-link freccia_feed" >Replies'+
'<i class="fa fa-chevron-up"></i>'+
'</a></li></ul>'+
'<div class="x_content" style="display: none;">'+
'<div class="input-group col-md-12 col-sm-12 col-xs-12">'+
'<input data-role="tagsinput" id="risposta_'+j+'_D_'+element+'" class="form-control risposta_domanda_'+element+'" name="reply"'+
'value="" placeholder="Insert one solution" type="text">'+
'<span class="input-group-btn"><button id="elimina_risp_'+j+'_D_'+element+'" class="btn btn-danger glyphicon glyphicon-trash" >'+
'</button></span>'+
'</div></div></div>');
I've tried many options to make this string works inside append() and the only one that seems working it to wrap the whole string with single ' using double " for ids class etc. and then inject javascript variable with single ' and +. Same thing for new line.
I even try to escape the whole string with online escape tools like https://www.freeformatter.com/javascript-escape.html
but still the same result, the component not works if is appended!
the problem is in the "inizialization" of the class ".collapse-link" by gentelella js.
So i move the function under my "div" generation function's.
I even add a "unbind()" func to resolve the problem that "inizialization" can toggle even the allready rendered div making them open anc closing several time...
thats the code if someone can find it usefull
cheers
$(".collapse-link").unbind("click");
$(".collapse-link").on("click", function() {
var a = $(this).closest(".x_panel")
, b = $(this).find("i")
, c = a.find(".x_content");
a.attr("style") ? c.slideToggle(200, function() {
a.removeAttr("style")
}) : (c.slideToggle(200),
a.css("height", "auto")),
b.toggleClass("fa-chevron-up fa-chevron-down")
});
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>
I m developping an application in which I need to redirect the current user to a different state after a ressource creation.
Actually, I have a list of demands, and I need to show or create a quotation based on that demand.
Here's the view code :
<div class="landing-diags">
<div class="current-projects">
<div class="row project-summary" ng-repeat="demand in landingdiag.demandsList">
<div class="col-md-2 project-block first-block {{project.projectType}}">
<p class="project-strong">{{demand.user.firstname}} {{demand.user.lastname}}</p>
</div>
<div class="col-md-2 project-block">
<p class="project-strong">{{demand.creationDate | date:"dd/MM/yyyy"}}</p>
</div>
<div class="col-md-4">
</div>
<div class="col-md-2">
<div ng-if="!demand.quotation">
<button ng-click="landingdiag.createQuotation(demand)" class="btn btn-primary pull-right bar-btn">Create</button>
</div>
<div ng-if="demand.quotation">
<button ui-sref="app.state.concerned({id: demand._id})" class="btn btn-primary pull-right bar-btn">Show</button>
</div>
</div>
</div>
</div>
</div>
And here's the controller methods implied :
createQuotation (demand) {
this.DemandsService.createQuotation(demand).$promise.then((response) => {
this.redirectToQuote(demand);
});
}
redirectToQuote (demand) {
this.$state.transitionTo('app.state.concerned', {id: demand._id});
}
Problem
My problem is that I m never redirected when creating a quotation. If I console log the redirectToQuote method, I pass inside of it. So it seems that my problem is on the $state.go call.
However, when I try to redirect directly using the redirectToQuote method inside of my view on the "show" button like following :
<div ng-if="demand.quotation">
<button ng-click="landingdiag.redirectToQuote(demand)" class="btn btn-primary pull-right bar-btn">Accéder au devis</button>
</div>
I m well redirected to the concerned state
I am concerned about the this.redirectToQuote within createQuotation() which is called by then() as a callback. So the this object will definitely not be your controller.
Look at the first code snippet from todd: https://toddmotto.com/resolve-promises-in-angular-routes/
He is using bind.
You can also look at https://github.com/getify/You-Dont-Know-JS/tree/master/this%20%26%20object%20prototypes from awesome Kyle Simpson
or shorter from myself: http://blog.monkey-development.com/javascript/java/2015/12/18/javascript-this.html
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.
I have a table containing next & previous pages. I am able to navigate to next/previous pages using next & previous buttons.
On previous & next page actions on call(controller methods) I am pushing checked ticket ids by pushing in an array $scope.checkedTicketIds
angular.forEach($scope.tickets, function(ticket) {
if(ticket.checked) {
$scope.checkedTicketIds.push(ticket.id);
}
});
HTML code is
<div class="mail-tools tooltip-demo m-t-md">
<div class="btn-group pull-right">
<button ng-click="previousPage()" ng-disabled="previousPageBtnDisabled()" class="btn btn-white btn-sm"><i class="fa fa-arrow-left"></i></button>
<button ng-click="nextPage()" ng-disabled="nextPageBtnDisabled()" class="btn btn-white btn-sm"><i class="fa fa-arrow-right"></i></button>
</div>
<div class="input-group">
<div class="input-group-btn" dropdown>
<button ng-disabled="ticketsChecked()" class="btn btn-white dropdown-toggle pull-left" dropdown-toggle type="button">{{'ACTIONS' | translate}} <span class="caret"></span></button>
<ul class="dropdown-menu pull-left">
<li ng-repeat="(key, value) in actions"><a ng-click="convertAction(key)">{{key | translate}}</a></li>
</ul>
</div>
</div>
</div>
In controller on clicking previous page button calling method
$scope.previousPage = function() {
angular.forEach($scope.tickets, function(ticket) {
if(ticket.checked) {
$scope.checkedTicketIds.push(ticket.id);
}
});
$scope.ticketsUpdatedQueryCriteria.page = --$scope.page;
Tickets.query($scope.ticketsUpdatedQueryCriteria).then(function(tickets) {
$scope.tickets = tickets.data;
$scope.ticketsPageData = tickets.cursor;
});
};
How to pop/remove id on uncheck & I wanted to maintain checked ticket ids for further bulk actions, like change status of one/more tickets. How can I do this?
I implement an example on jsbin, using an independent checked list.
Please, look at:
http://jsbin.com/rudifa/3/
Hope I help you.