Vue.js directives do not work in JSP - javascript

I wish to incorporate some reactive vueJS within my JSP file. However the Vue directives are not recognized by the JSP parser and this throws an error: net::ERR_INCOMPLETE_CHUNKED_ENCODING.
The example is :
<tbody id="items-${job.id}" v-for="item in items">
<tr>Item id = {{item.id}}</tr>
....
Here the v-for directive seems to be a problem.
Anyway you can suggest to solve this ? I'd love to use Vue within my JSP.

The above code did not work because I was referencing my vue 'el' to the wrong element.
The following snippet works and shows that one can use Vue.js with JSPs.
<div id="vue-test">
<div v-for="item in items" :key="item.id">
<p>Item id={{item.id}}, jobItemStatus = {{item.jobItemStatus}}</p>
</div>
</div>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script>
var vueItems = new Vue({
el: '#vue-test',
data: {
items : []
},
mounted: function(){
<c:forEach items="${job.jobItems}" var="item" varStatus="status">
this.items = this.items.concat({
id: ${item.id},
receptionDate : "${item.receptionDate}",
deliveryDate : "${item.deliveryDate}",
jobItemStatus : "${item.jobItemStatus}"
});
</c:forEach>
}
});
</script>

Related

VueJS v-for loop breaking when array values are equal to each other

my pen: http://codepen.io/leetzorr/pen/aprZqO
html
<template v-for="spot in bars" :key="item.$index">
<div id="bar-holder">
<div class="bars">
<ul>
<span>{{ $index }}</span>
<li v-for="n in bars[$index]"></li>
</ul>
<button v-on:click="increase($index)">+</button>
</div>
</div>
</template>
javascript
var par = {
bars : [ 1, 5, 6 ]
}
var cl = new Vue({
el: '#container',
data: par,
methods: {
increase: function (index) {
var value = this.bars[index];
value++;
par.bars.$set(index, value);
},
}
})
So whenever you click the increase button under each group of bars, that value in the par.bars array increases. For some reason, whenever par.bar[index]'s value equals that of one of its siblings, one of the bar elements disappears.
I've went over my code for about an hour now, and cannot figure out where this is breaking.
Replace
<template v-for="spot in bars" :key="spot.$index">
with:
<template v-for="spot in bars" :key="spot.$index" track-by="$index">
Explanation in the Vue.js guide: http://v1.vuejs.org/guide/list.html#track-by-index
This is because Vue reuse templates with same key.
To avoid that you could use index as key (apparently that was you were trying to do in first place!)
Change your template's directive v-for to something like this
<template v-for="spot in bars.length">
Please see this working fiddle

Use the same data object across multiple templates in Handlebars.js

