I have implemented handsontable for getting data from user.
This is my script
<script type="text/javascript">
$(document).ready(function() {
$('#quiz_questions').handsontable({
rowHeaders: true,
colHeaders: ['Question', 'Option 1', 'Option 2', 'Option 3', 'Option 4', 'Answer', 'Marks'],
columns: [
{
type: 'text',
allowEmpty: false
},
{
type: 'text',
allowEmpty: false
},
{
type: 'text',
allowEmpty: false
},
{
type: 'text',
allowEmpty: true
},
{
type: 'text',
allowEmpty: true
},
{
type: 'dropdown',
source: ['Option 1', 'Option 2', 'Option 3', 'Option 4'],
allowEmpty: false
},
{
type: 'numeric',
allowEmpty: false
}
],
stretchH: 'all',
minSpareRows: 0,
minSpareColumns: 0,
minRows : 25
});
var hotInstance = $("#quiz_questions").handsontable('getInstance');
$('#btnSave').click(function(e){
e.preventDefault();
$('#btnSave').prop("disabled", true);
//alert('btnclicked');
var dynFrm = $('<form>', {
'action': '{{ action('QuizQuestionController#storeBulk') }}',
'method': 'POST'
}).append($('<input>', {
'type': 'hidden',
'name': '_token',
'value': '{{ csrf_token() }}'
})).append($('<input>', {
'type': 'hidden',
'name': 'quiz_id',
'value': '{{ $quiz->quiz_id }}'
})).append($('<input>', {
'type': 'hidden',
'name': 'data',
'value': JSON.stringify(hotInstance.getData())
}));
dynFrm.appendTo(document.body).submit();
});
});
</script>
The storeBulk() function of QuizQuestionController processes the data.
public function storeBulk()
{
// get the quiz model
$quiz = Quiz::findOrFail(Input::get('quiz_id'));
// get the data
$data = Input::get('data');
$jData = json_decode($data);
//process the recevied data
foreach($jData as $row) {
$quizQuestion = new QuizQuestion();
$quizQuestion->quiz_id = $quiz->quiz_id;
$quizQuestion->question_no = $cnt;
$quizQuestion->question_text = trim($row[0]) ? : null;
$quizQuestion->options = $this->processOptions([
trim($row[1]),
trim($row[2]),
trim($row[3]),
trim($row[4])
]);
$quizQuestion->answer = $this->processAnswer($row[5]);
$quizQuestion->marks = trim($row[6]) ? : null;
...
}
Now the problem is, for rows that are left empty in the handsontable while filling the data, I should get data for those rows as [null,null,null,null,null,null,null]. But this is not the case. For some rows I get [null,null,null,null,null] (only 5 values). Thus I get an ErrorException saying Undefined offset: 5.
I have noticed this happens for first 5 rows only. What could be the problem?
Pinpointed the problem.
I have noticed this happens for first 5 rows only. What could be the
problem?
There's a startRows property of handsontable which defaults to 5. Hence the problem with the first 5 rows. I set the property explicitly to
startRows: 0,
And also modified the storeBulk() function to ignore errors.
$quizQuestion->question_text = trim(#$row[0]) ? : null;
$quizQuestion->options = $this->processOptions([
trim(#$row[2]),
trim(#$row[3]),
trim(#$row[4]),
trim(#$row[5])
]);
$quizQuestion->answer = $this->processAnswer(#$row[6]);
$quizQuestion->marks = trim(#$row[7]) ? : null;
Now everything works correctly.
Have you tried using hotInstance.getSourceData() instead of hotInstance.getData()? The functionality for this method changed with its latest release which has been causing similar issues for other people.
Related
I'm trying to add dynamic values for the column section in an ajax request so that the users can have control over what fields are in the data tables.
I tried with default values and it worked but when i changed to use dynamic values from a variable, the ajax field gives me errors
this works fine;
$(function() {
$('#myTable').DataTable({
processing: true,
serverSide: true,
ajax: '{{ route('members.create') }}',
columns: [
{ data: 'name', name: 'name' },
{ data: 'email', name: 'email' },
{ data: 'address', name: 'address' },
{ data: 'contact', name: 'contact' },
{ data: 'nationality', name: 'nationality' },
{ data: 'dob', name: 'dob' },
{ data: 'hometown', name: 'hometown' },
{ data: 'action', name: 'action', orderable: false, searchable: false }
]
});
});
this is where the problem comes in;
$(function() {
$('#myTable').DataTable({
processing: true,
serverSide: true,
ajax: '{{ route('members.create') }}',
columns: [
var memberFields = <?php echo json_encode($chosen_member_fields, JSON_UNESCAPED_UNICODE); ?>;
for(var i = 0; i < memberFields.length; i++){
{ data: memberFields[i], name: memberFields[i] };
},
{ data: 'action', name: 'action', orderable: false, searchable: false }
]
});
});
Thats because column property wants an array .
And your structure to build array is incorrect .
Do this :
$(function() {
var memberFields = <?php echo json_encode($chosen_member_fields, JSON_UNESCAPED_UNICODE); ?>;
var columnArray = [];//To save for value into an Array
for(var i = 0; i < memberFields.length; i++){
columnArray.push({ data: memberFields[i], name: memberFields[i] });//push valuse to array
},
columnArray.push({ data: 'action', name: 'action', orderable: false, searchable: false });//push last value
$('#myTable').DataTable({
processing: true,
serverSide: true,
ajax: '{{ route('members.create') }}',
columns: columnArray , //just say Array name !
});
});
Didnt test but hope works
I am looking for a method to have my table pre-sorted by date descending on the date column. I have gone through the datatables documentation on sorting but have not found a workable solution when using window.dtDefaultOptions. It seemed like window.dtDefaultOptions.order = [[3, "desc"]] should be the way to accomplish this but it didn't work for me.
I have also tried window.dtDefaultOptions.columnDefs = [{orderable: true, targets: 3}] but that didn't solve the problem either.
This is my code in my index.blade:
$(document).ready(function () {
window.dtDefaultOptions.ajax = '{!! route(' admin.feedback.index ') !!}';
window.dtDefaultOptions.stateSave = true;
//window.dtDefaultOptions.scrollY = '50vh';
window.dtDefaultOptions.scrollCollapse = true;
window.dtDefaultOptions.order = [[3, "desc"]];
window.dtDefaultOptions.columns = [{
data: 'user.name',
name: 'user.name'
}, {
data: 'type',
name: 'type'
}, {
data: 'comment',
name: 'feedback.comment'
}, {
data: 'date',
name: 'created_at'
}, {
data: 'actions',
name: 'actions',
searchable: false,
sortable: false
}
];
window.dtDefaultOptions.buttons = [];
processAjaxTables();
});
I found a way to get the column to order by descending upon rendering.
window.dtDefaultOptions = {
columnDefs: [],
"order": [3,'desc'],
};
The problem is that to get it to work I have to delete or comment out the saveState and scrollCollapes lines of code.
$(document).ready(function () {
window.dtDefaultOptions.ajax = '{!! route('admin.feedback.index') !!}';
window.dtDefaultOptions = {
columnDefs: [],
"order": [3,'desc'],
};
//window.dtDefaultOptions.stateSave = true;
//window.dtDefaultOptions.scrollY = '50vh';
//window.dtDefaultOptions.scrollCollapse = true;
window.dtDefaultOptions.columns = [{
data: 'user.name',
name: 'user.name'
}, {
data: 'type',
name: 'type'
}, {
data: 'comment',
name: 'feedback.comment'
}, {
data: 'date',
name: 'created_at'
}, {
data: 'actions',
name: 'actions', searchable: false, sortable: false
}
];
window.dtDefaultOptions.buttons = [];
processAjaxTables();
});
So we have an answer that works for the stated question but it breaks other aspects of the code. In this case, I can live with this since the column order is more important than stateSave and scrollCollapse on this particular table. But if anyone knows how to achieve the column order along with stateSave, and scrollCollapse I would be interested in learning.
I'm building a configurator in AngularJS that uses the object $scope.data to allow users to edit the object via the front-end. The user can then save this object to a separate array in $scope.builds, allowing them to have multiple configurations. Here is the function that adds another configuration to $scope.builds.
$scope.addition = function(){
var newData = angular.copy($scope.data);
$scope.builds.push(newData);
}
Unfortunately, despite using the angular.copy function, all of the objects in the array of $scope.builds seem to be the same $scope.data object duplicated over and over.
EDIT:
Here is an abridged version of what $scope.data looks like:
$scope.data = [
{
'title': 'Select your configuration',
'required': true,
'options': [
{
'name': 'Option 1',
'select': true,
'filter': true
}, {
'name': 'Option 2',
'select': false,
'filter': true
}, {
'name': 'Option 3',
'select': false,
'filter': true
}
]
}, {
'title': 'Select your configuration',
'required': true,
'options': [
{
'name': 'Option 1',
'select': true,
'filter': true
}, {
'name': 'Option 2',
'select': false,
'filter': true
}, {
'name': 'Option 3',
'select': false,
'filter': true
}
]
}
];
How to pass an jquery ajax response after success into a php variable. this is my code :
process.php
$start = "";
$end = "";
if(isset($_POST['tampStart']))
{
$start = $_POST['tampStart'];
}
if(isset($_POST['tampEnd']))
{
$end = $_POST['tampEnd'];
}
$SQL = "SELECT * FROM `values` WHERE date BETWEEN '".$start."' and '".$end."'";
$result = mysql_query($SQL);
$prefix = '';
while ( $row = mysql_fetch_assoc( $result ) ) {
$prefix .= "[\n"."'".$row['month']."'".', '.$row['days']."]".",";
}
echo rtrim($prefix, ",");
index.php
var dStart = $('#textInput1').val();
var dEnd = $('#textInput2').val();
var form_data = {
tampStart: dStart,
tampEnd: dEnd
};
$.ajax({
url: 'process.php',
type: 'POST',
async : true,
data: form_data,
dataType: 'text',
success: function(resp){
$('#content').html(resp);
//pass to php variable ?
}
});
there is no problem when I put the response into a div ($('#content').append(resp);), but how to put the response into an php variable. Thanks for advance..
update my Highcharts code :
function createChart(datan) {
//alert(datan);
Highcharts.setOptions({
lang: {
drillUpText: 'Back to {series.name}'
}
});
var options = {
chart: {
height: 300
},
title: {
text: 'Highcharts Drilldown Plugin'
},
xAxis: {
categories: true
},
drilldown: {
series: [{
id: 'fruits',
name: 'Fruits',
data: [datan] //here #*
}, {
id: 'cars',
name: 'Cars',
data: [{
name: 'Toyota',
y: 4,
drilldown: 'toyota'
},
['Volkswagen', 3],
['Opel', 5]
]
}, {
id: 'toyota',
name: 'Toyota',
data: [
['RAV4', 3],
['Corolla', 1],
['Carina', 4],
['Land Cruiser', 5]
]
}]
},
legend: {
enabled: false
},
plotOptions: {
series: {
dataLabels: {
enabled: true
},
shadow: false
},
pie: {
size: '80%'
}
},
series: [{
name: 'Overview',
colorByPoint: true,
data: [{
name: 'Fruits',
y: 10,
drilldown: 'fruits'
}, {
name: 'Cars',
y: 12,
drilldown: 'cars'
}, {
name: 'Countries',
y: 8
}]
}]
};
// Column chart
options.chart.renderTo = 'container1';
options.chart.type = 'column';
var chart1 = new Highcharts.Chart(options);
}
I make the highcharts config to a function. when I alert(datan), its shown the data from ajax response, but when I put on Drilldown option data (see sign #* above), the highchart config cant read it..
PHP runs on server not on client so the thing you asking is possible only on server. You have to customize this code for your need it gives framework.
$.ajax({
url: 'process.php',
type: 'POST',
async : true,
data: form_data,
dataType: 'text',
success: function(resp){
// $('#content').html(resp);
createChart(resp);
}
});
var chart;
function createChart(data) {
var options = {
chart: {
height: 300
},
title: {
text: 'Highcharts Drilldown Plugin'
},
xAxis: {
categories: true
},
drilldown: {
series: data}
};
options.chart.renderTo = 'content';
options.chart.type = 'column';
var chart1 = new Highcharts.Chart(options);
}
Javascript is a client side scripting. You can't assign the javascript value directly to the php variable.
One way is to set a SESSION variable in PHP. In your case in process.php file.
Another way is to use Database/files.
Well, if you really want to do it this way, you can set a cookie with the desired variable in Javascript and afterwards access it with PHP.
But, there is another way. You can do whatever you want on the client side and when you want to transmit the variable to server-side, just open an ajax connection on the php page which will handle the variable and hand it the actual variable through POST data.
I have inherited an ExtJs4 project, and I've got a fairly basic question.
I have a view that has a newly added checkbox field as one of the items, like so:
{
boxLabel: 'Test Message?',
xtype: 'checkboxfield',
id: 'cbTextMessage',
checked: false,
name: 'testMessage',
inputValue: true,
uncheckedValue: false
}
When the record is active, this value changes to the appropriate checked or unchecked state. When creating a new record, the value is set to the value of the checkbox. However, when editing an existing record, the model never gets updated to any value other than the original value.
The model:
Ext.define('PushAdmin.model.Message', {
extend: 'Ext.data.Model',
idProperty: 'id',
requires: ['Proxy.ParameterProxy'],
fields: [
{ name: 'id', type: 'int' },
{ name: 'games', type: 'auto',
convert: function(data, model) {
data = ( data && !Ext.isArray(data) ) ? [data] : data;
return data;
}
},
{ name: 'msgEnglish', type: 'string' },
{ name: 'msgFrench', type: 'string' },
{ name: 'msgSpanish', type: 'string' },
{ name: 'testMessage', type: 'bool' },
{ name: 'sendAt', type: 'date' },
{ name: 'note', type: 'string'},
{ name: 'status', type: 'string' },
],
proxy: {
type: 'rest',
url: '/apnsadmin/rest/Message',
pageParam: undefined,
startParam: undefined,
limitParam: undefined,
reader: {
type: 'json',
root: 'data',
successProperty: 'success'
}
}
});
And finally this is the function that gets called when the save button is clicked.
click: function () {
var grid = this.getQueuedMessagesGrid();
var sm = grid.getSelectionModel();
var selectedRecord = sm.getCount() > 0 ? sm.getSelection()[0] : undefined;
this.getMessageForm().getForm().updateRecord();
var newRecord = this.getMessageForm().getForm().getRecord();
if (selectedRecord!=undefined) {
console.log(selectedRecord);
console.log(newRecord);
selectedRecord.save();
} else {
// New record!
console.log("Saving new record");
grid.getStore().add(newRecord);
newRecord.save();
}
this.getMessageForm().setDisabled(true);
this.getMessageForm().getForm().reset();
}
},
I am aware that things are probably not the proper ExtJS way to do things, but since this is mostly working I am trying not to have to rewrite large chunks of it. I'd just like to know what I'm doing wrong in adding this checkbox/boolean field to the form.