In my angular 6 app, I have used ng2-smart-table. Now I need to show and hide custom action features based on their access rights.
I'm able to mange add, edir and delete part. With that I have also put some custom icons also for extra features.
custom: [
{ name: 'up', title: '<img src="/pathOfIcon" class="tableIcon up-arrow-true-icon">' },
{ name: 'up-cancel', title: '<img src="/pathOfIcon" class="tableIcon up-arrow-cancel-icon">' },
{ name: 'down', title: '<img src="/pathOfIcon" class="tableIcon down-arrow-true-icon">' },
{ name: 'down-cancel', title: '<img src="/pathOfIcon" class="tableIcon down-arrow-cancel-icon">' },
]
Now I need to manage this thing based on access.
So how could I enable and disable this icons.
Note: I can apply css on each row and then hide icon, But I need to do once not on each row.
You can add icons while add a icons in custom array...
Try this way
if(access){ // Set you access condition
this.settings.custom.push('{ name: 'up', title: '<img src="/pathOfIcon" class="tableIcon up-arrow-true-icon">' }');
this.settings.custom.push('{ name: 'up-cancel', title: '<img src="/pathOfIcon" class="tableIcon up-arrow-cancel-icon">' },');
}else{
this.settings.custom.push(' { name: 'down', title: '<img src="/pathOfIcon" class="tableIcon down-arrow-true-icon">' }');
this.settings.custom.push('{ name: 'down-cancel', title: '<img src="/pathOfIcon" class="tableIcon down-arrow-cancel-icon">' }');
}
This the simple way to add icons... Because custom is array so you can push icons in that...
Hope this may help you... :)
Related
hopefully someone there who can guide me on rite way. trying to create dynamic html with dynamic control. here is my example.
const [oHtml, setoHtml] = React.useState([
{
type: "html",
control: "<table><tr><td>",
},
{
type: "control",
control: (
<CustomInput
labelText="Password"
id="password"
formControlProps={{
fullWidth: true,
}}
inputProps={{
type: "password",
autoComplete: "off",
}}
/>
),
},
{
type: "html",
control: "</td></tr></table>",
},
]);
and here how i am rendering.
return (
<div>
{Object.keys(oHtml).map(function (keyName, keyIndex) {
if (oHtml[keyName].type === "html") {
console.log(oHtml[keyName].control);
return ReactHtmlParser(oHtml[keyName].control);
} else {
return oHtml[keyName].control;
}
})}
</div>
);
issue is when React run <table><tr><td> its auto fixing tag and making it <table><tr><td></td></tr></table>
what i want to control inside td.
is there any way i can disable react to add missing tags itself?
The thing is that ReactHtmlParser can't be used to parse partial html.
You can try
return ReactHtmlParser(
oHtml.map(v => v.control).join("")
)
Btw, your oHtml is an array, so no need for Object.keys.
When any user lands on the page, he should see the first step as written below and clicking on the next button, he should redirect on the next page where I wish to send the user but it's not.
Here when I tried to do multi-step i.e. on landing show user some data and on the next step I redirect the page then it works absolutely fine but for single step only, it is not working.
I am using the latest version of the bootstrap tour files i.e. downloaded from their official site yesterday.
See the code below:-
var tour = new Tour({
steps: [
/* {
element: "#site-tour-1-1",
title: "1",
},*/
{
element: "#site-tour-1-1",
title: "Search any business by typing initials",
//path: "/index2.html",
multipage: true,
onNext: function() {
window.location = "/index2.html"
}
}
],
debug: true,
backdrop: true,
redirect:false,
storage: window.localStorage,
template: " <div class='popover tour'><div class='arrow'></div><h3 class='popover-title'></h3><div class='popover-content'></div><div class='popover-navigation'><button class='btn btn-default' data-role='prev'>« Prev</button> </span><button class='btn btn-default' data-role='next'>Next »</button><button class='btn btn-default end-tour' data-role='end'>End tour</button></div></div>",
});
tour.init();
tour.restart();
Like said in the documentation of bootstrap-tour, you can manage a multipage tour by adding a field 'path' to one of your step. (See here : http://bootstraptour.com/api/#multipage)
In your case, you should do that :
var tour = new Tour({
steps: [
{
element: "#site-tour-1-1",
title: "Search any business by typing initials",
},
{
element: "#site-tour-1-2",
title: "This is my second step";
path: "/index2.html"
}
],
debug: true,
backdrop: true,
storage: window.localStorage,
template: " <div class='popover tour'><div class='arrow'></div><h3 class='popover-title'></h3><div class='popover-content'></div><div class='popover-navigation'><button class='btn btn-default' data-role='prev'>« Prev</button> </span><button class='btn btn-default' data-role='next'>Next »</button><button class='btn btn-default end-tour' data-role='end'>End tour</button></div></div>",
});
tour.init();
tour.restart();
Let me know if it helps you.
I am having trouble getting the knockoutjs checked binding to work properly. Not sure if I'm just doing something wrong or what. I have this piece of html
<ul data-bind="foreach: ListItems" >
<li style="padding-left: 0px; margin-left: 0px; color: white; font-size: 12px;">
<div class="title" style="margin-right: 3em; line-height: 20px;">
<input type="checkbox" data-bind="checked: IsActive" />
<label data-bind="text: Quantity, disable: IsActive"</label>
<label data-bind="text: Description, disable: IsActive" ></label>
</div>
</li>
</ul>
Where I want a checkbox that allows users to mark items off this list by clicking the checkbox which should either strikeout the text or grey it out or something.
My view model is created by getting the following json data format.
{"$id":"1","Description":"New List","Categories":
[{"$id":"2","Description":"Bread/Bakery","ListItems":
[{"$id":"3","IsActive":1,"Description":"Bread","Quantity":"1 Loaf"}]},
{"$id":"4","Description":"Beverages","ListItems":
[{"$id":"5","IsActive":1,"Description":"Coke","Quantity":"1 Case"},
So the problem is that checking the checkbox doesn't actually do anything here. It should be disabling the other labels but it doesn't. All my other values are displayed correctly and if I do a data-bind=text: IsActive I can see the value that should be changing with the checkbox but it never changes.
Edit: following suggestion below:
var mydata = ko.observableArray([
{
Categories: ko.observableArray([
{
Description: "Dairy", ListItems: ko.observableArray([
{ Description: "Eggs", Quantity: "1 Dz.", IsActive: ko.observable(false) },
{ Description: "Milk", Quantity: "1 Gallon", IsActive: ko.observable(false) }
])
},
{
Description: "Produce", ListItems: ko.observableArray([
{ Description: "Lettuce", Quantity: "1 Head", IsActive: ko.observable(false) },
{ Description: "Oranges", Quantity: "5 ea.", IsActive: ko.observable(false) },
{ Description: "Greenbeans", Quantity: "1 Thingy", IsActive: ko.observable(false) },
])
},
])
}
]);
The issue you are having is because your data is a plain JSON object and that will get bound only once.
To get the bidirectional binding behaviour you are looking for, your objects need to be "observables", so for example:
var mydata = ko.observable({
Categories: ko.observableArray([
{ IsActive: ko.observable(true) }
])
});
Note that it is up to you to determine which items in your structure need to be observables; it will depend on how you want the bindings to behave.
I am changing the size of the containing div using ng-class and an expression that evaluates whether or not an edit form is displayed. If the edit form is displayed I want to change the size of the div containing the ng-grid and the ng-grid itself.
<div class=" row-fluid">
<div ng-class="{'span7' : displayEditForm == true, 'span12': displayEditForm == false}" >
<ul class="nav nav-tabs" style="margin-bottom: 5px;">
<li class="active">Activities Needing My Approval</li>
<li>My Activities Needing Approval </li>
<li>My Activities</li>
</ul>
<div class="edus-admin-manage-grid span12" style="margin-left:0;" ng-grid="gridOptions"></div>
</div>
<div class="span5" ng-show="displayEditForm">
<div class="edus-activity-container">
<div class="edus-admin-activities-grid">
<div ng-include="'/partials/' + activity.object.objectType + '.html'" class="edus-activity"></div>
<!-- <div ng-include="'/partials/admin-activity-actions.html'"></div>-->
</div>
</div>
<div ng-include="'/partials/admin-edit-activity-grid-form.html'"></div>
</div>
</div>
The div containing the navbar and grid changes size via ng-class (from span12 to span7), but the ng-grid does not refresh. How can I trigger the refresh of ng-grid given the change in the parent div?
I've included my gridOptions below:
$scope.gridOptions = {
plugins: [gridLayoutPlugin],
data : 'activities',
showFilter: true,
/* enablePaging: true,*/
showColumnMenu: true,
/* showFooter: true,*/
rowHeight: 70,
enableColumnResize: true,
multiSelect: false,
selectedItems: $scope.selectedActivities,
afterSelectionChange: function(rowItem,event){
if($scope.selectedActivities && $scope.selectedActivities.length > 0){
$scope.activity = $scope.selectedActivities[0];
$scope.activityViewState.index = $scope.activities.indexOf($scope.activity);
$scope.displayEditForm = true;
console.log("DEBUG :::::::::::::::: updated displayEditForm.", $scope.displayEditForm);
if($scope.activity.ucdEdusMeta.startDate) {
// $scope.activity.ucdEdusMeta.startDate = new Date($scope.activity.ucdEdusMeta.startDate);
$scope.edit.startDate = moment($scope.activity.ucdEdusMeta.startDate).format("MM/DD/YYYY");
$scope.edit.startTime = moment($scope.activity.ucdEdusMeta.startDate).format("hh:mm A");
}
if($scope.activity.ucdEdusMeta.endDate) {
// $scope.activity.ucdEdusMeta.endDate = new Date($scope.activity.ucdEdusMeta.endDate);
$scope.edit.endDate = moment($scope.activity.ucdEdusMeta.endDate).format("MM/DD/YYYY");
$scope.edit.endTime = moment($scope.activity.ucdEdusMeta.endDate).format("hh:mm A");
}
}
},
/* pagingOptions: { pageSizes: [5, 10, 20], pageSize: 10, totalServerItems: 0, currentPage: 1 },*/
columnDefs: [
{field: 'title', displayName: 'Title', width:'15%',
cellTemplate: '<div class="ngCellText", style="white-space: normal;">{{row.getProperty(col.field)}}</div>'},
{field: 'actor.displayName', displayName: 'DisplayName', width:'10%',
cellTemplate: '<div class="ngCellText", style="white-space: normal;">{{row.getProperty(col.field)}}</div>'},
{field: 'object.content', displayName:'Content', width:'35%',
cellTemplate: '<div class="ngCellText", style="white-space: normal;">{{row.getProperty(col.field)}}</div>'},
{field: 'ucdEdusMeta.startDate', displayName: 'Start Date', width:'20%',
cellTemplate: '<div class="ngCellText" ng-class="col.colIndex()"><span ng-cell-text>{{row.getProperty(col.field) | date:"short"}} </span></div>'},
{field: 'ucdEdusMeta.endDate', displayName: 'End Date', width:'20%',
cellTemplate: '<div class="ngCellText" ng-class="col.colIndex()"><span ng-cell-text>{{row.getProperty(col.field) | date:"short"}} </span></div>'}
// {field: '', displayName: ''},
]
};
Here's the CSS used by the grid:
.edus-admin-manage-grid {
border: 1px solid rgb(212,212,212);
width: 100%;
height: 700px
}
You can use ng-grid's layout plugin (ng-grid-layout.js). It should come with ngGrid located at:
ng-grid/plugins/ng-grid-layout.js
(UPDATED: now at https://github.com/angular-ui/ng-grid/blob/2.x/plugins/ng-grid-layout.js)
You will have to include an additional script tag pointing to this js file in your main index.html file. And the order of including this versus ng-grid.js is important.
You would have to set a watch on displayEditForm and then call the plugin's updateGridLayout() function.
So it would be something like:
var gridLayoutPlugin = new ngGridLayoutPlugin();
// include this plugin with your grid options
$scope.gridOptions = {
// your options and:
plugins: [gridLayoutPlugin]
};
// make sure grid redraws itself whenever
// the variable that ng-class uses has changed:
$scope.$watch('displayEditForm', function() {
gridLayoutPlugin.updateGridLayout();
});
From my understanding, watches generally belong in the link function rather than the controller but it will work in either spot. You could also go a bit further and say:
$scope.$watch('displayEditForm', function(newVal, oldVal) {
if (newVal !== undefined && newVal !== oldVal) {
gridLayoutPlugin.updateGridLayout();
}
});
To make sure this only fires when the data switches from true/false. This would matter if your data is initially undefined and you waste time calling grid redraw before you give it an initial value.
i am trying to show data from webserver json and it is not shown in view. At first i tried to show message only but could not succed. following this link and sample provided by #rdougan i have been able to parse upto categories but unable parse latter value can any one guide me.
code i have done till now are as follow:
{
xtype: 'panel',
padding: '20px',
//height: 100,
styleHtmlContent:true,
store: 'TodaysWordStore',
models: 'TodaysWordModel',
tpl:
[
'<tpl for=".">',
'<ul class="parabox">',
'<li><h2 onclick = "ratingStar()">{message} </h2> ',
'<ul class="para-box-wrapper">',
'<li class="greenbox"><div class="paragraph-def">',
'{dictionaryDef}',
'<span class="authorBox">Author: {authorName}</span>',
'</div><div class="starBox">',
'{ratingBox}',
'</div></li>',
'</ul></li></ul>',
'</tpl>',
]
// '<div><strong>{dictionaryWord}</strong>, {dictionaryDef} <em class="muted">({role})</em></div></tpl>']
},
My store is
Ext.define('appname.store.TodaysWordStore',{
extend: 'Ext.data.Store',
config:
{
model: 'appname.model.TodaysWordModel',
autoLoad:true,
proxy:
{
type: 'ajax',
url : 'location' //Your file containing json data
reader:
{
type: 'json',
//rootProperty:'accountInfo'
}
}
}
});
My model is
Ext.define('appname.model.TodaysWordModel', {
extend: 'Ext.data.Model',
config: {
fields:[
{name: 'message', mapping: 'accountInfo.message'}
]
}
});
The json i want to parse
({"accountInfo":
{"expire_date":"2014-07-02 08:01:09",
"subscribe_date":"2013-07-02 08:01:09",
"time_remain":" 358 Days 1 Hour 24 Minutes",
"status":"not expired"},
"status":"TRUE",
"message":"Todays Word",
"data":
[{"name":"curtain",
"author":"admin",
"word_id":"35",
"category":"business",
"definition":
[{"rating":
{"red":"0",
"green":"1",
"yellow":"0",
"total_rating":1,
"final_rating":"Green"},
"defintion":"curtain",
"def_id":"11",
"example":"This is a sample example.",
"author":"admin"},
{"rating":
{"red":0,
"green":0,
"yellow":0,
"total_rating":0,
"final_rating":"This definition is not rated yet."},
"defintion":"to cover something",
"def_id":null,
"example":"This is curtain example.",
"author":"admin"}],
"is_favourite":"No"}]})
Help me
You are trying to use a panel, when you should be using a dataview. The tpl is meant to be used with the data config option when using an Ext.panel.Panel, where data is just an Object containing the data to be used by the tpl. However, when you are using a store for your data, you should use an Ext.view.view instead of the panel. See the docs here: http://docs.sencha.com/extjs/4.2.1/#!/api/Ext.view.View
I solved it by adding an extra itemTpl. Since i had tpl for data only it was not able to fetch data from definitions node.
{
xtype: 'list',
store: 'ghak',
height: 140,
layout: 'fit',
scrollable: {
direction: 'vertical',
directionLock: true,
},
margin: '0 0 5px 0',
itemTpl: [
'<div>',
'<tpl for="data">',
'<ul class="parabox">',
'<li><h2 class="noStar" onclick = "addtofavourite({word_id})">{name} </h2>',
'<tpl for="definitions">',
'<ul class="para-box-wrapper">',
'<li class="{rating}"><div class="paragraph-def" onclick = "rating({def_id})">','{defintion}',
'<span class="authorBox">Author: {author}</span>',
'</li>' ,
'</div>',
'</ul></li>',
'</tpl>',
'</ul>',
'</tpl>',
'</div>'
].join('')
Hope it would help someone.
Thanks.