twbsPagination plugin Issue - pagination

I am using twbsPagination, and I am stuck with the issue below.
onPageClick event never fires after I destroy and initialize new options like totalpages.
Here is my code:
function ShowPages(update, TotalPages) {
if (update) {
var $pagination = $('#pagination');
var defaultOpts = {
totalPages: 10
};
var currentPage = $pagination.twbsPagination('getCurrentPage');
$pagination.twbsPagination('destroy');
$pagination.twbsPagination($.extend({}, defaultOpts, {
startPage: currentPage,
totalPages: TotalPages,
first: '<span> <i class="ace-icon fa fa-angle-double-left bigger-140"></i> </span>',
prev: '<span> <i class="ace-icon fa fa-angle-left bigger-150"></i></i></span>',
next: '<span> <i class="ace-icon fa fa-angle-right bigger-150"></i></i></span>',
last: '<span> <i class="ace-icon fa fa-angle-double-right bigger-140"></i></span>'
}));
}
else {
$('#pagination').twbsPagination({
totalPages: TotalPages,
visiblePages: 7,
first: '<span> <i class="ace-icon fa fa-angle-double-left bigger-140"></i> </span>',
prev: '<span> <i class="ace-icon fa fa-angle-left bigger-150"></i></i></span>',
next: '<span> <i class="ace-icon fa fa-angle-right bigger-150"></i></i></span>',
last: '<span> <i class="ace-icon fa fa-angle-double-right bigger-140"></i></span>',
onPageClick: function (event, page) {
GetMyTasks(page);
}
});
}
}

The destroy method totally destroys your plugin, which means your callback on click event also was destroyed (onPageClick event). So try to add your callback after destroying plugin.
For example:
function ShowPages(update, TotalPages) {
if (update) {
var $pagination = $('#pagination');
var currentPage = $pagination.twbsPagination('getCurrentPage');
$pagination.twbsPagination('destroy');
renderPagination(currentPage, TotalPages)
}
else {
renderPagination(1, TotalPages)
}
}
function renderPagination(currentPage, totalPages) {
$('#pagination').twbsPagination({
startPage: currentPage,
totalPages: totalPages,
initiateStartPageClick: false,
onPageClick: function (event, page) {
GetMyTasks(page);
}
});
}
Be careful with initiateStartPageClick option, by default:
Fire click at start page when plugin initialized
From Official doc

Related

Add and update function is not working in SharePoint online list using SPfx PnP.js coding

