class not updating via jquery - javascript

$(document).ready(function() {
var session = {};
// Getting PHP session variables into javascript object in order to restric actions for certain users.
$.getJSON('session.php',function(data){
session = data;
console.log(session.role); // currently showing 2.
});
// Display datagrid on page
getRecords();
// If not admin, disable certain actions
if(session.role != 1){ // means it is 2
$("#deletecustomer").attr('class','btn btn-danger disabled');
}
});
Hi,
i m trying to disable the delete record button based on the user role. But i dont know why it is not updating the class of my button even though the console is showing role = 2.
Thanks

Since AJAX is asynchronous, please play with it in the callback:
$(document).ready(function() {
var session = {};
// Getting PHP session variables into javascript object in order to restric actions for certain users.
$.getJSON('session.php',function(data){
session = data;
console.log(session.role); // currently showing 2.
// Display datagrid on page
getRecords();
// If not admin, disable certain actions
if(session.role != 1){ // means it is 2
$("#deletecustomer").attr('class','btn btn-danger disabled');
}
});
});
EDIT: Without possibility to put thisinside the same parts of code, you can do:
var session = {};
var getSessionData = function(callback) {
$.getJSON('session.php',function(data){
session = data;
console.log(session.role); // currently showing 2.
// Display datagrid on page
callback.call();
});
}
var updateButton = function() {
getRecords();
// If not admin, disable certain actions
if(session.role != 1){ // means it is 2
$("#deletecustomer").attr('class','btn btn-danger disabled');
}
}
getSessionData(updateButton);

Related

Wait until ajax request is completed

I have a form with several comboboxes within a window.
If I display the window and close it immediately (with a button close method), sometimes I have poor connection to the server and the request to load the data in comboboxes is interrupted.
Response is "Failed to load response data".
Sometimes, the same happens when a combobox is expanded and the store has not yet been loaded.
For these cases, in my Application.js file I have the following function which displays an error message.
Ext.util.Observable.observe(Ext.data.Connection, {
requestexception: function (connection, response, options) {
Ext.Ajax.abort(store.operation.request);
Ext.Msg.show({
title: 'Error!',
msg: 'Message...',
icon: Ext.Msg.ERROR,
buttons: Ext.Msg.OK
});
}
}
});
I'm trying to prevent the window from being closed until the requests were completed and the data was loaded into the comboboxs.
I do not want to use setTimeout().
Maybe use a mask in window and do the unmask when the request is completed ou disabled/enable de close button.
I appreciated suggestions for finding a solution to this.
EDITED:
Another possibility, probably simpler, is to iterate through all the combobox of the form and check if, in each combobox, the store.isLoading (): If yes, it displays a message to wait until the load is finished.
EDITED
If the form has only one combobox the following handler seems to solve the problem: it creates an initial mask and unmasks it after the store is loaded:
handler: function (btn) {
var win = Ext.widget('winSearch', {
animateTarget: this
}).showBy(this, 'bl');
win.getEl().mask('Loading...');
var store = Ext.getStore('storeCombo1Id');
if(store.isLoading()){
store.on('load', function() {
win.getEl().unmask();
});
}else{
win.getEl().unmask();
}
}
The problem is to iterate through several combobox: I tried the following code, without success (the stores are in a viewmodel):
handler: function (btn) {
var win = Ext.widget('winSearch', {
animateTarget: this
}).showBy(this, 'bl');
win.getEl().mask('Loading...');
// var store1 = Ext.getStore('storeCombo1Id');
// var store2 = Ext.getStore('storeCombo2Id');
// var store3 = Ext.getStore('storeCombo3Id');
// var allComboboxStores = [store1, store2, store3];
var allComboboxStores = ['storeCombo1Id', 'storeCombo2Id', 'storeCombo3Id'];
Ext.each(allComboboxStores, function(storeId) {
var store = Ext.getStore(storeId);
console.log(store); //console show 3 stores
if(store.isLoading()){
store.on('load', function() {
win.getEl().unmask();
});
}else{
win.getEl().unmask();
}
});
}
The problem with this solution is that if the store of one of the comboboxs is loaded it triggers the unmask method independently of other comboboxs still to be loaded.
How to wait until all stores are loaded?
EDITED
I have tried different types of iterations and loops and the following solution seems to work.
handler: function () {
var win = Ext.widget('mywindow', {
animateTarget: this
}).showBy(this, 'bl');
win.getEl().mask('Loading...');
var allComboboxStores = ['storeCombo1Id', 'storeCombo2Id', 'storeCombo3Id'];
var indexStores = 0;
Ext.each(allComboboxStores, function(storeId) {
var store = Ext.getStore(storeId);
if(store){
if(store.isLoading()){
indexStores++
store.on('load', function() {
indexStores--;
if (indexStores == 0){
win.getEl().unmask();
}
});
}
else if(!store.isLoading() && indexStores == 0){
win.getEl().unmask();
}
}
});
}
I appreciated suggestions to improve this solution or suggestions to do otherwise.
If jQuery is not a problem ... I suggest using Promises
Description: Return a Promise object to observe when all actions of a certain type bound to the collection, queued or not, have finished.

