Issue in pagination in backbone - backbone.js

I want to do pagination in backbone. I have a selectbox and when I click on it I want it to show sepcific number of data.
<div class="results right" >
<form>
<label for="results">Results pr. page</label>
<select name="results" id="ShowSelect">
<option value="25" >25</option>
<option value="50" >50</option>
<option value="100" >100</option>
<option value="500" >500</option>
</select>
</form>
</div>
Model
defaults : {
id : null,
created : null,
timestamp : null
},
parse : function(response){
response.id = response._id.$oid;
response.created = response.created.$date;
response.timestamp = response.timestamp.$date;
return response;
},
This is my collection:
pagination : function(perPage, page) {
page = page - 1;
var collection = this;
collection = _(collection.rest(perPage * page));
collection = _(collection.first(perPage));
return collection.map( function(model) {
return model.toJSON();
});
},
and this is my view in a separate file: (uncompleted)
events : {
"change #messageSelect" : "changedGroup",
},
changedGroup : function(e){
e.preventDefault();
console.log("selector changed");
this.currentPage = 1;
this.selectedGroupId = $("#messageSelect :selected").attr("value");
console.log("id of select is", this.selectedGroupId);
//Resets current groups when changed.
this.currentGroup = this.collection.get(this.selectedGroupId);
},
renderRecentList : function(groupID, pageToLoad) {
var banPage = pageToLoad || this.currentBansPage ;
console.log("Load page", banPage);
this.selectedGroup = this.collection.get(groupID);
}
To be honset, I do not know how to evaluate max page in view. What I did is that I get the id of selector when the user click on it (the number of data I want to load e.g. 100, 50 etc) and created another function for evaluating max page to load. but how can I get the number of data
var maxPages = Math.ceil(? / this.pageSize);
console.log("max", maxPages);
var pageToLoad = this.currentPage + 1;
console.log("load me page", pageToLoad);
if(pageToLoad <= maxPages) this.renderRecentList(this.selectedGroupId, pageToLoad);
else{
console.log("no more pages to load");
this.setGlobalMessage("no more pages to load", "information");
}
return this;

I would suggest to you to do this on the server side. Load only the items you want to show and if the parameters change create a new request.
So the steps:
Create a service that recives the per page and page number parameters and returns only the corresponding items.
When the user first enter this page do a request with the default parameters and render the items.
When the user changes the page or the items per page do a new request and render the items that came from the server.

Related

ng-if Angularjs expression for if there is data in the MongoDB

