Laravel only gets checked items from checklist - laravel

I have form with multiple input data and checklists but in controller I'm just getting checked items and no result for unchecked items.
This is what I get
"send_mail" => array:2 [▼
0 => "on"
1 => "on"
]
This is what I need
"send_mail" => array:2 [▼
0 => "off"
1 => "on"
2 => "off"
3 => "on"
]
Blade
<form enctype="multipart/form-data" action="{{route(''xxxxxxxx)}}" method="POST">
#csrf
#method('POST')
<input name="name" id="name" class="form-control">
<div class="form-check">
<input class="form-check-input" checked type="checkbox" name="send_mail[]">
<label class="form-check-label">Send Mail</label>
</div>
<div id="newRows">
// new rows (same as above) will add here by javascript
</div>
<button type="submit" class="btn btn-primary">Send</button>
</form>
Controller
public function test(Request $request) {
dd($request->all());
}

By default <input type="checkbox"> won't return if it hasn't been checked.
A classic method of fixing this is to duplicate the checkbox with a hidden input:
<input type="hidden" name="send_mail" value="0" />
<input type="checkbox" name="send_mail" value="1" />
This would require, however, moving away from the array of checkboxes you currently have.
The alternative is to use Javascript to submit your form.

I faced a similar scenario back then. I managed to solve it by using JavaScript (jQuery to be specific) to submit the form.
I wrote up a reusable function to append the unchecked items.
Reusable function:
const prepareJQCheckboxFormData = (jQForm, jQSerializedFormData, checkboxNameAttr) => {
let name;
let data = [];
checkboxNameAttr?.substr(-2) === "[]"
? name = checkboxNameAttr
: name = `${checkboxNameAttr}[]`;
let hasItem = false;
jQForm.find("input[name='" + name + "']")
.add(jQForm.find("input[name='" + name?.substr(0, name.length - 2) + "']"))
.each(function () {
if (($(this).attr("checked") === true) || $(this).is(":checked")) {
hasItem = true;
}
});
if (!hasItem) {
jQSerializedFormData.push({
name, value: [""]
});
}
$(jQSerializedFormData).each(function (i, field) {
if (field.name !== name?.substr(0, name.length - 2)) {
data.push(field);
} else {
data.push({
name: `${field.name}[]`,
value: field.value
});
}
});
return data;
};
Form submission:
Assuming that the form 'id' is 'mail-form'
const form = $("#mail-form");
const btnSave = $("#mail-form button[type='submit']");
btnSave.click(function (e) {
e.preventDefault();
$.ajax({
type: form.attr("method"),
url: form.attr("action"),
processData: false, // Important for multipart-formdata submissions!
contentType: false, // Important for multipart-formdata submissions!
cache: false,
data: prepareJQCheckboxFormData(form, form.serializeArray(), "send_mail[]"),
success: function (response) {
// ...
},
error: function (jqXHR) {
// ...
},
beforeSend: function () {
// ...
}
});
});

<div class="form-check">
<input type="checkbox" name="send_mail[]">
<label>Name1</label>
</div>
<div class="form-check">
<input checked type="checkbox" name="send_mail[]">
<label>Name2</label>
</div>
(another 2 div tag here)

Related

Laravel AJAX getting all records in one JSON request

