Console.log shows my element as an array instead of an element - javascript

I'm doing a view where the customer is able to edit items, it comes with a filter so he/she can select between the options given. Everytime I edit it and save it works, however, if I return to the edit section the text box is empty and even though it was saved. If i use the inspect tool, the Console shows this:
impuestos_compra: Array [ {…} ]
If I open it, this is the information displayed:
impuestos_compra: (1) […]
"$$hashKey": "object:87"
0: Object { id: 2, empresa_id: 6, nombre: "IVA", … }
​​
length: 1
​​
<prototype>: Array []
This is the <DIV> label where I display this:
<div class="form-group col-md-6">
<label>
Impuestos de Mario
</label>
<select ng-model="articulo.impuestos_compra" name="impuestos_compra" class="form-control input-lg" required>
<option value="">Seleccione impuesto de compra</option>
<option ng-repeat="item in impuestos_compra" value="#{{ item.abreviacion }}">#{{ item.abreviacion }}</option>
</select>
</div>
In my try to iterate it, I did this code:
impuestos_compra = ['IVA' , 'IVAT0' ];
impuestos_compra.forEach(function(impuestos_compra) {
console.log(impuestos_compra);
});
And, finally, the controller from Laravel with the edit function looks like this:
public function edit($id)
{
$articulo = Articulo::with('sat_producto:clave,descripcion', 'sat_unidad:clave,descripcion')->findOrFail($id);
return view('panel.configuracion.articulo', [
'id' => $id,
'presentaciones' => Presentacion::select('nombre')->get()->toArray(),
'impuestos_compra' => Impuesto::select('abreviacion')->where('tipo' , 'compra')->get(),
]);
What am'I doing wrong? I tried ->get()->toArray() and it works neither.
Thanks in advance.

I think the problem is in your impuestos_compra initialization. You can try pluck instead of select. Pluck returns the value of the column as a collection. Try the following code.
public function edit($id)
{
$articulo = Articulo::with('sat_producto:clave,descripcion', 'sat_unidad:clave,descripcion')->findOrFail($id);
return view('panel.configuracion.articulo', [
'id' => $id,
'presentaciones' => Presentacion::select('nombre')->get()->toArray(),
'impuestos_compra' => Impuesto::where('tipo' , 'compra')->pluck('abreviacion')->toArray(),
]);
}

Related

Changing exists rule based on choosen option

So i have this simple code to input value based on database value in registration form and it's work great,
The code below located at register.blade.php
This for selecting branch
<div class="form-group form-material floating">
<select class="form-control" name="branch" id="branch">
<option value="1">Option A</option>
<option value="2">Option B</option>
</select>
<label class="floating-label" for="inputStatus">Branch</label>
</div>
This one for inputing reference
<div class="form-group form-material floating {{ $errors->has('reference') ? ' has-error' : '' }}">
<input type="text" class="form-control empty" id="reference" name="reference">
<label class="floating-label" for="inputStatus">Reference</label>
#if ($errors->has('reference'))
<span class="help-block">
<strong>{{ $errors->first('reference') }}</strong>
</span>
#endif
</div>
the code below located atRegisterController.php
And this one for validation
protected function validator(array $data)
{
return Validator::make($data, [
'name' => 'required|string|max:255',
'email' => 'required|string|email|max:255|unique:users',
'password' => 'required|string|min:6|confirmed',
'phone' => 'required|string|min:5|max:20',
'rate' => 'required',
'product' => 'required',
'branch' => 'required',
'reference' => [
'required',
Rule::exists('references')->where(function ($query) {
if( 'branch' == 1 ){
$query->where('references.type', '=', "TOP");
}
else{
$query->where('references.type', '=', "BOTTOM");
}
}),
],
]
);
}
In registration form when user choose the first option on branch, the user can only write (Example : 'ABC', 'DEF', 'GHI') if the user write another value it will return Error Message : 'Wrong reference code', but when the user choose second option on branch, the user can only write (Example : '123', '456', '789'), , does anyone have and idea how to do it? Thanks
Edit 1 :
The code above works fine, but the exists rule for reference is not working, user still able to input 'ABC', 'DEF', or 'GHI' when choosing second option.
Edit 2 :
I also have this custom validation inside register.blade.php
fields: {
reference: {
validators: {
notEmpty: {
message: 'Reference must be filled'
},
stringLength: {
max: 8,
message: 'Max 8 character'
}
}
}
}
For this you need Custom Validation .Custom Validation . and about query, you can do that inside
public function passes($attribute, $value){
//value will have your reference value
//Logic here and return true/false
}
public function message()
{
//error message
//return "The :attribute value doesnt exist.";
}
and if you want to pass parameters in custom rule then you need to use constructor and use it . i.e
protected $customParams;
public function __construct($customParams)
{
$this->customParams = $customParams;
}
and rules would look like this
'reference' => ['required',new CustomRule('customvalue')]
Hope this helps.
You can make custom validation. So you can move this extra validation inside your custom validation. May be it can solve your problem.
Refer this for more on custom validation: Laravel custom validation
Hope it helps:)