I am trying to make a web app using Mean stack.
I want to use ng-if to display a certain div, in case if userID value inside of form equal to who registered which is user_id in user in MongoDB. Basically,
Show form.name where form.userId == user._id
So its like
<div ng-if="form.userID == user._id">
//display {{ form.name }}
</div>
<div ng-if="form.userID != user._id">
//display button to create form
</div>
In this way it will show/hide the div and bind the values like filtered.
Inside of my formSchema I have a propery called userId : {type: Schema.Types.ObjectId, ref: User} and assigned in formCtrl.js.
$scope.addForm = function () {
$scope.form.userId = $window.localStorage.getItem("userId");
$http.post(//code);
};
I have a factory for calling the userID in authServices.js
.factory('AuthUser', function($window){
var authUserFactory = {};
authUserFactory.setUserId = function(userId){
if(userId){
$window.localStorage.setItem('userId', userId);
}else{
$window.localStorage.removeItem('userId');
}
}
authUserFactory.getUserId = function(){
return $window.localStorage.getItem('userId');
};
return authUserFactory;
})
I have tried,
ng-if="form.userId | filter:_id:getUserId"
ng-if="form.userID == $window.localStorage.getItem(userId)"
ng-if="form.userId == user._id"
but all of them didn't work.

Updating an array in SharePoint spfx using React & PnPJS

I'm creating a web app that allows the user to update their status and location.
I have a data list table on SharePoint with the user's name, email address, status (for example: online, offline, or busy), location (which is a select field), along with other fields.
The web app is just 2 different select fields. Which allows the user to update his status and location.
When the user accesses the page on componentDidMount() I'm getting the user's email addresses (since he's logged into SharePoint) and then filtering the data list array to view the element for his information (so looking for his email address in the MyList. The part I'm stuck at now is updating the MyList list with the selected response that the user selected.
Using PnP-JS i found this should be possible here are two links showing the update() function.
https://github.com/SharePoint/PnP-JS-Core/wiki/Basic--Operations
https://github.com/SharePoint/PnP-JS-Core/wiki/Working-With:-Items
My code found here:
export default class SigninLocationWebpart extends React.Component<ISigninLocationWebpartProps, {Status: string, Location: string, userName: string, getEmail: string, selectedUser: any}> {
constructor(props) {
super(props);
this.state = {
Status: 'Online',
Location: 'New York',
userName: '',
getEmail: '',
selectedUser: {},
};
this.handleChangeStatus = this.handleChangeStatus.bind(this);
this.handleChangeLocation = this.handleChangeLocation.bind(this);
}
handleChangeStatus(event) {
const { value } = event.target;
this.setState({ Status: value });
}
handleChangeLocation(event) {
const { value } = event.target;
this.setState({ Location: value });
}
private _onUpdate(event) {
event.preventDefault();
//This is where I need help on updating list
let list = pnp.sp.web.lists.getByTitle("MyList")
//Instead of getting by ID i need to get by that selectUser array I believe
list.items.getById(1).update({
Status: this.state.Status, //User changing from Online to Offline
Location: this.state.Location //User changing from New York to Los Angeles
}).then(i => {
console.log(i);
});
}
public componentDidMount() {
if (Environment.type === EnvironmentType.Local) {
}
else if (Environment.type === EnvironmentType.SharePoint || Environment.type === EnvironmentType.ClassicSharePoint) {
//This gets the current users info and sets it to username and email
sp.web.currentUser.get().then((response : CurrentUser) => {
//console.log(response);
this.setState({
userName: response["Title"],
getEmail: response["Email"],
})
})
//This gets the list of all all items in the list
pnp.sp.web.lists.getByTitle("MyList").items.get().then((items: any[]) => {
console.log(items);
//Comparing email from sign in user and filtering items array to get that element
var compareEmail = this.state.getEmail;
console.log(compareEmail);
let selectedUser = _.filter(items, function(item) {
return item.Email_x0020_Address.toLowerCase() === compareEmail.toLowerCase();
});
console.log(selectedUser);
});
}
}
public render(): React.ReactElement<ISigninLocationWebpartProps> {
return (
<div className={ styles.signinLocationWebpart }>
<h3>Hello {this.state.userName}</h3>
<form onSubmit={this._onUpdate}>
<label>
Check In our Out
</label>
<select name="Status" value={this.state.Status} onChange={this.handleChangeStatus}>
<option value="Online">Online</option>
<option value="Offline">Offline</option>
<option value="Busy">Busy</option>
</select>
<label>
Location
</label>
<select name="Location" value={this.state.Location} onChange={this.handleChangeLocation}>
<option value="New York">New York</option>
<option value="Michigan">Michigan</option>
<option value="Los Angeles">Los Angeles</option>
</select>
<input type="submit" value="Submit" />
</form>
</div>
);
}
}
First of all, instead of getting all items in the List, and then filtering for the current user, you should get only the item(s) for the current user to begin with. Once you list gets large, you would be performing a lot of overhead by retrieving all items.
Secondly, and what you allude to in your comments, is that you need to specify the ID of the item to update. So, in your componentDidMount, after you get the List Item for the current user, save that Item in your state.
public componentDidMount() {
if (Environment.type === EnvironmentType.Local) {
}
else if (Environment.type === EnvironmentType.SharePoint || Environment.type === EnvironmentType.ClassicSharePoint) {
//This gets the current users info and sets it to username and email
sp.web.currentUser.get().then((response : CurrentUser) => {
//console.log(response);
this.setState({
userName: response["Title"],
getEmail: response["Email"],
});
pnp.sp.web.lists.getByTitle("MyList").items.filter("Email_x0020_Address eq '" + this.state.getEmail + "'").top(1).get().then((items: any[]) => {
if (items && items.length) {
this.setState( { selectedUser: items[0] } );
}
});
})
}
}
Then at update time, you can use the ID of that item to save it.
private _onUpdate(event) {
event.preventDefault();
//This is where I need help on updating list
let list = pnp.sp.web.lists.getByTitle("MyList")
//Instead of getting by ID i need to get by that selectUser array I believe
list.items.getById(this.state.selectedUser.ID).update({
Status: this.state.Status, //User changing from Online to Offline
Location: this.state.Location //User changing from New York to Los Angeles
}).then(i => {
console.log(i);
});
}
Additionally, you'll want to make sure you are binding your submission handler just like you are doing for your onchange handlers in your constructor:
this._onUpdate = this._onUpdate.bind(this);
I will also add, that unless you've make sure to pre-populate the List with all possible users, and will always keep it updated with new users, it would be best in to put a check in your _onUpdate that if this.state.selectedUser == null || this.state.selectedUser.ID == null then you should create a new item (and add the new item to your this.state.selectedUser), instead of updating.

Vue.js: Manipulate Array and post form with new data

In my Vue.js application I want to post form data to my Node.js/MongoDB Backend.
This is my source code: https://github.com/markusdanek/t2w-vue/blob/master/src/components/backend/JobEdit.vue
JSON for my job entry: http://t2w-api.herokuapp.com/jobs/591c09a55ba85d0400e5eb61
Relevant code for my question:
HTML:
<div class="row">
<input type='text'
:name="'qual'+index"
v-model="qualifications[index]">
<button #click.prevent="removeQualifiaction(index)">X</button>
</div>
Methods:
onChange(value, $event){
if (!this.job.xmlOnline)
this.job.xmlOnline = []
const index = this.job.xmlOnline.findIndex(v => v == value)
const checked = $event.target.checked
if (checked && index < 0)
this.job.xmlOnline.push(value)
if (!checked && index >= 0)
this.job.xmlOnline.splice(index, 1)
}
removeQualifiaction() {
this.qualifications.splice(this.qualifications.index, 1);
}
Sending the form data with submit button on form end:
editJob() {
let job = Object.assign({}, this.job);
job.qualifications = this.qualifications;
job.responsibility = this.responsibility;
this.$http.post('https://t2w-api.herokuapp.com/jobs/' + this.$route.params.id, job).then(response => {
console.log(response);
}, response => {
console.log(response);
});
}
My problems now:
When I edit a "Job", I have a list of "qualification items", that are input fields in my form.
Clicking the "delete" button results that the first input gets deleted, not the one I am clicking. Done with #thanksd answer.
How do I add a button and method to add a new input field and to append it to my job.qualifications?
In my JobAdd.vue implemented, to add a new entry to job.qualifications, like this:
<a #click.prevent="addQualification">+</a>
addQualification() {
this.qualification.push({ text: '' });
}
addJob() {
let job = Object.assign({}, this.job);
job.qualifications = this.qualification.map(q => q.text);
this.$http.post('https://t2w-api.herokuapp.com/jobs/', job).then(response => {....
Full source for my JobAdd.vue: https://github.com/markusdanek/t2w-vue/blob/master/src/components/backend/JobAdd.vue
this.qualification.push({ text: '' }); doesnt work obviously not in my JobEdit.vue when there are already strings in my job.qualifications.
Change your removeQualifiaction method to use the index being passed in:
removeQualifiaction(index) {
this.qualifications.splice(index, 1);
}

Multiple dropdown selection in ag-grid (link Attached)

I need to have a column in ag-grid where i can select multiple values from dropdown. I just googled online to see if it is already implemented but i could find only one link.
https://gist.github.com/gaborsomogyi/00f46f3c0ee989b73c92
Can someone let me know how to implement it. show the full code as an example please.
Here is the code shared over there.
function agDropDownEditor(params, optionsName, optionsList) {
_.set(params.$scope, optionsName+'.optionsList', optionsList);
var html = '<span style="width:100%; display:inline-block" ng-show="!'+optionsName+'.editing" ng-click="'+optionsName+'.startEditing()">{{data.'+params.colDef.field+'}}</span> ' +
'<select style="width:100%" ng-blur="'+optionsName+'.editing=false" ng-change="'+optionsName+'.editing=false" ng-show="'+optionsName+'.editing" ng-options="item for item in '+optionsName+'.optionsList" ng-model="data.'+params.colDef.field+'">';
// we could return the html as a string, however we want to add a 'onfocus' listener, which is not possible in AngularJS
var domElement = document.createElement("span");
domElement.innerHTML = html;
_.set(params.$scope, optionsName+'.startEditing', function() {
_.set(params.$scope, optionsName+'.editing', true); // set to true, to show dropdown
// put this into $timeout, so it happens AFTER the digest cycle,
// otherwise the item we are trying to focus is not visible
$timeout(function () {
var select = domElement.querySelector('select');
select.focus();
}, 0);
});
return domElement;
}
Hope this helps, this is just a snippet of my code what i'm doing is I'm fetching from an array using map and then creating my object which is col and returning it and this will repeat till the last index of that array.
var col = {};
col.field = "fieldName";
col.headerName = "colName";
col.headerCellTemplate = function() {
var eCell = document.createElement('span');
eCell.field = obj.expr;
eCell.headerName = obj.colName;
eCell.innerHTML = "<select>"+"<option>"+
'Abc'+"</option>" +"<option>"+
'Xyz'+"</option>" +"</select>"
//$scope.dropDownTemplate;
var eselect = eCell.querySelector('select');
eselect.focus();
return eCell;
};
return col ;
}));

Setting default item of select box using angularjs

I'm trying to set the default item of a select box on load using angularjs.
I load both select boxes from 2 json's, so the second select box, named 'city' relies off the first select box 'country':
<label>Country:</label>
<select name="country" ng-model="form.country"
ng-options="c.n for c in countryList"
ng-change="countryChanged()" required></select>
<label>City:</label>
<select name="city" ng-model="form.city"
ng-options="c for c in cityList" required></select>
PLUNKER
http://plnkr.co/edit/hKZLbMbwGfmaa8CtSy0H?p=preview
It loads the select boxes using $http.get. It loads all well and good if i default it to the first option. But lets say, I want to specify a certain option to be selected on load, but I can only send it a particular value from the json, how would I do this? In the code below, the commented line is what I've tried, but all it does is load the correct city list, but leave the country select box unselected.
countries.json
[
{"c":"au","n":"Australia","g":"1"},
{"c":"fr","n":"France","g":"2"},
{"c":"ge","n":"Germany","g":"2"}
]
Controller:
$http.get('countries.json')
.success(function (data) {
$scope.countryList = data;
$scope.form.country = data[0];
// $scope.form.country.c = 'fr'; <<<--- *trying to set default*
$scope.countryChanged();
});
$scope.countryChanged = function() {
$http.get($scope.form.country.c + '-cities.json')
.success(function (data) {
$scope.cityList = data;
$scope.form.city = data[0];
});
}
Also, if there is a better way to achieve this, please post it.
Note: I can't join the json up. I split it because in the real world, there could be 100 countries each with 100 cities each and the json would be quite massive.
Not sure, but does this satisfy the requirement?
http://plnkr.co/edit/rBDVzg7iXfaHu4XmiVsb?p=preview
var selectCountry = function( data, code ) {
for ( var i = 0; i < data.length; i++ ) {
var country = data[ i ];
if ( country.c !== code ) { continue; }
return country
}
};
$http.get('countries.json')
.success(function (data) {
$scope.countryList = data;
$scope.form.country = selectCountry( data, 'fr');
$scope.countryChanged();
});
Just set inside your controller at line 12:
$scope.form.country = data[1];
It sets France as default, Hope I understood your question.

Resources