Pass array to Laravel view in Vue - arrays

in laravel i have ProdoctController and CategoryController,
im passing the category data with this function:
public function view(){
$category = Category::all();
return view('admin.product.main',['category'=>$category]);
}
its working with normal mode in laravel:
<select>
#foreach(category as categories)
<option value='{{category->id}}">{{category->name}}</option>
#endforeach
</select>
but in vue js i have a categories:[] in data,
and i want to use this:
<select v-model="ProductCategory">
<option v-for="category in categories" :value="categories.id">categories.name</option>
</select>
how can i pass the data in categories array?

You can do something like this:
<script type="text/javascript">
window.data = {!! json_encode([
'categories' => $categories,
]) !!};
</script>
<select v-model="ProductCategory">
<option v-for="category in window.data.categories" :value="category.id">category.name</option>
</select>
First part gets you the categories onto the view in the JavaScript and then Vue will have access to them. I think you should fix your category/categories variables, if this is a real code you've been using them not correctly, e.g. when you have a collection of many and when you have only one.

Related

Angular change detection ngFor

I have an array called peoples on my tab view. I need to change the array items based on a change function. While the change function is working successfully and printing the array differently after each change on the console, the view itself is not changing from the initial value assigned from ngInit();
ngOnInit(){
this.someservice.loadallpeople().subscribe(data=>{
this.peoples=data.Data;
});
}
loadpeople(category:any){
this.someservice.getpeoplebycat(category).subscribe(data=>{
this.peoples=data.Data;
});
}
<select [(ngModel)]="category.name"
(ngModelChange)="loadpeople(category.name)">
<option *ngFor="let cat of category">{{category.name}} </option>
</select>
<div *ngFor="let people of peoples">
<span>{{people.name}}</span>
</div>
I have used some methods but none of them seems to work. Any small help will be appreciated.
Some things are not clear on what you show.
First you use [(ngModel)]="category.name" and (ngModelChange)="loadpeople(category.name)" on category.name, but next you iterate over category and you get cat.name, so there cannot be a category.name element if it's an array.
Second I will just use (change) instead of [ngModel] + (ngModelChange) according to what you show, because as said before, category.name cannot return anything.
So with all this updates, I will do something like this
ngOnInit(){
this.someservice.loadallpeople().subscribe(data=>{
this.peoples=data.Data;
});
}
loadpeople(event){
this.someservice.getpeoplebycat(event.target.value).subscribe(data=>{
this.peoples=data.Data;
});
}
<select (change)="loadpeople($event)">
<option *ngFor="let cat of category">{{cat.name}} </option>
</select>
<div *ngFor="let people of peoples">
<span>{{people.name}}</span>
</div>

AngularJS - Populating HTML Drop-Down with JSON from REST API (without $scope)

A lot of solutions on Stack Overflow in relation to populating drop down menus include $scope.
My second drop-down depends on the value of my first drop-down therefore I use ng-changeon the first HTML select to parameter pass the model ID into the 2nd drop-down's function.
1st Drop-Down HTML and Angular JS:
<select data-ng-controller="addAssetController as addAssetCtrl" id="functionalOrg" data-ng-model="addAssetFormCtrl.functionalOrg.id" ng-change="addAssetCtrl.getLocations(addAssetFormCtrl.functionalOrg.id)">
<option data-ng-repeat="functionalOrg in addAssetCtrl.functionalOrgs | orderBy:'id' track by $index" value="{{functionalOrg.id}}">
{{functionalOrg.id}} - {{functionalOrg.account}}
</option>
</select>
Hence ng-change:
ng-change="addAssetCtrl.getLocations(addAssetFormCtrl.functionalOrg.id)"
-
var vm = this;
functionalOrganisationRepository.getFunctionalOrganisation().then(function (results) {
vm.functionalOrgs = results;
}, function (error) {
vm.error = true;
vm.errorMessage = error;
});
The 2nd Drop-Down HTML and Angular:
<select data-ng-controller="addAssetController as addAssetCtrl" id="location" data-ng-model="addAssetFormCtrl.location.id">
<option data-ng-repeat="location in addAssetCtrl.locations | orderBy:'id' track by $index" value="{{location.id}}">
{{location.id}} - {{location.address6}}
</option>
</select>
-
vm.getLocations = function(id) {
console.log("Functional org ID:" + id);
locationRepository.getLocation(id).then(function (results) {
vm.locations = results;
}, function (error) {
vm.error = true;
vm.errorMessage = error;
});
}
Assuming my service layer is fine and brings back a JSON object with everything I require, what could the problem be? The vm.getLocations function is definitely getting called because my console log is being printed. The service layer is also fine because a JSON object to being logged to my command prompt.
My question is how do I populate my second drop-down from whatever JSON is returned by getLocations? Please hence I do not want to make use of $scope in Angular.
The "ng-controller" attribute is repeated on each select. Put the attribute only one time on a parent element!
<div data-ng-controller="addAssetController as addAssetCtrl">
<!-- Drop Down 1 and 2 here -->
</div>
If you dont share scope you can't do what you want to do. Meaning if you dont have a parent vm or pass something to your directive = you can't tell what is selected.
Pull up your controller a level and share it among selected or you are going to have to either watch a shared variable in a service, or rely on $on & $broadcast to communicate.
Pretty sure that this is because they have different scopes and different controllers.
Assuming that the actual HTML looks like the following:
<select data-ng-controller="addAssetController as addAssetCtrl" id="location" data-ng-model="addAssetFormCtrl.location.id">
<option data-ng-repeat="location in addAssetCtrl.locations | orderBy:'id' track by $index" value="{{location.id}}">
{{location.id}} - {{location.address6}}
</option>
</select>
<select data-ng-controller="addAssetController as addAssetCtrl" id="functionalOrg" data-ng-model="addAssetFormCtrl.functionalOrg.id" ng-change="addAssetCtrl.getLocations(addAssetFormCtrl.functionalOrg.id)">
<option data-ng-repeat="functionalOrg in addAssetCtrl.functionalOrgs | orderBy:'id' track by $index" value="{{functionalOrg.id}}">
{{functionalOrg.id}} - {{functionalOrg.account}}
</option>
</select>
Then, to the best of my knowledge, each select will get a different instance of the controller, each with different scopes. So you've effectively got a controller addAssetCtrl1 and addAssetCtrl2, so setting data on 1 does not set it on 2.
The solution would be to set the data on a parent controller, or, probably more simply, to do the following:
<div data-ng-controller="addAssetController as addAssetCtrl">
<select id="location" data-ng-model="addAssetFormCtrl.location.id">
<option data-ng-repeat="location in addAssetCtrl.locations | orderBy:'id' track by $index" value="{{location.id}}">
{{location.id}} - {{location.address6}}
</option>
</select>
<select id="functionalOrg" data-ng-model="addAssetFormCtrl.functionalOrg.id" ng-change="addAssetCtrl.getLocations(addAssetFormCtrl.functionalOrg.id)">
<option data-ng-repeat="functionalOrg in addAssetCtrl.functionalOrgs | orderBy:'id' track by $index" value="{{functionalOrg.id}}">
{{functionalOrg.id}} - {{functionalOrg.account}}
</option>
</select>
</div>