AngularJS ng-repeat questions and init inputs with matching answer object

I am using an ng-repeat to repeat through questions provided by an ajax response and I need the ng-model of each question input to point to a separate answers array.
The question array looks like this
bookingQuestions: [
0: {
label: 'Any allergies?',
type: 'text',
id: 1234
},
1: {
label: 'Names of attendees',
type: 'text',
id: 1235
}
]
I create the answers array by looping through all the questions and pushing the id and an empty answerValue property into my empty bookingAnswers array. The answers array looks like this:
bookingAnswers: [
0: {
id: 1234,
answerValue: ''
},
1: {
id: 1235,
answerValue: ''
}
]
In the markup, I'm attempting to init the answerObj by getting the correct answer object to match the corresponding question.
<div class="question" ng-repeat="question in bookingQuestions">
<label class="question-label" for="{{question.id}}">{{question.label}}
</label>
<input type="text" name="{{question.id}}" ng-model="answerObj"
ng-init="answerObj = getAnswerObj(question)">
</div>
The JS function:
$scope.getAnswerObj = function(question) {
angular.forEach(bookingAnswers, function(answer) {
if(question.id === answer.id) {
return answer.answerValue;
}
});
}
Even though the JS function successfully returns the correct object property, the ng-model isn't being updated to use it. How do I get this working?
You bind the ng-model of all your inputs to some answerObj meaning they all point to the same variable. Using $index you can access the index of the current iteration. So you could do something like this:
<input type=“text“ name="{{question.id}}"
ng-model="bookingAnswers[$index].answerValue"> </div>
<div class="question" ng-repeat="question in bookingQuestions">
<label class="question-label" for="{{question.id}}">{{question.label}}
</label>
̶<̶i̶n̶p̶u̶t̶ ̶t̶y̶p̶e̶=̶"̶t̶e̶x̶t̶"̶ ̶n̶a̶m̶e̶=̶"̶{̶{̶q̶u̶e̶s̶t̶i̶o̶n̶.̶i̶d̶}̶}̶"̶ ̶n̶g̶-̶m̶o̶d̶e̶l̶=̶"̶a̶n̶s̶w̶e̶r̶O̶b̶j̶"̶
<input type="text" name="{{question.id}}" ng-model="answerObj.answerValue"
ng-init="answerObj = getAnswerObj(question)" />
</div>
$scope.getAnswerObj = function(question) {
angular.forEach(bookingAnswers, function(answer) {
if(question.id === answer.id) {
̶r̶e̶t̶u̶r̶n̶ ̶a̶n̶s̶w̶e̶r̶.̶a̶n̶s̶w̶e̶r̶V̶a̶l̶u̶e̶;̶
return answer;
}
});
}

Managing a Reactive Form value and the value is an object