i am trying to edit record in my database using ajax, my code is working fine, but i have to mention each column by name, how i can get same result without typing all columns name.
Edit Controller: i am using columns name [efirst,esecond etc] i want to pass everything from database without mentioning name
public function edit($id)
{
$teacher = Teacher::find($id);
return response()->json([
'status' => 'success',
'id' => $teacher->id,
'efirst' => $teacher->efirst,
'esecond' => $teacher->esecond,
]);
}
Edit.js:
jQuery(document).ready(function($) {
$(".table-container").on("click touchstart", ".edit-btn", function () {
$.ajax({
type: "GET",
url: "lists/" + $(this).attr("value") + "/edit",
dataType: 'json',
headers: { 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') },
beforeSend: function() {
$('#esecond-not-found').remove();
},
success: function (data) {
$("#update-id").val(data['id']);
$("#update-efirst").val(data['efirst']);
$("#update-esecond").val(data['esecond']);
$('#update-form').show();
},
});
});
});
View:
<form method="post" id="update-form">
{{ method_field('PATCH') }}
<input type="hidden" name="id" id="update-id">
<div class="">
<label for="efirst">efirst</label>
<input type="text" class="form-control" name="efirst" id="update-efirst">
<label for="esecond">esecond body</label>
<textarea name="esecond" class="form-control" id="update-esecond" rows="6"></textarea>
</div>
<div class="">
<button type="submit" class="btn btn-success" id="update-submit">Update</button>
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</form>
A teacher object can be passed instead of writing every table field
return response()->json([ 'status' => 'success', 'teacher' => $teacher ]);
So in order for this code to work the id of the form needs to match the name of the column
let teacher = Object.entries(data.teacher);
teacher.forEach(item => { $("#"+item[0]).val(item[1]); });
Let's say we have four inputs
<input id="data1" type="text" class="form-control">
<input id="data2" type="text" class="form-control">
<input id="data3" type="text" class="form-control">
<input id="data4" type="text" class="form-control">
and you do this
success: function (data) {
let teacher = Object.entries(data.teacher);
teacher.forEach(item => {
console.log(item)
$("#"+item[0]).val(item[1]);
});
}
the console log gives the following
(2) ["data1", "test1"]
(2) ["data2", "test2"]
(2) ["data3", "test3"]
(2) ["data4", "test4"]
you get an array of arrays that you can loop where the index position 0 is your input id and the index position 1 is your value.

Display Multidimensional array via ajax in laravel

The form displays data from DB for the entry to be edited. One of the columns is a 2D Array and I do not know how to pass the data.
Tried the normal AJAX display codes
The data coming via COntroller is:
res.credential looks like
[
[
"Facebook","x11111111",
"q1111111","w11111111"
],
[
"Linkedin","x222222222",
"q222222","w222222222222"
],
[
"Twitter","x333",
"q3333333","w3333333"
]
]
The AJAX looks like:
$('.password-edit-btn').on('click', function (){
var client_sel = $(this).data('id');
if (client_sel) {
$.ajax({
type: "GET",
url: "/get_password_data?id="+client_sel,
success: function (res) {
if (res) {
console.log(res.credential);
$("#edit-password-client").empty();
$("#edit-password-client").append('<option>'+ res.client +'</option>');
$('#edit-password-remarks').val(res.remarks);
}
// The problematic area is below
if (res.credential) {
$.each(res.credential, function (key, value) {
console.log(value)
$(".add-hf-accounts").append()
});
}
}
});
}
});
Simply display the data in the div with class "add-hf-accounts".
$.each(res.credential, function (key, value) {
for(var i=0;i<value.length;i++)
{
if(i==0)
{
$(".add-hf-accounts").append('<h2>'+value[i]+'</h2>');
}
$(".add-hf-accounts").append('<li>'+value[i]+'<li>');
}
});
Try It...Will be Work Fine
Thanks a lot for the help guys.
The problem was in parsing. I had to use JSON.parse and then it worked beautifully. Below is the final working answer.
if (res.credential) {
$.each(JSON.parse(res.credential), function (key, value) {
$(".add-hf-accounts").append('<div class="hidden_event"><div class="form-group col-sm-2"><label>Account</label><select class="form-control" name="account[]"><option value="'+ value[0] +'"> '+ value[0] +'</option></select></div><div class="form-group col-sm-3"><label>URL</label><input type="text" class="form-control" placeholder="Accoutn URL" name="url[]" value="'+ value[1] +'"></div><div class="form-group col-sm-3"><label>Username</label><input type="text" class="form-control" placeholder="User Name" name="user[]" value="'+ value[2] +'"></div><div class="form-group col-sm-3"><label>Password</label><input type="text" class="form-control" placeholder="Password" name="password[]" value="'+ value[3] +'"></div><div class="form-group col-sm-1 acc-btn"> <br><button class="btn btn-danger remove " type="button"><i class="glyphicon glyphicon-remove"></i></button></div></div>');
});
}

Autocomplete dropdown in codeigniter doesn't works

I'm still new using jquery in codeigniter so i hope you can gladly help me.
I want to create autocomplete dropdown where when one option of autocomplete is selected, it will show other related fields.
The output become like this, there's no value to display
And this is my codes :
Model
function search_mtk($kode_mtk){
$this->db->like('kode_mtk', $kode_mtk , 'both');
$this->db->order_by('kode_mtk', 'ASC');
$this->db->limit(5);
return $this->db->get('m_mata_kuliah')->result();
}
Controller
public function get_mtk(){
if (isset($_GET['term'])) {
$result = $this->kit_model->search_mtk($_GET['term']);
if (count($result) > 0) {
foreach ($result as $row)
$arr_result[] = array(
'kode' => $row->kode_mtk,
'nama' => $row->nama_mtk,
);
echo json_encode($arr_result);
}
}
}
<script type="text/javascript">
$( "#kode_mtk" ).autocomplete({
source: "<?php echo base_url('fak/kit/get_mtk/?');?>",
select: function (event, ui) {
$('[name="kode_mtk"]').val(ui.item.kode);
$('[name="nama_mtk"]').val(ui.item.nama);
}
});
});
</script>
<?php echo form_open_multipart('fak/kit/file_data');?>
<div class="form-group">
<label for="program">Kode Matakuliah <span style="color:#FF0000">*</span>:</label>
<input type="text" class="form-control" id="kode_mtk" name="kode_mtk" placeholder="Type course code" />
</div>
<div class="form-group">
<label for="program">Nama Matakuliah<span style="color:#FF0000">*</span>:</label>
<input type="text" class="form-control" name="nama_mtk" placeholder="Type course name" />
</div>
<button type="submit" class="btn btn-success">Submit</button>
I hope anyone can help me with this.
Your code seems working fine but the label value not showing in the drop-down. just add value and label key value in the array to check its working or not.
Your code should be like below
$arr_result[] = array(
'kode' => $row->kode_mtk,
'nama' => $row->nama_mtk,
'value' => $row->nama_mtk,
'label' => $row->nama_mtk,
);
also, add the following call back function inside autocomplete jquery function
$( "#kode_mtk" ).autocomplete({
source: "<?php echo base_url('fak/kit/get_mtk/?');?>",
select: function (event, ui) {
$('[name="kode_mtk"]').val(ui.item.kode);
$('[name="nama_mtk"]').val(ui.item.nama);
},
response: function(event, ui){
if(ui.content.length === 0){
console.log('No results loaded!');
}else{
console.log('success!');
}
},
});
});

