I am using ng-repeat in HTML to loop on a javascript array. showing this array in select.
what i want to do is to clear all selected data from these dropdownlists when press on a button
HTML
<div class="widget-title">
<div class="widget-controls">
<button class="btn btn-xs btn-primary" ng-click="newassignment()">New</button>
<button class="btn btn-xs btn-success" ng-click="saveavd()">Save</button>
</div>
<h3><i class="icon-ok-sign"></i>Assignment</h3>
</div>
<div id="vacation" class="widget-content" style="height:81vh; overflow:auto;">
<div class="row">
<table style="width: 70%;" border="1">
<thead>
<tr>
<th>Departments</th>
<th>Work Level</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="d in departments | filter : depts">
<td>
<input style=" margin-top: 0;" type="checkbox" ng-model="d.details"/> {{d.Dep_LDesc}}
</td>
<td>
<select class="form-control input-sm" ng-model="wrklevel2">
<option ng-repeat="w in worklevel" value="{{w.lvlid}}">{{w.lvlnm}}</option>
</select>
</td>
</tr>
</tbody>
</table>
angularjs
$scope.worklevel = [
{ lvlid: 1, lvlnm: 'First Level' },
{ lvlid: 2, lvlnm: 'Second Level' }
]
$scope.newassignment = function () {
$scope.wrklevel2 = {};
angular.forEach($scope.departments, function (d) {
d.details = false;
})
}
You should have different models for your selects inside your ng-repeat to achieve that you can try the following
(ng-model="d.wrklevel2")
<select class="form-control input-sm" ng-model="d.wrklevel2">
<option ng-repeat="w in worklevel" value="{{w.lvlid}}">{{w.lvlnm}}</option>
</select>
after that you can also clear values of select inside your forEach loop
angular.forEach($scope.departments, function (d) {
d.details = false;
d.wrklevel2 = undefined;
})
set the ngModel of select to empty string -
function saveavd()
{
$scope.wrklevel2 = ""
// ...
}
Related
I have a validation problem regarding multiple input fieldL to store in the database. When I submit, the errors show "additional mark field is required." I try to test dd($request) but the attributes is null. How can I store in DB with multiple input fields?
Controller
public function StoreAdditionalProcuments(Request $request)
{
$request->validate([
'additional_remark' => 'required',
]);
foreach ($request->addmore as $key => $value) {
$input = $request->all();
$input['additional_remark'] = $value['additional_remark'];
AssetProcument::create($input);
}
return redirect('asset')->with('success', 'Maklumat Aset berjaya disimpan.');
}
AssetProcument.php Model
class AssetProcument extends Model
{
public $fillable = [
'additional_remark',
];
Blade
<form action="{{ route('asset_store_additional_procument') }}" method="POST">
#csrf
<div class="card-body">
<div class="col">
<table class="table table-bordered" id="dynamicTable">
<thead>
<tr>
<th>Catatan</th>
</tr>
</thead>
<tbody>
<tr>
<td style="width:50%"><textarea type="text" name="addmore[][additional_remark]"
class="form-control"></textarea></td>
<td>
<button type="button" name="add" id="add" class="btn btn-success">Tambah</button>
</td>
</tr>
</body>
</table>
</div>
<div class="col-12">
<input type="submit" value="Save Changes" class="btn btn-success float-right">
</div>
</div>
</form>
<script type="text/javascript">
var i = 0;
$("#add").click(function(){
++i;
$("#dynamicTable").append('<tr><td><textarea type="text" name="addmore['+i+'][additional_remark]" class="form-control" /></textarea></td>'.'
<td><button type="button" class="btn btn-danger remove-tr">Remove</button></td></tr>');
});
$(document).on('click', '.remove-tr', function(){
$(this).parents('tr').remove();
});
Route
Route::post('asset_store_additionalprocuments',[AssetController::class,'StoreAdditionalProcuments'])->name('asset_store_additional_procument');
Since additional_remark input is addmore[][additional_remark], your validation should be like this
$request->validate([
'addmore.*.additional_remark' => 'required',
]);
* mark is all indexes of addmore array
I'm trying to insert multiple data into my database by using array and javascript. But what happened is, I only could submit one data into my complaints table. The balanced is not inserted. There is no error appeared.
users table
id
role
email
typable_id
typable_type
buyers table
id
name
buyer_id
address
phone_no
defects table
id
name
complaints table
id
defect_id
image
description
report_by
ComplaintController.php
class ComplaintController extends Controller
{
public function index()
{
return view('buyers.complaint');
}
public function create(Request $request)
{
if (count($request->defect_id) > 0) {
foreach($request->defect_id as $item=>$v) {
$data = array(
'defect_id' => $request->defect_id[$item],
'image' => $request->image[$item],
'description' => $request->description[$item],
'report_by' => auth()->user()->typable->buyer_id
);
Complaint::insert($data);
}
}
return redirect('/report-form')->with('success','Your report is submitted!');
}
complaint.blade.php
<div class="panel-heading">
<h3 class="panel-title"><strong>Make New Report</strong></h3>
</div>
<div class="panel-body">
<div>
<div class="panel">
<table class="table table-bordered">
<thead>
<tr>
<th><center>Type of Defect</center></th>
<th><center>Image</center></th>
<th><center>Description</center></th>
<th><center>Action</center></th>
</tr>
</thead>
<tbody>
<tr>
<td width="20%">
<form action="/report-create" method="post" enctype="multipart/form-data">
{{ csrf_field() }}
<select class="form-control" name="defect_id[]">
<option value="" selected>Choose Defect</option>
#foreach(App\Defect::all() as $defect)
<option value="{{$defect->id}}">{{$defect->name}}</option>
#endforeach
</form>
</td>
<td width="15%">
<input type="file" class="form-control-file" name="image[]">
</td>
<td width="45%">
<input type="text" class="form-control" name="description[]">
</td>
<td width="10%">
<button type="button" class="btn btn-info btn-sm" id="add-btn"><i class="glyphicon glyphicon-plus"></i></button>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<center><button type="submit" class="btn btn-primary">Submit</button></center>
</div>
javascript in blade
<script>
$(document).ready(function () {
$('#add-btn').on('click',function () {
var html = '';
html += '<tr>';
html += '<td><select class="form-control" name="defect_id[]"><option value="" selected>Choose Defect</option>#foreach(App\Defect::all() as $defect)<option value="{{$defect->id}}">{{$defect->name}}</option>#endforeach</td>';
html += '<td><input type="file" class="form-control-file" name="image[]"></td>';
html += '<td><input type="text" class="form-control" name="description[]"></td>';
html += '<td><button type="button" class="btn btn-danger btn-sm" id="remove-btn"><i class="glyphicon glyphicon-minus"></i></button></td>';
html += '</tr>';
$('tbody').append(html);
})
});
$(document).on('click','#remove-btn',function () {
$(this).closest('tr').remove();
});
</script>
I have a form where the user can add as much as he want of Table object that also can contains as much as he want of Columns object (like building tables in SQL).. I've tried the code bellow but nothing works and the form dosnt appear anymore when I've tried to bind the two lists.
Controller
#ModelAttribute("page")
public Page getTable() {
TableColumn column = new TableColumn();
List<TableColumn> columns = new ArrayList<>();
columns.add(column);
Table table = new Table();
table.setColumns(columns);
List<Table> tables = new ArrayList<>();
tables.add(table);
Page page = new Page();
page.setTables(tables);
return page;
}
#GetMapping("/scriptsqlgenerator")
public String viewForm(#ModelAttribute("page") Page page) {
return "ScriptSqlNext";
}
#PostMapping("/scriptsqlgenerator")
public String generateScript(#ModelAttribute("page") Page page) {
page.tables.forEach((t) ->{
System.out.println(t.getName());
t.getColumns().forEach((c) -> {
System.out.println(c.getName());
System.out.println(c.getType());
System.out.println(c.getIndex());
System.out.println(c.getNotnull());
});
});
}
HTML
<form th:object="${page}" class="list-group" th:action="#{/filegenerated}" method="get">
<a class="list-group-item list-group-item-action" data-toggle="collapse" data-target="#target1"> Create Table </a>
<div id="target1" class="collapse" style="margin: 30px;">
<div id="tablelist">
<div class="form-inline itemtable" th:each="table, itemStat :${page.tables}">
<div class="form-group mb-2 d-none">
<input th:field="*{tables[__${itemStat.index}__].id}" type="text" class="form-control">
</div>
<div class="form-group mb-2">
<input th:field="*{tables[__${itemStat.index}__].name}" type="text" class="form-control" placeholder="Table name">
</div>
<input type="button" class="btn btn-danger mb-2 ml-2" onclick="addRow()" value="Add column">
<div class="table-responsive">
<table class="table table-bordered">
<thead>
<tr>
<th scope="col" class="d-none">Id</th>
<th scope="col">Column Name</th>
<th scope="col">Type</th>
<th scope="col">Index</th>
<th scope="col">Null</th>
</tr>
</thead>
<tbody id="columnlist">
<tr class="item" th:each="column,status :
${table.columns}">
<td><input th:field="*{tables[__${itemStat.index}__].columns[__${status.index}__].name}" type="text" class="form-control" required></td>
<td><select th:field="*{tables[__${itemStat.index}__].columns[__${status.index}__].type}" id="inputState" class="form-control" required>
<option value="" selected
disabled>Choose</option>
<option th:value="${type}">int</option>
<option th:value="${type}">varchar</option>
</select>
</td>
<td><select th:field="*{tables[__${itemStat.index}__].columns[__${status.index}__].index}" id="inputState" class="form-control" required>
<option value="" selected
disabled>Choose</option>
<option th:value="${index}">on</option>
<option th:value="${index}">off</option>
</select>
</td>
<td><select th:field="*{tables[__${itemStat.index}__].columns[__${status.index}__].notnull}" id="inputState" class="form-control" required>
<option value="" selected
disabled>Choose</option>
<option th:value="${notnull}">on</option>
<option th:value="${notnull}">off</option>
</select>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<button class="btn btn-danger mb-2 text-center" type="button" id="addTable" style="margin-top: 30px;">Add table</button>
</div>
<div class="text-center">
<button type="submit" class="btn btn-outline-danger btn-lg" style="margin-
top: 50px;">Generate File</button>
</div>
</form>
For the JS part I was using some codes to implement the addRow() method which will add more Columns to the Table and addTable() method that would add another Table object, but nothing was working for my case
This is my view is looking like:
*PLEASE CAN ANYONE HELP ME TO SOLVE THAT .. I REALLY NEED IT .... *
Your approach is okay. But you need to fix a few things.
In the getTable method, you are setting empty lists for tables and columns. So there is nothing to iterate over in the view layer to show the form. Change to:
#ModelAttribute("page")
public Page getTable() {
Column column = new Column();
List<Column> columns = new ArrayList<>();
columns.add(column);
Table table = new Table();
table.setColumns(columns);
List<Table> tables = new ArrayList<>();
tables.add(table);
Page page = new Page();
page.setTables(tables);
return page;
}
And
Add missing } for th:field="*{tables[__${i.index}__].name" and close this input tag.
NOTE:
I am not sure how you wanted to handle the three select inputs. I tested omitting them, meaning, keeping only Column id and name in the form, data bind without any issue in that case.
Also I didn't check your JS, as you have mentioned that you haven't tested it yet.
Suggestions:
I see you are returning a view name from your POST handler. Take a look at the following article on Wikipedia.
Post/Redirect/Get
Hello there vue js guru's
Currently i'm creating some wizard with a little bit more "advanced" setup and need some help getting the correct outcome. I tried a few different methods but not with any success yet.
What i'm trying to do is the following:
I'm building a workout create wizard where it's possible to add sections and inside each section you could define one or more movements where each movement itself should have some sort of measurement this last one should change based on the selected movement and could have one or more options as an select to.
The data is fetched by axios (remotely) and saved to the data array for available movements like so:
[
'' => [
1 => [
'name' => 'pull ups',
'measure' => [
0 => 'none',
1 => 'distance',
],
],
2 => [
'name' => 'push ups',
'measure' => [
0 => 'none',
1 => 'weight',
],
],
...
],
...
]
this will then be stored in the this.movements = data.movements; data array in my vue js instance.
Here is my vue js code:
<script>
new Vue({
el: '#workout-wrapper',
data() {
return {
dynamicOptions: [],
name: null,
sections: [{
name: null,
rounds: null,
minutes: null,
measure: null,
movements: [{
reps: null,
movement: null,
measure: null,
remarks: null
}]
}],
movements: [],
...
}
},
methods: {
...
onMovementChange(group, movement) {
// TODO: this one combined with the computed options still isn't working correctly
if (group == '') {
this.options = { section: 0, movement: 0, options: this.movements[""][movement].measure };
} else {
this.options = { section: 0, movement: 0, options: this.movements[group][movement].measure };
}
},
...
},
computed: {
options: {
get(event, data) {
// TODO: now we should only return the options for section and movement indexes
return this.dynamicOptions;
},
set(data) {
this.dynamicOptions[data.section] = [];
this.dynamicOptions[data.section][data.movement] = data.options;
// console.log(this.dynamicOptions);
}
}
},
created() {
axios.get('/workouts/create/data').then(response => {
let data = response.data;
this.movements = data.movements;
...
}).catch(error => {
console.error(error);
});
}
});
</script>
And here the template:
<div class="row m-t-20" v-for="(section, index) in sections">
<div class="col-md-12">
<div class="card card-default no-border">
<div class="card-header separator">
<div class="row">
<div class="col-md-12">
<div class="form-group">
<label>Section name</label>
<div class="input-group m-b-15">
<input type="text" name="sections[0][name]" placeholder="e.g. Warming-Up" class="form-control" v-model="section.name">
<div class="input-group-btn">
<button type="button" class="btn btn-danger" data-title="Remove" data-tooltip #click="removeSection(index)">
<i class="fa fa-times"></i>
</button>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-4">
<div class="form-group">
<label>Rounds</label>
<input type="number" name="sections[0][rounds]" class="form-control" placeholder="Optional" min="0" v-model="section.rounds">
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<label for="">
Minutes
</label>
<input type="number" name="sections[0][minutes]" class="form-control" placeholder="Optional" min="0" v-model="section.minutes">
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<label>Measure</label>
<select name="sections[0][measure]" class="form-control" v-model="section.measure"> {{-- data-init-plugin="select2" --}}
<option :value="key" v-for="(measure, key) in measurements">#{{ measure }}</option>
</select>
</div>
</div>
</div>
</div>
<div class="card-block m-t-25">
<table class="table table-striped">
<thead>
<tr>
<th width="10%">
Reps
</th>
<th width="35%">
Movement
</th>
<th width="20%">
Measure
</th>
<th width="35%">
Remarks
</th>
<th></th>
</tr>
</thead>
<tbody>
<tr v-for="(movement, movementIndex) in section.movements">
<td>
<input type="number" name="sections[0][movements][0][reps]" class="form-control" min="0" v-model="movement.reps">
</td>
<td>
<select name="sections[0][movements][0][movement]" class="form-control" v-model="movement.movement" #change="onMovementChange('', movement.movement)">
<optgroup :label="group" v-for="(options, group) in movements">
<option :value="key" v-for="(option, key) in options">#{{ option.name }}</option>
</optgroup>
</select>
</td>
<td>
<select name="sections[0][movements][0][measure]" class="form-control" v-model="movement.measure" :disabled="!movement.movement">
<option :value="key" v-for="(measure, key) in options">#{{ measure }}</option>
</select>
</td>
<td>
<textarea name="sections[0][movements][0][remark]" rows="1" class="form-control" v-model="movement.remarks"></textarea>
</td>
<td>
<button type="button" class="btn btn-link text-danger" data-title="Remove" data-tooltip #click="removeMovement(index, movementIndex)">
<i class="fa fa-trash"></i>
</button>
</td>
</tr>
<tr>
<td colspan="5" class="text-center">
<button type="button" class="btn btn-cons btn-complete" data-title="Add movement" data-tooltip #click="addMovement(index)">
<i class="fa fa-plus"></i>
</button>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
With this current set up it's adding the data in the second select box but it's always changing, so when adding a second movement row then both select boxes are changing there options based on the selected movement in the second row etc... it should only change based on the current row instead and section off course.
Maybe some of you could help me with this problem... if more info is needed please let me know :-)
I am binding a scope variable, an array to ng-repeat div tag (a table basically).
When I dynamically add any data to the array, it works! A row is added to the table.
But when I remove an element from the array, the change doesn't reflect on the table. One row should be removed.
Following is the code that I'm working with (Javascript):
$scope.myfields = [];
$scope.addField = function () {
$scope.myfields.push({ "name": "", "type": "", "required": "", "enum": "" });
console.log("add: " + $scope.myfields.length);
console.log(JSON.stringify($scope.myfields));
}
$scope.removeField = function (index) {
$scope.myfields.splice(index, 1);
console.log("remove: " + $scope.myfields.length);
console.log(JSON.stringify($scope.myfields));
}
EJS: Please see below!
Weird thing is,
In console log, it says that changes are made as expected to $scope variable, only view(table) is not getting updated.
And if I don't put "track by $index", add and remove both stops reflecting in table!
Any help appreciated. Thanks!
EDIT 2:
The code you have asked for:
<div class="col-md-12">
<p style="text-align:center"><strong>DEFINE CUSTOM FIELDS:</strong></p>
<br>
<div style="text-align:center">
Click on '+' button to add custom field:
<div class="fa fa-plus-circle" ng-click='addField()'> </div>
<div class="fa fa-minus-circle" ng-click='removeField(0)'> </div>
</div>
<br>
<div data-responsive-table>
<table data-table>
<thead >
<tr >
<th data-event='sort'>
Field Name
</th>
<th data-event='sort'>
Type
</th>
<th data-event='sort'>
Is Required?
</th>
<th data-event='sort'>
Enumeration
</th>
</tr>
</thead>
<tbody >
<tr data-parent-row ng-repeat="um in dynamicFields track by $index">
<td>
<input placeholder="Name" ng-model="um.name" validation="required" >
</td>
<td>
<select style='height: 45px;' ng-model="um.type" >
<option value="string">string</option>
<option value="boolean">boolean</option>
<option value="integer">integer</option>
</select>
</td>
<td>
<select style='height: 45px;' ng-model="um.required" >
<option value="true">true</option>
<option value="false">false</option>
</select>
</td>
<td>
<input placeholder="Enum" ng-model="um.enum" validation="required" >
</td>
</tr>
</tbody>
</table>
</div>
</div>
The variable name in your ng-repeat should be myfields and not dynamicfields
Since in your controller it is $scope.myfields, in your view it should be
ng-repeat="um in myfields track by $index"