when hit enter go to next element vuejs2 - laravel

i have function on click vuejs2
this is the function
#change='units(chosed_item.id,$event)'
and this is the code for this function to send the id and put result inside array
units:function(item_id,$event){
var unit_id = event.target.value;
$.ajax({
type:'POST',
url: path+'unit_search',
data: {unit_id,item_id},
success:(data) => {
this.voucher_items.push({
id:data['id'],
item_desc_ar:data['item_desc_ar'],
item_unit_name:data['item_unit_name'],
item_smallest_unit_cost:data['item_smallest_unit_cost'],
item_smallest_unit:data['item_smallest_unit'],
item_smallest_unit_selling_price:data['item_smallest_unit_selling_price'],
item_discount_value:data['item_discount_value'],
item_tax_value:data['item_tax_value'],
});
this.chosed_items = [];
}
});
},
and i loop the voucher_items in loop
like this
<tr v-for="voucher_item , key in voucher_items">
<td>
<input name='items_quantity_coast[]' type='text' class='form-control' />
</td>
<td>
<input type='number' name='items_quantity_quantity[]' min='1' class='form-control' v-model='voucher_item.quantity' required />
</td>
<td>
<input type='number' name='items_quantity_discount[]' min='1' class='form-control' v-model='voucher_item.item_discount_value_input' min='1' max=''/>
</td>
</tr>
how can i make the input focus go to last input in voucher_items like when i click unit function do the code above and focus the input in
<input type='number' name='items_quantity_discount[]' min='1' class='form-control' v-model='voucher_item.item_discount_value_input' min='1' max=''/>
thanks

You can use a custom directive ..
In your component, add a directives option ..
directives: {
focus: {
inserted(el) {
el.focus()
}
}
}
Use your new v-focusdirective to focus on the desired element ..
This will focus on the last input on your last row. If you want finer control on which element to focus you can create a custom directive and use it on an upper level element (the table element for example), then use normal DOM traversing techniques(firtElementChild, lastElementChild et al.) to target specific elements. The process will be the same.

Related

VueJs and Laravel - multiple select fields

Using Laravel 5.4 and Vuejs 2.1
In code I have a select field with two input fields (quantity and stock) in tr (Table Row). Table Row with the fields can be dynamically added as much as user is needed, this is the code:
<tbody id="loads-content">
<tr v-for="(item, index) in items">
<td>
<select v-model="item.load_id" name="load_id[]" class="loads" v-on:change="getLoadStock()">
<option v-for="load in loads" :value="load.id" :id="load.id">{{load.name}}</option>
</select>
</td>
<td><input type="text" v-model="item.quantity" name="quantity[]" class="input is-hovered qty"></td>
<td><input type="text" v-model="item.stock" class="input is-hovered stock" disabled readonly="true"></td>
<td>
<button type="button" class="button is-danger remove" #click="items.splice(index, 1)"><i class="fa fa-minus-square-o" aria-hidden="true"></i></button>
</td>
</tr>
<a #click="addLine" class="button is-success"><i class="fa fa-plus-square-o" aria-hidden="true"></i></a>
</tbody>
When you choose some value from select field I need to populate the STOCK input field with stock data from the database. For that I used an API call. I made something like this:
methods: {
addLine() {
this.items.push({
load_id: '',
quantity: '',
stock: ''
})
},
getLoadStock(){
var loadsContent = $('#loads-content');
var tr = loadsContent.parent().parent();
var id = tr.find('.loads').val();
axios.get('/api/load/' + id)
.then(function(response) {
tr.find('.stock').val(response.data.stock);
})
.catch(function(error) {
console.log(error)
});
},
This code is not working as expected.
The goal is to fetch actual stock for current choosen load, to see how much quantity can you enter in the input field for quantity.
I am open for any suggestions, if anyone has a better approach and solution please help.
Thanks in advance! :)
You are mixing two different and incompatible ways of building a web app: Vue.js and jQuery.
When using Vue, you should not be manipulating the DOM directly. You should instead be binding the DOM elements to Vue model attributes. Then, if you need a DOM element to reflect a change, you change the model – not the DOM.
So for instance, you would want something like this (note adding index as an argument to getLoadStock):
<select v-model="item.load_id" name="load_id[]" class="loads" v-on:change="getLoadStock(index)">
<option v-for="load in loads" :value="load.id" :id="load.id">{{load.name}}</option>
</select>
and
getLoadStock(index){
axios.get('/api/load/' + this.items[index].load_id)
.then(function(response) {
this.items[index].stock = response.data.stock;
})
.catch(function(error) {
console.log(error)
});
},

