Adding row on the top using Angular - Xeditable - javascript

I want by clicking in the "Add row" button the new row will be on the top table.
I have this basic example.
I tried to add a filter to the function bellow, but I got hte same result.
// add user
$scope.addUser = function() {
$scope.inserted = {
id: $scope.users.length+1,
name: '',
status: null,
group: null
};
$scope.users.push($scope.inserted);
};
Thank you for help.

Use unshift instead of push so that the item is added to the start of the array:
$scope.users.unshift($scope.inserted);
Demo

Related

LWC: How to reset values of a multiselect combo box on click of a button in LWC

In my parent component I'm calling child component as:
<c-multiselect-picklist multi-picklist-values={picklistValues} onselect={handleChange}
preselected-string={selectedPicklistValue} data-id="first"></c-multiselect-picklist>
JS:
picklistValues = {};
picklistOptions = [ { label: 'First', value: 'First'},
{ label: 'Second', value: 'Second'},
{ label: 'Third', value: 'Third'},
{ label: 'Fourth', value: 'Fourth'}
];
connectedCallback() {
this.picklistValues.label = '';
this.picklistValues.optionsToSelect = this.picklistOptions;
this.selectedPicklistValue = 'Some String';
}
In the UI, I have a button reset and on click of that I would like to reset multiselect child LWC to initial state without any selections.
How this can be achieved in LWC.
I tried with making picklistValues as null but still lightning combobox shows selected options.
As already commented it is hard to tell what would work for your custom combobox without seeing your actual implementation, however I can show you a working solution:
Multi Select Combobox
I wrote an article on how to create a LWC multi select combobox that might help you: https://medium.com/#svierk/how-to-create-the-lwc-multi-select-combobox-that-salesforce-is-still-missing-c7bf3a2850dd
The source code including JEST unit tests and JSDoc comments is available here: https://github.com/svierk/awesome-lwc-collection/tree/main/force-app/main/default/lwc/multiSelectCombobox
Reset the current selection
To reset the current selection from outside using for example a button, you just have to add a reset method and make it available to the outside using the #api annotation. If you use my component, this method would looks like this:
#api
reset() {
this.selectedItems = this.placeholder;
this.currentOptions = [];
this.selectedOptions = [];
this.isLoaded = false;
}
You can then call your reset method from the respective parent component via query selector:
this.template.querySelector('c-multi-select-combobox').reset();

add a new empty line in ui-grid