Rerun original function upon completion of another function in jQuery AJAX

I'm still trying to master jQuery, AJAX, and JSON.
On my application, I have the following dropdown select menu:
<select id="serviceload" name="serviceload"></select>
I auto populate the OPTIONS with another function which I don't think is necessary to display here. Just know that the above SELECT has 1 or more OPTION values.
This is followed by the content section:
<div class="row" id="completeProfile">
// series of DIVS and TABLES
</div>
Initially, the content section is hidden, so the user will only see the dropdown menu:
$('#completeProfile').hide();
And now, the jQuery: this next piece of code is what I use when the user chooses a selection from the dropdown menu. Every time they pick a new selection, queries rerun, and new content is displayed to the screen, unless they select a blank OPTION.
$('#serviceload').change(function () {
var page = $('#serviceload').val();
if (page == "") {
$('#completeProfile').hide();
} else {
$.post('api/profileSearch.php', {
page: page
}, function (data) {
var obj = JSON.parse(data);
$('#portBody').empty();
var htmlToInsert = obj.map(function (item) {
return '<tr><td>' + item.PORT + '</td><td>' + item.NAME + '</tr>';
});
$('#portBody').html(htmlToInsert);
});
// I do several more $.post to return data into specific tables
// Take note of this next $.post
$.post('api/vesselSearch.php', {
page: page
}, function (data) {
var obj = JSON.parse(data);
$('#vesselinfo').empty();
var htmlToInsert = obj.map(function (item) {
return '<tr><td>Edit</td><td>' + item.VESSEL_NAME + '</td></tr>';
});
});
// after all the queries are ran, and the data is returned, now we show the content
$('#completeProfile').show();
}
});
In the vesselInfo portion above, there is section that prints a hyperlink with which you can click, and it opens a modal window. This is for editing purpose. This functions properly.
Here is where the issue lies.
Back in the content section, there is another hyperlink that opens a modal window to add a new vessel.
<h3>Vessels</h3> / Add New
This opens an Add New Vessel modal. In that modal there is a FORM with a button that reads like this:
<button type="button" id="addVesselSubmit">Add</button>
When this button is clicked, it sends the values entered by the user to a PHP script which updates a table.
$('#addVesselSubmit').click(function () {
var addservice = $('#addservice').val();
var addvessel = $('#addvessel').val();
$.post('api/addInfo.php', {
addservice: addservice,
addvessel: addvessel
}, function (data) {
// here is where my problem lies
if (data == 0) {
alert("Vessel was not saved");
} else {
alert("Vessel was saved");
// At this point, I need to rerun the main function above so that it shows the vessel that was added immediately to the content section without a page refresh
}
});
});
So in the code directly above, if the new record was successfully saved to the table, the whole content section should rerun without a page refresh, with the new record automatically showing in the vesselInfo section.
I think the code that is used to display the content needs to be turned into a main function that can be called when the addVesselSubmit is successful, but I am not sure how to proceed with that.
To reiterate my question: I need to be able to save a new record, and print the new record to the page without a page refresh.
$.post('api/addInfo.php', {
addservice: addservice,
addvessel: addvessel
}, function (data) {
// here is where my problem lies
if (data == 0) {
alert("Vessel was not saved");
} else {
alert("Vessel was saved");
// At this point, I need to rerun the main function above so that it shows the vessel that was added immediately to the content section without a page refresh
//Trigger a change on element
$('#serviceload').trigger('change');
/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
}
});

re-execute javascript after log-in

I have a series of buttons that execute different functions when clicked. The function checks whether the user is logged in, and if so proceeds, if not it displays an overlay with ability to log in/create account.
What I want to do is re-execute the button click after log-in, without the user having to reclick it.
I have it working at the moment, but I'm pretty sure that what I'm doing isn't best practice, so looking for advice on how I can improve...
Here's what I'm doing: setting a global variable "pending_request" that stores the function to be re-run and in the success part of the log-in ajax request calling "eval(pending_request)"
Example of one of the buttons:
jQuery('#maybe_button').click(function() {
pending_request = "jQuery('#maybe_button').click()"
var loggedin = get_login_status();
if (loggedin == true) {
rec_status("maybe");
}
});
.
success: function(data) {
if(data === "User not found"){
alert("Email or Password incorrect, please try again");
}else{
document.getElementById('loginscreen').style.display = 'none';
document.getElementById('locationover').style.display = 'none';
eval(pending_request);
pending_request = "";
}
}
Register a function to handle the click and then invoke that func directly without eval().
jQuery('#maybe_button').on('click', myFunction)
This executes myFunction when the button is clicked. Now you can "re-run" the function code every time you need it with myFunction().
And btw since you are using jQuery you can do $('#loginscreen').hide() where $ is an alias for jQuery that's auto defined.
EDIT
Please, take a look at the following code:
var pressedButton = null;
$('button1').on('click', function() {
if (!isLoggedIn()) {
pressedButton = $(this);
return;
}
// ...
});
And, in your success handler:
success: function() {
// ...
if (pressedButton) pressedButton.trigger('click');
// ...
}

