Vue select affecting other selector's currently selected choice [duplicate] - javascript

This question already has answers here:
use v-model inside a v-for loop
(5 answers)
Closed 2 years ago.
I have a table that displays a certain Nova resource. For each row, I have a selector that would allow me to perform one action from a dropdown. The problem is, let's say I have 3 rows. Each row would have the same selector. Let's say the selector has options A, B, and C. If I go to the first row and select option B, the other selectors also change their currently selected value to B. I'm assuming this is because all of the selectors have the same v-model binding, but I'm not sure how to get around this.
This is the code for the table and the selector:
<table id="favorites">
<tr>
<th>ID</th>
<th>Title</th>
<th>Source</th>
<th>Description</th>
<th>Date of Creation</th>
<th>Posted Status</th>
<th>Actions</th>
</tr>
<tr v-for="(favorite, index) in favorites" :key="index">
<td>{{favorite.id}}</td>
<td>{{favorite.title}}</td>
<td>{{favorite.source}}</td>
<td>{{favorite.description}}</td>
<td>{{favorite.created_at}}</td>
<td>
<div v-if="favorite.posted_status === 2">
<button class="button-posted button4">Posted</button>
</div>
<div v-else>
<button class="button-not-posted button4">Not Posted</button>
</div>
</td>
<td>
<select #change="toggle_posted(favorite)" v-model="selected_state" class="form-control form-control-lg">
<option selected disabled>Choose an action </option>
<option v-for="(state, index) in posted_states" :key="index" :value="state.id">{{state.name}}</option>
</select>
</td>
</tr>
</table>
I want to separate the selectors so that they don't mirror each other. It's also worth noting that while the other selectors change, they don't actually call the toggle_posted method. Only the selector I chose does.

