How can I make my delete button work? - sql

Please excuse me for being a noob when it comes to what is probably not that hard....
I am writing a page which has a table which allows users to add players into a game. Every <td> contains a <input type='hidden'... and a piece of information (player name, place, points etc). There is also a 'delete' button (for use when a player is mistakenly added twice, or the wrong player is added to the list). At this stage, when clicking save, the table submits all the hidden inputs to the "Confirm results" page before closing the page and updating the database.
The problem I am having is that the players need to be added to and deleted from the database live. To do this, I've created a form will post their details to the same page, then if (I'm paraphrasing here) if($form = 'new player') an SQL command will add a temp file to the database to show that player is registered, then an SQL SELECT will get all the players in that game and echo them to the page. I want the delete button to delete the players row from the database the moment it is clicked and refresh the page, but the only way I know to do this is with a form, and this would create a form within a form.
How else can I make the delete button remove a row from a database without leaving the current window and without using another form? Is this something that should be done with AJAX? (I know almost nothing about AJAX - learning it is next on my to do list, but right now I just want to get this page to work).
added: One idea I had was to make the delete button more like a msgbox to create an inner window that basically says "Are you sure you want to delete John Smith" and then run the SQL code in that window. Would something like that work? How can I do that?

You can call an action from a buton click via AJAX.
So if you have an action set up to do what you want (your delete) then you should be abkle to fire it.....
I use MVC razor and do it like this....
JQuery....
$("#yourButton").click(function (e) {
var url = "#Url.Action("YourActionName", "YourControllerName")";
//alert(url);
$.ajax({
url: url,
type: 'POST',
cache: false,
data: { param1: param1Val, param2: param2Val },
success: function (result) {
..Do something with result if required
}
});
return true;
});
I've had similar scenarios to you and I am pretty new to this also, however, this seems to work nicely.
Hope it helps.

Related

Revive/activate existing panels

My extension have sidebar webview that can create additional webviews as panels in the active text editor. Each of these additional webviews is for an unique item and I want to revive/activate existing webview, for the specific item, if it exists.
My issues:
I can get a list of the existing tabs with window.tabGroups.all and loop through the result. But there is no way, as far as i can see, to reactivate the desired tab. I can get some properties from there but no methods. The question here is: is there a API to get a list of the tabs and be able to revive/activate it?
Because of the first point ive decided to keep list of the instances of the additional webviews and when new webview is about the be created im checking if its unique id (in the title) is in the list and if it is then just revive the tab instead of creating a new one. Dont like this approach much but its working. The problem here is when the additional webview is closed. When closed it has to be removed from the array. Ive implemented onDidDispose for the panel but somehow the filter function, inside it, is not called:
// panels: vscode.WebviewPanel[]
// create new panel
const panel = vscode.window.createWebviewPanel(...)
// add the webview instance to the panel
const newWebview = new AdditionalWebview(panel, this.context);
this.panels.push(panel);
panel.onDidDispose(() => {
console.log("Before remove the panel"); // can see this in the console
this.panels = this.panels.filter((p) => p.title != panel.title);
console.log("Before remove the panel"); // for some reason this never appears
});
Not sure why but the panel filter functionality is never triggered (and everything after it is also not ran).
extra question: at the moment the uniqueness of the additional panels is based on their label/title. In my case thats is ok but is there any other way to get unique identifier of each tab? id/guid somewhere?
On your first question about activating a given editor, you have a couple of options.
If you know the editor's index/position in its group. That can be obtained from its tabGroup.tabs position - it seems that the tab's index in that array is faithfully its index in the editor. So you could do a Array.findIndex to get the tab uri you want to set to active.
await vscode.commands.executeCommand('workbench.action.openEditorAtIndex', [indexToOpen]);
// note the [] around the index argument
The only problem with this approach is that it works within the active group only, so you may have to activate the correct group first via:
await vscode.commands.executeCommand('workbench.action.focusSecondEditorGroup');
// or whichever group the tab you want to open is in
Or second method:
// assumes you have the tab
const openOptions = { preserveFocus: true, preview: tab.isPreview, viewColumn: tab.group.viewColumn};
// check if a uri, might be viewtype, etc., instead
if (tab.input instanceof vscode.TabInputText) {
await vscode.commands.executeCommand('vscode.open', tab.input.uri, openOptions);
}
// are your editors regular text editors?
This looks like it is opening a new tab but it will focus an existing tab if one exists at that location with that same uri.

Vuetify Data Table jump to page with selected item