Using the below SPFx PnP.js code I am doing the CRUD operation in SharePoint online list:
private _getListData(): Promise<ISPList[]> {
return pnp.sp.web.lists.getByTitle("EmployeeList").items.get().then((response) => {
return response;
});
}
private getListData(): void {
this._getListData()
.then((response) => {
this._renderList(response);
});
}
AddItem()
{
pnp.sp.web.lists.getByTitle('EmployeeList').items.add({
EmployeeName : document.getElementById('EmployeeName')["value"],
Experience : document.getElementById('Experience')["value"],
Location:document.getElementById('Location')["value"]
});
alert("Record with Employee Name : "+ document.getElementById('EmployeeName')["value"] + " Added !");
}
UpdateItem()
{
var id = document.getElementById('EmployeeId')["value"];
pnp.sp.web.lists.getByTitle("EmployeeList").items.getById(id).update({
EmployeeName : document.getElementById('EmployeeName')["value"],
Experience : document.getElementById('Experience')["value"],
Location:document.getElementById('Location')["value"]
});
alert("Record with Employee Name : "+ document.getElementById('EmployeeName')["value"] + " Updated !");
}
DeleteItem()
{
pnp.sp.web.lists.getByTitle("EmployeeList").items.getById(document.getElementById('EmployeeId')["value"]).delete();
alert("Record with Employee ID : "+ document.getElementById('EmployeeId')["value"] + " Deleted !");
}
In the above code AddItem() and UpdateItem() are not working but reading list items and deleting list item are working. I mean I am not able to add new record to the list and update also not getting any errors, getting the successful alert message but it is not adding or updating the items. Any issue with the AddItem() and updateItem() function code....any help will be much appreciated.
Updated
I am not getting any error though it add and update function is not working, by the way I am global administrator.
While clicking on the add button getting the successful alert message but it is not adding, screenshot attached:
Complete code reference:
import pnp from 'sp-pnp-js';
//import { default as pnp, ItemAddResult } from "sp-pnp-js";
import { Version } from '#microsoft/sp-core-library';
import {
BaseClientSideWebPart,
IPropertyPaneConfiguration,
PropertyPaneTextField
} from '#microsoft/sp-webpart-base';
import { escape } from '#microsoft/sp-lodash-subset';
import styles from './PnPspCrud.module.scss';
import * as strings from 'pnPspCrudStrings';
import { IPnPspCrudWebPartProps } from './IPnPspCrudWebPartProps';
export interface ISPList {
ID: string;
EmployeeName: string;
Experience: string;
Location: string;
}
export default class PnPspCrudWebPart extends BaseClientSideWebPart<IPnPspCrudWebPartProps> {
private AddEventListeners() : void{
document.getElementById('AddItem').addEventListener('click',()=>this.AddItem());
document.getElementById('UpdateItem').addEventListener('click',()=>this.UpdateItem());
document.getElementById('DeleteItem').addEventListener('click',()=>this.DeleteItem());
}
private _getListData(): Promise<ISPList[]> {
return pnp.sp.web.lists.getByTitle("EmployeeList").items.get().then((response) => {
return response;
});
}
private getListData(): void {
this._getListData()
.then((response) => {
this._renderList(response);
});
}
private _renderList(items: ISPList[]): void {
let html: string = '<table class="TFtable" border=1 width=100% style="border-collapse: collapse;">';
html += `<th>EmployeeId</th><th>EmployeeName</th><th>Experience</th><th>Location</th>`;
items.forEach((item: ISPList) => {
html += `
<tr>
<td>${item.ID}</td>
<td>${item.EmployeeName}</td>
<td>${item.Experience}</td>
<td>${item.Location}</td>
</tr>
`;
});
html += `</table>`;
const listContainer: Element = this.domElement.querySelector('#spGetListItems');
listContainer.innerHTML = html;
}
public render(): void {
this.domElement.innerHTML = `
<div class="parentContainer" style="background-color: lightgrey">
<div class="ms-Grid-row ms-bgColor-themeDark ms-fontColor-white ${styles.row}">
<div class="ms-Grid-col ms-u-lg10 ms-u-xl8 ms-u-xlPush2 ms-u-lgPush1">
<span class="ms-font-xl ms-fontColor-white" style="font-size:28px">Welcome to SharePoint Framework Development using PnP JS Library</span>
<p class="ms-font-l ms-fontColor-white" style="text-align: left">Demo : SharePoint List CRUD using PnP JS and SPFx</p>
</div>
</div>
<div class="ms-Grid-row ms-bgColor-themeDark ms-fontColor-white ${styles.row}">
<div style="background-color:Black;color:white;text-align: center;font-weight: bold;font-size:18px;">Employee Details</div>
</div>
<div style="background-color: lightgrey" >
<form >
<br>
<div data-role="header">
<h3>Add SharePoint List Items</h3>
</div>
<div data-role="main" class="ui-content">
<div >
<input id="EmployeeName" placeholder="EmployeeName" />
<input id="Experience" placeholder="Experience" />
<input id="Location" placeholder="Location" />
</div>
<div></br></div>
<div >
<button id="AddItem" type="submit" >Add</button>
</div>
</div>
<div data-role="header">
<h3>Update/Delete SharePoint List Items</h3>
</div>
<div data-role="main" class="ui-content">
<div >
<input id="EmployeeId" placeholder="EmployeeId" />
</div>
<div></br></div>
<div >
<button id="UpdateItem" type="submit" >Update</button>
<button id="DeleteItem" type="submit" >Delete</button>
</div>
</div>
</form>
</div>
<br>
<div style="background-color: lightgrey" id="spGetListItems" />
</div>
`;
this.getListData();
this.AddEventListeners();
}
AddItem()
{
pnp.sp.web.lists.getByTitle('EmployeeList').items.add({
EmployeeName : document.getElementById('EmployeeName')["value"],
Experience : document.getElementById('Experience')["value"],
Location:document.getElementById('Location')["value"]
});
alert("Record with Employee Name : "+ document.getElementById('EmployeeName')["value"] + " Added !");
}
/*
AddItem()
{
pnp.sp.web.lists.getByTitle('EmployeeList').items.add({
EmployeeName : document.getElementById('EmployeeName')["value"],
Experience : document.getElementById('Experience')["value"],
Location:document.getElementById('Location')["value"]
})
.then(addResponse => {
alert("Record with Employee Name : "+ document.getElementById('EmployeeName')["value"] + " Added !");
})
.catch(addError => alert("An error has occurred:" + JSON.stringify(addError)));
}
*/
/*
private AddItem():void
{
pnp.sp.web.lists.getByTitle("EmployeeList").items.add({
EmployeeName : document.getElementById('EmployeeName')["value"],
Experience : document.getElementById('Experience')["value"],
Location: document.getElementById('Location')["value"]
})
.then((iar: ItemAddResult) => {
console.log(iar);
})
.catch((error:any) => {
console.log("Error: ", error);
});
}
*/
UpdateItem()
{
var id = document.getElementById('EmployeeId')["value"];
pnp.sp.web.lists.getByTitle("EmployeeList").items.getById(id).update({
EmployeeName : document.getElementById('EmployeeName')["value"],
Experience : document.getElementById('Experience')["value"],
Location:document.getElementById('Location')["value"]
});
alert("Record with Employee Name : "+ document.getElementById('EmployeeName')["value"] + " Updated !");
}
DeleteItem()
{
pnp.sp.web.lists.getByTitle("EmployeeList").items.getById(document.getElementById('EmployeeId')["value"]).delete();
alert("Record with Employee ID : "+ document.getElementById('EmployeeId')["value"] + " Deleted !");
}
protected get dataVersion(): Version {
return Version.parse('1.0');
}
protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {
return {
pages: [
{
header: {
description: strings.PropertyPaneDescription
},
groups: [
{
groupName: strings.BasicGroupName,
groupFields: [
PropertyPaneTextField('description', {
label: strings.DescriptionFieldLabel
})
]
}
]
}
]
};
}
}
Note:
I am referring this link where complete code is available.
https://www.sharepoint-journey.com/SharePoint-Framework-Development-Create-List-CRUD-WebPart-PnPJS.html
Of course you get the alert function to call, because the add/update/delete functions from pnp/sp are asynchronous! you can try that:
pnp.sp.web.lists.getByTitle('EmployeeList').items.add({
EmployeeName : document.getElementById('EmployeeName')["value"],
Experience : document.getElementById('Experience')["value"],
Location:document.getElementById('Location')["value"]
})
.then(addResponse => {
alert("Record with Employee Name : "+ document.getElementById('EmployeeName')["value"] + " Added !");
})
.catch(addError => alert("An error has occurred:" + JSON.stringify(addError)));
I hope this helps, maybe if you get an error here you can update your post to dig deeper into the problem!
Greetings
code has no issue. Best practice should be as mentioend #j.Benda. It seems permission issue.
open in chorme network console (f12 and go to network). it may give u the error which is coming exactly. site url is not set kind. I will try ur code and let u know. try below.
import { default as pnp, ItemAddResult, Web } from "sp-pnp-js";
on button events set web url.
onclickevnet(){
var NewISiteUrl = this.props.siteurl;
var NewSiteUrl = NewISiteUrl.replace("/SitePages", "");
console.log(NewSiteUrl);
let webx = new Web(NewSiteUrl)
webx.lists.getByTitle('EmployeeList').items.add({
EmployeeName : document.getElementById('EmployeeName')["value"],
Experience : document.getElementById('Experience')["value"],
Location:document.getElementById('Location')["value"]
})
.then(addResponse => {
//error
})
.catch(addError => alert("An error has occurred:" + JSON.stringify(addError)));
}

