Laravel 'Illegal string offset 'leave_form' issue with array - javascript

I have an edit page where I display the data from a leave application form. I get an error 'Illegal string offset 'leave_form' when I update my form. I am using Vue.js and PHP. I manage to get the other data saved, that is in the leaveData object. When I try to save in the dateFrom in array of objects. leaveData['leave_form'] then I get the error. I suspect the problem lies in my foreach statement under the controller.
My array (just an example that I copied and pasted from console so you can see the object keys and values):
leaveData = [
alternativeName: "testos",
applicantSignature:"1",
applicantSignedDate:"2017-12-12",
contactDetailDuringLeave:"999999",
created_at:"2017-12-12 08:05:44",
created_by:6,
id:21,
leave_form = [
conditionsOfPay:"test",
created_at:"2017-12-12 08:05:44",
dateFrom:"2017-12-12",
dateTo:"2017-12-15",
id:15,
leave_application_id:21,
name:"Vacation Leave",
numberOfDays:2,
]
]
Here is a part of my blade HTML(just the leave_form part):
<tbody>
<tr v-for="leave in leaveData.leave_form">
<th scope="row">#{{ leave.name }}</th>
<td><input v-pikaday="leave.dateFrom" class="form-control" v-model="leave.dateFrom" type="text"/></td>
<td><input v-pikaday="leave.dateTo" class="form-control" v-model="leave.dateTo" type="text"/></td>
<td><input class="form-control" type="text" name="numberOfDays" v-model="leave.numberOfDays"></td>
<td><input class="form-control" type="text" name="conditionsOfPay" v-model="leave.conditionsOfPay"></td>
</tr>
</tbody>
Here is my Vue.js:
var leaveApply = new Vue({
el: '#leaveCreate',
data: {
leaveData: <?php echo $leaveApplication ?>,
getUserData: <?php echo $users ?>,
},
methods: {
submitForm: function(){
var that = this;
var value = that.leaveData;
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $("#_token").attr("content")
}
});
$.ajax({
url: '/admin/internal/leave/update/' + value.id,
type: 'POST',
data: {
leaveData: that.leaveData,
personnelNumber: that.leaveData.personnelNumber,
user_id: that.leaveData.user_id,
alternativeName: that.leaveData.alternativeName,
contactDetailDuringLeave: that.leaveData.contactDetailDuringLeave,
applicantSignature: that.leaveData.applicantSignature,
applicantSignedDate: that.leaveData.applicantSignedDate,
managerApproval: that.leaveData.managerApproval,
managerSignedDate: that.leaveData.managerSignedDate,
},
success: function(response) {
toastr.success('Leave Application Updated');
},
error: function(error){
toastr.error('Something went wrong');
}
});
},
},
});
My Controller:
public function update (Request $request, $id){
$leaveApplication = LeaveApplication::with('user','leaveDept','leaveForm', 'leaveTask')->find($id);
$leaveApplication->personnelNumber = $request->input('personnelNumber');
$leaveApplication->alternativeName = $request->input('alternativeName');
$leaveApplication->contactDetailDuringLeave = $request->input('contactDetailDuringLeave');
$leaveApplication->managerApproval = filter_var($request->input('managerApproval'), FILTER_VALIDATE_BOOLEAN);
$leaveApplication->applicantSignature = filter_var($request->input('applicantSignature'), FILTER_VALIDATE_BOOLEAN);
$leaveApplication->applicantSignedDate = $request->input('applicantSignedDate');
$leaveApplication->managerSignedDate = $request->input('managerSignedDate');
foreach($request->input('leaveData') as $leaveData){
$leaveApplication->dateFrom = $leaveData['leave_form']['dateFrom'];
$leaveApplication->update();
}
$leaveApplication->update();
return response()->json($leaveApplication);
}

$leaveApplication = LeaveApplication::with('user','leaveDept','leaveForm', 'leaveTask')->find($id);
$leaveApplication->dateFrom = $leaveData['leave_form']['dateFrom'];
You have leave_form and LeaveForm. Maybe the problem is here. Also this code
foreach($request->input('leaveData') as $leaveData){
$leaveApplication->dateFrom = $leaveData['leave_form']['dateFrom'];
$leaveApplication->update();
}
repeats the process and saves the last foreach value into your record.
It also means that you are calling update 2 times.

Related

How to load JSON response on each rows input fields