Angular 2 doesn't update my view after I add or edit item

I've finally made my app in angular 2. Everything is solved, except one thing. When I add item into my table or edited it, I can't see the change until I refresh page or click for example next page button (I have implemented pagination). I included:
<script src="node_modules/systemjs/dist/system-polyfills.js"></script>
<script src="node_modules/angular2/bundles/angular2-polyfills.js"></script>
in this order. My method for adding item is very simple:
addDepartment(item){
this._departmentService.addDepartment(item)
.subscribe(departments => this.department = departments.json());
this.getAll();}
Whhen I add item, and put breakpoint on get method, It is called correctly and I get right information from my DB, but I don't know why view isn't refreshed then. Do you have any idea why is it happened? Thanks for suggestions!
EDIT: department is just department: Department, where Department is interface with properties (departmentNo, departmentName, departmentLocation). The view for adding item looks like:
<form [ngFormModel]="myForm"
(ngSubmit)="addDepartment(newItem); showAddView=false" [hidden]="!showAddView" align="center">
<div>
<label for="editAbrv">Department name:</label><br>
<input type="text" [(ngModel)]="newItem.departmentName" [ngFormControl]="myForm.controls['departmentName']" >
<div *ngIf="myForm.controls['departmentName'].hasError('required')" class="ui error message"><b style="color:red;">Name is required</b></div>
</div>
<br/>
<div>
<label for="editAbrv">Department Location:</label><br>
<input type="text" [(ngModel)]="newItem.departmentLocation" [ngFormControl]="myForm.controls['departmentLocation']" >
<div *ngIf="myForm.controls['departmentLocation'].hasError('required')" class="ui error message"><b style="color:red;">Location is required</b></div>
</div>
<br/>
<div>
<button type="submit" [disabled]="!myForm.valid" class="ui button">Add item</button>
<button><a href="javascript:void(0);" (click)="showHide($event)" >
Cancel
</a></button>
</div>
</form>
and my department table is:
<table align="center">
<thead>
<tr>
<td>#</td>
<td><strong>Department</strong></td>
<td><strong>Department Location</strong></td>
<td><strong>Edit</strong></td>
<td><strong>Delete</strong></td>
</tr>
</thead>
<tbody>
<tr *ngFor="#department of departments | searchString:filter.value ; #i = index">
<td>{{i + 1}}.</td>
<td> {{department.departmentName}}</td>
<td>{{department.departmentLocation}}</td>
<td>
<button class="btnEdit" (click)="showEdit(department)">Edit</button>
</td>
<td>
<button class="btnDelete" (click)="deleteDepartment(department)" >Delete</button>
</td>
</tr>
</tbody>
</table>
With this code, you don't wait for the response of the addDepartment request and execute the getAll request directly.
addDepartment(item){
this._departmentService.addDepartment(item)
.subscribe(departments => this.department = departments.json());
this.getAll();
}
You should move the call to getAll within the callback registered in subscribe. At this moment, the addDepartment is actually done and you can reload the list...
The code could be refactored like this (it's a guess since I haven't the content of addDepartment and getAll methods):
addDepartment(item){
this._departmentService.addDepartment(item)
.subscribe(addedDepartment => {
this.department = this.getAll();
});
}
This issue occurs because of the way you're using departmant and how change detection works. When you use *ngFor="#department of departments", angular change detection looks for a object reference on departments array. When you update/change one of the items in this array object reference to the array itself doesn't change, so angular doesn't run change detection.
You have few options:
1) change reference of the array by replacing it with new array with updated values
2) tell angular explicitly to run change detection (which I think is easier in your case):
constructor(private _cdRef: ChangeDetectorRef) {...}
addDepartment(item){
this._departmentService.addDepartment(item)
.subscribe(departments => this.department = departments.json());
this.getAll();
this._cdRef.markForCheck();
}