I want to use the same data object across multiple templates in different contexts, how can I reuse it. By any chance, handlebars partials would be helpful in this situation.
$("document").ready(function(){
var source = $("#homePage-template").html();
var template = Handlebars.compile(source);
var dataPanel = {activites:[
{activity: "Events" , activityRedirect:"#", icon:"fa fa-camera-retro" , imageUrl:"xyz"},
{activity: "Ciriculars" , activityRedirect:"#", icon:"fa fa-paper-plane", imageUrl:"xyz"}
]};
$("#homePage-placeholder").html(template(dataPanel));
$("#another-placeholder").html(template(dataPanel));
});
And here is my template:
<script id="homePage-template" type="text/x-handlebars-template">
<ul>
{{#activites}}
<li><i class="{{icon}}" aria-hidden="true"></i>{{activity}}</li>
{{/activites}}
</ul>
</script>
Another Template
<script id="another-template" type="text/x-handlebars-template">
{{#activites}}
<div>
<img src="{{imageUrl}}"/>
<span>{{activity}}</span>
</div>
{{/activites}}
</script>
Now how can I reuse this data into "another-template", because I want an image and text in that but it renders like "homePage-template" only in form of a list, if anyone has an idea over this!
In order to have a second template you must fetch its HTML source from the DOM and compile it into a template method just as you are doing for the Home Page Template.
var homepage_template_source = $('#homePage-template').html();
var another_template_source = $('#another-template').html();
var homepage_template = Handlebars.compile(homepage_template_source);
var another_template = Handlebars.compile(another_template_source);
You must call the template method for the specific template you wish to render:
$("#homePage-placeholder").html(homepage_template(dataPanel));
$("#another-placeholder").html(another_template(dataPanel));
See this fiddle for an example.

When using vue.js 2.0, how do you pass an array index to a method inside of a v-on:click?

I am trying out vue 2.0 for the first time today. You can see my first attempt at using vue below. I am trying to pass the index of the array into a method. I have tried lots of different ways of doing this but none have been successful. What is the correct way to do this? Thanks!
<div id="app">
<div class="content_block" v-for="(entry, index) in entries" :key="entry.title">
<ul>
<li>title: {{entry.title}}</li>
<li>names: {{entry.names}}</li>
<li>index: {{index}}</li>
<button v-on:click="addName('{{index}}','susan')">Susan</button>
</ul>
</div>
</div>
<script>
var the_data = [{"title":"developer","names":["john","bob"]},{"title":"designer","names":[]}];
var vm = new Vue({
el:'#app',
data: {
entries: the_data
},
methods: {
addName: function(index, the_name){
console.log(index + " : " + the_name);
this.data.entries[index].names.push(the_name);
}
}
});
</script>
You should not use interpolation inside attribute values.
Please, try:
<button v-on:click="addName(index, 'susan')">Susan</button>
You can use the shorthand # for v-on:
<button #click="addName(index, 'susan')">Susan</button>

Update unrelated field when clicking Angular checkbox

I have a list of checkboxes for people, and I need to trigger an event that will display information about each person selected in another area of the view. I am getting the event to run in my controller and updating the array of staff information. However, the view is not updated with this information. I think this is probably some kind of scope issue, but cannot find anything that works. I have tried adding a $watch, my code seems to think that is already running. I have also tried adding a directive, but nothing in there seems to make this work any better. I am very, very new to Angular and do not know where to look for help on this.
My view includes the following:
<div data-ng-controller="staffController as staffCtrl" id="providerList" class="scrollDiv">
<fieldset>
<p data-ng-repeat="person in staffCtrl.persons">
<input type="checkbox" name="selectedPersons" value="{{ physician.StaffNumber }}" data-ng-model="person.isSelected"
data-ng-checked="isSelected(person.StaffNumber)" data-ng-change="staffCtrl.toggleSelection(person.StaffNumber)" />
{{ person.LastName }}, {{ person.FirstName }}<br />
</p>
</fieldset>
</div>
<div data-ng-controller="staffController as staffCtrl">
# of items: <span data-ng-bind="staffCtrl.infoList.length"></span>
<ul>
<li data-ng-repeat="info in staffCtrl.infoList">
<span data-ng-bind="info.staffInfoItem1"></span>
</li>
</ul>
</div>
My controller includes the following:
function getStaffInfo(staffId, date) {
staffService.getStaffInfoById(staffId)
.then(success)
.catch(failed);
function success(data) {
if (!self.infoList.length > 0) {
self.infoList = [];
}
var staffItems = { staffId: staffNumber, info: data };
self.infoList.push(staffItems);
}
function failed(err) {
self.errorMessage = err;
}
}
self.toggleSelection = function toggleSelection(staffId) {
var idx = self.selectedStaff.indexOf(staffId);
// is currently selected
if (idx >= 0) {
self.selectedStaff.splice(idx, 1);
removeInfoForStaff(staffId);
} else {
self.selectedStaff.push(staffId);
getStaffInfo(staffId);
}
};
Thanks in advance!!
In the code you posted, there are two main problems. One in the template, and one in the controller logic.
Your template is the following :
<div data-ng-controller="staffController as staffCtrl" id="providerList" class="scrollDiv">
<!-- ngRepeat where you select the persons -->
</div>
<div data-ng-controller="staffController as staffCtrl">
<!-- ngRepeat where you show persons info -->
</div>
Here, you declared twice the controller, therefore, you have two instances of it. When you select the persons, you are storing the info in the data structures of the first instance. But the part of the view that displays the infos is working with other instances of the data structures, that are undefined or empty. The controller should be declared on a parent element of the two divs.
The second mistake is the following :
if (!self.infoList.length > 0) {
self.infoList = [];
}
You probably meant :
if (!self.infoList) {
self.infoList = [];
}
which could be rewrited as :
self.infoList = self.infoList || [];

How to pass AngularJS ng-repeat Variable to Javascript click event

I would like to know how to pass Angular ng-repeat variable to my Javascript onclick event
My angular repeater
<div class="data" data-ng-repeat="sub in subs" >
<button onclick="ConfirmDialog(sub.SubID)">Cancel</button>
{{ sub.someOtherProperty}}
{{ sub.someOtherProperty}}
{{ sub.someOtherProperty}}
</div>
My script function
<script type='text/javascript'>
function ConfirmDialog(subID) {
console.log('Succesfully submitted id: ', subID);
});
</script>
The error : sub is not defined (in the onclick() call from the button element) all other properties show as expected.
You are running straight javascript onclick instead of ng-click.
move confirmDialog into your controller and ng-click can attach to it.
<div class="data" data-ng-repeat="sub in subs" >
<button ng-click="ConfirmDialog(sub.SubID)">Cancel</button>
</div>
$scope.ConfirmDialog = function (subID) {
console.log('Succesfully submitted id: ', subID);
});
If you don't want to use ng-click, you still have a chance! Try the following
<tr ng-repeat="supplier in suppliers" id="{{supplier.id}}">
<button onclick="readVariable(this);">
</tr>
<script>
function readVariable(elem){
id = elem.parentNode.id;
console.log(id); //it works!
}
</script>
You should use ng-click instead in order to access the ng-repeat variable
<button ng-click="ConfirmDialog(sub.SubID)">Cancel</button>

Categories