How to handle 'Enter' on Input in React

I have a form in React, with an Input and Search Button. Currently the Search Button is doing performing the search. I want if a user presses the Enter in Field, Search Button is triggered.
Currently Enter just clears the Input Field. I have onClickhandler on Search Button. I want to apply same handler on Keydown or Keypress event on Field as well.
Below is my code:
import React, {Component} from 'react';
import {FormattedMessage} from 'react-intl';
import {FormField, Form} from 'digitalexp-common-components-l9';
import Input from 'digitalexp-common-components-l9/lib/form-field/Input';
import messages from 'digitalexp-select-additional-charges-retail-module-l9/src/widget/SelectAdditionalCharges.i18n';
const {FormContainer} = Form;
#FormContainer({hasDefaults: true})
export default class SelectAdditionalChargesSearchBoxView extends Component {
constructor(props) {
super(props);
this.handleSearchClick = this.handleSearchClick.bind(this);
this.handleClearClick = this.handleClearClick.bind(this);
}
componentWillMount() {
this.props.initializeFormValues({searchkey: this.props.searchBy});
}
handleClearClick() {
const {updateField} = this.props;
updateField({name: 'searchkey', value: ''}).then(() => this.props.handleSearchBy({searchkey: ''}));
}
handleSearchClick(e) {
const {handleSubmit, handleSearchBy} = this.props;
e.preventDefault();
handleSubmit(handleSearchBy);
}
render() {
const {Field} = FormField;
return (
<div className="ds-search-panel">
<div className="ds-search-panel__header">
<FormattedMessage {...messages.SelectSearchAdditionalCharges} />
</div>
<form
className="ds-search-panel__footer"
autoComplete="off"
onSubmit={this.handleSearchClick}>
<span className="ds-search-panel__footer--names">
<FormattedMessage {...messages.nameLabel} />
</span>
<span className="ds-search-panel__footer--textfields">
<Field
Component={Input}
name="searchkey"
autoComplete="off"
config={{rowLabel: true}}
/>
</span>
<span className="ds-search-panel__footer--search">
<button className="ds-btn ds-btn--secondary ds-btn--searches" onClick={this.handleClearClick}>
<span className="ds-btn--span">
<FormattedMessage {...messages.clearButtonText} />
</span>
</button>
<button className="ds-btn ds-btn--primary ds-btn--searches" onClick={this.handleSearchClick}>
<span className="ds-btn--span">
<FormattedMessage {...messages.searchButtonText} />
</span>
</button>
</span>
</form>
</div>
);
}
}
And below is the Input.js class:
import React from 'react';
import classNames from 'classnames';
const Input = (props) => {
const {
input, label, type = 'text', usePlaceholder, meta: {error}, displayInlineError = true,
fieldIconClassName, showCloseButton, fieldIconEventListener, clearField
} = props;
let {fieldClassName = 'ds-text'} = props;
const {name, placeholder} = input;
fieldClassName = classNames('ds-form__input', {
[fieldClassName]: fieldClassName
});
let fieldIconProps = {
className: classNames({
'ds-form__icon': true,
[fieldIconClassName]: fieldIconClassName
})
};
if (fieldIconEventListener) {
fieldIconProps = {
...fieldIconProps,
onClick: fieldIconEventListener
};
}
return (
<div className="ds-form__input--wrapper">
<input
id={name}
{...input}
placeholder={usePlaceholder ? placeholder || label : ''}
type={type}
className={fieldClassName}
/>
{showCloseButton && <button className="ds-form__icon ds-form__icon--close" onMouseDown={clearField} />}
{fieldIconClassName && <div {...fieldIconProps} />}
{(error && displayInlineError) && <div className="ds-notification__error--text">{error}</div>}
</div>
);
};
export default Input;
Could anyone help?
You can just attach onKeyDown or onKeyUp handler to Field
handleKeyPress (e) {
// This is perfectly safe in react, it correctly detect the keys
if(event.key == 'Enter'){
this.handleSearchClick(e)
}
}
<Field onKeyDown={this.handleKeyPress}