Realod page in jquery mobile after editing

Hello i'm finished an app for android using phonegap, right now i'm trying to change the code for a webapp ( the app is simply a notes save ), But i have a problem when change pages, after a edit a note the app goes back to the index page and when you click on a note for view a single note, the apps goes again of the index page ( this happens once, if you click again , works fine)
DEMO
notesapp
THis is part of js code
editNote: function(e){
var noteId = $("#id-note").attr("value");
var newText = $.trim($("#textarea-edit").val());
var storage = window.localStorage.getItem("notes");
storage = JSON.parse(storage);
var newStorage = [];
for( obj in storage ){
if(noteId == storage[obj].id){
newStorage.push({
id: storage[obj].id,
text: newText,
created: storage[obj].created
});
}else{
newStorage.push(storage[obj])
}
}
window.localStorage.setItem("notes", JSON.stringify(newStorage));
notes.showNotes();
$.mobile.changePage($('#index'));
}
$(document).bind("pagebeforechange", function(e, data){
var u = $.mobile.path.parseUrl( data.toPage )
if(u.hash){
var page = u.hash.split("?")[0],
idNote = u.hash.split("=")[1],
storage = window.localStorage.getItem("notes"),
singleText
;
storage = JSON.parse(storage);
// GET CURRENT NOTE TEXT
for( obj in storage ){
if(idNote == storage[obj].id){
singleText = storage[obj].text;
}
}
// SET ID-NOTE TO A INPUT HIDE FOR LATER RETRIEVE
$("#id-note").attr("value", idNote)
if(page == "#single"){
if(idNote){
console.log("show single page")
$("#single-note").html(singleText);
$("#editnote-button").attr("href","#editnote?id=" + idNote);
}
}else if(page == "#editnote"){
console.log("Show edit")
$("#textarea-edit").val(singleText);
}
}
});
Your problem lies in executing notes.init() whenever a page is initiated pageinit. As per your code, notes.init() adds multiple click listener to the buttons below.
$("#save-note").on("click", notes.saveNote);
$("#delete-note").on("click", notes.deleteNote);
$("#edit-note-button").on("click", notes.editNote);
To solve the problem, either bind pageinit to #index page. This way notes.init() will run once only. Or remove old click binding and re-bind it to same buttons.
$("#save-note").off("click").on("click", notes.saveNote);
$("#delete-note").off("click").on("click", notes.deleteNote);
$("#edit-note-button").off("click").on("click", notes.editNote);
Or run pageinit one time only.
$(document).one("pageinit", function () {
notes.init();
});

Validate context menu item for each tab

I am developing a simple Safari extension that adds a context menu item, which when clicked will let me perform a specific task with the data on the page current. In my injected-scripts.js I have a function validForContextMenu which determines wether or not the context menu should be displayed for the clicked tab. Along with this function I am dispatching the following message to my global.html in order to let it know if the tab should display my context menu item or not.
safari.self.tab.dispatchMessage("validate", validForContextMenu());
In global.html I am doing the following to listen to message, store the data returned by injected-scripts.js, and perform the actual validation:
var contextMenuDisabled = true;
function respondToMessage(theMessageEvent) {
if (theMessageEvent.name === "validate") {
contextMenuDisabled = theMessageEvent.message;
}
}
safari.application.activeBrowserWindow.activeTab.addEventListener("message", respondToMessage, false);
function validateCommand(event) {
event.target.disabled = contextMenuDisabled;
}
safari.application.addEventListener("validate", validateCommand, false);
This all works out quite fine apart from the fact that the validation is only performed once, and only for the tab/page being frontmost at the time my extension loads. If that page is valid for context menu, then so will all other pages and vice versa. I would like the validation to be performed individually for each of Safaris tabs.
Ca this be done? Am I missing something on the way injected scripts or dispatched messages works?
The global.html is singleton and therefore your have only one variable contextMenuDisabled for all tabs. Safari has the special API for this task - safari.self.tab.setContextMenuEventUserInfo.
I use the next code in my extension. In inject.js:
document.addEventListener('contextmenu', onContextMenu, false);
function onContextMenu(ev) {
var UserInfo = {
pageId: pageId
};
var sel = document.getSelection();
if (sel && !sel.isCollapsed)
UserInfo.isSel = true;
safari.self.tab.setContextMenuEventUserInfo(ev, UserInfo);
};
In global.js:
safari.application.addEventListener('validate', onValidate, false);
function onValidate(ev) {
switch (ev.command) {
case 'DownloadSel':
if (!ev.userInfo || !ev.userInfo.isSel)
ev.target.disabled = true;
break;
};
};

Categories