AngularJS: need to split/parse ng-options value

A legacy database I am working with stores lookup values in a semi-colon separated list (within a single field/column in the table) - which worked fine as a data source for an ASP.NET. But for migrating to AngularJS - I've found no way to intercept the value and split it for separate options in the select element.
In the select drop down it simply shows (for example) "1 rep; 2 reps; 3 reps" etc.
Can anyone suggest how to split this value so the select options render vertically - each one in it's own option row?
This is how the select element looks now:
<select
ng-model="exerciseVals[$index].reps1" ng-options="value.REPS as value.REPS for (key,value) in lkps
></select>
ng-options works on an array or an object.
If I understand your situation correctily, you're getting a large string from the server with semicolon-separated entries. You need to split it into an array.
$scope.lkps = stringFromServer.split(";");
Then in HTML:
<select ng-model="selectedVal"
ng-options="item for item in lkps">
</select>
You can try This , i have included in my code too !
Working Code
<div ng-app>
<div ng-controller="tempCtrl">
<select>
<option ng-repeat="temp in tempdata">
{{temp}}
</option>
</select>
</div>
</div>
JS CODE
var myApp = angular.module('App', ["xeditable"]);
myApp.controller('tempCtrl',function ($scope) {
alert();
$scope.tempdata = ["1 rep","2 rep","3 rep"];
console.log($scope);
});
You can also use angular filter :
<select ng-model ='select' ng-options="item for item in 'd;g;f'|split:';'">
<option value="">Nothing selected</option>
</select>
JS:
myApp.filter('split',function(){
return function(str,delimeter)
{
return str.split(delimeter);
}
check working example

How to set the value attribute for select options?

Source JSON data is:
[
{"name":"Alabama","code":"AL"},
{"name":"Alaska","code":"AK"},
{"name":"American Samoa","code":"AS"},
...
]
I try
ng-options="i.code as i.name for i in regions"
but am getting:
<option value="?" selected="selected"></option>
<option value="0">Alabama</option>
<option value="1">Alaska</option>
<option value="2">American Samoa</option>
while I am expecting to get:
<option value="AL">Alabama</option>
<option value="AK">Alaska</option>
<option value="AS">American Samoa</option>
So, how to get value attributes and get rid of "?" item?
By the way, if I set the $scope.regions to a static JSON instead of AJAX request's result, the empty item disappears.
What you first tried should work, but the HTML is not what we would expect. I added an option to handle the initial "no item selected" case:
<select ng-options="region.code as region.name for region in regions" ng-model="region">
<option style="display:none" value="">select a region</option>
</select>
<br>selected: {{region}}
The above generates this HTML:
<select ng-options="..." ng-model="region" class="...">
<option style="display:none" value class>select a region</option>
<option value="0">Alabama</option>
<option value="1">Alaska</option>
<option value="2">American Samoa</option>
</select>
Fiddle
Even though Angular uses numeric integers for the value, the model (i.e., $scope.region) will be set to AL, AK, or AS, as desired. (The numeric value is used by Angular to lookup the correct array entry when an option is selected from the list.)
This may be confusing when first learning how Angular implements its "select" directive.
You can't really do this unless you build them yourself in an ng-repeat.
<select ng-model="foo">
<option ng-repeat="item in items" value="{{item.code}}">{{item.name}}</option>
</select>
BUT... it's probably not worth it. It's better to leave it function as designed and let Angular handle the inner workings. Angular uses the index this way so you can actually use an entire object as a value. So you can use a drop down binding to select a whole value rather than just a string, which is pretty awesome:
<select ng-model="foo" ng-options="item as item.name for item in items"></select>
{{foo | json}}
If you use the track by option, the value attribute is correctly written, e.g.:
<div ng-init="a = [{label: 'one', value: 15}, {label: 'two', value: 20}]">
<select ng-model="foo" ng-options="x for x in a track by x.value"/>
</div>
produces:
<select>
<option value="" selected="selected"></option>
<option value="15">one</option>
<option value="20">two</option>
</select>
If the model specified for the drop down does not exist then angular will generate an empty options element. So you will have to explicitly specify the model on the select like this:
<select ng-model="regions[index]" ng-options="....">
Refer to the following as it has been answered before:
Why does AngularJS include an empty option in select? and this fiddle
Update: Try this instead:
<select ng-model="regions[index].code" ng-options="i.code as i.name for i in regions">
</select>
or
<select ng-model="regions[2]" ng-options="r.name for r in regions">
</select>
Note that there is no empty options element in the select.
You could modify you model to look like this:
$scope.options = {
"AL" : "Alabama",
"AK" : "Alaska",
"AS" : "American Samoa"
};
Then use
<select ng-options="k as v for (k,v) in options"></select>
It appears it's not possible to actually use the "value" of a select in any meaningful way as a normal HTML form element and also hook it up to Angular in the approved way with ng-options. As a compromise, I ended up having to put a hidden input alongside my select and have it track the same model as my select, like this (all very much simplified from real production code for brevity):
HTML:
<select ng-model="profile" ng-options="o.id as o.name for o in profiles" name="something_i_dont_care_about">
</select>
<input name="profile_id" type="text" style="margin-left:-10000px;" ng-model="profile"/>
Javascript:
App.controller('ConnectCtrl',function ConnectCtrl($scope) {
$scope.profiles = [{id:'xyz', name:'a profile'},{id:'abc', name:'another profile'}];
$scope.profile = -1;
}
Then, in my server-side code I just looked for params[:profile_id] (this happened to be a Rails app, but the same principle applies anywhere). Because the hidden input tracks the same model as the select, they stay in sync automagically (no additional javascript necessary). This is the cool part of Angular. It almost makes up for what it does to the value attribute as a side effect.
Interestingly, I found this technique only worked with input tags that were not hidden (which is why I had to use the margin-left:-10000px; trick to move the input off the page). These two variations did not work:
<input name="profile_id" type="text" style="display:none;" ng-model="profile"/>
and
<input name="profile_id" type="hidden" ng-model="profile"/>
I feel like that must mean I'm missing something. It seems too weird for it to be a problem with Angular.
you can use
state.name for state in states track by state.code
Where states in the JSON array, state is the variable name for each object in the array.
Hope this helps
Try it as below:
var scope = $(this).scope();
alert(JSON.stringify(scope.model.options[$('#selOptions').val()].value));

Country/State Dropdown in CakePHP

How do i deal with dependent combo boxes in the views with the form helper. For example:
Country Select Box (Choosing a country shall filter out the states of the selected country)
States Select Box
This should happen with the help of Javascript / Jquery etc. I came across an example for the same with Cake's core AJAX helper but it would be very nice if someone can help with a Javascript example.
Thanks
In views/ edit.ctp
<script type="text/javascript">
$(document).ready(function (){
$('#country').change(function() {
$('#state').load('/controller/getStates/'+$(this).val());
});
});
</script>
<select id="country" name="country">
<option value="1">Greece</option>
</select>
<span id="state">
<select name="state">
<option value=""></option>
</select>
</span>
and in controller.php
function getStates(int countryID){
$this->set('selectbox',
$this->State->find('list',array('conditions'=>'State.Country_id='.$countryID,
'fields;=>array('description')));
}
and views/getStates.ctp
<select name="state">
<option value=""></option>
<?php
foreach($selectbox as $option)
echo '<option value="'.$option['id'].'">'.$option['description'].'</option>'."\n";
?>
</select>
I hope I don't forget something
#gong's solution works well. Just remember to add:
$this->layout = 'ajax';
in the controller and ensure there is a clean ajax.ctp in the layouts folder... otherwise all the layout code will be returned in the ajax response as well as just the dropdown code!
$states = $this->State->find('list', array(
'conditions' => array('State.country_id' =>$codePassed),
'order'=>array('State.stateName ASC'),
'fields' =>array('id','stateName'),
'recursive' => -1
));
$a='';
$a.= "<select name=\"state\">";
$a.= "<option value=\"\">Select state</option>";
foreach($states as $key=>$value){
$a.="<option value=\"$key\">".$value."</option>";
}
$a.="</select>";

Resources