Get uid and iterate over an array of objects using Angular4 and Fireabse

I am building a 1-1 chat using Angular4 and Firebase and I am pretty new to Angular.
In order to initiate a conversation, I am trying to display all available users form '/users' subcollection. So, I need to get user/{user.uid}/username.
This is my chat.component.ts:
import { Component, OnInit } from '#angular/core';
import {AngularFireDatabase, FirebaseListObservable} from 'angularfire2/database';
import { AngularFireAuth } from 'angularfire2/auth';
import { UserSessionService } from '../_services/user-session.service';
#Component({
selector: 'app-chat',
templateUrl: './chat.component.html',
styleUrls: ['./chat.component.css']
})
export class ChatComponent implements OnInit {
items: FirebaseListObservable<any[]>;
other_users: FirebaseListObservable<any[]>;
user_id: any;
from: any;
msgVal: string = '';
constructor(public afAuth: AngularFireAuth, public af: AngularFireDatabase, public logged_user: UserSessionService ){ }
ngOnInit() {
this.from= this.logged_user.getFirebaseUid();
this.user_id= this.logged_user.getFirebaseUid();
this.items = this.af.list('/personalMessages', {
query: { limitToLast: 5 }
});
this.other_users= this.af.list('/users');
}
findChat(){
this.other_users= this.other_users;
this.user_id = this.user_id;
}
chatSend(theirMessage: string) {
this.items.push({ text: theirMessage, from: this.logged_user.getFirebaseUid(), isRead: false, timestamp: + new Date() });
this.msgVal = '';
this.user_id = this.user_id;
this.other_users= this.other_users;
}
}
And this is my chat.component.html:
<div class="users-chat-container" *ngFor="let other_user of other_users| async">
<div id="circle" style="background-color:pink;">
</div>
<br/> {{other_user.username}}
</div>
<div class="chat-container" *ngFor="let item of items | async">
<div id="circle" style="background-image:url( http://www.ics.forth.gr/mobile/female.png);">
</div>
<br/> {{item.from}}
<p>{{item.text}}</p>
</div>
<input type="text" id="message" placeholder="Type a message..." (keyup.enter)="chatSend($event.target.value)" [(ngModel)]="msgVal" />
How can I iterate over the array of objects I get from '/users' collection? Thank you! :)
you need use ForkJoin. ForkJoin will take users list as input and fire parallel request for all users list
try some thing like this
this.af.list('/users')
.mergeMap((users) => {
if (users.length > 0) {
return Observable.forkJoin(
users.map((user) => this.af.database
.object(`user/${user.$uid}/username`)
.first()
),
(...values) => { // here you can assign username
users.forEach((user, index) => { user.username = values[index]; });
return users;
}
);
}
return Observable.of([]);
});
more info about forkJoin
https://www.learnrxjs.io/operators/combination/forkjoin.html
You need an array for *ngFor. With object.keys you can create an array of the objects. In the example below I have done this with players from a group, coming as objects from firebase.
private getPlayersPerGroup(group: Group) {
this.playersInGroup = [];
if (group["players"]) {
Object.keys(group["players"]).forEach((key) => {
this.groupService.getPlayerById(key).then((player) => {
this.playersInGroup.push(player);
});
});
}
}

