I have a MVC web app that receives data from a database and displays it in a table for the user. The user goes through a series of dropdowns and buttons, each being populated using AJAX calls. Then a table is created and shown. As an example, here is one such section of code.
#Html.LabelFor(model => model.RootID)
#Html.DropDownListFor(model => model.RootID, Model.AvailableRoots)
<input type="button" id="RootsBtn" value="Go" />
<script language="javascript" type="text/javascript">
$(function () {
$("#RootsBtn").click(function () {
var selectedItem = $('#RootID').val();
$("#MiscTable").empty();
$.ajax({
cache: false,
type: "GET",
url: RootDirectory + "Home/GetTableData/",
data: { "id": selectedItem },
success: function (data) {
var myTable = $('#MiscTable');
$.ajax({
cache: false,
type: "GET",
url: RootDirectory + "Home/GetProperties/",
data: { "id": selectedItem },
success: function (data2) {
if (data2['IsAddAvailable'] == 'True' && data2['IsViewOnly'] == 'False' && data2['IsEnabled'] == 'True' &&
data2['IsViewOnly_User'] == 'False' && data2['IsEnabled_User'] == 'True') {
$('#Add' + data2['TableName']).show();
}
if (data.length > 0) {
var firstRecord = data[0];
var headerRow = $('<thead>');
for (var columnTitle in firstRecord) {
headerRow.append($('<th>', { text: columnTitle }));
}
headerRow.append($('<th>', { text: " " }));
myTable.append(headerRow);
var record;
var dataRow;
for (var dataIndex = 0; dataIndex < data.length; dataIndex++) {
record = data[dataIndex];
dataRow = $('<tr>');
for (var column in firstRecord) {
dataRow.append($('<td>', { text: record[column] }));
}
var id = record['ID'];
var showDelete = ((record['IsDeleteAvailable'] == 'True' || ((record['IsDeleteAvailable'] == null || record['IsDeleteAvailable'] == "") && data2['IsDeleteAvailable'] == 'True')) && data2['IsDeleteAvailable_User'] == 'True');
var showEdit = ((record['IsEditAvailable'] == 'True' || ((record['IsEditAvailable'] == null || record['IsEditAvailable'] == "") && data2['IsEditAvailable'] == 'True')) && data2['IsEditAvailable_User'] == 'True');
var str1 = RootDirectory + data2['TableName'] + "/Edit/" + id;
var str2 = RootDirectory + data2['TableName'] + "/Details/" + id;
var str3 = RootDirectory + data2['TableName'] + "/Delete/" + id;
if (showDelete && showEdit && data2['IsViewOnly'] != 'True' && data2['IsViewOnly_User'] != 'True') {
dataRow.append('<td>Edit<br />Details<br />Delete</td>');
}
else if (!showDelete && showEdit && data2['IsViewOnly'] != 'True' && data2['IsViewOnly_User'] != 'True') {
dataRow.append('<td>Edit<br />Details</td>');
}
else if (showDelete && !showEdit && data2['IsViewOnly'] != 'True' && data2['IsViewOnly_User'] != 'True') {
dataRow.append('<td>Details<br />Delete</td>');
}
else {
dataRow.append('<td>Details</td>');
}
myTable.append(dataRow);
}
}
},
error: function (xhr, ajaxOptions, throwError) {
alert("Error");
}
});
$('#MiscTable').show();
},
error: function (xhr, ajaxOptions, throwError) {
alert("Error");
$('#MiscTable').hide();
}
});
});
});
</script>
Everything works right now to display whatever table has been chosen by the user in the dropdown list. When the user uses a link in the table (Edit, Details, Delete) they are taken to a new page to handle this action. When finished it takes them back to this main page. Unfortunately the state of their dropdowns and table were obviously not stored, so they have to go through the menus again to see their changes.
I have heard that there are anchors that can allow a page to go to a specific configuration of javascript/AJAX. I've tried to search for it but haven't been successful. What I am wanting is the ability for the user to search through my dropdowns and select table X. Then in table X they can say to edit item Y. When finished editing Y and clicking submit (or back to table to undo changes) rather than going back to the start of the main page, it should repopulate the dropdowns and go back to showing table X.
Maybe a link like /Home/Index/#X?
Is this possible and how would it be done?
You're talking about hash fragments. In a general sense, all this is doing is using the target as a dumping ground for data needed to render the page as it was, since the target portion of the URL is not sent to the server and doesn't cause a page refresh. On it's own this does nothing, but you could have JavaScript on page that parses this information out of the URL and does something meaningful with it.
So for your purposes you could go with something like:
`/path/to/page#select1=foo&select2=bar`
Then, you would need JS on that page that pulls out the fragment (location.hash) and parses out the name value pairs to finally use that to set the selects back to the state they were in previously and load whatever data needs to be loaded via AJAX.
Related
I have a web application with Common.js and it has the following function which is calling when this button btnBookingStatus was clicked.
$(document).on('click', '#btnBookingStatus', function () {
var req = new Object();
req.strMinNo = $(parent.document).find('#hdnFMinNo').val();
req.strSeqNo = $(parent.document).find("#hdnPSeqNo").val();
req.strUserId = $(parent.document).find("#hdnUserId").val();
if (req.strMinNo == undefined || req.strMinNo == '') {
req.strMinNo = $(parent.document).find('#hdnMinNo').val();
}
if (req.strSeqNo == undefined || req.strSeqNo == '') {
req.strSeqNo = $(parent.document).find('#hdnFinSeqNo').val();
}
if (req.strUserId == undefined || req.strUserId == '') {
req.strUserId = $(parent.document).find('#hdnCurrentUserId').val();
}
$.ajax({
type: "POST",
data: JSON.stringify(req),
url: "../Common/LibUiUtilities.aspx/fnCreamsBookingStatus",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {
if (data != null) {
var retData = JSON.parse(data.d);
if (retData.oRetunStatus == 'P' || retData.oRetunStatus == 'null') {
alert("Creams Booking still in progress...");
}
else {
$(parent.document).find('#drpBookingStatus').removeAttr('disabled');
$(parent.document).find('#drpBookingStatus').val(retData.oRetunStatus);
$(parent.document).find('#drpBookingStatus').attr('readonly', true);
alert("Creams Booking Success");
}
if (retData.oReturnMsg != undefined && retData.oReturnMsg != 'null') {
$(parent.document).find('#lblBkWarningMsg').text(retData.oReturnMsg);
} else {
$(parent.document).find('#lblBkWarningMsg').empty();
}
}
}
});
});
There are 5 client windows with the same btnBookingStatus button with the same functionality, which needs to be called the above-mentioned JS function. But the hidden field names which pass the parameters are different.
For eg:-
Form1.aspx --> hdnFMinNo, hdnFSeqNo
Form2.aspx --> hdnPMinNo, hdnPSeqNo
Form3.aspx --> hdnMinNo, hdnSeqNo
These element Ids can not be changed
I wanted to pass the parameters (MIN_NO and SEQ_NO) from ASPX to the Common.js without accessing the parent window's elements.
Please help me out with this.
So I have a jQuery code for sending keywords to another page.On that page I have names of all countries. my code works good also, I have defined my function in a condition that if the lenght of text of input was longer than 2 then runs the function inside it but, I have problem with this for Example when I write the city name it works good and returns the correct data from the ajax page my issue is when the user wants to delete that word with backspace or somthing else I want to remove all previous data was sent to ajax page but because of my condition it does not work.
how can I define if user delete the word run my function ?
here is my code :
var prevXHR = null; //global
$('.country').each(function() {
$(this).on('keyup', function(e) {
var _this = this;
var element = $(this).val().length;
if (e.which !== 0 &&
!e.ctrlKey && !e.metaKey && !e.altKey
){
if (element > 2) {
var val = $(this).val()
$(this).val(val)
prevXHR = $.ajax({
url: "ajaxpage.htm",
type: "get",
contentType: 'application/json; charset=utf-8',
data: {
key: $(this).val()
},
success: function(result) {
$(_this).closest(".search_div").find(".co").empty().html(result)
},
beforeSend: function(){
if(prevXHR && prevXHR.readyState != 20){
//before sending any new request neutralize any pending ajax call
prevXHR.abort();
prevXHR = null;
}
}
});
}
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<div class="search_div">
<input type="text" value="" class="country" autocomplete="off" />
<div class="result"></div>
</div>
In your code, you are already checking to see if the length of the input was greater than 2, then proceeding with ajax call.
Just add else part afterwards.
if (element > 2) {
// ...do the ajax stuff here
} else {
// the input length was shorter than 2 characters...
// remove all HTML elements here
$('div#to_be_removed').remove(); //or something like that
}
Please note that I had already tried to apply the solution on Handling session timeout in ajax calls but did not worked for me.
In an ASP.NET MVC5 project, I open pages by rendering partialview via AJAX as shown below:
function renderPartial(e, controller, action) {
var controllerName = controller;
var actionName = action;
if (String(actionName).trim() == '') {
return false;
}
if (typeof (controllerName) == "undefined") {
return false;
}
var url = "/" + controllerName + "/" + actionName;
$.ajax({
url: url,
data: { /* additional parameters */ },
cache: false,
type: "POST",
dataType: "html",
error: function (jqXHR, textStatus, errorThrown) {
var message = errorThrown;
if (jqXHR.responseJSON != null) {
message = jqXHR.responseJSON.message;
}
},
success: function (data) {
var requestedUrl = String(this.url).replace(/[&?]X-Requested-With=XMLHttpRequest/i, "");
if (typeof (requestedUrl) == "undefined" || requestedUrl == 'undefined') {
requestedUrl = window.location.href;
}
// if the url is the same, replace the state
if (typeof (history.pushState) != "undefined") {
if (window.location.href == requestedUrl) {
history.replaceState({ html: '' }, document.title, requestedUrl);
}
else {
history.pushState({ html: '' }, document.title, requestedUrl);
}
}
//Load partialview
$("#div-page-content").html(data);
}
});
};
On the other hand, when session timeout and call this method by a hyperlink, there is an empty white page on the partialview field where partialview page should be rendered. So, is it possible:
1) to display a partialview at this field?
2) to redirect user Login page?
Note: I would also be happy if you suggest a smart way to Handle Session Expire in ASP.NET MVC. Thanks in advance...
I have method who populate menu, it be like:
function MenuPopulate(url, listname, target) {
var lang = "Espanol";
if ((window.location.href.indexOf("lang=en") > 0)) {
lang = "English";
}
$(function () {
$.ajax({
url: "https://myapi.company.com/api/myapi/getmenu?idioma=" + lang ,
async: false,
type: 'GET',
dataType: "json",
success: function (data) {
console.log(data);
completeMenu(data, target)
//localStorage.setItem('data', JSON.stringify(data))
},
error: function (response) {
failureMenu(response, target)
}
});
});
}
function completeMenu(data, target) {
var prefix = "<ul class='nav navbar-nav navbar-right'>";
var sufix = "</ul>";
var items = data;
var menu = "";
for (item in items) {
if(items[item].Titile == "JOIN US" ){
menu += "<li><a href='#mymodal' data-toggle='modal' data-target='#mymodal'>" + items[item].Titile + "</a></li><li class='divider-vertical'></li>"
}
else if(items[item].Titile == "CONTACT US"){
menu += "<li><a href='#mymodal2' data-toggle='modal' data-target='#mymodal2'>" + items[item].Titile + "</a></li><li class='divider-vertical'></li>"
}
else{
menu += "<li>" + items[item].Titile + "</li><li class='divider-vertical'></li>";
}
}
$(target).html(prefix + menu + sufix);
}
function failureMenu(data, target) {
console.log(data);
$(target).text("Ocurrió un error en la carga del menú. Por favor revise la consola para más información");
}
And it runs perfectly except for the time to load page, so now I store methods in cache with localStorage , so I made this class:
$(document).ready(function() {
GetGlobal();
});
function GetGlobal() {
var lang = "Espanol";
if ((window.location.href.indexOf("lang=en") > 0)) {
lang = "English";
}
var page = window.location.pathname.replace("/SitePages/", "");
if (localStorage.getItem("Menu") == null) {
$.ajax({
url: "https://myapi.company.com/api/myapi/getglobalresources?idioma=" + lang + "&pagina=" + page,
async: false,
type: 'GET',
dataType: "json",
success: function(data) {
CompleteGlobal(data);
//alert("Cargo con exito");
},
error: function(data) {
//failureGlobal(data);
alert("No cargo");
}
})
} else {
// alert("la cookie esta cargada");
CargaGlobal();
//localStorage.getItem("Menu")
}
}
function CargaMenu() {
$.ajax({
url: "https://myapi.company.com/api/myapi/getmenu?idioma=" + lang,
async: false,
cache:true,
type: 'GET',
dataType: "json",
success: function(data) {
console.log(data);
completeMenu(data, target)
},
error: function(response) {
failureMenu(response, target)
}
});
}
function CompleteGlobal(data) {
data.Menu //lista de menus
data.Pie // lista pie de pagina
data.Mapa
data.Ligas
localStorage.setItem("Menu", JSON.stringify(data.Menu));
localStorage.setItem("Pie", JSON.stringify(data.Pie));
localStorage.setItem("Mapa", JSON.stringify(data.Mapa));
localStorage.setItem("Ligas", JSON.stringify(data.Ligas));
localStorage.setItem("Enlace", JSON.stringify(data.Enlace));
CargaGlobal();
}
function CargaGlobal() {
completeMenu(JSON.parse(localStorage.getItem("Menu")), "#BarraNavegacion");
completeSiteMap(JSON.parse(localStorage.getItem("Mapa")), "#MapaSitio");
completeImgLinks(JSON.parse(localStorage.getItem("Enlace")), "#EnlacesImagen");
completeFooter(JSON.parse(localStorage.getItem("Pie")), "#Footer");
}
function completeBanner3(target) {
var items = localStorage.getItem("Menu");
var menu = "";
for (var item in items) {
menu += "<div class='col-md-4 text-center'><div><a href='" + items[item].Enlace + "'><img src='" + items[item].Imagen + "' class='img-responsive img-center' /></a></div><div class='t02 text-center'>" + items[item].Titulo + "</div><div class='t03 text-center'>" + items[item].Descripcion + "</div></div>";
}
$(target).html(menu);
}
But when I change language of my site it just no load the other language menu, and I think to load cookie again if language is different to "Espanol" so I think I can do something like
if (localStorage.getItem("Menu") == null && lang == "Espanol") {
$.ajax({
url: "https://myapi.company.com/api/myapi/getglobalresources?idioma=" + lang + "&pagina=" + page,
async: false,
type: 'GET',
dataType: "json",
success: function(data) {
CompleteGlobal(data);
//alert("Cargo con exito");
}else if(localStorage.getItem("Menu") == null && lang == "English"){
$.ajax({
url: "https://myapi.company.com/api/myapi/getglobalresources?idioma=" + lang + "&pagina=" + page,
async: false,
type: 'GET',
dataType: "json",
success: function(data) {
CompleteGlobal(data);
},
error: function(data) {
alert("No cargo");
}
})
} else {
CargaGlobal();
}
}
But it doesn´t works, any idea what I need to do in this case? Regards
Instead of saving individual parts to the localStorage, sometimes it's easier just to get and fetch an object by using JSON.parse and JSON.stringify.
This is a rather long example, but I commented it a lot to try to make it easier to follow. It's an illustration of various concepts so it doesn't exactly solve your problem, but I believe it will get you closer to a solution.
EDIT: The StackOverflow script runner does not like localStorage. Here's a JSFiddle to see it in action: https://jsfiddle.net/subterrane/9prr5ks6/
EDIT, EDIT: Also, I don't speak Spanish, so blame Google Translate for the silly menu button labels.
var lang = "Espanol";
if ((window.location.href.indexOf("lang=en") > 0)) {
lang = "English";
}
// function to getMenuData
function getMenuData() {
// get the saved data from localStorage
var menuData = JSON.parse(localStorage.getItem('menuData'));
// if it doesn't exist, or if our language is missing, fetch the data from the server
if (menuData == null || menuData[lang] == null) {
// this is a stub function. Pretend it's doing an ajax request
// the second argument here is a callback function. It would be
// the ajax success function.
fetchMenuData(lang, function(data) {
// if we did have some of the data, use it, or start with an empty object
menuData = menuData || {};
// set the server response to the menuData object
menuData[lang] = data;
// stringify the object and stash it in localStorage
localStorage.setItem('menuData', JSON.stringify(menuData));
// display the menu
displayMenu(menuData);
});
} else {
// we go the data from the cache, so display the menu
displayMenu(menuData);
}
}
// this is a fake function that pretends to get menuData from a server
function fetchMenuData(lang, callback) {
// wait 2 seconds, then call the response function
setTimeout(response, 2000);
// response function sends some data back to the callback depending on the requested language
function response() {
callback(lang == "Espanol" ? [{
name: 'Casa',
link: 'something.html'
}, {
name: 'Lejos',
link: 'somethingelse.html'
}] : [{
name: 'Home',
link: 'something.html'
}, {
name: 'Away',
link: 'somethingelse.html'
}]);
}
}
// function to display the menu
function displayMenu(data) {
// update the text in some of the buttons
document.getElementById('home').innerHTML = data[lang][0].name;
document.getElementById('away').innerHTML = data[lang][1].name;
// looks kinda funny, but this just puts the opposite of the current language
// on the button to make it feel like a toggle button
document.getElementById('toggle').innerHTML = lang == "Espanol" ? "English" : "Espanol";
// show the menu now that it's filled in
document.getElementById('menu').classList.remove('hide');
}
// set up a click handler on the language toggle button
document.getElementById('toggle').addEventListener('click', function() {
// hide the menu while we mess with it. Could take a while to get the menu
// data back from our 'server'
document.getElementById('menu').classList.add('hide');
// set the language to the opposite of whatever it was before
lang = lang == "Espanol" ? "English" : "Espanol";
// get the menu data from the cache or server
getMenuData();
});
// kick it all off by getting the menu data from the server
getMenuData();
.hide {
display: none;
}
<link href="//cdnjs.cloudflare.com/ajax/libs/skeleton/2.0.4/skeleton.min.css" rel="stylesheet" />
<div class="container">
<div id="menu" class="hide">
<button id="home"></button>
<button id="away"></button>
<button id="toggle"></button>
</div>
</div>
I have a basic search feature where I can enter a search query into a field which will display a drop down list of suggested results. I can click on any of the suggested results and the value for that record (stored in a MySQL database) is inserted into the field, as I have intended. However, if I try to do the same thing immediately after the first run of the script, then it doesn't work. But, if I reload the page, then it will work again. In other words, it will work the first time I run the script, but not on subsequent runs of the script, unless I reload the page. It's as if by running the script it 'turns itself off' after the first run, not letting me run the script again. Any ideas? Here is the code:
<script>
$(function(){
var index = -1;
$('#myID').keyup(function(e){
if (e.keyCode == 38){
index = (index == 0) ? 0 : index - 1;
$('tr.myRow').removeClass('gray');
$('tr.myRow:eq(' + index + ')').addClass('gray');
return false;
}
else if (e.keyCode == 40){
index = (index + 1 >= $('tr.myRow').length) ? $('tr.myRow').length - 1 : index + 1;
$('tr.myRow').removeClass('gray');
$('tr.myRow:eq(' + index + ')').addClass('gray');
return false;
}
else
{
var str = $('#myID').val();
mySearch(str);
}
index = -1;
});
});
</script>
<script>
$(function(){
$('#myID').keydown(function(e){
if (e.keyCode == 13){
var functionName = $('#pageSearch1 > tbody > tr.gray').attr("onclick");
setTimeout(functionName, 0)
$('#pageSearch').css({'visibility': 'hidden'});
return false;
}
});
});
</script>
The "onClick" attribute is the following script:
function insertPageIDIntoHiddenField(pageID,pageName)
{
$('tr#eventPageID td#loc input#locationID').val(pageID);
$('tr#eventPageID td#loc input#myID').replaceWith('<input id="myID" class="event_form_long" type="text" name="location" value="'+pageName+'" autocomplete="off" />');
$('tr#eventPageID td#loc input#myID').text(pageName);
$('#pageSearch').replaceWith('<div id="pageSearch"></div>');
}
I have used the autocomplete function of jquery to achieve the suggestion on keypress I hope this could help u
$('#txtSearchText').autocomplete({
source: function(request, response) {
$.ajax({
url: SearchPath + "SearchWebService.asmx/GetUserList",
data: JSON2.stringify({ userName: $('#txtSearchText').val()}),
dataType: "json",
type: "POST",
contentType: "application/json; charset=utf-8",
dataFilter: function(data) { return data; },
success: function(data) {
response($.map(data.d, function(item) {
return {
value:item.UserName
}
}))
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
alert(textStatus);
}
});
},
minLength: 1
});