Using Vuetify Data Tables, I'm trying to figure out if there's a way to determine what page the current selected item is on, then jump to that page. My use case for this is, I'm pulling data out of the route to determine which item was selected in a Data Table so when a user follows that URL or refreshes the page that same item is automatically selected for them. This is working just fine, however, I can't figure out how to get the Data Table to display the correct page of the selection.
For example, user visits mysite.com/11
The Data Table shows 10 items per page.
When the user enters the site, item #11 is currently auto-selected, but it is on the 2nd page of items. How can I get this to show items 11-20 on page load?
I ended up using a solution similar to what #ExcessJudgement posted. Thank you for putting that code pen together, BTW! I created this function:
jumpToSelection: function(){
this.$nextTick(() => {
let selected = this.selected[0];
let page = Math.ceil((this.products.indexOf(selected) + 1) / this.pagination.rowsPerPage);
this.pagination.sortBy = "id";
this.$nextTick(() => {
this.pagination.page = page;
});
});
}
I'm not sure why I needed to put this into a $nextTick(), but it would not work otherwise. If anybody has any insight into this, it would be useful to know why this is the case.
The second $nextTick() was needed because updating the sortBy, then the page was causing the page to not update, and since I'm finding the page based on the ID, I need to make sure it's sorted properly before jumping pages. A bit convoluted, but it's working.

Yii2 Gridview get all selected row for all pagination

I wrapped my gridview with Pjax widget like this
\yii\widgets\Pjax::begin();
gridview
\yii\widgets\Pjax::end();
in order to make the gridview make ajax request when I click on each pagination.
I also use ['class' => 'yii\grid\CheckboxColumn'], in column as well.
and I find that when I'm on first pagination I checked some rows and then go to second page and check some rows but when I go back to first page what I've checked is gone.
My question is how can I keep all checkedrow for all pagination
With current conditions (Pjax, multiple pages, yii\grid\CheckboxColumn) it's impossible because of the way it works.
When you click on the pagination links all GridView html content is replaced by new one that comes from the AJAX response.
So obviously all selected checkboxes on the previous page are gone.
Few possible ways to solve that:
1) Write custom javascript and server side logic.
As one of the options, you can send AJAX request to server with parameter meaning that user has chosen to select all data for the bulk delete operation (or use separate controller action for bulk deletion). In this case actually we don't need to get the selected data from user, because we can simply get them from database (credits - Seng).
2) Increase number of displayed rows per page.
3) Use infinite scroll extension, for example this.
4) Break desired action in several iterations:
select needed rows on first page, do action (for example, delete).
repeat this again for other pages.
You can get selected rows like that:
$('#your-grid-view').yiiGridView('getSelectedRows');
[infinite scroll] : http://kop.github.io/yii2-scroll-pager/ will work good if you do not have any pjax filters. If you have filters also in play, do not use this plugin as it does not support pjax filters with it. For rest of the applications it is perfect to use.
Update1 : it seems to be straight forward than expected, here is the how I accomplished it
Add following lines to the checkbox column
'checkboxOptions' => function($data){
return ['id' => $data->id, 'onClick' => 'selectedRow(this)'];
}
Now add following JS to the common js file you will have in your project of the page where this datagrid resides
var selectedItems=[]; //global variable
/**
* Store the value of the selected row or delete it if it is unselected
*
* #param {checkbox} ele
*/
function selectedRow(ele){
if($(ele).is(':checked')) {
//push the element
if(!selectedItems.includes($(ele).attr('id'))) {
selectedItems.push($(ele).attr('id'));
}
} else {
//pop the element
if(selectedItems.includes($(ele).attr('id'))) {
selectedItems.pop($(ele).attr('id'));
}
}
}
Above function will store the selected row ids in the global variable array
Now add following lines to pjax:end event handler
$(document).on('pjax:end', function () {
//Select the already selected items on the grid view
if(!empty(selectedItems)){
$.each(selectedItems, function (index,value) {
$("#"+value).attr('checked',true);
});
}
});
Hope it helps.
I just solved this problem and it works properly with Pjax.
You may use my CheckboxColumn. I hope this can help. The checked items are recorded with cookies.
You can read the part with //add by hezll to understand how to fix it, because I didn't provide a complete general one.
Hope it works for you.
https://owncloud.xiwangkt.com/index.php/s/dGH3fezC5MGCx4H

web2py SQLFORM accepting too fast