What is the right way to call React component?

I encountered problem with react component. Basically, i use NPM integrated with Rails and called React component in my rails app.
I try to call react-file-base64 module in my code like below :
const FileBase64 = require('react-file-base64');
var MembersNew = React.createClass(
{
render()
{
return(
<div>
<h5>ACCOUNT DETAILS</h5>
<hr/>
<p>Fill in your member account details below</p>
<b>Membership ID : </b>
<div className="row">
<div className="medium-6 columns">
<FileBase64/> <------ Called component
<label>Username*
<input ref="name" type="text"/>
</label>
<label>First Name*
<input ref="name" type="text"/>
</label>
<label>Last Name*
<input ref="name" type="text"/>
</label>
<label>Email Address*
<input ref="name" type="text"/>
</label>
</div>
</div>
)
I got following error :
Below is react-file-base64.js :
import React from 'react';
import ReactDOM from 'react-dom';
class FileBase64 extends React.Component {
constructor() {
super()
this.state = {
files: []
}
this.props = {
multiple: false
}
}
handleChange(e){
// get the files
let files = e.target.files;
// Process each file
var allFiles = []
for (var i = 0; i < files.length; i++) {
let file = files[i]
// Make new FileReader
let reader = new FileReader()
// Convert the file to base64 text
reader.readAsDataURL(file)
// on reader load somthing...
reader.onload = () => {
// Make a fileInfo Object
let fileInfo = {
name: file.name,
type: file.type,
size: Math.round(file.size / 1000)+' kB',
base64: reader.result,
file: file
}
// Push it to the state
allFiles.push(fileInfo)
// If all files have been proceed
if(allFiles.length == files.length){
// Apply Callback function
if(this.props.multiple) this.props.onDone(allFiles)
else this.props.onDone(allFiles[0])
}
} // reader.onload
} // for
}
render(){
return (
<div>
<input
type="file"
onChange={ this.handleChange.bind(this) }
multiple={ this.props.multiple } />
</div>
)
}
}
export default FileBase64;
I think what i did was wrong. If there's anyone could guide me on how can i achieve this. I really appreciate that.

search mvc staying same page

I'm using MVC5 and I want to search for a result and stay at the same page, here is my method in my controller (LiaisonsProjetsPPController) that do the operation of searching :
public ActionResult IndexAjoutML(int id, string SearchString)
{
PartiesPrenantesEntities db = new PartiesPrenantesEntities();
ViewBag.idProjet = id;
ViewBag.searchString = SearchString;
IQueryable<ActivitesPP> qry = this.db.ActivitesPP.Intersect(from item in this.db.LiaisonsProjetsPP where item.idProjet == id select item.ActivitesPP).Include(model => model.Activites.CatActivites);
var act = from s in db.CatActivites
select s;
if (!String.IsNullOrEmpty(SearchString))
return PartialView("~/Views/ActivitesPP/IndexAjoutProjet.cshtml", this.db.ActivitesPP.Where(s => s.PartiesPrenantes.nomPP.Contains(SearchString)).Except(qry));
else
return PartialView("~/Views/ActivitesPP/IndexAjoutProjet.cshtml", this.db.ActivitesPP.Except(qry));
}
Then in my view (Views/ActivitesPP/IndexAjoutProjet) I have my search form and the div of the display result :
#using (Ajax.BeginForm("IndexAjoutML", "LiaisonsProjetsPP", FormMethod.Post,
new AjaxOptions
{
InsertionMode = InsertionMode.Replace,
HttpMethod = "POST",
UpdateTargetId = "search-results"
}, new { #id = "searchFormPP" }))
{
<p>
<label>Partie prenante: </label> #Html.TextBox("SearchString")
<input id="inputRecherche" name="SearchString" type="submit" value="Rechercher" />
</p>
}
<div id="search-results">
#{foreach (var catactivite in Model.GroupBy(model => model.Activites.CatActivites))
{
String couleurCategorie = catactivite.Key.couleurCategorie;
String couleurTexte = CustomHelpers.GetForegroundColor(couleurCategorie);
//Image de la partie prenante
<div class="panel-heading unhide" style="background-image: none; color: #couleurTexte; background-color: #couleurCategorie; padding: 2px;">
</div>
foreach (var pp in catactivite)
{
String nomPP = (pp.idPP == null ? "Inconnu" : pp.PartiesPrenantes.nomPP);
String dateAffichee;
String imgPP = "../../Images/Profils/" + (pp.PartiesPrenantes.imgPP ?? "avatar.png");
if (pp.finActivite == null)
{
dateAffichee = "Depuis le " + String.Format("{0:d/MM/yyyy}", pp.debutActivite);
}
else
{
dateAffichee = "Depuis le " + String.Format("{0:d/MM/yyyy}", pp.debutActivite) + ", jusqu'au " + String.Format("{0:d/MM/yyyy}", pp.finActivite);
}
<div class="panel panel-primary">
<div class="panel-heading unhide" style="color: #couleurTexte; background-color: #couleurCategorie;">
<div style="float: left">
<img class="imgPP img-circle" src="#(imgPP)" />
</div>
<h5>#pp.Activites.libelleActivite (#Html.Raw(pp.idLieu == 999 ? "National" : pp.Lieux.nomLieu))</h5>
<h6>#pp.PartiesPrenantes.nomPP</h6>
</div>
<div class="panel-body hiddenPart">
#if (pp.idPP != null)
{
<label>Commentaire</label>
<p>#(pp.commentaireActivite ?? "Pas plus de détails..")</p>
#Html.Action("CreateForm", "LiaisonsProjetsPP", new { idActivite = pp.idActivite, idProjet = ViewBag.idProjet })
}
</div>
</div>
}
}
}
</div>
}
else
{
#Html.Raw("<p>Aucune partie prenante disponible..")
#Html.Raw("(attention: pour être ajoutée, une partie prenante doit posséder au moins une activité référencée..)</p>")
}
In my view i call my method of search (Views/Projets/Details): #{ Html.RenderAction("IndexAjoutML", "LiaisonsProjetsPP", new { idProjet = Model.idProjet, searchString = Model.searchString }); }
The search work but it redirects me to another page http://localhost:49612/LiaisonsProjetsPP/IndexAjout/1 instead of staying at this page http://localhost:49612/Projets/Details/1.
What you are trying to do seems to be loading results unobtrusively with an AJAX form. The Professional ASP.NET MVC 5 book by John Galloway et al. has a nice section on this, but realizing that no one reads books I will provide a link to a site with a code sample for it.
The .NET Funda site describes here exactly how to search and return the results to the same page without a complete refresh using unobtrusive-ajax.
Likely what you are missing is a reference to jquery.unobtrusive-ajax.min.js. Other posts on Stack Overflow also reference this topic, but I realize you might not know the correct search terms. Try looking further into "AJAX partial view unobtrusive loading" as search terms for further research.
This example is from the book I mentioned from John Galloway.
A JavaScript error message.
function searchFailed(){
$("#searchresults").html("Sorry, there was a problem searching.");
}
This is what a simple Ajax form should look like. Note the "GET" form method.
<div class="panel panel-default">
<div class="panel-heading">
Artist Search
</div>
<div class="panel-body">
#using(Ajax.BeginForm("ArtistSearch", "Home",
new AjaxOptions
{
InsertionMode = InsertionMode.Replace,
HttpMethod = "GET",
OnFailure = "searchFailed",
LoadingElementID = "ajax-loader",
UpdateTargetId = "searchresults",
}))
{
<input type="text" name="q" />
<input type="submit" value="search" />
<img id="ajax-loader"
src="#Url.Content("~/Images/ajax-loader.gif")"
style="display:none" />
}
<div id="searchresults"></div>
</div>
</div>
This is the method responsible for returning the partial view:
public ActionResult ArtistSearch(string q)
{
var artists = GetArtists(q);
return PartialView(artists);
}
This is a search method.
public List<Artist> GetArtists(string searchString)
{
return storeDB.Artist.Where(a => a.Name.Contains(searchString)).ToList();
}
Note that the method for returning the partial view is simply "return PartialView(model);"

Resources