good day;
i new in laravel and vue.js when i submit form if i have problem in validate one of input it show correctly like The Brand Name field is required. but my real problem is when submitted form successfully when i show response message that i get from controller **i get only one capital** **litter of message appear** only like ***Y*** like "Your Data Added Successfully" but i get the first litter isY` like attached photo that appear how can i solve this problem
thanks
here is my controller
<?php
namespace App\Http\Controllers;
use App\PhoneBook;
use Illuminate\Http\Request;
use Validator;
class PhoneBookController extends Controller
{
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\Response
*/
public function index()
{
//
return view('phonebook');
}
}
public function add(Request $request)
{
//prepare data for validation
$validationarray=Validator::make($request->all(),
[
'name' => 'required',
'phone' => 'required|min:2|required',
'email' => 'required',
]
,[],[
"name"=>"Brand Name",
'phone' => 'phone',
'email' => 'Email',
]);
if($validationarray->fails())
{
foreach ($validationarray ->messages()->getMessages() as $field_name =>$message):
$response['message']=$message;
endforeach;
$response['status']="failed";
return response()->json($response);
}
// start pass data to model
$branddata=array(
'name' =>$request->name,
'phone' =>$request->phone,
'email' =>$request->email,
);
// start add data
$add=PhoneBook::create($branddata)->id;
if(false !=$add)
{
return response(['status'=>'success',"message"=>"Your Data Added Successfully"]);
}else{
return response(['status'=>'failed',"message"=>"Error Adding data please try again !!"]);
}
}
then my route is
Route::post('phonebook/add',"PhoneBookController#add")->name("cart.deleteProductFromCart");
my view code template
<template>
<div>
<div class="modal fade" id="addData" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">New message</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<span v-if="list.status=='success'" >Record submitted successfully!</span>
<div v-model="list.message" >{{list.message?list.message[0]:''}}</div>
<div class="form-group">
<label for="exampleInputEmail1">Brand Name</label>
<input type="text" name="name" v-model="list.name" class="form-control" id="exampleInputEmail1" placeholder="Example : Kia - Renault">
<p class="help-block">Example : Kia - Renault</p>
</div>
<div class="form-group">
<label class="col-form-label">phone:</label>
<input type="text" name="phone" v-model="list.phone" class="form-control" id="reckipient-name">
<p class="help-block">Example : Kia - Renault</p>
</div>
<div class="form-group">
<label class="col-form-label">email:</label>
<input type="text" class="form-control" v-model="list.email" name="email" id="recikpient-name">
<p class="help-block">Example : Kia - Renault</p>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary" #click="save">Send message</button>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: "addData",
data: function () {
return {
list: {
name: '',
phone: '',
email: '',
message:'',
},
}
},
methods: {
save: function () {
axios.post('/phonebook/add',this.$data.list)
.then((response) => this.list.message=response.data.message)
.catch((error) => this.list.message=error.response.data.message)
}
}
}
</script>
<style scoped>
</style>
[![enter image description here][1]][1]
[1]: https://i.stack.imgur.com/sZpDS.png
It's good to pass response as JSON Format
YourXYZController.php
....
$data = new stdClass;
$data->status = "success";
$data->message = "your message";
return response(json_encode($data));
in Vuejs
axios.post('YourXYZController URL', params)
.then(response => {
console.log(response)
})
.catch(error => {
console.log(response)
})
})
And also it's best practice to check request and response in network tab of browser.
Related
My main idea is to show data from database and beside each row, there is an accept and reject button .onClick, the value of the button gets passed to controller and saved to database.so far so good, the issue is when I tried to add a popup modal that has input text to add a note . it should appear only when I click the reject button only. I opened the developer tools and found it passes the double of the whole number of the data rows and i don't know how to pass the id of the row I'm in, the value of the rejected button and finally the message that is going to be written to the controller. I tried to pass the modal in the reject button method in the controller but it passes as null. what am I doing wrong? is my script part is organized or even accurate after I added the ajax or not?
I appreciate any help.
my view:
#model AllmyTries.Models.fulfillmentVM
<!-- page content -->
#using (Html.BeginForm("Add_Fulfillment_Reject", "Feedback", FormMethod.Post))
{
#Html.AntiForgeryToken()
<td>
<button id="btnReject" class="btn btn-lg btn-danger" name="button" data-toggle="modal" data-target="#exampleModal" type="submit" onclick="reject(0)" value="0">Reject</button>
#Html.Hidden("Request_ID", Model._Requests[i].Request_ID)
#Html.Hidden("Status", Model._Requests[i].Status, new { id = "myEdit", value = "" })
</td>
<div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">New message</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<form id="myform">
<div class="form-group">
<textarea class="form-control" id="message-text"></textarea>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<input type="reset" value="submit" class="btn btn-success" id="finalSave" />
</div>
</div>
</div>
</div>
}
<!-- /page content -->
#section Scripts {
<script>
$('[name = "button"]').click(function () {
$('[name = "Status"]').val($('[name = "button"]').val());
})
$(document).ready(function () {
$('#finalSave').click(function () {
var dataform = $('#myform').serialize();
$.ajax({
type: 'POST',
url: '/Feedback/Add_Fulfillment_Reject',
data: dataform,
success: function () {
$('#exampleModal').modal('hide');
}
})
})
})
</script>
}
the controller:
#region fulfillment
[HttpPost]
public ActionResult Add_Fulfillment_Accept(int Request_ID, int? Status)
{
var user = db.TBL_Request.Find(Request_ID);
user.Inserted_by = Status ?? 0;
db.SaveChanges();
return RedirectToAction("Index");
}
//this is the one with the issue
[HttpPost]
public ActionResult Add_Fulfillment_Reject(fulfillmentVM vM)
{
//save the status
//save the note
db.SaveChanges();
return RedirectToAction("Index");
}
#endregion
}
Your Javascript submits only the textarea that is in the <form id="myForm"> to a controller action that is expecting a fulfillmentVM object. Change your Html.Hidden fields to Html.HiddenFor. This will bind those values on post.
Use a TextAreaFor instead of a textarea for model binding, and make sure your viewmodel has an appropriate property for it.
#Html.HiddenFor(m => m._Requests[i].Request_ID)
#Html.HiddenFor(m => m._Requests[i].Status, new { id = "myEdit", value = "" })
#Html.TextAreaFor(m => m.RejectMessage, htmlAttributes: new { #class = "form-control" })
Remove the <form id="myForm"> tags, they're unnecessary.
Keep the button as a submit button, and it will post to the Add_Fulfillment_Reject controller, passing all the bound values for your fulfillmentVM.
Where to put the form
Personally, I would put it starting right before the text box, move the hidden fields down there, too. End it right after the submit button.
#using (Html.BeginForm("Add_Fulfillment_Reject", "Feedback", FormMethod.Post))
{
#Html.HiddenFor(m => m._Requests[i].Request_ID)
#Html.HiddenFor(m => m._Requests[i].Status, new { id = "myEdit", value = "" })
#Html.TextAreaFor(m => m.RejectMessage, htmlAttributes: new { #class = "form-control" })
// rest of modal code
<input type="submit" class="btn btn-success" id="finalSave" />
} // end form
I dont know whats happening with my code in the controller. I just want to send an email based on the select option from my vue component. It just says undefined variable request. Im using vform package from vue. But in my controller I already defined the request variable with with the id of the select option from my vue component. But when I put some static email, it can send email and it worked. Can someone know what is the solution? Thanks.
Error in preview in network tab
{message: "Undefined variable: request", exception: "ErrorException",…}
exception: "ErrorException"
file: "C:\Users\bustillo-ronald\Desktop\Laravel-SPA\app\Http\Controllers\API\UserController.php"
line: 196
message: "Undefined variable: request"
trace: [,…]
My controller
public function sendEmail(Request $request){
$beautymail = app()->make(\Snowfire\Beautymail\Beautymail::class);
$beautymail->send('emails.welcome', [], function($message)
{
$message
->from('test#gmail.com')
//->to('sampleemail#gmail.com')//this is working with static data
->to($request->email)
->subject('Welcome!');
});
}
My vue component with vform
<form #submit.prevent="sendEmail()">
<div class="modal-body">
<div class="form-group">
<label>Users Lsit</label>
<select v-model="form.email" name="email" id="email" class="form-control" :class="{ 'is-invalid': form.errors.has('email') }">
<option v-for="user in users.data" :key="user.id" >{{user.email}}</option>
</select>
<has-error :form="form" field="type"></has-error>
</div>
<div class="form-group">
<label>Message</label>
<textarea v-model="form.message" name="message" placeholder="Message" class="form-control" :class="{ 'is-invalid': form.errors.has('message') }"></textarea>
<has-error :form="form" field="message"></has-error>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="submit" class="btn btn-primary">Send Email</button>
</div>
</form>
The script.
export default {
data() {
return {
form: new Form({
id:'',
email: '',
message: ''
}),
users: []
}
},
methods: {
getUsers() {
axios.get('api/user')
.then((res) => {
this.users = res.data
})
},
sendEmail(){
this.form.post('api/sendemail')
.then(()=>{
$('#exampleModal').modal('hide');
$(".modal-backdrop").remove();
swal.fire("Email sent!", "", "success");
})
.catch((e)=>{
console.log(e)
})
}
},
created() {
this.getUsers();
console.log('Component mounted.')
}
}
Vue devtools
you are not passing the $request variable inside the closure.
public function sendEmail(Request $request){
$beautymail = app()->make(\Snowfire\Beautymail\Beautymail::class);
$beautymail->send('emails.welcome', [], function($message) use($request) // add use($request)
{
$message
->from('test#gmail.com')
//->to('sampleemail#gmail.com')//this is working with static data
->to($request->email)
->subject('Welcome!');
});
}
On trying to update data in the array from the modal box. The data is not updated in the dom v-for list.
The following consists of modal and details. The data is entered in the modal box which updates the data in details. The cdata is an array which is updated through out the process. When the data is entered in the modal box. This data is pushed in the cdata. Which should update the details v-for loop but it is not happening rather. I tried updating by listening thru events still there's no effects.
data.vue
export default {
props: ["c-data"],
data: function() {
return {};
},
mounted: function() {},
methods: {}
};
<template>
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#aModal">Add </button>
<data-detail :cdata="cData"></data-detail>
<add-modal :cdata="cData"></add-modal>
</template>
The following contains code for add modal which updates the data in cData array which is data entered in the data modal.
add-modal.vue
export default {
props: ["c-data"],
data: function() {
return {
cName: "",
cEmail: ""
};
},
mounted() {
console.log(this.cData);
},
methods: {
addC() {
this.cData.push({ cName: this.cName, cEmail: this.cEmail });
console.log(this.cData);
this.$root.$emit("cEvent", this.cData);
}
}
};
<template id="add-modal">
<div class="modal fade" id="aModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog modal-large" role="document">
<div class="modal-content">
<div class="modal-body">
<div class="box">
<div class="row">
<div class="form-group col-sm-6 col-lg-6 col-xl-4">
<div class="input-section">
<input type="text" name="cName" class="form-control" id="c-name" v-model="cName" placeholder="Enter name" value="" required>
<label for="c-name"> Name*</label>
</div>
</div>
<div class="form-group col-sm-6 col-lg-6 col-xl-4">
<div class="input-section">
<input type="text" v-model="cEmail" name="cEmail" class="form-control" id="c-email" placeholder="Enter email" required>
<label for="c-email"> Email*</label>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-outline-primary" data-dismiss="modal">Close</button>
<button type="button" #click="addC" class="btn btn-primary">Save</button>
</div>
</div>
</div>
</div>
</template>
The follow consists of list of v-for which needs to be updated but are not updating.
export default {
props: ["c-data"],
data: function() {
return {};
},
mounted() {
console.log(this.cData);
},
methods: {}
};
<div v-for="(item, i) in cData" :key="item.id">
{{item.name}}
</div>
I have tried to update it thru listening events but no results as cData was already update in the data component.
You should never directly manipulate data that is passed in as a property.
Using events was the right way to go, you just have to de-couple the newly added data from the properties object.
Use
this.$emit("cEvent", { name: this.cName, email: this.cEmail } );
And listen for it in the parent component
<add-modal :cdata="cData" #cEvent="handleNewData"></add-modal>
...
handleNewData(d) {
this.cData.push(d);
}
Your cData object should only be manipulated directly by the actual owner of that data i.e. the parent where the cData object originates from, not in any component where you pass it in as a property.
Full working example that you can use as a reference: https://codesandbox.io/s/n4lk7rmxx4
I'm writing a webpage using .Net Core and I recently started using jQuery within my webpage.
PartialView shown in <div id="details"></div>
#model Program.Models.Device
<dl>
<dt>
#Html.DisplayNameFor(model => model.Alias)
</dt>
<dd>
#Html.DisplayFor(model => model.Alias)
</dd>
<dt>
#Html.DisplayNameFor(model => model.Log)
</dt>
<dd>
<a data-toggle="modal" data-target="#logData">Open</a>
<div class="modal fade" id="logData" tabindex="-1" role="dialog" aria-labelledby="logDataLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title" id="myModalLabel">Log for #Html.DisplayFor(model => model.Alias)</h4>
</div>
<div class="modal-body">
#Html.TextAreaFor(m => m.Log, htmlAttributes: new { #class = "form-control", #id = "logTextArea", #placeholder = "Log is empty" })
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
#*This will be used to find the deviceID*#
#Html.HiddenFor(m => m.DeviceID, new { #class = "deviceID" })
<button type="button" class="btn btn-primary" id="save">Save changes</button>
</div>
</div>
</div>
</div>
</dd>
</dl>
To give a general idea of what I will be using the modal for it is for updating a log from one of my models called a Device. The textarea will hold the log for the Device and that is working as intended. However I want to write a JavaScript/jQuery function that takes the text from the textarea and passes it to a function in my controller:
.CS function
public void UpdateLog(int id, string logText)
{
Device device = new Device { DeviceID = id, Log = logText };
_context.Devices.Attach(device);
_context.Entry(device).Property(x => x.Log).IsModified = true;
_context.SaveChanges();
}
JQuery click code
$('#details').on('click', '#save', function () {
var text = $("#logTextArea").val();
var id = $(this).siblings('deviceID').val(); //Getting deviceID
//Running C# method somehow?
});
How would I got about getting the DeviceID in the best manner? EDIT: See modal code and jQuery
Furthermore I've found that to run my controller function I need an #Url.Action('<function name>', '<controller name>') but how do I pass variables to such a function as I now would have the log and the id required for the function?
EDIT:
Code has undergone some changes now and I am getting the deviceID now (was previously misunderstanding with vehicleID). My only problem is how to run the .CS function and passing in the two parameters to my .CS function in my jQuery click code.
Thanks!
You need to make an ajax call to post that data (assuming you want to stay in the same page).
You should start by wrapping your form controls inside a <form> tag and adding #Html.ValidationMessageFor(m => m.Log) and change the button to type="submit" so that you get (and can check) client side validation before posting the data.
<div class="modal-dialog" role="document">
<div class="modal-content">
...
<form>
<div class="modal-body">
#Html.HiddenFor(m => m.DeviceID)
#Html.TextAreaFor(m => m.Log, htmlAttributes: new { #class = "form-control", #placeholder = "Log is empty" })
#Html.ValidationMessageFor(m => m.Log)
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</form>
</div>
</div>
Then the script will be
var url = '#Url.Action("UpdateLog")'; // assumes its the same controller that generated the view
$('#details').on('submit', 'form', function () { // handle to forms submit() event
if (!$(this).valid()) {
return; // cancel (the validation message will be displayed)
}
var data = $(this).serialize()
$.post(url, data, function(response) {
// do something with the response
})
return false; // cancel the default submit
});
Your POST method will then be public ActionResult UpdateLog(int id, string log), however to catch server side validation, you should create a view model decorated with the necessary validation attributes
public class DeviceLogVM
{
public int ID { get; set; }
[Required(ErrorMessage = "..")] // add StringLength etc as needed
public string Log { get; set; }
}
so that the method becomes
public ActionResult UpdateLog(DeviceLogVM model)
so that you can check if ModelState is invalid before saving. Note also that the method should be ActionResult so that you can return something back to the client indicating success or otherwise.
You can do ajax call like:
var data={
logText:text,
id :id
};
$.post('ControllerName/UpdateLog',data)
.done(function(data){
//When success return logic
}).fail(function(xhr){
//if request failed
});
I am trying to edit and delete a data in Mongo.Collection. I have a document with a number of fields including an email address.
I check while updating the data if email exists just update the email else first create a user with that email using Accounts.createUser and then update the data. Although the data is being updated successfully in the database but showing it using the helpers is not working properly. I am trying to fill the form with the saved values, either form comes half-filled, or completely-filled(usually in the first edit attempt) or completely empty. I cannot understand the reason behind this beviour.
The form template
<template name="addUnit">
<div class="modal fade" id="addUnitModal" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title">{{#if isEdit}}Edit {{else}}Add {{/if}}Unit</h4>
</div>
{{#if tenantError}}
<div class="alert alert-danger" role="alert">{{tenantError}}</div>
{{/if}}
<form class="frmUnit" id="frmUnit">
<div class="modal-body">
<input class="form-control" type="text" placeholder="Unit Name" name="unitName" value="{{selectedUnit.unitName}}"/>
<input class="form-control" type="number" placeholder="Number of Residents" name="residents" value="{{selectedUnit.residents}}"/>
<input class="form-control" type="number" placeholder="Area sqft." name="area" value="{{selectedUnit.area}}"/>
<input class="form-control" type="text" placeholder="Primary Tenant" name="primaryTenant" value="{{selectedUnit.primaryTenant}}"/>
<input class="form-control" type="email" name="tenantEmail" placeholder="Tenant's Email" value="{{selectedUnit.tenantEmail}}"/>
<input class="form-control" type="password" name="tenantPassword" placeholder="Tenant's Password"/>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
{{#if isEdit}}
<button type="submit" class="btnEditUnit btn btn-primary">Edit Unit</button>
{{else}}
<button type="submit" class="btnAddUnit btn btn-primary">Add Unit</button>
{{/if}}
</div>
</form>
</div>
</div>
</div>
</template>
Helpers
Template.addUnit.helpers({
isEdit: function() {
return Session.get('isEdit');
},
tenantError: function(){
return Session.get('tenantError');
},
selectedUnit: function(){
return Session.get('selectedUnit');
}
});
Events
Template.addUnit.events({
"submit .frmUnit": function(event){
event.preventDefault();
var form = event.target;
if(!Session.get('isEdit')){
console.log('adding');
Meteor.call('addUnit',
Session.get('selectedBuilding')._id,
{
unitName: form.unitName.value,
primaryTenant: form.primaryTenant.value,
tenantEmail: form.tenantEmail.value,
tenantPassword: form.tenantPassword.value,
residents: form.residents.value,
area: form.area.value
}, function(error, result) {
console.log(error, result);
if(!error){
$('#frmUnit')[0].reset();
$('#addUnitModal').modal('hide');
Session.set('tenantError', null);
}else{
Session.set('tenantError', error.reason);
}
});
}else{
console.log('editing');
Meteor.call('editUnit',Session.get('selectedUnit')._id,{
unitName: form.unitName.value,
primaryTenant: form.primaryTenant.value,
residents: form.residents.value,
area: form.area.value,
tenantEmail: form.tenantEmail.value,
tenantPassword: form.tenantPassword.value
}, function(error, result) {
if(!error) {
$('#frmUnit')[0].reset();
$('#addUnitModal').modal('hide');
}else{
Session.set('tenantError', error.reason);
}
});
}
}
});
Edit unit on the server
editUnit: function(unitId, unit){
//if the email entered already exists update the email and password
var updatedTenant = Accounts.findUserByEmail(unit.tenantEmail);
if(updatedTenant){
if(unit.tenantPassword && unit.tenantPassword !== ""){
Accounts.setPassword(updatedTenant._id, unit.tenantPassword);
}
Units.update({_id: unitId},
{
$set :{
unitName:unit.unitName,
primaryTenant:unit.primaryTenant,
residents: unit.residents,
area: unit.area,
tenantEmail: unit.tenantEmail
}
});
}else{
//if email doesn't exist already, create a new user first
var newUserId = Accounts.createUser(
{
email: unit.tenantEmail,
password: unit.tenantPassword,
profile:{
firstname: unit.primaryTenant,
lastname:"",
phone:"",
isTenant:true
}
});
if(newUserId){
Units.update({_id: unitId},
{
$set :{
unitName:unit.unitName,
primaryTenant:unit.primaryTenant,
residents: unit.residents,
area: unit.area,
tenantEmail:unit.tenantEmail
}
});
}
}
},
Session.get('selectedUnit') is being set from a different click handler, which displays the form. The value is being set correctly I can see that by logging it to the console.
'isEdit' is also being set from a click handler of a different template.
I have other forms working with the same approach, but they don't have Account creation and validation in them. Is it because of that?
Edit
Template.owner.events({
"click .editUnit":function(){
Session.set('isEdit', true);
Session.set('selectedUnit', this);
}
});
{{#each buildingUnits}}
<tr>
<td>
{{unitName}}
</td>
<td>
<span class= "editUnit list-icon glyphicon glyphicon-edit" data-target="#addUnitModal" data-toggle="modal" aria-hidden="true" style="padding-right: 4px;"></span>
<span class= "deleteUnit list-icon glyphicon glyphicon-remove" aria-hidden="true"></span>
</td>
</tr>
{{/each}}
I have tried to log this onto the console, I am getting the correct result, just after the two lines I tried to get the session back using Session.get('selectedUnit') and tried logging it to console, this also gives me the correct result, which means session is being successfully set.