I saw this Question but here no approach shown.
"element": [
{
"value": "<button #click='changeTheme()' class='theme-link btn btn-light'>Default</button>",
"class": "text-success"
}
]
I have bind the JSON data with Vue Component like the below:
<p v-else v-html="element[0].value"></p>
Now, I am trying to call this method. But it's not firing!
methods: {
changeTheme() {
alert("Y");
}
}
Maybe separate the action from the button by putting it on the object on a different key, and calling it on click of the element:
"element": [
{
"value": "<button class='theme-link btn btn-light'>Default</button>",
"class": "text-success",
"action": function () {alert("Y")}
}
]
<p v-else v-html="element[0].value" #click="element[0].action"></p>
Related
Requirement:
Showing dynamic data using ngx-datatable and use paging using page id
Description :
I have a dynamic data where I am displaying it using the ngx-datatable in angular and here everything works but the issue I m not sure how to apply the paging using the page_id (sent to the server using post body). Here I am getting the page_id along with the API response this is 1st API call. here page_id has to be sent as a body for the very same API for getting the rest of results.
Ex: Suppose I have 20 results in the 1ST API call I will get the 10 records and a page id by using the page id how can I get the next 10 results
What I implemented:
Getting data and displaying it in table basic paging applied
Below is my code :
Result=[];
reorderable: boolean = true;
selected = [];
rows = [];
columns = [];
DataArray = [];
Results = {
"data": [
{
"_score": 0.36464313,
"_type": "data",
"_id": "abcd",
"_source": {
"filter": "data",
"information": {
"product_id": "abcd",
"creation_utctime": "1477335693653"
},
"enduser": "free"
},
"_index": "dell_laptop"
},
{
"_score": 0.36464314,
"_type": "data",
"_id": "abcde",
"_source": {
"filter": "data",
"information": {
"product_id": "abcde",
"creation_utctime": "1477335693653"
},
"enduser": "free"
},
"_index": "lenovo_laptop"
},
{
"_score": 0.36464314,
"_type": "data",
"_id": "abcdef",
"_source": {
"filter": "data",
"information": {
"product_id": "abcde",
"creation_utctime": "1477335693653"
},
"enduser": "free"
},
"_index": "lenovo_laptop"
}
],
"total": 4,
"page_id": "WpNdVJMMjlJVnJTYTFuUklB"
}
LoadInfo(){
this.DataArray = ["filter","information.product_id","information.creation_utctime","enduser"];
this.rows=[];
this.Result = this.Results['data'];
// tslint:disable-next-line: forin
for (var res in this.Result) {
var row = {};
for (var key in this.Result[res]['_source']) {
if (typeof this.Result[res]['_source'][key] === 'object') {
for (var k in this.Result[res]['_source'][key]) {
let temp = key + "." + k;
row[temp] = this.Result[res]['_source'][key][k];
}
} else {
row[key] = this.Result[res]['_source'][key]
}
row['_id'] = this.Result[res]['_id'];
}
this.rows.push(row);
}
console.log(this.rows);
}
onActivate(event) {
// console.log('Activate Event', event);
}
onSelect({ selected }) {
// console.log('Select Event', selected, this.selected);
this.selected.splice(0, this.selected.length);
this.selected.push(...selected);
}
HTML Code:
<button type="button" (click)="LoadInfo()">LoadData</button>
<div>
<ngx-datatable class="material ui" [rows]="rows" [columnMode]="'force'" [headerHeight]="50"
[footerHeight]="50" [limit]="2" [rowHeight]="'auto'" [reorderable]="reorderable" [selected]="selected"
[selectionType]="'checkbox'" [scrollbarH]="true" [sortType]="'multi'" (activate)="onActivate($event)"
(select)='onSelect($event)'>
<ngx-datatable-column [width]="30" [sortable]="true" [canAutoResize]="false" [draggable]="false"
[resizeable]="false" class="uih">
<ng-template ngx-datatable-header-template let-value="value" let-allRowsSelected="allRowsSelected"
let-selectFn="selectFn">
<input type="checkbox" [checked]="allRowsSelected" (change)="selectFn(!allRowsSelected)" />
</ng-template>
<ng-template ngx-datatable-cell-template let-value="value" let-isSelected="isSelected"
let-onCheckboxChangeFn="onCheckboxChangeFn">
<input type="checkbox" [checked]="isSelected" (change)="onCheckboxChangeFn($event)" />
</ng-template>
</ngx-datatable-column>
<ngx-datatable-column *ngFor="let attr of DataArray" [sortable]="true" prop={{attr}} name={{attr}}>
</ngx-datatable-column>
</ngx-datatable>
</div>
Stackblitz link: https://stackblitz.com/edit/angular-secw8u
Note: even though if there is pageid also some times after 10 records there may not be more records also
here api call is simple post request
api : https://xxxx.xxxx..com/<some method>
body: { "key1":"data1","key2":"data2","pageid":"ss"}
here in the first api call we wont send page id as after calling the first api call we will get response in that we will get the pageid and for the second api call i mean for paging then we have to use the pageid
For pagination you need to know total number of pages. Otherwise you need total number
of items along with number of items per page (to derive total number of pages). In your case
you only have a page-id which does not even say the which page you are on. The page-id
only gives you access to next page items.
This API is useful if you implement an infinite scroll feature. Otherwise you can only
implement a more button to which loads new items to table. The link
you provided in comments implements this more button feature.
So you can override the default footer of ngx-datatable to add your more button to load
more items to table.
<ngx-datatable-footer>
<ng-template ngx-datatable-footer-template
let-rowCount="rowCount"
let-pageSize="pageSize"
let-selectedCount="selectedCount"
let-curPage="curPage"
let-offset="offset"
let-isVisible="isVisible">
<div class="datatable-footer-inner selected-count">
<div class="page-count" *ngIf="selectedCount">
<span> {{selectedCount}} selected / </span> {{rowCount}} total
</div>
<div class="datatable-pager">
<ul class="pager">
<li class="pages active" role="button" aria-label="next" *ngIf="rowCount">
Next
</li>
</ul>
</div>
</div>
</ng-template>
</ngx-datatable-footer>
Stackblitz Demo
I am trying to make a simple multilanguage site!
I have 3 buttons for 3 languages, when I press one of them, I get the value of that button value with jQuery and store it in a variable named clicked and I want to get data from JSON like this: data.clicked.name
How can i get the value of clicked on data.clicked.name?
html file
<div id="container">
<input class="btnL" type="button" value="MK">
<input class="btnL" type="button" value="EN">
<input class="btnL" type="button" value="AL">
</div>
script
<script type="text/javascript">
$(document).ready(function () {
$(".btnL").click(function () {
var clicked = $(this).attr("value");
$.getJSON('language.json', function (data) {
console.log(data.clicked.name);
// ex. if the value of clicked variable is="EN"
// I want to get this console.log(data.EN.name)
});
});
});
</script>
language.json
{
"EN": {
"name": "Name",
"surname": "Surname"
},
"AL": {
"name": "Emri",
"surname": "Mbiemri"
},
"MK": {
"name": "Име",
"surname": "Презиме"
}
}
Use brackets
console.log(data[clicked].name);
I am creating a form dynamically with the data that I get from the backend:
{
"title": "Contact Me",
"fields": [
{
"label": "Name",
"type": "textbox",
"required": "1"
},
{
"label": "Email",
"type": "email",
"required": "1"
},
{
"label": "Message",
"type": "textarea",
"required": "1"
},
{
"label": "Submit",
"type": "submit",
"required": null
}
]
}
In Vue the component where I am making this form looks like this:
<form #submit.prevent="submit()" class="form">
<template v-for="input in ninjaForm.fields">
<div v-if="input.type != 'submit' && input.type != 'textarea'" class="control">
<input
v-bind:value="form[input.label]"
class="input is-large"
:type="input.type"
:name="input.label.toLowerCase()"
:required="input.required == 1">
<label>{{ input.label }}</label>
</div>
<div v-if="input.type == 'textarea'" class="control">
<textarea
v-bind:value="form[input.label]"
class="textarea"
:name="input.label.toLowerCase()">
</textarea>
<label>{{ input.label }}</label>
</div>
<div v-if="input.type == 'submit'">
<button class="button is-primary">{{ input.label }}</button>
</div>
</template>
</form>
I would like to submit this data back to the backend, but I am not sure how to do that, I have tried with something like this:
data() {
return {
form: {},
};
},
methods: {
submit() {
let payload = {
headers: {
'Content-Type': 'application/json'
},
params: JSON.parse(JSON.stringify(this.form))
};
console.log(payload);
this.$backend.post('submit', null, payload)
.then(_ => {
this.response = 'Meldingen ble sendt!';
}, err => {
console.warn(err);
this.response = 'En feil oppstod under innsending av skjemaet, prøv igjen senere.';
});
}
}
But when I am doing console.log(this.form) I get an observer object, and if I do console.log(payload) I get an empty params property. What am I doing wrong and how should I fix this so that I can send form data as a params object?
I have tried with setting the form properties on created method, like this:
created() {
this.ninjaForm.fields.forEach(field => this.form[field.label.toLowerCase()] = '');
},
Which has made an object with properties that looks like this:
form: {
email:"",
message:"",
name:"",
submit:""
}
But, when I was submitting the form, the values of this properties where still empty:
v-bind:value="form[input.label.toLowerCase()]"
I have also tried with changing v-bind:value to v-model, but then I have got an error:
v-model does not support dynamic input types. Use v-if branches
instead.
Please check this thread:
https://github.com/vuejs/vue/issues/3915#issuecomment-294707727
Seems like it works with v-model. However, this doesn't work when you use a v-bind on the input type. The only workaround is to create a v-if for every possible form type. Really annoying, but there seems to be no apparent other solution.
Hopefully this isn't bad practice, but I am trying to understand Knockout observables within the context of my previous question.
I want to update the view with 'red flower' or 'blue sky', depending on which button is clicked. Let's presume the JSON will be static. How can I go about using observables to update the view while only applying my bindings a single time?
Fiddle:
https://jsfiddle.net/ft8a6jbk/3/
HTML:
<button class="blue">Blue</button>
<button class="red">Red</button>
<div data-bind="text: name"></div>
<div data-bind="text: things()[0].item1"></div>
<script>
ko.applyBindings(viewModel);
</script>
JS:
var data = {
"colors": [{
"name": "blue",
"things": [{
"item1": "sky",
"item2": "ocean",
}, ]
}, {
"name": "red",
"things": [{
"item1": "flower",
"item2": "sun",
}, ]
}, ]
};
$('.blue').click(function() {
var viewModel = ko.mapping.fromJS(data.colors[0]);
});
$('.red').click(function() {
var viewModel = ko.mapping.fromJS(data.colors[1]);
});
How can I [...] while only applying my bindings a single time?
Like this:
function Sample(data) {
var self = this;
self.colors = ko.observableArray();
self.currentColor = ko.observable();
ko.mapping.fromJS(data, {}, self);
}
var sample = new Sample({
"colors": [{
"name": "blue",
"things": ["sky", "ocean"]
}, {
"name": "red",
"things": ["flower", "sun"]
}]
});
ko.applyBindings(sample);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.min.js"></script>
<div data-bind="foreach: colors">
<button data-bind="text: name, click: $root.currentColor"></button>
</div>
<div data-bind="with: currentColor">
<h4 data-bind="text: name"></h4>
<div data-bind="foreach: things">
<span data-bind="text: $data" />
</div>
</div>
Notes:
Don't write jQuery event handlers. Remove jQuery from your knockout code entirely. The two exceptions to this rule are: Using Ajax (since knockout has no Ajax functions) and writing custom binding handlers. Anything else, most prominently DOM manipulation, should be governed by Knockout completely.
An observable is a function. You can use it as an event handler, like I did above in the click binding. Here is how this works:
Knockout passes the context data, in this case a single "color" item, to the event handler function, in this case the currentColor observable.
When an observable is called with a value, it stores that value.
Effect: Instant event handler and application state storage - without writing a single function yourself.
I've seen so many ways to do this, but most are pretty old and I want to make sure I'm doing this correctly. Right now, the way I'm using isn't working and I feel like I'm missing something.
I'm getting the JSON back fine, I just need to get it to display in a table after I click the button.
Here is the JSON. This is how I'm going to get it from our server, I can't add any "var JSON =" or add any scope like "$scope.carrier" to the data, unless there's a way to add it after I've fetched the data.
{
"carrier":
[
{
"entity": "carrier",
"id": 1,
"parentEntity": "ORMS",
"value": "Medica"
}, {
"entity": "carrier",
"id": 2,
"parentEntity": "ORMS",
"value": "UHG"
}, {
"entity": "carrier",
"id": 3,
"parentEntity": "ORMS",
"value": "Optum"
}, {
"entity": "carrier",
"id": 4,
"parentEntity": "ORMS",
"value": "Insight"
}, {
"entity": "carrier",
"id": 5,
"parentEntity": "ORMS",
"value": "Insight"
}
]
}
Here is the app.js file to bring back the JSON data:
var app = angular.module('myTestApp', []);
app.controller('myController', ['$scope', '$http', function($scope, $http) {
var url = 'test.json';
$scope.clickButton = function() {
$http.get(url).success(function(data) {
console.log(data);
});
}
}]);
And then of course the HTML:
<div class="col-lg-12 text-center">
<button type=button class="btn btn-primary load" ng-click="clickButton()">Click!</button>
<table class="">
<tbody ng-repeat="carrier in carriers">
<tr>
<td>
<h3 class="">{{ module.entity }}</h3>
<h3 class="">{{ module.id }}</h3>
<h3 class="">{{ module.parentEntity }}</h3>
<h3 class="">{{ module.value }}</h3>
</td>
</tr>
</tbody>
</table>
</div>
I'm also wondering if I can use the ng-grid to put this in a table. I know they just upgraded it to ui grid so I'm not sure if this is still a feasible approach.
Also, I'm not getting errors, the data just won't display in the table right now. All I know is its returning the data properly, just not displaying in the table.
Any help is appreciated.
I looked at your plunker seems like you need to:
add angular script
wire the app and the controller
your variable in the repeater is wrong, I change it
take a look to this fixed plunker:
http://plnkr.co/edit/TAjnUCMOBxQTC6lNJL8j?p=preview
$scope.clickButton = function() {
$http.get(url).success(function(returnValue) {
alert(JSON.stringify(returnValue.carrier));
$scope.carriers = returnValue.carrier;
});
}
You never assign the value of the returned array to $scope.carriers.
At the line where you say console.log(data); add this:
$scope.carriers = data.data;
Here is the updated clickButton function (with a variable name change to reduce confusion):
$scope.clickButton = function() {
$http.get(url).success(function(returnValue) {
$scope.carriers = returnValue.data;
});
};