I have an Array I'm getting from the server, which contains Objects like this:
[
{LanguageName: 'English', ID : 2},
{LanguageName: 'Dutch', ID : 1},
{LanguageName: 'portuguese', ID: 3},
]
I'm handling this by by creating a Form-Array.
My Issue:
I want that if the user changes this input, it will change only the property of the Name, something like: anyFormName.controls.value.LanguageName, and not replacing the whole value altogether to a string, so insted of end up getting :
anyFormName.controls.value = "User's Input"
, I'll get:
anyFormName.controls.value = {LanguageName: "User's Input", ID : 2}
I've worked around this issue before with setValue() to the specific control, and saving the data in another array so I can compare the position by the indexes of the form Array. seems to me there probably be a better way...
thanks a lot!
Tal, in general you'll get a formArray like
<div *ngIf="myFormArray" [formGroup]="myFormArray">
<div *ngFor="let item of myFormArray.controls; let i=index" [formGroupName]="i">
<input formControlName="ID">
<input formControlName="LanguageName">
</div>
</div>
{{myFormArray?.value|json}}
//Or
<div *ngIf="myForm" [formGroup]="myForm">
<div formArrayName="data">
<div *ngFor="let item of myForm.get('data').controls; let i=index" [formGroupName]="i">
<input formControlName="ID">
<input formControlName="LanguageName">
</div>
</div>
</div>
{{myForm?.value|json}}
where you has some like
myForm:FormGroup
myFormArray:FormArray;
values=[
{LanguageName: 'English', ID : 2},
{LanguageName: 'Dutch', ID : 1},
{LanguageName: 'portuguese', ID: 3},
]
ngOnInit() {
this.myForm=this.fb.group({
data:this.fb.array(this.createFormArray(this.values))
})
this.myFormArray=this.fb.array(this.createFormArray(this.values));
}
createFormArray(values:any):FormGroup[]
{
return values.map(x=>{
return this.fb.group(
{
LanguageName:x.LanguageName,
ID:x.ID
}
)
})
}
Just not include the input formControlName="ID"
As long as I understand you properly, you're trying to change the form control name instead of its value. That can be accomplished by this method:
changeFormFieldName(oldField: string, newField: string): void {
var newControls: {[key: string]: FormControl} = {};
Object.keys(this.form.controls).map((field: string) => {
if (field==oldField) {
newControls[newField] = this.form.controls[field];
} else {
newControls[field] = this.form.controls[field];
}
});
this.form = new FormGroup(newControls);
}
assuming your form group object is under this.form.

Fetch Data and Populate in Text Boxes if Selected Dropdown Option