How to send input hidden in React JS?

I have this form, and I would like to send these values. I know we have to use setState() to store data but how does it work for input type="hidden"?
First question: How to store input hidden to setState ?
Second question: How to serialize data like form.serialize() ?
Third question: How to send these serialize values? Ajax or Axios, who is the better?
Here is the code:
handleSubmit(e) {
e.preventDefault();
/**
$.ajax({
url: "post.php",
type: "POST",
data: DATA,
success:function(data) {
}
});
**/
}
<form onSubmit={this.handleSubmit}>
<input type="hidden" name="action" value="login" />
<input type="email" name="email_user" placeholder="Email" />
<input type="password" name="password_user" placeholder="Mot de passe" />
<button type="submit">Login</button>
</form>
The answer is complex for all your questions.
First of all, it depends on the task: if you just want to send asynchonous request to server on form submit, you don't need to use Component state. Here is a link to the relevant section of the documentation. And use refs to access inputs data.
class FormComponent extends React.Component {
constructor(props) {
super(props);
this.onSubmit = this.onSubmit.bind(this);
}
onSubmit(e) {
e.preventDefault();
// Send your ajax query via jQuery or Axios (I prefer Axios)
axios.get('your_url', {
params: {
action: this.actionInput.value,
email: this.emailInput.value,
password: this.passwordInput.value,
}
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
}
render() {
return (
<form onSubmit={this.onSubmit}>
<input type="hidden" name="action" value="login"
ref={(input) => { this.actionInput = input }} />
<input type="email" name="email_user" placeholder="Email"
ref={(input) => { this.emailInput = input }}/>
<input type="password" name="password_user" placeholder="Mot de passe"
ref={(input) => { this.passwordInput = input }}/>
<button type="submit">Login</button>
</form>
);
}
}
All data can be stored on React's state, but if you still need to have inputs on your form you can do something like this:
const handleSubmit = e => {
e.preventDefault();
const inputs = Object.values(e.target)
.filter(c => typeof c.tagName === 'string' && c.tagName.toLowerCase() === 'input')
.reduce((acc, curr) => ({ ...acc, [curr.name]: curr.value }), {});
setFormVals({ ...formVals, ...inputs });
}
See the demo below:
const Demo = () => {
const [formValues] = React.useState({});
const handleSubmit = e => {
e.preventDefault();
const inputs = Object.values(e.target)
.filter(c => typeof c.tagName === 'string' && c.tagName.toLowerCase() === 'input')
.reduce((acc, curr) => ({ ...acc, [curr.name]: curr.value }), {});
console.log(inputs);
}
return (
<form onSubmit={handleSubmit}>
<input name="name" placeholder="Name" value={formValues.name} />
<input name="email" placeholder="Email" value={formValues.email} />
<input name="hiddenInput" value="hiddenValue" type="hidden" />
<button type="submit">Submit</button>
</form>
);
}
ReactDOM.render(<Demo />, document.getElementById('demo'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.0/umd/react-dom.production.min.js"></script>
<div id="demo"></div>
If you know what the inputs that you need you can do something like this:
const Demo = () => {
const formRef = React.useRef(null);
const [formValues, setFormValues] = React.useState({});
const handleChange = e => {
setFormValues({
...formValues,
[e.target.name]: e.target.value,
});
}
const handleSubmit = e => {
e.preventDefault();
setFormValues({ ...formValues, hiddenInput: formRef.current.hiddenInput.value });
}
return (
<form onSubmit={handleSubmit} ref={formRef}>
<input name="name" placeholder="Name" value={formValues.name} onChange={handleChange} />
<input name="email" placeholder="Email" value={formValues.email} onChange={handleChange} />
<input name="hiddenInput" value="hiddenValue" type="hidden" />
<button type="submit">Submit</button>
<pre>{JSON.stringify(formValues, null, 2)}</pre>
</form>
);
}
ReactDOM.render(<Demo />, document.getElementById('demo'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.0/umd/react-dom.production.min.js"></script>
<div id="demo"></div>
Answering your questions:
Since you know how to use component's state you may set the value as : <input type='text' value={this.state.foo} /> or even via props passing <input type='hidden' value={this.props.foo} />
You don't need to serialise anything at all. Use your component's local state or even a state container like Redux or Flux in order to pick the appropriate data. Take a look at this fairly simple example:
var SuperForm = React.createClass({
getInitialState() {
return {
name: 'foo',
email: 'baz#example.com'
};
},
submit(e){
e.preventDefault();
console.log("send via AJAX", this.state)
},
change(e,key){
const newState = {};
newState[key] = e.currentTarget.value;
this.setState(newState)
},
render: function() {
return (
<div>
<label>Name</label>
<input
onChange={(e) => this.change(e,'name')}
type="text"
value={this.state.name} />
<label>Email</label>
<input
onChange={(e) => this.change(e,'email')}
type="text"
value={this.state.email} />
<button onClick={this.submit}>Submit</button>
</div>
);
}});
Demo
AJAX is a set of web development techniques while Axios is a JavaScript framework. You may use jQuery, Axios or even vanilla JavaScript.

Client-Side form validation with Vue 2

I am developing an application with with Laravel 5.3 and Vue 2 I implemented a form-validation via Vue 2 but the it doesn't check the request for any errors on client-side it firstly lets every single request to be sent to the server and then displays the errors which are sent back from the server, in the following you can find my code
class Form {
constructor(data) {
this.originalData = data;
for (let field in data) {
this[field] = data[field];
}
this.errors = new Errors();
}
data() {
let data = {};
for (let property in this.originalData) {
data[property] = this[property];
}
return data;
}
reset() {
for (let field in this.originalData) {
this[field] = '';
}
this.errors.clear();
}
post(url) {
return this.submit('post', url);
}
submit(requestType, url) {
return new Promise((resolve, reject) => {
axios[requestType](url, this.data())
.then(response => {
this.onSuccess(response.data);
resolve(response.data);
})
.catch(error => {
this.onFail(error.response.data);
reject(error.response.data);
});
});
}
onSuccess(data) {
alert(data.message);
this.reset();
}
onFail(errors) {
this.errors.record(errors);
}
}
and this is the `Vue class
` `new Vue({
el: "#form",
data: {
form: new Form({
name: '',
description: ''
})
},
methods: {
onSubmit() {
this.form.post('/admin/category');
//.then(response => alert('Item created successfully.'));
//.catch(errors => console.log(errors));
},
onSuccess(response) {
alert(response.data.message);
form.reset();
}
}
});`
and this is my HTML form
<form method="post" id="form" action="{{ url('admin/category') }}" '
#submit.prevent="onSubmit" #keydown="form.errors.clear($event.target.name)">
{{ csrf_field() }}
<div class="form-group">
<label for="name">Name</label>
<input type="text" class="form-control" id="name" name="name"
v-model="form.name" placeholder="Name">
<span class="help is-danger"
v-if="form.errors.has('name')" v-text="form.errors.get('name')"></span>
</div>
<div class="form-group">
<label for="description">Description</label>
<textarea class="form-control" id="description" name="description"
v-model="form.description" placeholder="Description"></textarea>
<span class="help is-danger"
v-if="form.errors.has('description')"
v-text="form.errors.get('description')"></span>
</div>
<button type="submit" class="btn btn-default" :disabled="form.errors.any()">Create New Category</button>
</form>
Question:
I need to modify the code in a way that firstly it checks on client side and if it finds any errors prevent the request from being sent to the server not letting every single request to be sent to server and then displays the errors sent back from the server
You can use any type of client side validation with your setup, just before you submit the form you can take the data from the Form class and validate it with vanilla javascript or any other validation library.
Let's use validate.js as an example:
in your onSubmit method you can do:
onSubmit() {
//get all the fields
let formData = this.form.data();
//setup the constraints for validate.js
var constraints = {
name: {
presence: true
},
description: {
presence: true
}
};
//validate the fields
validate(formData, constraints); //you can use this promise to catch errors
//then submit the form to the server
this.form.post('/admin/category');
//.then(response => alert('Item created successfully.'));
//.catch(errors => console.log(errors));
},

Resources