Sort five numbers inserted through user form and send it through AJAX and retrieve the result as JSON on same page

I am a beginner to ajax, jQuery and json. I want to sort five numbers and for that I need to insert data through an user form and send it through ajax and retrieve the result as json on the same page. Can you please help me out here?
(UPDATE)
The HTML code is like this:
<td><input type="number" name="array[]" />
<td><input type="number" name="array[]" />
<td><input type="number" name="array[]" />
<td><input type="number" name="array[]" />
<td><input type="submit" name="submit" value="SUBMIT" id="submit" />
And PHP in another file sort.php goes like this:
$a=$_POST['array'];
sort($a);
$b=count($a);
for($i=0;$i<$b;$i++)
{
echo "$a[$i] <br>";
}
<script type="text/javascript">
var array=[];
function addElement() //this function take the value from the text box and assign the value to an array
{
var number=$("#addvalue").val();
array.push(number);
$("#addvalue").val(' ');
$("#addvalue").focus();
}
function Sort() //this function display the number in desending order
{
for(i=0;i<array.length;i++) {
for(j=i+1;j<array.length;j++) {
if(parseInt(array[j]) > parseInt(array[i])) {
var temp=array[i];
array[i]=array[j];
array[j]=temp;
}}}
$.each(array,function(index) //and this function display the number.
{
var span=document.createElement("span");
span.appendChild(document.createTextNode(array[index]));
var i =document.getElementById("array");
i.appendChild(span);
var br=document.createElement("br");
i.appendChild(br);
});
$("div#array span:first").css("color","green");
};<script>
<body>
<input type="text" id="addvalue"/>
<br/><input type="button" onclick="addElement()" value="Add Number"/> <input type="button" onclick="Greater()" value="Sort">
<div id="array"></div>
</body>

Can I access the same controller multiple times in one view without changing the view?

I am using Spring MVC. I have a view that dynamically populates 2 dropdown lists based on queries called from the controller. I want to dynamically run a query based on the first dropdown selection to change the second dropdown, which means access the controller again (I think). Can I access the controller multiple times from the same view without changing the view? So for example, say starting out the first dropdown was a list of US States and the second started out as a list of all US cities, if I selected NC from the first list I would want to change the second list to include only NC cities.
Here is an example of the first dropdown:
<select name = "states" onChange = "populateCityList(this.options[this.selectedIndex].value)">
<option value ="*">All States</option>
<c:forEach items="${states}" var ="state">
<option value ="${state}">${state}</option>
Pretty straightforward, but I don't really know where to go from there. I have it calling a Javascript function within the current view right now, but I don't know if that is correct or what to even do within that function.
The magic word is AJAX.
Your JavaScript function needs to make an AJAX request to your controller, which should ideally return a JSON data structure containing the values for the second drop down. Your JS function should then have a callback that catches the JSON from your controller and populates the drop down HTML by manipulating the DOM. JQuery is the way to go. There are lots of examples on the web, just search for it.
Hi #user2033734 you can do something like this:
JQuery code
$(document).ready(function() {
$("#id1").change(function () {
position = $(this).attr("name");
val = $(this).val()
if((position == 'id1') && (val == 0)) {
$("#id2").html('<option value="0" selected="selected">Select...</option>')
} else {
$("#id2").html('<option selected="selected" value="0">Loading...</option>')
var id = $("#id1").find(':selected').val()
$("#id2").load('controllerMethod?yourVariable=' + id, function(response, status, xhr) {
if(status == "error") {
alert("No can getting Data. \nPlease, Try to late");
}
})
}
})
})
And JSP within
<table style="width: 100%;">
<tr>
<td width="40%"><form:label path="">Data 1: </form:label></td>
<td width="60%">
<form:select path="" cssClass="" id="id1">
<form:option value="" label="Select..." />
<form:options items="${yourList1FromController}" itemValue="id1" itemLabel="nameLabel1" />
</form:select>
</td>
</tr>
<tr>
<td width="40%"><form:label path="">Data 2: </form:label></td>
<td width="60%">
<form:select path="" cssClass="" id="id2">
<form:option value="" label="Select..." />
<form:options items="${yourList2FromController}" itemValue="id2" itemLabel="nameLabel2" />
</form:select>
</td>
</tr>
</table>
I hope help you :)
One solution would be to move some of the data gathering out into a service, so your main controller could use the service to gather the data before sending to the view.