QUESTION UPDATED WITH CURRENT STATUS
I'm using Laravel 5.7 & VueJs 2.5.* ...
I want to autofill my form textboxes with the values in database when i select dropdown option. i've been finding solution since days but didn't get any success. I'm very new at this.
WHAT I WANT TO DO:
I have two invoices VendorInvoice and CustomerInvoice…
I created my VendorInvoice, fill all data and store in DB…
But when i want to create CustomerInvoice, i need to fetch & autofill the same data which i filled and stored in DB for VendorInvoice.
So when i create CustomerInvoice, I have a <select> options of VendorInvoice _no, by selecting any option CustomerInvoice form fields should auto fill with the VendorInvoice & VendorInvoiceItems data.
So i don’t have to fill same data by myself again in CustomerInvoice…
In my code:
VendorInvoice = ticketInvoice && VendorInvoiceItems = ticketInvoiceItems
CustomerInvoice = ctInvoice && CustomerInvoiceItems = ctInvoiceItems
If anyone could help to get me out from this issue i'll be very grateful. Thank You.
Here Is my HTML <select> & some ctInvoice & ctInvoiceItems fields which i want to autofill:
<form #submit.prevent="editmode ? updateCtInvoice() : createCtInvoice()">
<div class="modal-body">
<div class="row">
<!-- =====VENDOR INVOICE SELECTION===== -->
<select id="ticket_invoice_no" v-model="selectedTicketInvoiceId" #change="getRecord" name="ticket_invoice_no" type="text" class="form-control">
<option v-for="ticketInvoice in ticketInvoices" :key="ticketInvoice.id" :value="ticketInvoice.id">{{ ticketInvoice.ticket_invoice_no }}</option>
</select>
<!-- =====CUSTOMER TICKET INVOICE NUMBER===== -->
<input v-model="form.ct_invoice_no" type="text" name="ct_invoice_no" class="form-control">
<!-- =====CUSTOMER TICKET INVOICE ITEMS===== -->
<tbody>
<tr v-for="(ctInvoiceItem, key) in form.ctInvoiceItems" :key="key">
<!--Passenger Name-->
<td>
<input v-model="ctInvoiceItem.ct_passenger_name" size="40" type="text" name="ct_passenger_name" class="table-control form-control">
</td>
<!--Ticket No.-->
<td>
<input v-model="ctInvoiceItem.ct_ticket_no" size="24" type="text" name="ct_ticket_no" class="table-control form-control">
</td>
<!--Flight No.-->
<td>
<input v-model="ctInvoiceItem.ct_flight_no" size="7" type="text" name="ct_flight_no" class="table-control form-control">
</td>
</tbody>
My #change="getRecord" method:
getRecord: function(e) {
axios
.get("api/ticket-invoice/fetch/" + this.selectedTicketInvoiceId)
.then(({
data
}) => {
console.log(data);
this.form = data; // assumes the data keys maps directly to the form properties!!
})
.catch(error => {
console.log(error.response);
});
}
Route:
Route::get('ticket-invoice/fetch/{ticket_invoice}', 'API\TicketInvoiceController#fetch')->name('ticket-invoice.fetch');
My fetch(){} method:
public function fetch($id) {
$ticketInvoices = TicketInvoice::findOrFail($id);
return response() ->json([
'id' => '',
'customer_id' => '',
'ct_invoice_no' => $ticketInvoices->ticket_invoice_no,
'ct_invoice_date' => $ticketInvoices->ticket_invoice_date,
'ct_invoice_fares_total' => $ticketInvoices->ticket_invoice_fares_total,
'ct_invoice_grand_total' => $ticketInvoices->ticket_invoice_grand_total,
'ctInvoiceItems' => $ticketInvoices->ticketInvoiceItems->map(function($item) {
return [
// get the relevant $item->property for each key below
'id' => "",
'ct_invoice_id' => "",
'ct_passenger_name' => $item->passenger_name,
'ct_fares' => $item->fares,
'ct_sub_total' => $item->sub_total
];
}) ->all()
]);
}
My data() in Vue Component:
data() {
return {
editmode: true,
selectedTicketInvoiceId: false,
ticketInvoices: {},
ctInvoices: {},
customers: null,
form: new Form({
id: "",
customer_id: "",
ct_invoice_no: "",
ct_invoice_date: "",
ct_invoice_fares_total: 0,
ct_invoice_grand_total: 0,
ctInvoiceItems: [{
id: "",
ct_invoice_id: "",
ct_passenger_name: "",
ct_fares: 0,
ct_sub_total: 0
}]
})
};
},
When i select option i see in my Vue Component that specific id data fill in my form:. but its not actually fill my input fields with that data, so i could do some changes in the data and finally store it in DB as a customerInvoice.
Vue Dev Tool BEFORE SELECTING OPTION:
Vue Dev Tool AFTER SELECTING OPTION:
BUT NOT FILLING FIELDS:
I don't know Laravel 5.7 or vue but the concept remains the same
1- I would give an example of what I would do, I'll make a php file that has a select * from database and echo the result in json
2- Then use ajax, fetch to the php file and get that json, I will use the data retrieved in the javascript file
3 - I will have a function like on Dropdown Option onclick fetch or ajax, make the dropdown options equal to to the json fetched.

select - populate when editing post

I have my angularjs view in wich I must populate my select box with value saved in database, and to allow for other options to be selected. I have tryed like this:
<div class="form-group">
<label class="control-label" for="status">Status zaposlenika</label>
<div class="controls">
<select required name="status" class="form-control" ng-model="employee.status" ng-options="statusType.name for statusType in statusTypes" >
</select>
</div>
But my value is not populated in my view. ( {{employee.status}} - > "test" )
$scope.statusTypes = [
{
name: 'test'
},
{
name:'Test1'
},
{
name: 'Test2'
},
{
name:'Test3'
}
];
How can I do this ?
EDIT
My model employee.status is populated with value "test". But my select box is not. Othe values are listed as items for selection. How can I set default value that is saved in my database to be pre-selected in my select box.
Your model employee.name is a string and selectbox is bound to an object similar to {name: "Test1"}. So if you want to select option from statusTypes you have to find corresponding object in array of object.
$scope.statusTypes = [
{name: 'Test1'},
{name: 'Test2'},
{name: 'Test3'}
];
var selectedStatus = $scope.statusTypes.filter(function(type) {
return type.name = 'Test2';
})[0];
$scope.employee = {
status: selectedStatus
};
So you have to make employee.status to be one of the objects from statusTypes array.
Or other option is to continue to use string for employee.status and change ngOptions to bind to a string instead of object:
ng-options="statusType.name as statusType.name for statusType in statusTypes"

Categories