I am novice in Programming and searching answer for the below problem in this site over days but couldn’t figure anything yet.
Firstly, A input form will prompt to the user, then the user will define how many rows there will be.
Then in the HTML table, each rows has 3 input fields(ID, Name, Number).
When a user gives an ID, the name and number of that ID will be placed in the next input fields of that row. For better understanding I am attaching an img.
demo_img.png
studentInfo.php page, Ajax response will set here:
<form class="" action="" method="POST">
<?php
$count = $_REQUEST["countID"]; //<--get the number from the user
for($i=1; $i<=$count; $i++){
?>
<tr>
<td>
<input type="number" name="id[]" class="id">
</td>
<td>
<input type="text" name="fname[]" class="fname">
</td>
<td>
<input type="number" name="num[]" class="num">
</td>
</tr>
<?php
}
?>
</form>
The Ajax portion:
$(".id").change(function(){
var sid = $(this).val();
$.ajax({
method: "GET",
url: "getData.php",
data: {sid: sid},
dataType: "json",
success: function(data, textStatus, jqXHR){
if(data.length == 0){
alert("No data found");
} else {
// I am stuck here. If I console.log(data) the JSON format coming from getData.php is showing like this: {name: 'JACKS DONUTS', num: '185'}
}
},
error: function(jqXHR, textStatus, errorThrown) {
//Show the error msg
}
});
});
Now, How do I set the result to the input fields.
Any suggestion in my code will be greatly appreciated. Thanks in advance.
Your requirement can be achieve by post an array of IDs to an URL e.g. getData.php using ajax.
['1001', '1002', '1003']
Then the getData.php will return an array of student data with ID as key.
{
"1001": {
"name": "Student A",
"number": 20
},
"1002": {
"name": "Student B",
"number": 21
},
"1003": {
"name": "Student C",
"number": 23
}
}
Once you retrieved the student data, try to look for the student data by using the input ID as key, if the data exists, append the data to the form.
if (data[inputId]) {
const studentData = data[inputId];
/* following methods will find input with class name and set the input value with given value */
setValue('name', studentData.name);
setValue('number', studentData.number);
}
Following is the SAMPLE by post the IDs to an API placeholder URL and SIMULATE the return data:
/* bind click event to buttons */
$(document).ready(function() {
$("#add-row").click(addRow);
$("#get-data").click(getData);
});
/* add extra row for input ID */
function addRow() {
$rowHtml = `
<tr class="student-data">
<td><input type="text" class="id" name="id[]" /></td>
<td><input type="text" class="name" /></td>
<td><input type="text" class="number" /></td>
</tr>
`;
$("#form-table").append($rowHtml);
}
/* get data when user submit */
function getData() {
const fieldset = $('#fieldset')
const message = $('#message')
const inputs = $(`input[name="id[]"]`)
/* get multiple ids as array where which by the user */
const ids = inputs.toArray().map(function(input) {
return input.value
})
/* store ids in a data object */
const dataToSubmit = {
ids: ids
}
/* url to post to submit the data e.g. "getData.php" */
/* following is just a demo url */
const url = "https://jsonplaceholder.typicode.com/posts"
$.ajax({
method: "POST",
url: url,
data: dataToSubmit,
dataType: "json",
beforeSend: function() {
/* disable the form when submitting */
fieldset.prop("disabled", true);
message.html('Getting data...');
},
success: function(data, textStatus, jqXHR) {
/* your data should return an array of objects with the key is the id */
/* e.g. {1001: {name: "Student A", number: 20}, 1002: {name: "Student B", number: 21},…} */
/* THIS IS NOT PART OF THE CODE! this is just a simulation of fetching the data */
data = JSON.parse(`{"1001":{"name":"Student A","number":20},"1002":{"name":"Student B","number":21},"1003":{"name":"Student C","number":23}}`);
/* fill the student data once retrieved data */
fillStudentData(data);
},
complete: function() {
/* enable back the form after form was submitted */
fieldset.prop("disabled", false);
message.html('');
}
});
}
function fillStudentData(data) {
$('.student-data').each(function() {
/* get the id by find the input with "id" class */
const inputId = $(this).children().find(".id")[0].value;
/* get student data using id key */
const studentData = data[inputId];
/* set the name and number if there is data found */
if (studentData) {
/* this function will find the inputs in "student-data" class and filled the input with value */
const setValue = (className, value) => {
$(this).children().find("." + className)[0].value = value;
};
setValue('name', studentData.name);
setValue('number', studentData.number);
}
})
}
<form style="display: flex;">
<fieldset id="fieldset">
<table id="form-table" border="1" cellpadding="10">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Number</th>
</tr>
</thead>
<tbody>
<tr class="student-data">
<td><input type="text" class="id" name="id[]" /></td>
<td><input type="text" class="name" /></td>
<td><input type="text" class="number" /></td>
</tr>
</tbody>
</table>
<span>Sample ID: 1001, 1002, 1003</span>
<button type="button" id="add-row">Add Row</button>
<button type="button" id="get-data">Get Data</button>
<span id="message"></span>
</fieldset>
</form>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Trouble with datatables reload()