I have a web2py SQLFORM that gets generated and returned by an AJAX call and the form is put in a DIV I defined.. I want that SQLFORM to be an update form, not an insert form. The problem is the form immediately runs it's accept function once it is written to that DIV. This doesn't happen if the form is for inserting, only updating. That initial accept fails and hitting the submit button does not allow for a second accept.
I don't know why the accept fails or why it happens immediately.
heres the JavaScript function that makes the AJAX call
function displayForm(currID){
//Remove everything from the DIV we want to use
$('#window').empty();
//Call the ajax to bring down the form to update the series
ajax('{{=URL('newForm')}}/'+currID,
[], 'window');
}
And here is the newForm controller
def newSerForm():
record = db.myTable(request.args[0])
form = SQLFORM(db.myTable, record, fields=['series_name','image_thumbnail'])
if form.accepts(request.vars,session):
print 'Series update successful!'
else:
print 'Series update Failed...'
return form
displayForm is fired by clicking a button and once you do the form accepts and fails and the submit button doesn't work again. Is there a way to make an SQLFORM do this? The weird thing is if I change this to make inserts into myTable, it works fine. It behaves exactly as it should. But doing it this way doesn't work.
Ok now this is where it gets weird.
I tried to achieve the same functionality here with a totally different approach, an iFrame. I made new functions in my controllers that create the form based on request.args[0]. looks like this
def editEntry():
print request.args[0]
record = db.myTable(request.args[0])
form = SQLFORM(db.CC_user_submission, record, fields=['series_name', 'image_thumbnail']).process()
return dict(form=form)
And then a corresponding HTML page that just displays form. What could be simpler right? I go to that page based on a link that gives the correct argument. Take me to a page with a form for updating. Updating works perfect. Great, now lets put it in an iFrame instead of linking to it. I put it in an iFrame on the original page. Open up the iFrame. Doesn't work. I have no idea what is going is there any part of an explanation to this?
By using the iFrame method I actually got this one to work. Since it required an iFrame to be appended with jQuery which needs quotes and the iFrame URL which also needs quotes, the notation got pretty confusing but it's doable. Looked like this:
var myURL = "{{=URL('editEntry')}}/"+idArg.toString();
$('#window').append("<iframe src = " + myURL + " width='450' height='400'> </iframe>");
It's not pretty but it works.

Jquery live does not seem to work in nested calls

I am encountering a problem of jquery live function not consistently working for me (or that what I think).
I have the same html form which is used for both adding new comment and editing an existing one; this form is propagated using a php code at the server side through a GET call. The two forms are displayed in two different tabs (tab1: adding a comment, tab2: listing the comments; tab3: edit a comment selected in tab2) based on the tab selection. The "Add comment" form appears as the main content of the tab1; however, the 'edit' form appears based on the selection of the comment that needs to be edit in tab2, so let assume that the "edit comment" form appears as tab3. The below code work perfectly for tab1 when the form is the main content of that tab; but it doesn't work consistently when it is the main content of tab3, which is showed based on which comment need to be edit in tab2.
$("input.sample_radio").live('change',function(){
if ($(this).val() == 'no')
$('#sample_table').hide();
else if ($(this).val() == 'yes')
$('#sample_table').show();
return false;
});
If you can provide me with some thoughts, it would be appreciated. My observations were:
I used $("input[name='sample_radio']") but this didn't work for the form of tab3 because it always end up at the form of tab1
by using $("input.sample_radio") I assumed all the classes of type 'sample_radio' would work, but it not working either.
live is supposed to bind events to the new elements added to the DOM tree after jquery calls, but it seems this is not the case for me.
Thanks
Following the suggestion of Mark Schultheiss
Look into .delegate() which was presented specifically to address this by allowing you to specify a context.
I managed to solve this issue by binding the event to the selected parents (tab1 and tab3) of the radio buttons and then filtering based on the selector which is here is the name of the radio button element and as shown below:
$('#tab1,#tab3').delegate('input[name="policy_radio"]','change',function(){
if ($(this).val() == 'no')
$('.policy_table').hide();
else if ($(this).val() == 'yes')
$('.policy_table').show();
return false;
});
Thanks for pointing me to this point.
By using .live you have ran into one of it's challenges. When you change the selection context you prevent it from working properly.
Look into .delegate() which was presented specifically to address this by allowing you to specify a context.
See this post for some notes on delegate from Brandon Aaron: http://brandonaaron.net/blog/2010/03/4/event-delegation-with-jquery
And see this nice one on context: http://brandonaaron.net/blog/2009/06/24/understanding-the-context-in-jquery