I have a datatable populated by 4 fields via a Laravel route. That is fine and works great.
Additionally I have added 2 columns with icons, again that is fine. One is to show a sliding panel of information and one will be a link to more details.
I show these by rendering column info.
I wish to have an onlick event for one which will use the data in column 0 which is a key field. I have tried:
{
"targets": [4],
"render": function ( data, type, full, meta ) {
{return '<div align="center"><img src="{{ asset("siteicons/Info_Box_Blue.png") }}" id="trigger" onclick="ShowSlider( {{ ' + 0 + '}} )"></div>';}
}
},
This is in the columnDefs, but clicking does not do anything - even if I put a simple alert.
Help, please!
"render": function ( data, type, full, meta ) {
return '<div align="center"><img src="{{ asset("siteicons/Info_Box_Blue.png") }}" id="trigger" onclick="ShowSlider(' + full[0] + ')"></div>';
}
If you're trying to get data from the row add it like this.
Extra curly braces are there in your render function. Could u please remove and try it ?
"render": function ( data, type, full, meta ) {
return '<div align="center"><img src="{{ asset("siteicons/Info_Box_Blue.png") }}" id="trigger" onclick="ShowSlider(0)"></div>';
}
Related
I have a datatable that fetches orders and is working and displaying properly. I show the orders to the users that initiated them. Then they can only search on their owns orders. Now I need to display a message to a user, if an order was found but it was initiated by another user, instead of displaying an empty result in the datatable. This will happen after typing in the search box and not when loading the datatable in the beggining. The problem is that the query already filters the results by user id so I cannot change it during manual search.
I can display code if needed but the function is quite big and I don't really need code but the logic/way of doing that.
Do you have any suggestions on how I could accomplish this?
Well, maybe not the best way to do it but that's how I solved it:
In the controller, I check for the search field, and run a query on the relationship but only on the orders that have different seller than the logged in user:
$otherSeller = "";
if(!empty($request->search['value']))
{
$ordersOtherSeller = Order::where('status_id', "!=", 3)->where('seller_id', '!=', $loggedUser->id)->whereHas('user', function ($q) use ($request){
$q->searchFullName($request->search['value']);
})->first();
if($ordersOtherSeller != NULL && $ordersOtherSeller->count() > 0)
$otherSeller = $ordersOtherSeller->user->full_name . ' ' . $ordersOtherSeller->seller->full_name;
}
And I set a custom variable with the table's json:
...
->with('otherSeller', $otherSeller)
->make(true);
Then on the datatable jquery drawCallBack, I check for a populated string that guarantees that the result is not returned by a query from the current user:
fnDrawCallback: function( oSettings ) {
var api = this.api();
if(api.ajax.json().otherSeller != "")
{
$('#alert-info span').text(api.ajax.json().otherSeller);
$('#alert-info').show();
}
else
$('#alert-info').hide();
},
And last is the toggling of the materialert element with updated text:
<div id="alert-info" class="materialert info" style="display: none;">
<i class="material-icons">info</i> <span></span>
<button type="button" class="close-alert">×</button>
</div>
I'm facing difficulty in doing this task :
- I have a table that have an add delete , update buttons for every single row I've done the add and delete thing by adding data-attribute for each button according to the row's data Id. It works perfectly for deleting and inserting elements. Yet i can't find a way to update every single row so i need help !
Note: I'm updating my elements using Ajax.
Any strategy ? i can post a screenshot for my code/view cause it is a bit too long .
More explanation : when you click on the edit button $(this) and delete button hide , and check button appears . inputs are no longer hidden for this row so the user updates the data of this row then he checks it.
The data must update inside the database .
I'm stuck nowhere because every row has its own id and its own values and only one query must be run for every row ( which is the same query for all the rows ) . It's more likely having one form for the whole table that updates only the row that must be updated .
After you click on edit button
$(document).on('click', '.btn-edit-interview', function() {
var id = $(this).attr('data-interview-id');
var selector = ('' + '.tr' + id + '');
var selectordelt = ('' + '.' + id + '');
var selectorsave = ('' + '#save-'+id + '');
$(this).hide();
$(selectordelt).hide();
$(selectorsave).show();
$(selector).prop('disabled', false);
$(selector).addClass("form-control");
$(selector).css('border: 1px solid rgb(204, 204, 204);margin-top: 16px;');
});
I just need help in finding a way do make the update query for every single row .
//HTML
<tr data-unique="{!! $yourVariable->id !!}">
<td><input value="{!! $yourVariable->value !!}"></td>
<td><button data-update="{!! $yourVariable->id !!}">Update</button></td>
</tr>
//AJAX
$('button[data-update]').click(function() {
var itemID = $(this).attr('data-update');
//Will contain value of input in that tr only
var input = $('tr[data-unique="+itemID+"] input').val();
$.ajax({
url: '/update',
type: 'POST',
dataType: 'json',
data: {item: itemID, anotherValue: input},
success:function(data){
if(data['status'] == "success"){
alert("Updated");
}
}
});
return false;
});
//Controller
public function update(Request $req){
YourModel::where('id', $req->input('item'))->update(['column' => 'value']);
return response()->json(['status' => 'success']);
}
//Route
Route::post('/update', 'YourController#update');
Hope that help
If I have columns (name, amount) how do I best create a row / footer that shows ("Total",8877)? Clearly you can do it by adding a row to the data, but this ruins the sorting capability. It appears relatively easy to group by name and show the amount for each name, but I have not found how to do the simpler case (though I have found others asking - https://github.com/angular-ui/ng-grid/issues/679 for example)
You can include a custom footer template on the gridOptions. I looked for the default formatting of the footer in the source code and copied that, but added the function that calculates the totals. Something like this:
$scope.gridOptions = {
data: 'hereGoesTheData',
columnDefs : [list of your column names],
showFooter: true,
footerTemplate:
'<div ng-show="showFooter" class="ngFooterPanel" ng-class="{\'ui-widget-content\': jqueryUITheme, \'ui-corner-bottom\': jqueryUITheme}" ' +
'ng-style="footerStyle()"><div ng-style="{ \'cursor\': row.cursor }" ng-repeat="col in renderedColumns" ng-class="col.colIndex()" class="ngCell {{col.cellClass}} " ng-cell style="text-align:right;">' +
'{{getTotal(col.field)}}</div></div>'
};
And then define $scope.getTotal to do whatever you want it to do.
Quite possibly not the best solution, but I ended up adding a totals row to the top of the footer. https://github.com/mchapman/forms-angular/commit/9f02ba1cdafe050f5cb5e7bb7d26325b08c85ad2
without modifying ng grid, you could just provide your own footer template, that somehow gets the total for each column.
In my case, as I ""build"" the table from server data, I also accumulate a totals hash.
My template looks like this:
total_cell_footer = """
<div ng-show="showFooter" class="ngFooterPanel" ng-class="{'ui-widget-content': jqueryUITheme, 'ui-corner-bottom': jqueryUITheme}" ng-style="footerStyle()">
<div class="ngTotalSelectContainer" >
<div ng-style="{ 'cursor': row.cursor }" ng-repeat="col in renderedColumns" ng-class="col.colIndex()" class="ngCell {{col.cellClass}}">
<span class="ngCellText">{{ get_total(col) | currency:"$"}} </span>
<div class="ngVerticalBar" ng-style="{height: rowHeight}" ng-class="{ ngVerticalBarVisible: !$last }"> </div>
</div>
</div>
</div>
"""
The get_total function is defined in my scope (which is the parent of the ngGrid scope, hence inherited), as follows:
$scope.get_total= (col) ->
# used by the footer template to access column totals.
$scope.totals[col.field]
Take a look at the "Server side paging" example it has exactly what you want! you can slice and dice depending on what you need.
http://angular-ui.github.io/ng-grid/
in your grid options put
enablePaging: true,
showFooter: true,
showFilter: true,
totalServerItems: 'totalServerItems',
pagingOptions: $scope.pagingOptions,
and up top
$scope.pagingOptions = {
pageSizes: [100, 500, 1000],
pageSize: 100,
totalServerItems: 0,
currentPage: 1
};
$scope.setPagingData = function (data, page, pageSize) {
var pagedData = data.slice((page - 1) * pageSize, page * pageSize);
$scope.myData = pagedData;
**$scope.pagingOptions.totalServerItems = data.length**;
if (!$scope.$$phase) {
$scope.$apply();
}
};
I'm working on a CI project and implemented scriptaculous InPlaceEdit. It works, but behaves strangly when and after updating a value.
1) When I click to edit, even though the field is just one word and should be 1 line, it produces a text area with 3 cols and 50 rows. It seems the script added empty space before the original value.
2) I save the new value and want to re-edit it, it gives me twice the form. after that 4x and so on...
HTML
So when the site is rendered, the line looks like this:
<h2 id="case_title-editme-27" class="editable savetitle" onclick="EditInput('case_title','27', 'cases');"> One line </h2>
Clicking to edit in place procudes:
<form id="case_title-editme-27-inplaceeditor" class="input-edit">
<textarea class="editor_field" rows="3" cols="40" name="value"></textarea>
<br>
<input class="editor_ok_button" type="submit" value="Save">
<a class="editor_cancel_link editor_cancel" href="#">cancel</a>
</form>
<h2 id="case_title-editme-27" class="editable savetitle" onclick="EditInput('case_title','27', 'cases');" title="Click to edit" style="display: none;"> One line </h2>
Here's my JS:
function EditInput(field, id, table) {
var id = id;
var table = table;
var field = field;
new Ajax.InPlaceEditor(
field+'-editme-'+id,
'<?PHP echo base_url();?>saveajax/'+id, {
okText: 'Save',
formClassName: 'input-edit',
callback: function(form, value) { return 'table=' + table + '&field=' + field + '&value=' + escape(value) },
}
);
}
And the PHP view
<?php foreach($caseheadlines as $headline):?>
<h2 class="editable savetitle" id="case_title-editme-<?php echo $headline['case_id']; ?>" onclick="EditInput('case_title','<?PHP echo $headline['case_id']; ?>', 'cases');">
<?php echo $headline['case_title']; ?>
</h2>
<?php endforeach;?>
So when clicking on the div, the js function get's fired and everything works expect the problems above. controller and models are fine, data get's saved to the DB.
Anyone has any idea?
The javascript you have provided is creating multiple inplace editors. I would change it like this.
for all the fields that you want to have editable add a specific class to those fields. I see you already have the editable class on the <h2> above - lets use that.
When the DOM is loaded trigger all those elements with that class to be inplace editors like this
document.observe("dom:loaded",function(){
$$('.editable').each(function(element){
new Ajax.InPlaceEditor(element,
'<?PHP echo base_url();?>saveajax/'+id, {
rows : 1,
cols : 15,
okText: 'Save',
formClassName: 'input-edit',
callback: function(form, value) { return 'table=' + table + '&field=' + field + '&value=' + escape(value) },
}
);
});
});
Now there will only be 1 instance of the inplace editor for each field. The inplace editor handles the on click turn into an editable field part.
as far as the row and cols problem if you set the rows and cols options in the instance for exactly what you want that should help - I've added them to my example
I was able to successfully render my first django form inside an extjs tab. The form data displayed properly and the form validation appears to be working properly.
My problem is that django wants to render the whole new page, not just push the results back into the same tab. I think my app will function better if I can keep all this inside a single tab without complete page rendering.
Background: I used the EXTJS ajax tab example to get this working. Then only problem is that the example didn't have multiple get/post calls getting rendered into the same tab, so I'm not sure how to do that.
Question: How do I keep the results of the POST data inside the EXTJS tab? Also, from experts who develop a lot of these apps, am I using the correct pattern here?
Here's my basic layout:
File: grid.js - Builds an EXTJS grid, user clicks 'edit' icon which does a call to django to grab the edit form.
var createColModel = function (finish, start) {
var columns = [{
dataIndex: 'pk',
header: 'Student ID',
filterable: true
//,filter: {type: 'numeric'}
}, {
// ... More column data here
},{
header: 'Actions',
id: 'actions',
xtype: 'actioncolumn',
width: 50,
items: [{
icon : '/site_media/icons/application_edit.png',
tooltip: 'Edit Record',
handler: function(grid, rowIndex, colIndex) {
var rec = studentStore.getAt(rowIndex);
mainTabPnl.add({
title: rec.get('fields.first_name') + ', ' + rec.get('fields.last_name'),
iconCls: 'tabs',
autoLoad: {url: '/app/edit_student/' + rec.get('pk')},
closable:true
}).show();
}
}]
}];
File: views.py
def edit_student_view(request, sid):
print "Edit Student: " + sid
student = Student.objects.get(pk=sid)
if request.method == 'POST':
form = StudentProfileForm(request.POST, instance=student)
if form.is_valid():
student=form.save()
message="Edit successful"
c = {'form' : form, 'student':student, 'message':message}
return render_to_response('app/edit_student.html', c, context_instance=RequestContext(request))
else:
message = "The form contains errors."
c = {'form':form, 'student':student, 'message':message}
// Problem: This is now rendered as the whole page, not inside the tab
return render_to_response('app/edit_student.html', c, context_instance=RequestContext(request))
else:
form = StudentProfileForm(instance=student)
c = {'form':form, 'student':student}
//Initial GET: renders in correct EXTJS window.
return render_to_response('app/edit_student.html', c, context_instance=RequestContext(request))
File: edit_student.html - renders the django form
{% block mainpanel %}
{% if form.errors %}
<p>The Registration form had errors. Please try again.</p>
{% endif %}
{% if form %}
<form action="/app/edit_student/{{student.student_id}}/" method="post">
<table>
{{ form.as_table }}
</table>
<input type="submit" value="Submit" />
</form>
{%endif%}
{% endblock %}
If you want to keep it within the tab then you'll need to forgo the standard HTML form mechanisms and instead set the onclick event on a button to perform a POST via AJAX.