I want to populate a jQuery datatable based on the content of a textarea. Note: my datatables implementation is not serverside. That is: sorting/filtering happens on the client.
I know my php works as it returns expected results in my test scenario (see below). I have included a lot of code to provide context. I am new to datatables and php.
My html looks like this:
// DataTable Initialization
// (no ajax yet)
$('#selectedEmails').DataTable({
select: {
sytle: 'multiple',
items: 'row'
},
paging: false,
scrollY: '60vh',
scrollCollapse: true,
columns: [
{data: "CONICAL_NAME"},
{data: "EMAIL_ADDRESS"}
]
});
// javascript that defines the ajax (called by textarea 'onfocus' event)
function getEmails(componentID) {
deselectTabs();
assignedEmails = document.getElementById(componentID).value.toUpperCase().split(",");
alert(JSON.stringify(assignedEmails)); //returns expected json
document.getElementById('email').style.display = "block";
//emailTable = $('#selectedEmails').DataTable();
try {
$('#selectedEmails').DataTable().ajax =
{
url: "php/email.php",
contentType: "application/json",
type: "POST",
data: JSON.stringify(assignedEmails)
};
$('#selectedEmails').DataTable().ajax.reload();
} catch (err) {
alert(err.message); //I get CANNOT SET PROPERTY 'DATA' OF null
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<!-- table skeleton -->
<table id="selectedEmails" class="display" style="width: 100%">
<thead>
<tr>
<th colspan='2'>SELECTED ADDRESSES</th>
</tr>
<tr>
<th>Conical Name</th>
<th>Email Address</th>
</tr>
</thead>
</table>
<!-- textarea definition -->
<textarea id='distribution' name='distribution' rows='3'
style='width: 100%' onblur="validateEmail('INFO_DISTRIBUTION', 'distribution');"
onfocus="getEmails('distribution');">
</textarea>
The following code returns the expected json:
var url = "php/email.php";
emailList = ["someone#mycompany.com","someoneelse#mycompany.com"];
fetch(url, {
method: 'post',
body: JSON.stringify(emailList),
headers: {
'Content-Type': 'application/json'
}
}).then(function (response) {
return response.text();
}).then(function (text) {
alert( JSON.stringify( JSON.parse(text))); //expencted json
}).catch(function (error) {
alert(error);
});
php code:
require "openDB.php";
if (!$ora) {
$rowsx = array();
$rowx = array("CONICAL_NAME" => "COULD NOT CONNECT", "EMAIL_ADDRESS" => "");
$rowsx[0] = $rowx;
echo json_encode($rowsx);
} else {
//basic query
$query = "SELECT CONICAL_NAME, EMAIL_ADDRESS "
. "FROM SCRPT_APP.BCBSM_PEOPLE "
. "WHERE KEY_EMAIL LIKE '%#MYCOMANY.COM' ";
//alter query to get specified entries if first entry is not 'everybody'
if ($emailList[0]!='everybody') {
$p = 0;
$parameters = array();
foreach ($emailList as $email) {
$parmName = ":email" . $p;
$parmValue = strtoupper(trim($email));
$parameters[$p] = array($parmName,$parmValue);
$p++;
}
$p0=0;
$query = $query . "AND KEY_EMAIL IN (";
foreach ($parameters as $parameter) {
if ($p0 >0) {
$query = $query.",";
}
$query = $query.$parameter[0];
$p0++;
}
$query = $query . ") ";
$query = $query . "ORDER BY CONICAL_NAME";
$getEmails = oci_parse($ora, $query);
foreach ($parameters as $parameter) {
oci_bind_by_name($getEmails, $parameter[0], $parameter[1]);
}
}
oci_execute($getEmails);
$row_num = 0;
try {
while (( $row = oci_fetch_array($getEmails, OCI_ASSOC + OCI_RETURN_NULLS)) != false) {
$rows[$row_num] = $row;
$row_num++;
}
$jsonEmails = json_encode($rows, JSON_INVALID_UTF8_IGNORE);
if (json_last_error() != 0) {
echo json_last_error();
}
} catch (Exception $ex) {
echo $ex;
}
echo $jsonEmails;
oci_free_statement($getEmails);
oci_close($ora);
}
Looking at a couple of examples on the DataTables site, I found I was making this more difficult than it needed to be: Here is my solution:
HTML: (unchanged)
<table id="selectedEmails" class="display" style="width: 100%">
<thead>
<tr>
<th colspan='2'>SELECTED ADDRESSES</th>
</tr>
<tr>
<th>Conical Name</th>
<th>Email Address</th>
</tr>
</thead>
</table>
<textarea id='distribution' name='distribution' rows='3'
style='width: 100%'
onblur="validateEmail('INFO_DISTRIBUTION', 'distribution');"
onfocus="getEmailsForTextBox('distribution');">
</textarea>
javascript:
Note: The key was the function for data: which returns json. (My php code expects json as input, and of course, outputs json).
[initialization]
var textbox = 'developer'; //global variable of id of textbox so datatables can use different textboxes to populate table
$(document).ready(function () {
$('#selectedEmails').DataTable({
select: {
sytle: 'multiple',
items: 'row'
},
ajax: {
url: "php/emailForList.php",
contentType: "application/json",
type: "post",
data: function (d) {
return JSON.stringify(document.getElementById(textbox).value.toUpperCase().split(","));
},
dataSrc: ""
},
paging: false,
scrollY: '60vh',
scrollCollapse: true,
columns: [
{data: "CONICAL_NAME"},
{data: "EMAIL_ADDRESS"}
]
});
});
[code that redraws table]
function getEmailsForTextBox(componentID) {
deselectTabs();
document.getElementById('email').style.display = "block";
textbox = componentID; //textbox is global variable that DataTable uses as source control
$('#selectedEmails').DataTable().ajax.reload();
}

Storing HTML form input in a JS object

I know there is a very similar question asked over here but my object hierarchy is different than the one in that question.
Anyways, I want to store the HTML form input data in to my JavaScript object. Here is my HTML form code:
<form id="newAuction">
<input id="title" name="title" required type="text" value="" />
<input id="edate" name="edate" required type="datetime" value="" />
<input id="minbid" name="minbid" required type="number" value="" />
<button class="btn btn-primary">Submit</button>
</form>
What I want is to get the values of these 3 inputs and store it in my JS object.
I know the proper JSON format needed to post the data to my API. (I tried POSTing with POSTman and I get a status 200, so it works). The proper format is:
{
"auction": {
"Title": "Auction1",
"EDate": "01/01/1990",
"MinBid": 30
},
"productIds": [1,2,3]
}
This is what my JS object looks like:
<script>
$(document).ready(function() {
var vm = {
auction: {},
productIds: []
};
//validation and posting to api
var validator = $("#newAuction").validate({
//assigning values
vm.auction.Title = document.getElementById('title').value;
vm.auction.MinBid = document.getElementById('minbid').value;
vm.auction.EDate = document.getElementById('edate').value;
vm.productIds.push(1);
submitHandler: function () {
$.ajax({
url: "/api/newAuction",
method: "post",
data: vm
})
.done(function () {
toastr.success("Auction Added to the db");
//setting the vm to a new vm to get rid of the old values
var vm = { auction: {}, productIds: [] };
validator.resetForm();
})
.fail(function () {
toastr.error("something wrong");
});
return false;
}
});
});
</script>
As you can see, I am using document.getElementById('title').value; to get the values and assign them but I'm getting the syntax error Expected : Comma expected
Not sure if this matters, but this is inside a .NET MVC5 project.
Move your value assignment set of codes inside submitHandler. Check the syntax of validate() https://jqueryvalidation.org/validate/
//validation and posting to api
var validator = $("#newAuction").validate({
submitHandler: function () {
//assigning values
vm.auction.Title = document.getElementById('title').value;
vm.auction.MinBid = document.getElementById('minbid').value;
vm.auction.EDate = document.getElementById('edate').value;
vm.productIds.push(1);
$.ajax({
url: "/api/newAuction",
method: "post",
data: vm
})
.done(function () {
toastr.success("Auction Added to the db");
//setting the vm to a new vm to get rid of the old values
var vm = { auction: {}, productIds: [] };
validator.resetForm();
})
.fail(function () {
toastr.error("something wrong");
});
return false;
}
});

Jquery UI Autocomplete in codeigniter using table oracle

views.php
<div class="input-group">
<input class="form-control" id="nomor_cari" maxlength="16" placeholder="No. CM / No. KTP">
script autocomplete
$('#nomor_cari').autocomplete({
source: get_no,
dataType: 'JSON'
});
function get_no
<?php
function get_no($q)
{
$this->db->select('NO_MEDREC');
$this->db->like('NO_MEDREC', $q);
$query = $this->db->get('PASIEN_IRJ');
if($query->num_rows > 0)
{
foreach ($query->result_array() as $row)
{
$row_set[] = htmlentities(ucfirst($row['NO_MEDREC']));
}
$this->output
->set_content_type('application/json')
->set_output(json_encode($row_set));
}
echo $query->row();
}?>
but autocomplete didn't show anything.
if i use local variable , autocomplete works like it should be.
<script> var availableNumber = [
"0000000002",
"0000000020",
"0000000200",
"0000002000"
];
/<script>
and changes autocomplete to
$('#nomor_cari').autocomplete({
source: availableNumber,
dataType: 'JSON'
});
what did i missed? (im sure .js are loaded because when using local var , it works like charm)
just in case needed , here's my autoload
$autoload['libraries'] = array('database', 'email', 'session');
$autoload['helper'] = array('url', 'template', 'message', 'misc');
I think issue is in "source". Please try to use json like this
$('#nomor_cari').autocomplete({
source: function (request, response) {
$.getJSON("ful_url/get_no?term=" + request.term, function (data) {
response($.map(data.dealers, function (value, key) {
return {
label: value,
value: key
};
}));
});
},
});

Putting dynamic sets of fields in form into JSON with JavaScript

I have a form that has a dynamic number of rows. Each row has 3 fields, a hidden id, code, and exchange.
<form id="form_in_question">
<table>
<tr>
<td>0</td>
<td>
<input type="hidden" id="id[]" value="123" />
<input type="input" id="code[]" value="abc" />
</td>
<td>
<select id="exchange[]">
<!-- Options... -->
<select>
<td>
<tr>
<!-- unlimited rows... -->
</table>
</form>
I am trying to get an object that looks like:
data: {
"0": {
id: "123",
code: "abc",
exchange: "2"
},
"1": {
id: "124",
code: "bcd",
exchange: "4"
}
}
So I can pass it a JSON object via AJAX like:
$("#dialogEditor").dialog('option', 'buttons', {'Save' : function() {
/* Define variables */
var data = $("#form_in_question").serializeArray();
$.ajax({
url: 'ajax.codes.php',
dataType: 'json',
data: {
action: "update_codes",
entryId: entry,
data: data
},
type: 'POST',
success: function() {
ui.showMsg("Codes Updated");
}
});
This is what the JSON looks like that I am actually passing:
data[0][name] id[]
data[0][value]
data[1][name] code[]
data[1][value] zxc
data[2][name] exchange[]
data[2][value] 15
data[3][name] id[]
data[3][value]
data[4][name] code[]
data[4][value] BVA
data[5][name] exchange[]
data[5][value] 5
or the raw data:
action=update_codes&ResortId=12&data%5B0%5D%5Bname%5D=id%5B%5D&data%5B0%5D%5Bvalue%5D=&data%5B1%5D%5Bname%5D=code%5B%5D&data%5B1%5D%5Bvalue%5D=zxc&data%5B2%5D%5Bname%5D=exchange%5B%5D&data%5B2%5D%5Bvalue%5D=15&data%5B3%5D%5Bname%5D=id%5B%5D&data%5B3%5D%5Bvalue%5D=&data%5B4%5D%5Bname%5D=code%5B%5D&data%5B4%5D%5Bvalue%5D=BVA&data%5B5%5D%5Bname%5D=exchange%5B%5D&data%5B5%5D%5Bvalue%5D=5
I tried a method I found on SO but it didn't group the 3 fields together.
The following code should work:
var data = [];
var table = $("table").get()[0];
for (var i=0; i<table.rows.length; i++) {
var tableRow = table.rows[i];
var rowData = {};
var inputData = {};
inputData["id"] = $("input[id^='id']", $(tableRow.cells[1])).val();
inputData["code"] = $("input[id^='code']", $(tableRow.cells[1])).val();
inputData["exchange"] = $("select[id^='exchange']",$(tableRow.cells[2])).val();
rowData[$(tableRow.cells[0]).text()] = inputData;
data.push(rowData);
}
console.log(JSON.stringify(data));

Categories

Resources