How to retrieve multiple records from Jquery to my RazorView page

I have a button "btnGetAddress" on my razor page .On clik of this button,I am calling a Jquery to get my addressItmes object to be displayed on to my View page.
On clicking "btnGetAddress" I am able to hit my "JsonResult GetAddresses()" and retrieve records within my Jquery (success: function (data)).and this data has multiple address records. But I do not know how to take this data to my view .Please help me to get my data to be displayed on to my View
When my page get loaded,the user will see only the "btnGetAddress" button .When the user click on the btnGetAddress, it will call the Jquery Click function to fetch all address records from database and display each set of records on the page
$("#btnGetAddress").click(function () {
debugger;
var selected = $("#ddlType").val();
if (selected == "")
{ selected = 0; }
var dataToSend = {
SelectedTypeId: selected
};
$.ajax({
type: "GET",
url: '#Url.Action("GetAddresses", "Content")',
data: { SelectedTypeId: selected },
success: function (data) {
debugger;
},
error: function (error) {
var verr = error;
alert(verr);
}
});
pasted below is my JsonResult GetAddresses() which gets called to retrieve addressItems
public JsonResult GetAddresses()
{
model.AddressItems = AddressService.RetrieveAllAddress();
// My AddressItems is of type IEnumerable<AddressItems>
return Json(model.AddressItems, JsonRequestBehavior.AllowGet);
}
Here is my razor View Page where the address records are to be displayed.
........................
<input type="submit" id="btnGetAddress" name="btnSubmit" value="Show Addresses" />
if (!UtilityHelper.IsNullOrEmpty(Model.AddressItems))
{
foreach (var AddressRecord in Model.AddressItems)
{
<fieldset >
<legend style="padding-top: 10px; font-size: small;">Address Queue(#Model.NumRecords)
</legend>
<table>
<tr>
<td>
<span>Index</span>
</td>
<td>
</td>
<td>
<input type="submit" id="btnDelete" name="btnSubmit" value="X" />
<br />
</td>
</tr>
<tr>
<td>
<span>Address1</span>
<br />
</td>
<td>
#Html.EditorFor(model => AddressRecord.Address )
#Html.ValidationMessageFor(model => AddressRecord.Address)
</td>
</tr>
<tr>
<td>
<span>Description</span>
<br />
</td>
<td>
#Html.EditorFor(model => AddressRecord.Description)
#Html.ValidationMessageFor(model => AddressRecord.Description)
</td>
</tr>
<tr>
<td>
<input type="submit" id="btnSave" name="btnSubmit" value="Save" />
</td>
<td>
<input type="submit" id="btnDelete" name="btnSubmit" value="Delete" />
</td>
</tr>
</table>
</fieldset>
}
}
<fieldset>
Or is there any better way to achieve my objective?
Since you are getting the data via ajax you should use a jquery template engine. Basically get the data the way you are and on success you do something like
<script language="javascript" type="text/javascript">
$(function () {
$.getJSON("/getprojects", "", function (data) {
$("#projectsTemplate").tmpl(data).appendTo("#projectsList");
});
});
</script>
<script id="projectsTemplate" type="text/html">
<section>
<header><h2>Projects</h2></header>
<table id="projects">
<th>Name</th>
{{tmpl(items) "#projectRowTemplate"}}
</table>
</section>
</script>
<script id="projectRowTemplate" type="x-jquery-tmpl">
<tr>
<td>${name}</td>
</tr>
</script>
<div id="projectsList"></div>
Now each template engine is different but the above gives you an idea of what you can do
If you want to return JSON object in your controller, you are going have to turn your view into a string and return it as part of the message. If you google there are some methods out there that can do this.
However, I really think that's the hard way, why not take the data you get from the JSON in the controller and put it in a MODEL and then return your VIEW with the model data passed in. I think that's the easier way.

Resources