A straight-forward way to fix this would be adding a selected_state attribute for each list item in favorites:
new Vue({
el:"#app",
data: () => ({
favorites: [
{ id:1, title:'1', source:'1', description:'1', created_at:'1', posted_status: 1, selected_state:null },
{ id:2, title:'2', source:'2', description:'2', created_at:'2', posted_status: 2, selected_state:null }
],
selected_state: null,
posted_states: [
{ id:1, name:'1' }, { id:2, name:'2' }
]
}),
methods: {
toggle_posted(favorite) {
console.log(favorite)
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<table id="favorites">
<tr>
<th>ID</th>
<th>Title</th>
<th>Source</th>
<th>Description</th>
<th>Date of Creation</th>
<th>Posted Status</th>
<th>Actions</th>
</tr>
<tr v-for="(favorite, index) in favorites" :key="index">
<td>{{favorite.id}}</td>
<td>{{favorite.title}}</td>
<td>{{favorite.source}}</td>
<td>{{favorite.description}}</td>
<td>{{favorite.created_at}}</td>
<td>
<div v-if="favorite.posted_status === 2">
<button class="button-posted button4">Posted</button>
</div>
<div v-else>
<button class="button-not-posted button4">Not Posted</button>
</div>
</td>
<td>
<select #change="toggle_posted(favorite)" v-model="favorite.selected_state" class="form-control form-control-lg">
<option selected disabled>Choose an action </option>
<option v-for="(state, index) in posted_states" :key="index" :value="state.id">{{state.name}}</option>
</select>
</td>
</tr>
</table>
</div>

Related

How to restrict dropdown select option for that particular row

I am using nuxt.js to develop a web application ,in that i have on page that page responsible for the custom forms ,please refer the following image
In this page if i click on increment decrement buttons it will create another row upto this part it's working fine,now if i select any column dropdown in first row it's selecting but it's automatically updating all rows column dropdown ,can you please help me to fix this issue ..?
<template>
<div class="pt-5 table-responsive">
<h3>Conditions</h3>
<table class="table table-bordered table-hover">
<thead class="thead-light">
<tr>
<th scope="col">#</th>
<th scope="col">Column</th>
<th scope="col">Condition</th>
<th scope="col">Input Field</th>
<th scope="col" class="text-right">Add/Remove</th>
</tr>
</thead>
<tbody>
<tr v-for="(input, index) in inputs" :key="index">
<td>{{ index + 1 }}</td>
<td>
<select v-model="fields" class="form-select form-control">
<option
v-for="conditionField in conditionFields"
:key="conditionField.id"
>
{{ conditionField.name }}
</option>
</select>
</td>
<td>
<select v-model="condFies" class="form-select form-control">
<option
v-for="typeCondition in typeConditions"
:key="typeCondition.id"
>
{{ typeCondition.name }}
</option>
</select>
</td>
<td>
<base-input placeholder="Type here"></base-input>
</td>
<td class="text-right">
<base-button type="secondary" #click="addRow(input)"
><i class="ni ni-fat-add"></i>
</base-button>
<base-button type="secondary" #click="removeRow(index, input)"
><i class="ni ni-fat-delete"></i>
</base-button>
</td>
</tr>
</tbody>
</table>
</div>
</template>
<script>
export default {
data() {
return {
inputs: [{}],
fieldInputs: [{}],
conditions: [],
forms: [],
selectedForm: [],
loadedForm: [],
conditionFields: [],
selectFields: [],
condFies: [],
fields: [],
selFields: [],
report: [],
typeConditions: [],
}
},
methods: {
getQueryConditions() {
try {
const axios = this.$axios.create()
axios
.get(
'queryconditions'
// , {
// transformRequest: (headers) => {
// delete headers.common['Organization-Id'];
// }
// }
)
.then((response) => {
this.conditions = response.data.data
this.conditions.forEach((element) => {
if (element.type.includes('condition')) {
console.log(element)
this.typeConditions = this.conditions
}
})
})
} catch (e) {
console.log('error', e)
}
},
},
}
</script>

Set selected option selected inside a loop Vue.js

Im looping over a list of objects and I'm trying to have the status of the object be selected by default.
<template>
<table class="table is-striped">
<thead>
<tr>
<th>
Client
</th>
<th>
Status
</th>
</tr>
</thead>
<tbody>
<tr v-for="client in filteredClients">
<td>
<router-link :to="{ name:'client-show' , params:{clientId: client.uuid}}"
v-on:click.native="selectClient(client)">
{{ client.name }}
</router-link>
</td>
<td>
<div class="select is-rounded">
<select v-model="selectedStatus" #change="statusChange($event, client)">
<option v-for="status in statuses" > {{status}}</option>
</select>
</div>
</td>
</tr>
</tbody>
</table>
</template>
<script>
export default {
props: [
'filteredClients'
],
data: function() {
return {
statuses: [ 'Started', 'Awaiting Payment', 'Paid', 'Onboarding', 'Live']
}
},
computed: {},
mounted() {},
methods: {}
}
</script>
Here i have all the statuses that i need to display but im having a hard time getting a selected value to be selected for each object that im looping over through.
you need to $emit the status change to parent Component so that new status will be assigned to specific client object. (no mutation of props in child)
<select :value="client.status" #change="$emit('change', $event.target.value, client.uuid)">
<option v-for="status in statuses" :selected="status == client.status">{{status}}</option>
</select>
and on your parent Component, capture this emit and assign it to the client
<ParentComponent #change="(status, uuid) => clients.find(c => c.uuid === uuid).status = status">
// child with props: filteredClients
</ParentComponent>

Maintain Form Value After Submission

I have an html (no php) form on a cloud-based server. I have no access to the server files. I am struggling to do two things:
1) Show/hide div based on dropdown value (I do have this working on my site, but for some reason it's not working in my jsfiddle)
2) Maintain the dropdown value after the form is saved.
//Use to hide Analysis div when analysisPub question is answered no
$('.analysisPub').on('change', function () {
if(this.value === "Yes"){
$("#analysis").show();
} else {
$("#analysis").hide();
}
});
/*Hide Analysis div by default*/
.analysis {
display:none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<td>Does this publication include in any form?</td>
</tr>
<tr>
<td class="analysisPub" id="analysisPub" name="analysisPub">
<select class="analysisPub" id="analysisPub" name="analysisPub">
<option value="No">No</option>
<option value="Yes">Yes</option>
</select>
</tr>
</table>
<!-- ANALYSIS DIV -->
<div id="analysis" class="analysis">
<h1>
Analysis Details
</h1>
<table>
<tr>
<td><label>Project Name</label>
</td>
<td class="text-area">
</td>
</tr>
<tr>
<td><label>Manager Name</label>
</td>
<td class="text-area">
</td>
</tr>
</table>
</div>
I want the div to remain hidden if the user has chosen 'No' from the dropdown, and the div should remain visible if the user has chosen 'Yes'. Currently, it doesn't matter what the user chooses, whenever the form is saved and re-opened, the div defaults back to hidden (because of the CSS).
I am very new to javascript and this project has been dropped in my lap last minute (sigh).
You have 2 elements with the ID "analysisPub" in your markup, if you remove the ID from the td element and change
$('.analysisPub').on('change', function () {
to
$('#analysisPub').on('change', function () {
So that you are using the ID, your code works just fine.
To remember the choice you can use the localStorage API.
//Use to hide Analysis div when analysisPub question is answered no
$('#analysisPub').on('change', function() {
window.localStorage.setItem("showAnalysis", this.value);
if (this.value === "Yes") {
$("#analysis").show();
} else {
$("#analysis").hide();
}
});
// check if value is already remembered and set it to the saved value:
if (window.localStorage.getItem("showAnalysis")) {
$('#analysisPub').val(window.localStorage.getItem("showAnalysis"));
}
/*Hide Analysis div by default*/
.analysis {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<td>Does this publication include in any form?</td>
</tr>
<tr>
<td class="analysisPub" name="analysisPub">
<select class="analysisPub" id="analysisPub" name="analysisPub">
<option value="No">No</option>
<option value="Yes">Yes</option>
</select>
</tr>
</table>
<!-- ANALYSIS DIV -->
<div id="analysis" class="analysis">
<h1>
Analysis Details
</h1>
<table>
<tr>
<td><label>Project Name</label>
</td>
<td class="text-area">
</td>
</tr>
<tr>
<td><label>Manager Name</label>
</td>
<td class="text-area">
</td>
</tr>
</table>
</div>

Filter next dropdown values based on already selected value

I have a dropdown with four options. I select the first option as 'John (1)' and add a row. Now the next dropdown should only show me three options in the dropdown ie, it should exclude the value of the previous dropdown selected value which is 'John (1)'. On the next add row it should exclude the previous two selected dropdown values. Can this be achieved. Thank you in advance. Below is the fiddle.
<div ng-app ng-controller="LoginController">
<table class="table table-striped">
<thead>
<tr>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="mapping in viewTemplateRow">
<td>
<select class="form-dropdown" id="templateId" ng-model="mapping.id">
<option value="">Please Select...</option>
<option ng-repeat="option in viewTemplateData" value="{{option.id}}" ng-selected="{{option.id == mapping.id}}" ng-model="viewTemplateData">{{option.name}} ( {{option.id}} )</option>
</select>
</td>
</tr>
</tbody>
</table>
<button type="button" class="button button-compact" ng-click="addRow();">Add New Row</button>
</div>
https://jsfiddle.net/Lt7aP/3787/
Add a filter to your ng-repeat in order to avoid allready added objects:
$scope.notSelected = function(item){
for (var i in $scope.viewTemplateRow){
if ($scope.viewTemplateRow[i].id==item.id)
return false
}
return true;
}
Your html will look like this:
<option ng-repeat="option in viewTemplateData | filter: notSelected" value="{{option.id}}" ng-selected="{{option.id == mapping.id}}" ng-model="viewTemplateData">{{option.name}} ( {{option.id}} )</option>
Note: Consider replace ng-repeat directive for ng-options for a selector item.

How to display the details about the selected option of a select box in Laravel using Blade?

I am a Laravel Newbie Some how I managed to display DB content in to a select box. What i wanted is that, i need to get data from another table based on the ID selected in the select box. My code is given below
Blade
<h2 class="comment-listings">Subscriber listings</h2><hr>
<table>
<thead>
<tr>
<th>Slelect a List:</th>
<th><select class="form-control input" name="list1s" id="list1s" >
<option selected disabled>Please select one option</option>
#foreach($list1s as $list1)
<option value="{{$list1->id}}">{{$list1->name}}</option>
#endforeach
</select>
</th>
</tr>
</thead>
</table>
<table>
<thead>
<tr>
<th>Device ID</th>
<th>Status</th>
<th>Delete</th>
</tr>
</thead>
<tbody>
#foreach($subscribers as $subscriber)
<tr>
<td>{{{$subscriber->device_id}}}</td>
<td>{{$subscriber->list1->name}}</td>
<td>
{{Form::open(['route'=>['subscriber.update',$subscriber->id]])}}
{{Form::select('status',['approved'=>'Approved','blocked'=>'Blocked'],$subscriber->status,['style'=>'margin-bottom:0','onchange'=>'submit()'])}}
{{Form::close()}}
</td>
<td>{{HTML::linkRoute('subscriber.delete','Delete',$subscriber->id)}}</td>
</tr>
#endforeach
</tbody>
</table>
<script>
$('#list1s').on('change',function(e){
console.log(e);
var list_id = e.target.value;
$.get('/subscriber/get?list_id=' + list_id, function(data){
console.log(data);
})
})
</script>
{{$subscribers->links()}}
Controller for populating select box
public function listList()
{
$list1s = List1::all();
$this->layout->title = 'Subscriber Listings';
$this->layout->main = View::make('dash')->nest('content', 'subscribers.list', compact('list1s'));
$subscribers = Subscriber::orderBy('id', 'desc')->paginate(20);
View::share('subscribers', $subscribers);
}
This shows all the Lists and Subscribers.
Since i need to display subscribers of list selected in select box i have added a script at the bottom of the Blade and added other controller function at route to perform task based on the list_id passed from the script.
Route::get('/subscriber/get', function(){
$list_id = Input::get('list_id');
$subscribers = Subscriber::where('list1_id','=', $list_id)->get();
return Response::eloquent($subscribers);
});
But no changes are taking place, Where am I wrong?
I have Edited my code, and was successful.
Blade
<h2 class="comment-listings">Campaign listings</h2><hr>
<script data-require="jquery#2.1.1" data-semver="2.1.1" src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<thead>
<tr>
<th>Select a List:</th>
<th>
<select class="form-control input" name="list1s" id="list1s" onchange="displayVals(this.value)">
<option selected disabled>Please select a list</option>
#foreach($list1s as $list1)
<option value="{{$list1->id}}">{{$list1->name}}</option>
#endforeach
</select>
</th>
</tr>
</thead>
</table>
<div id="campaign">
</div>
<script>
function displayVals(data)
{
var val = data;
$.ajax({
type: "POST",
url: "get",
data: { id : val },
success:function(campaigns)
{
$("#campaign").html(campaigns);
}
});
}
</script>
Route
Route::any('/campaigns/get', [
'as' => '/campaigns/get',
'uses' => 'CampaignController#getCampaigns'
]);
Controller
public function getCampaigns()
{
$list1 = Input::get('id');
$campaigns = Campaign::orderBy('id', 'desc')
->where('list1_id','=', $list1)
->where('user_id','=',Auth::user()->id)
->paginate(10);
return View::make('campaigns.ajaxShow')->with('campaigns', $campaigns);
}
I have a separate blade now (ajaxShow) to load when option changed in select box.
<table>
<thead>
<tr>
<th>Campaign title</th>
<th>Status</th>
<th>Delete</th>
</tr>
</thead>
<tbody>
#foreach($campaigns as $campaign)
<tr>
<td>{{{$campaign->template->title}}}</td>
<td>
{{Form::open(['route'=>['campaign.update',$campaign->id]])}}
{{Form::select('status',['yes'=>'Running','no'=>'Stoped'],$campaign->running,['style'=>'margin-bottom:0','onchange'=>'submit()'])}}
{{Form::close()}}
</td>
<td>{{HTML::linkRoute('campaign.delete','Delete',$campaign->id)}}</td>
</tr>
#endforeach
</tbody>
</table>
{{$campaigns->links()}}
There is no eloquent method implemented in Illuminate\Http\Response in Laravel 4 and above (I believe that method is only available in Laravel 3). But you can return a json response instead:
Route::get('/subscriber/list', function(){
$list_id = Input::get('list_id');
$subscribers = Subscriber::where('list1_id','=', $list_id)->get();
return Response::json($subscribers);
});

Categories

Resources