I'm trying to add a new empty line in ui-grid. I've tried looking in different tuto and example, but all that I found didn't reply to my spec, and I wasn't able to adapt it to what I'm looking for.
In fact I'm looking how to add a new empty line in an existing ui-grid neither using a button outside the grid nor a button in the rowfooter.
I'm looking to add a abutton in the grid like the + button shown in the screen shot below
or may be render automatically a new empty line when the rendering the ui-grid and a new one when all rows were filled.
I tried doing that using function in cell template but it's not working.
any help is really appreciated
The first option sounds like more of a CSS issue to me. Essentially, the add button would use some sort of font library containing a +, and you would need to position it in the corner of the grid. Perhaps looking at the grid footer would be a starting place. It sounds like you've seen the basics of creating an add row button here: http://ui-grid.info/docs/#/tutorial/112_swapping_data
The second option (render automatically a new empty line when the rendering the ui-grid and a new one when all rows were filled) requires a JavaScript approach.
The basic logic I followed is:
(Assume) Some data loads from somewhere in a backend (in this sample, it's a simulated load returning a promise as $http or $resource would).
After that data is loaded, we append a new row. We wait for the data first; otherwise we'd not be pushing the new row to the correct location.
Upon completion of the edit action, we set a timeout to ensure subsequent edits on other cells do not keep firing a new row. If the timeout is reached, we append a new row. If a subsequent edit action occurs, and a timeout promise exists (for adding a new row), we cancel it. Once no edit actions occur, and the timeout is reached, we push the new row.
To ensure that we are only taking action when our "extra row" is modified, when we create a row, a reference is maintained to the current row such that we can evaluate whether or not a received event is of interest (var newRowTimeoutPromise).
The core logic in code is below, with a sample implementation in Plnkr:
var extraRow = null,
addNewTimeoutMillis = 2000,
newRowTimeoutPromise = null;
loadData().then(function(data) {
$scope.gridOpts.data = data;
}).finally(function() {
// add initial empty row, and set our reference to it
extraRow = addEmptyRow($scope.gridOpts.data);
})
$scope.gridOpts = {
showGridFooter: true,
onRegisterApi: function(gridApi) {
$scope.gridApi = gridApi;
// listen for cell edit completion
gridApi.edit.on.afterCellEdit($scope, function(rowEntity, colDef, newValue, oldValue) {
// test if the edited row was the "extra row"
// otherwise, and edit to any row would fire a new row
// Set a timeout so we don't create a new row if the user has
// not finished their edit(s) on other fields
newRowTimeoutPromise = $timeout(function() {
if (rowEntity == extraRow) {
// add a new empty row, and set our reference to it
extraRow = addEmptyRow($scope.gridOpts.data);
newRowTimeoutPromise = null;
}
}, addNewTimeoutMillis);
})
// Listen for cell edit start, and cancel if we have a pending new
// row add. Otherwise, each time you finish the edit on a cell,
// this will fire.
gridApi.edit.on.beginCellEdit($scope, function(rowEntity, colDef, newValue, oldValue) {
if (newRowTimeoutPromise != null) {
$timeout.cancel(newRowTimeoutPromise);
}
})
}
};
http://plnkr.co/edit/IMisQEHlaZDCmCSpmnMZ?p=preview
I used jQuery to fetch and change style of specific cell elements of the cell template.
Here is a helpful Fiddle
Here is the controller script : -
var app = angular.module('app', ['ngTouch', 'ui.grid']);
app.controller('MainCtrl', ['$scope',
function($scope) {
$scope.gridOptions = {};
$scope.Add = function() {
$scope.gridOptions.data.push( { firstName: ' ',lastName:'',company:'' });
$(".ui-grid-coluiGrid").prevObject["0"].activeElement.style.display="none";
$(".ui-grid-cell")[$scope.gridOptions.data.length-2].style.display="inline";
};
$scope.gridOptions.onRegisterApi = registerGridApi;
function registerGridApi(gridApi) {
$scope.gridApi= gridApi
};
$scope.gridOptions.columnDefs = [{
name: 'firstName',
field: 'firstName',
}, {
name: 'lastNamer',
field: 'firstName'
}, {
name: 'ShowScope',
cellTemplate: '<button id="btb" ng-click="grid.appScope.Add()">+</button>'
}];
$scope.gridOptions.data = [{ yourdata}];
}
]);
To make it work properly 2 more things have to be done
Use cellContentEditable to make the rows editable
In order to disable display style of cell template button that appears on cells corresponding to rows of already existing data,you could use angular foreach or a for loop to iterate through these rows and disable style(I tried using renderContainers but it always returns the length of rendered rows outside Add functions as 0).
I have a working plunker over here.
http://plnkr.co/edit/Vnn4K5DcCdiercc22Vry?p=preview
In columnDefs, I have defined a separate column for add:
{
name: 'add',
displayName: '',
enableCellEdit: false,
enableColumnMenu: false,
width: '3%',
cellTemplate: '<div class="ui-grid-cell-contents" ng-click="grid.appScope.addRow()"><span ng-click="grid.appScope.addRow()">Add</span></div>'
}
And
$scope.addRow= function(){
var newlist = {"remarks":'',"testName":''};
$scope.gridOptions.data.push(newlist);
}
Update: A second plunker with bootstrap icons for add/remove
http://plnkr.co/edit/FjsA2r?p=preview

Displaying content based on radio button selection

I’m pretty new to backbonejs and i’m trying to create a basic application.
The application is something like this:
I have 5 sections: A, B, C, D and E
Each section has 2 radio buttons.
Section A - Radio1, Radio2
Section B - Radio3, Radio4
Section C - Radio5, Radio6
Section D - Radio7, Radio8
Section E - Radio9, Radio10
Depending on what radio button is selected, I need to display a section (previous sections must also display)
I have had a look at maybe using a model to determine which radio was selected and also what section is displayed. Is this the correct approach?
var State = Backbone.Model.extend({
defaults: {
id: null,
name: "",
isOn: false
}
});
var Section = Backbone.View.extend({
model: State,
events: {
'change [type="checkbox"]': function (event) {
var $checkbox = $(event.target);
this.model.set("isOn", $checkbox.is(":checked"));
this.model.get("dispatcher").trigger("toggle", this.model.get("id"));
}
},
initialize: function (options) {
this.listenTo(this.model, "change:isOn", function (model, isOn) {
if ( isOn ) {
this.$el.find(".section").show();
this.$el.find("input").prop("checked", true);
}
else {
this.$el.find(".section").hide();
this.$el.find("input").prop("checked", false);
}
});
this.listenTo(dispatcher, "toggle", function (id) {
if ( this.model.get("id") < id ) {
this.model.set("isOn", true);
}
if ( this.model.get("id") > id ) {
this.model.set("isOn", false);
}
});
},
render: function () {
this.$el.html('<div>' + this.model.get("name") + '</div><input type="checkbox"><div class="section" style="min-height:100px; background-color:grey; display:none;"></div>');
this.$el.appendTo("body");
}
});
var dispatcher = _.extend({}, Backbone.Events);
_.each([
{id: 1, name: "A", isOn: false, dispatcher: dispatcher},
{id: 2, name: "B", isOn: false, dispatcher: dispatcher},
{id: 3, name: "C", isOn: false, dispatcher: dispatcher},
{id: 4, name: "D", isOn: false, dispatcher: dispatcher},
{id: 5, name: "E", isOn: false, dispatcher: dispatcher}
], function (item) {
var view = new Section({model: new State(item)});
view.render();
});
I didn't understand the meaning of two radio.. so I used checkbox per section.. Hope this will uncover some basics of backbone.
Yes this approach will work. I recommend if you need to communicate between views to use models via events - this will generally result in better architecture (your views will be more decoupled).
You can react to the change event in the view (using the events hash) and update an attribute on a model for each group, e.g. this.model.set('termsAccepted', true/false) then as long as the other view(s) have access to this model you can react to the change event of that attribute, e.g. this.listenTo(this.model, 'change:termsAccepted', this.onTermsAcceptedChange).
There may be a very simple solution to your objective. If you monitor the radio-button state via a javascript function, then you can use that function to change a class statement for the parent div. In CSS, you can then define actions to hide or display a div based on it's class. This would only take a few lines of javascript and a few lines of CSS.
For example, this example in codepen shows a way to accomplish the hide/show for a variably sized div. The number of divs in this approach is arbitrary - you can have as many or few as you like, and the only action required of the user is to click on the header to expand or collapse the associated div. In this example, clicking on the header acts as a toggle to expand or collapse the associated div. The example is set up so that only one div is expanded at a time and clicking on a different header automatically collapses any open div so that only one div is open at a time. If you do not want that behavior, just remove the for loop in the accOff() function.
It's kinda like a choose-your-own-adventure, ya sipher_z?
I advise using the Backbone Router with route parameters storing the current state, that is, which section is currently showing.
Each component of the view should be a Backbone.View.extend({...}). Components might be Section and Radio.
On each Radio button, in HTML, put a data-go-to attribute, with a value of the section to go to next. Then, in your RadioView code, put a click event. When clicked, extract this data-go-to, and do something like location.hash = '/section/' + section to trigger your router.
Then, all your router does is hide all the Sections except the selected one whenever triggered. If there's no selection, it just shows the first one!
I'm not 100% sure of this strategy, but this is definitely "the Backbone way". Let me know if I can clear anything up.

Multiple <select> using selectize, option removal when already selected

I'm new in using selectize.js, and this is the simplified version of my problem. Please see fiddle below.
Fiddle
What I want is not to select the item when it is already selected.
Ex.
click the Add button and then select the full name.
click the Add again.
Full name should not be selected in the second <select> or should not be visible.
How will I be able to do this?
HTML
<button>Add</button><br/><br/>
<div id="container"></div>
JS
var saveAsOptions = [
{ value: 'full-name', text: 'Full Name' },
{ value: 'first-name', text: 'First Name' },
{ value: 'last-name', text: 'Last Name' }
];
var i = 1;
var $selectSaveAs;
$('button').on('click', function(){
$('#container').append(generateSaveAs(i));
$selectSaveAs = $('#saveAs' + i).selectize({
options: saveAsOptions,
placeholder: '- Fields -'
});
i++;
});
function generateSaveAs(id){
return '<select id="saveAs' + id + '"></select>';
}
So every time you are creating a new drop down you are inserting static values. By analyzing the code I see the selected value always have a class item. So what we can do is create a new array to show in dropdown and filter out the ones already selected. And then we can bind it in drop down.
To filter out you can use filter
saveAsOptionsFiltered = saveAsOptions; //Initialize with your all drop down options
$(".item").each(function(index,element) {
/*Filter out the already selected ones*/
saveAsOptionsFiltered = saveAsOptionsFiltered.filter(function (savevalue) {return savevalue.text !== $(element).text() });
});
JSFiddle
I have not handled the condition when all are selected and you stop adding more I have just shared the code in which you can filter out the selected ones.

create a array of kendo multi-select selected id

i am try to create a array of selected id using kendo multi select.
here is jsfiddle
this is kendo script:-
$("#multiselect").kendoMultiSelect({
dataSource: [
{ id: 1, name: "Apples" },
{ id: 2, name: "Oranges" }
],
dataTextField: "name",
dataValueField: "id",
select:onSelect
});
kendo select function:-
function onSelect(e){
var dataItem = this.dataSource.view()[e.item.index()];
onchng(dataItem.id);
}
create a array:-
function onchng(id){
var checkarr = [];
checkarr.push(id);
console.log(checkarr);
}
here is output is [1] [2]
but i want it ['1','2']
is it possible??
thanks
When your select event fired, 'checkarr' redefined again and again. Your problem is that. If you want values in one array, you must use a button to take values together, then push them to array in single function. Or you can use session or something like that
This is how you can do it from the Controller. Note I'm doing Request.Form, that's because for whatever reason MVC Model and Kendo UI wouldn't work together when using MultiComplete. But this will put them in an array, and this is fired off a button click like the other answer suggested.
string[] advertisers = Request.Form["Name"].ToString().Split(',');
I think that there is a much easier approach and with less side effects...
Bind change event instead of select. Why? Two reasons:
select is fired just before the element is added to the list of values so you cannot get current list and you need to add the value being selected to the values already selected.
select is not fired when you remove the selection of an option.
The code using change would be as simple as:
var multi = $("#multiselect").kendoMultiSelect({
dataSource: [
{ id: 1, name: "Apples" },
{ id: 2, name: "Oranges" }
],
dataTextField: "name",
dataValueField: "id",
change : onSelect
}).data("kendoMultiSelect");
function onSelect(){
console.log("here", multi.value());
}
Just need to use value method from your multiselect.
Your Fiddle modified in here : http://docs.telerik.com/kendo-ui/api/framework/datasource#events-change
NOTE: change event belongs to DataSource if you need to see the documentation, check it here

Categories

Resources