I am trying to edit and delete a data in Mongo.Collection. I have a document with a number of fields including an email address.
I check while updating the data if email exists just update the email else first create a user with that email using Accounts.createUser and then update the data. Although the data is being updated successfully in the database but showing it using the helpers is not working properly. I am trying to fill the form with the saved values, either form comes half-filled, or completely-filled(usually in the first edit attempt) or completely empty. I cannot understand the reason behind this beviour.
The form template
<template name="addUnit">
<div class="modal fade" id="addUnitModal" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title">{{#if isEdit}}Edit {{else}}Add {{/if}}Unit</h4>
</div>
{{#if tenantError}}
<div class="alert alert-danger" role="alert">{{tenantError}}</div>
{{/if}}
<form class="frmUnit" id="frmUnit">
<div class="modal-body">
<input class="form-control" type="text" placeholder="Unit Name" name="unitName" value="{{selectedUnit.unitName}}"/>
<input class="form-control" type="number" placeholder="Number of Residents" name="residents" value="{{selectedUnit.residents}}"/>
<input class="form-control" type="number" placeholder="Area sqft." name="area" value="{{selectedUnit.area}}"/>
<input class="form-control" type="text" placeholder="Primary Tenant" name="primaryTenant" value="{{selectedUnit.primaryTenant}}"/>
<input class="form-control" type="email" name="tenantEmail" placeholder="Tenant's Email" value="{{selectedUnit.tenantEmail}}"/>
<input class="form-control" type="password" name="tenantPassword" placeholder="Tenant's Password"/>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
{{#if isEdit}}
<button type="submit" class="btnEditUnit btn btn-primary">Edit Unit</button>
{{else}}
<button type="submit" class="btnAddUnit btn btn-primary">Add Unit</button>
{{/if}}
</div>
</form>
</div>
</div>
</div>
</template>
Helpers
Template.addUnit.helpers({
isEdit: function() {
return Session.get('isEdit');
},
tenantError: function(){
return Session.get('tenantError');
},
selectedUnit: function(){
return Session.get('selectedUnit');
}
});
Events
Template.addUnit.events({
"submit .frmUnit": function(event){
event.preventDefault();
var form = event.target;
if(!Session.get('isEdit')){
console.log('adding');
Meteor.call('addUnit',
Session.get('selectedBuilding')._id,
{
unitName: form.unitName.value,
primaryTenant: form.primaryTenant.value,
tenantEmail: form.tenantEmail.value,
tenantPassword: form.tenantPassword.value,
residents: form.residents.value,
area: form.area.value
}, function(error, result) {
console.log(error, result);
if(!error){
$('#frmUnit')[0].reset();
$('#addUnitModal').modal('hide');
Session.set('tenantError', null);
}else{
Session.set('tenantError', error.reason);
}
});
}else{
console.log('editing');
Meteor.call('editUnit',Session.get('selectedUnit')._id,{
unitName: form.unitName.value,
primaryTenant: form.primaryTenant.value,
residents: form.residents.value,
area: form.area.value,
tenantEmail: form.tenantEmail.value,
tenantPassword: form.tenantPassword.value
}, function(error, result) {
if(!error) {
$('#frmUnit')[0].reset();
$('#addUnitModal').modal('hide');
}else{
Session.set('tenantError', error.reason);
}
});
}
}
});
Edit unit on the server
editUnit: function(unitId, unit){
//if the email entered already exists update the email and password
var updatedTenant = Accounts.findUserByEmail(unit.tenantEmail);
if(updatedTenant){
if(unit.tenantPassword && unit.tenantPassword !== ""){
Accounts.setPassword(updatedTenant._id, unit.tenantPassword);
}
Units.update({_id: unitId},
{
$set :{
unitName:unit.unitName,
primaryTenant:unit.primaryTenant,
residents: unit.residents,
area: unit.area,
tenantEmail: unit.tenantEmail
}
});
}else{
//if email doesn't exist already, create a new user first
var newUserId = Accounts.createUser(
{
email: unit.tenantEmail,
password: unit.tenantPassword,
profile:{
firstname: unit.primaryTenant,
lastname:"",
phone:"",
isTenant:true
}
});
if(newUserId){
Units.update({_id: unitId},
{
$set :{
unitName:unit.unitName,
primaryTenant:unit.primaryTenant,
residents: unit.residents,
area: unit.area,
tenantEmail:unit.tenantEmail
}
});
}
}
},
Session.get('selectedUnit') is being set from a different click handler, which displays the form. The value is being set correctly I can see that by logging it to the console.
'isEdit' is also being set from a click handler of a different template.
I have other forms working with the same approach, but they don't have Account creation and validation in them. Is it because of that?
Edit
Template.owner.events({
"click .editUnit":function(){
Session.set('isEdit', true);
Session.set('selectedUnit', this);
}
});
{{#each buildingUnits}}
<tr>
<td>
{{unitName}}
</td>
<td>
<span class= "editUnit list-icon glyphicon glyphicon-edit" data-target="#addUnitModal" data-toggle="modal" aria-hidden="true" style="padding-right: 4px;"></span>
<span class= "deleteUnit list-icon glyphicon glyphicon-remove" aria-hidden="true"></span>
</td>
</tr>
{{/each}}
I have tried to log this onto the console, I am getting the correct result, just after the two lines I tried to get the session back using Session.get('selectedUnit') and tried logging it to console, this also gives me the correct result, which means session is being successfully set.
Related
I am trying to validate the length of ID value in userForm in Angular14, I tried for
if(this.userForm.value.id.length < 6 || this.userForm.value.id.length >9){
console.log("length error")
}
But this is not giving the expected result. the above snippet is working for != and = only.
How can I validate this value for the range.
Adding the .ts and .html snippets for the better understanding.
component.ts
userSubmit(){
console.log(this.userForm.get('image').value);
console.log(this.userForm.value);
const formData = new FormData();
formData.append('image', this.images);
formData.append('id', this.userForm.value.id);
formData.append('des', this.userForm.value.des);
formData.append('name', this.userForm.value.name);
if(this.userForm.value.id.length < 6 || this.userForm.value.id.length > 9){
console.log("length error")
}
component.html
<div class="container">
<div *ngIf="errorMsg" class="alert alert-danger alert-dismissible fade show" role="alert">
<strong>{{errorMsg}}</strong>
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
<form [formGroup]="userForm" >
<div class="col-lg-4 mt-2" >
<label>Employee ID:</label>
<input type="number" class="form-control" formControlName="id" [(ngModel)]="id">
</div>
<div class="col-lg-4 mt-2" *ngIf="!getParamId" >
<button class="btn btn-primary btn-sm" [disabled]="!name || !des ||!photo||!id" (click)="userSubmit()">
Submit!!
</button>
</div>
<div class="col-lg-4 mt-2" *ngIf="getParamId" >
<button class="btn btn-dark btn-sm" (click)="userUpdate()" >
Update
</button>
</div>
</form>
</div>
From what I understand from your question, you are performing the validation for id with the length within a range.
The problem is currently your id is not a string, but it is a number.
<input type="number" class="form-control" formControlName="id" [(ngModel)]="id">
Hence you can't use .length as this property doesn't exist in the number value.
Change the <input> element from type="number" to type="text" or without type. (By default type is text).
Since you are using the Reactive form, you don't need the [(ngModel)].
<input type="text" class="form-control" formControlName="id" />
Add Validators.minLength() and Validators.maxLength() validators to id form control.
import { Validators } from '#angular/forms';
this.userForm = this.fb.group({
id: [
'',
[Validators.required, Validators.minLength(6), Validators.maxLength(9)],
],
// Following controls
});
Note: If you want the id input to be numeric characters, you need Validators.pattern():
Validators.pattern('[0-9]+')
Or validate with the length as well, so the Validators.minLength() and Validators.maxLength() can be omitted.
Validators.pattern('[0-9]{6,9}')
To disable the submit button when there is any control(s) that failed the validation:
<button
class="btn btn-primary btn-sm"
[disabled]="idHasError /* or other form controls */"
(click)="userSubmit()"
>
Submit!!
</button>
And implementing the getter.
get idHasError() {
return this.userForm.controls.id.errors;
}
Implement the getter method(s) for the rest form control(s) to return a boolean value that the form control has errors or not.
Demo # StackBlitz
So idea is Id like the user to click a button, have the page submit through the post method which will populate fields for a form, then return the page with a modal displayed. I have this working, except the issue is that the page is at the top even if the user clicked halfway down. Id like the page to redisplay where it was, with the modal displaying.
I know that there is a fragment parameter, but only for redirecttopage and not page()? Sending it back to get resets everything, so thats not realy ideal. Ive also tried altering the url with javascript which works with setting the page position, but somehow it will not display the modal with that?
Does anyone know how to easily return the page in the post method to a specific spot on the page?
Javascript: (Modal shows up for one second then disappers when it goes to the page position)
function OnLoad() { //Used for redisplaying on error purposes
if ("#TempData["EditingParty"]" == "Yes") {
var loadedURL = window.location.href;
var fragmentPieceOfURL = "#TempData["EndOfURL"]"
location.href = loadedURL + fragmentPieceOfURL;
document.getElementById("EditUsersForm").style.display = "inline-block";
}
else {
document.getElementById("EditUsersForm").style.display = "none";
}
}
Cshtml
Button that goes to post (i is counter to keep track of anchor tag for redisplay location):
<a id="#i"></a>
<button type="submit" style="white-space:nowrap" class="btn btn-secondary btn-sm" formnovalidate asp-page-handler="DisplayEdit" asp-route-id="#Model.UsersOnCaseList.ElementAtOrDefault(i).UserID" asp-route-AttorneyRole="#Model.UsersOnCaseList.ElementAtOrDefault(i).AttorneyRole" asp-route-email="#Model.UsersOnCaseList.ElementAtOrDefault(i).EmailAddress" asp-route-pAttorneyRoleID="#Model.UsersOnCaseList.ElementAtOrDefault(i).AttorneyRoleID" asp-route-PageFragment="#i" asp-route-pEditAttorneyUserID="#Model.UsersOnCaseList.ElementAtOrDefault(i).UserID">Edit <i class="fas fa-ribbon"></i></button>
Modal:
<div class="modal" tabindex="-1" role="dialog" id="EditUsersForm" style="display:none">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Edit User</h5>
<button type="button" onclick="closeEditUsersForm()" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="form-group" style="margin-top:15px;padding-left:15px">
<label asp-for="EditUserEmailInput"></label> <span class="red">*</span>
<input asp-for="EditUserEmailInput" class="form-control" id="EmailInputBox" value="#Model.EditUserEmailInput" style="display:block;width:25em" />
<span style="display:block" asp-validation-for="EditUserEmailInput" class="text-danger" id="AddUserInputValidation"></span>
</div>
<div class="form-group" style="margin-top:15px;padding-left:15px">
<label class="control-label">Role</label> <span class="red">*</span>
<select asp-for="AttorneyRoleIDEditForm" asp-items="#(new SelectList(Model.AttorneyRolesList, "AttorneyRoleID","AttorneyRole"))" name="AttorneyRoleIDEditForm" id="SelectAttorneyRoleIDEditForm" class="form-control" style="width:25em" onchange="DidSelectPlaintiffEdit()">
<option class="form-control" value=-1>Select a Role</option>
</select>
<span asp-validation-for="AttorneyRoleIDEditForm" class="text-danger"></span>
</div>
<div class="form-group" style="margin-top:15px;padding-left:15px">
<label asp-for="EditUserPartyInput"></label> <span class="red">*</span><br />
<input asp-for="EditUserPartyInput" value="#Model.EditUserPartyInput" class="form-control" id="PartyNameInputEdit" style="display:inline-block;width:25em" />
<span style="display:block" asp-validation-for="EditUserPartyInput" class="text-danger" id="PartyNameInputValidation"></span>
</div>
<div class="modal-footer">
<button class="btn btn-primary" style="margin:0 auto" asp-page-handler="SaveUserEdits" asp-route-UserBeingEdited="" id="EditSubmitButton" name="EditUserSubmit" value="Yes">Submit</button>
<button class="btn btn-primary" style="margin:0 auto; display:none" asp-page-handler="SaveUserEdits" disabled id="SubmitButtonDisabled" name="AddUserSubmit" value="Yes">Submit</button>
</div>
</div>
</div>
</div>
CS file:
public IActionResult OnPostDisplayEdit(int id, string email,string AttorneyRole,int pAttorneyRoleID,int pAttorney,int pEditAttorneyUserID,int PageFragment)
{
EditUserEmailInput = email;
string curDictionaryAttorneyRole;
if (AttorneyRole.Contains('('))//Just because in development user didnt always have ability to enter a party
{
curDictionaryAttorneyRole = AttorneyRole.Split(new[] { '(' }, 2)[0].Trim();
EditUserPartyInput = AttorneyRole.Split(new[] { '(' }, 2)[1];
var LastRightParenIndex = EditUserPartyInput.LastIndexOf(')');
EditUserPartyInput = EditUserPartyInput.Substring(0, LastRightParenIndex); //Pulling the right parenthesis out
}
else //Its just the dictionary role
{
curDictionaryAttorneyRole = AttorneyRole;
EditUserPartyInput = null;
}
TempData["EditingParty"] = "Yes";
TempData["EndOfURL"] = PageFragment.ToString() + "&#" + PageFragment.ToString();
SetFileSequenceField();
ModelState.Clear(); //Used to remove the validations
SetAttorneyRoleList();
var selectedIndex = AttorneyRolesList.Where(arl => arl.AttorneyRole == curDictionaryAttorneyRole).Select(arl => arl.AttorneyRoleID).FirstOrDefault();
AttorneyRoleIDEditForm = selectedIndex;
EditAttorneyUserID = pEditAttorneyUserID;
UneditedEmail = email;
UneditedAttorneyRoleID = pAttorneyRoleID;
PopulateUserList();
//return RedirectToPage("AddUsersToCase","GET",fragment:PageFragment.ToString());
return Page();
//var PageURL = Page();
//PageURL = PageURL. + "&#" + PageFragment.ToString();
//return PageURL;
}
You can try to replace
location.href = loadedURL + fragmentPieceOfURL;
to
history.pushState({}, null, loadedURL + fragmentPieceOfURL);
So that the page will not be refreshed with location.href.
good day;
i new in laravel and vue.js when i submit form if i have problem in validate one of input it show correctly like The Brand Name field is required. but my real problem is when submitted form successfully when i show response message that i get from controller **i get only one capital** **litter of message appear** only like ***Y*** like "Your Data Added Successfully" but i get the first litter isY` like attached photo that appear how can i solve this problem
thanks
here is my controller
<?php
namespace App\Http\Controllers;
use App\PhoneBook;
use Illuminate\Http\Request;
use Validator;
class PhoneBookController extends Controller
{
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\Response
*/
public function index()
{
//
return view('phonebook');
}
}
public function add(Request $request)
{
//prepare data for validation
$validationarray=Validator::make($request->all(),
[
'name' => 'required',
'phone' => 'required|min:2|required',
'email' => 'required',
]
,[],[
"name"=>"Brand Name",
'phone' => 'phone',
'email' => 'Email',
]);
if($validationarray->fails())
{
foreach ($validationarray ->messages()->getMessages() as $field_name =>$message):
$response['message']=$message;
endforeach;
$response['status']="failed";
return response()->json($response);
}
// start pass data to model
$branddata=array(
'name' =>$request->name,
'phone' =>$request->phone,
'email' =>$request->email,
);
// start add data
$add=PhoneBook::create($branddata)->id;
if(false !=$add)
{
return response(['status'=>'success',"message"=>"Your Data Added Successfully"]);
}else{
return response(['status'=>'failed',"message"=>"Error Adding data please try again !!"]);
}
}
then my route is
Route::post('phonebook/add',"PhoneBookController#add")->name("cart.deleteProductFromCart");
my view code template
<template>
<div>
<div class="modal fade" id="addData" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">New message</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<span v-if="list.status=='success'" >Record submitted successfully!</span>
<div v-model="list.message" >{{list.message?list.message[0]:''}}</div>
<div class="form-group">
<label for="exampleInputEmail1">Brand Name</label>
<input type="text" name="name" v-model="list.name" class="form-control" id="exampleInputEmail1" placeholder="Example : Kia - Renault">
<p class="help-block">Example : Kia - Renault</p>
</div>
<div class="form-group">
<label class="col-form-label">phone:</label>
<input type="text" name="phone" v-model="list.phone" class="form-control" id="reckipient-name">
<p class="help-block">Example : Kia - Renault</p>
</div>
<div class="form-group">
<label class="col-form-label">email:</label>
<input type="text" class="form-control" v-model="list.email" name="email" id="recikpient-name">
<p class="help-block">Example : Kia - Renault</p>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary" #click="save">Send message</button>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: "addData",
data: function () {
return {
list: {
name: '',
phone: '',
email: '',
message:'',
},
}
},
methods: {
save: function () {
axios.post('/phonebook/add',this.$data.list)
.then((response) => this.list.message=response.data.message)
.catch((error) => this.list.message=error.response.data.message)
}
}
}
</script>
<style scoped>
</style>
[![enter image description here][1]][1]
[1]: https://i.stack.imgur.com/sZpDS.png
It's good to pass response as JSON Format
YourXYZController.php
....
$data = new stdClass;
$data->status = "success";
$data->message = "your message";
return response(json_encode($data));
in Vuejs
axios.post('YourXYZController URL', params)
.then(response => {
console.log(response)
})
.catch(error => {
console.log(response)
})
})
And also it's best practice to check request and response in network tab of browser.
I Have a change password form which I have tried to code so that it gets submitted through ajax.
I needed to do validation too.
Below is the code that I've written. Is there anyway so that we can use this js ajax function for multiple modal forms?
Or will we need to create a seperate function for submitting each modal form?
Also I wanted to make the parent page reload after user closes the modal so I have added this code:
$('#edit').on('hidden.bs.modal', function() {
location.reload();
});
but it reloads the page when someone clicks cancel button too. Is there any way to prevent reloading when clicking cancel button and only do reloading only by clicking "x".
Here is the code
index.php file where the modal is
<p data-placement="top" data-toggle="tooltip" title="Edit" data-original-title="Edit">
<button class="btn btn-primary btn-xs" data-title="Edit" data-toggle="modal" data-target="#edit" data-backdrop="static" data-keyboard="false">
<span class="glyphicon glyphicon-pencil"> Edit</span>
</button>
</p>
<div class="modal fade" id="edit" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title" id="myModalLabel">Edit Your Detail</h4>
</div>
<!--/.modal-header-->
<div class="modal-body">
<form method="post" id="updateForm" action="update-info.php">
<input type="hidden" name="userID" value="<?php echo $_SESSION['user']; ?>" />
<div class="form-group">
<label for="customer_name">Customer Name :</label>
<input class="form-control" type="text" name="customer_name" id="customer_name" value="<?php echo $userRow['fullName']; ?>" />
</div>
<h4><u><strong>Change Password</strong></u></h4>
<div class="form-group" id="currentPass-group">
<label for="current_pass">Current Password :</label>
<input class="form-control" type="password" name="current_pass" id="current_pass">
</div>
<div class="form-group">
<label for="new_pass">New Password :</label>
<input class="form-control" type="password" name="new_pass" id="new_pass">
</div>
<div class="form-group">
<label for="confirm_pass">Confirm Password :</label>
<input class="form-control" type="password" name="confirm_pass" id="confirm_pass">
</div>
<div class="modal-footer">
<!-- <input type="submit" name="submit" class="btn btn-block btn-warning" value="Save changes" /> -->
<button type="submit" name="submit" class="btn btn-success" id="submitForm" value="Save changes">Save Changes</button>
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
</div>
</form>
</div>
</div>
</div>
</div>
<!--/.modal -->
custom.js file:
$('#edit').on('hidden.bs.modal', function() {
location.reload();
});
/* must apply only after HTML has loaded */
$(document).ready(function() {
$("#updateForm").on("submit", function(e) {
$(".error").hide();
var hasError = false;
var currentpass = $("#current_pass").val();
var newpass = $("#new_pass").val();
var cnfpass = $("#confirm_pass").val();
if (currentpass == '') {
$("#current_pass").after('<span class="error text-danger"><em>Please enter your current password.</em></span>');
//$('#currentPass-group').addClass('has-error'); // add the error class to show red input
//$('#current_pass').append('<div class="help-block">Please enter your current password.</div>'); // add the actual error message under our input
hasError = true;
} else if (newpass == '') {
$("#new_pass").after('<span class="error text-danger"><em>Please enter a password.</em></span>');
hasError = true;
} else if (cnfpass == '') {
$("#confirm_pass").after('<span class="error text-danger"><em>Please re-enter your password.</em></span>');
hasError = true;
} else if (newpass != cnfpass) {
$("#confirm_pass").after('<span class="error text-danger"><em>Passwords do not match.</em></span>');
hasError = true;
}
if (hasError == true) {
return false;
}
if (hasError == false) {
var postData = $(this).serializeArray();
var formURL = $(this).attr("action");
$.ajax({
url: formURL,
type: "POST",
data: postData,
success: function(data, textStatus, jqXHR) {
$('#edit .modal-header .modal-title').html("Result");
$('#edit .modal-body').html(data);
$("#submitForm").remove();
//document.location.reload();
},
error: function(jqXHR, status, error) {
console.log(status + ": " + error);
}
});
e.preventDefault();
}
});
$("#submitForm").on('click', function() {
$("#updateForm").submit();
});
});
update-info.php
To use this code for multiple form add ajax code in one function and call that function whenever you want to.
To prevent page from reloading when someone click on cancel
Instead of using
$('#edit').on('hidden.bs.modal', function () {
location.reload();
});
Add one click event on cross and then reload page by location.reload();
You can use e.preventDefault(); and instead of submit use click event
$("#submitForm").on("click", function(e) {
e.preventDefault();
I'm banging my head against the wall here. I'm using ng-repeat to populate a table. Inside each row i have 2 buttons, one for updating the row content and for uploading files. The upload button opens a bootstrap modal window, where the user selects the files and clicks on submit.
The submit button uses ng-click to run a function which uses $index as parameter. But the $index value is always the same no matter which row is selected.
The thing I don't understand is that I use the exact same syntax (although outside of a modal window) on my update button, which works just fine.
HTML:
<tr ng-repeat="item in items | filter:search " ng-class="{'selected':$index == selectedRow}" ng-click="setClickedRow($index)">
<td>{{$index}}</td>
<td ng-hide="idHidden" ng-bind="item.Id"></td>
<td ng-hide="titleHidden">
<span data-ng-hide="editMode">{{item.Title}}</span>
<input type="text" data-ng-show="editMode" data-ng-model="item.Title" data-ng-required />
<td>
<button type="button" class="btn btn-primary uploadBtn" data-ng-show="editMode" data-toggle="modal" data-target="#uploadModal">Upload file <i class="fa fa-cloud-upload"></i></button>
<!-- Upload Modal -->
<div class="modal fade" id="uploadModal" tabindex="-1" role="dialog" aria-labelledby="uploadModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h3 class="modal-title" id="uploadModalLabel">Options</h3>
</div>
<div class="modal-body">
<h4>Upload Documents</h4>
<form>
<div class="form-group">
<select data-ng-model="type" class="form-control" id="fileTypeSelect">
<option value="Policy">Policy</option>
<option value="SOP">SOP</option>
</select>
<br>
<div class="input-group"> <span class="input-group-btn">
<input type="file" id="file">
</span>
</div>
<br>
<button type="button" class="btn btn-default" data-ng-click="uploadAttachment($index, type)">Upload</button>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</div>
<button type="button" data-ng-hide="editMode" data-ng-click="editMode = true;" class="btn btn-default pull-right">Edit <i class="fa fa-pencil-square-o"></i></button>
<button type="button" data-ng-show="editMode" data-ng-click="editMode = false; updateItem($index)" class="btn btn-default">Save</button>
<button type="button" data-ng-show="editMode" data-ng-click="editMode = false; cancel()" class="btn btn-default">Cancel</button>
</td>`
JS:
$scope.uploadAttachment = function executeUploadAttachment(index, type) {
var listname = "Risk Register";
var id = $scope.items[index].Id;
console.log(indexID);
readFile("uploadControlId").done(function(buffer, fileName) {
uploadAttachment(type, id, listname, fileName, buffer).done(function() {
alert("success");
}).fail(function() {
alert("error in uploading attachment");
})
}).fail(function(err) {
alert("error in reading file content");
});
}
So the function uploadAttachment($index, type) which is triggered by ng-click doesn't pass the right index number. It always passes the same, no matter what row it is clicked in.
I have omitted some of the code that is irrelevant. If needed i can provide the whole thing.
Any suggestions to what I am missing?
Edit:
I have tried to implement DonJuwe suggestions.
I have added this inside my controller:
$scope.openModal = function(index) {
var modalInstance = $modal.open({
templateUrl: 'www.test.xxx/App/uploadModal.html',
controller: 'riskListCtrl',
resolve: {
index: function() {
return index;
}
}
});
};
This is my modal template:
<div class="modal-header">
<h3 class="modal-title" id="uploadModalLabel">Options</h3>
</div>
<div class="modal-body">
<h4>Upload Documents</h4>
<form>
<div class="form-group">
<select data-ng-model="type" class="form-control" id="fileTypeSelect">
<option value="Policy">Policy</option>
<option value="SOP">SOP</option>
</select>
<br>
<div class="input-group"> <span class="input-group-btn">
<input type="file" id="file">
</span>
</div>
<br>
<button type="button" class="btn btn-default" data-ng-click="uploadAttachment($index, type)">Upload</button>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
And finally my function which resides inside RiskListCtrl (the only controller i use):
$scope.uploadAttachment = function executeUploadAttachment(index, type) {
var listname = "Risk Register";
var id = $scope.items[index].Id;
console.log(indexID);
readFile("uploadControlId").done(function(buffer, fileName) {
uploadAttachment(type, id, listname, fileName, buffer).done(function() {
alert("success");
}).fail(function() {
alert("error in uploading attachment");
})
}).fail(function(err) {
alert("error in reading file content");
});
}
It seems that $scope.items[index].Id is empty. Error: Cannot read property 'Id' of undefined
The modal window has its own scope. That means you need to resolve data you want to pass into the modal's scope. To do so, use resolve within the modals open(options) method.
Before I will give you an example, I want to suggest having only one modal for all your table items. This will let you keep a single template where you can easily use id (now, you create a template for each of your table items which is not valid). Just call a controller function and pass your $index:
<button type="button" class="btn btn-primary uploadBtn" data-ng-show="editMode" ng-click="openModal($index)">Upload file <i class="fa fa-cloud-upload"></i></button>
In your controller, create the modal instance and refer to the template:
$scope.openModal = function(index) {
var modalInstance = $modal.open({
templateUrl: 'myPath/myTemplate.html',
controller: 'MyModalCtrl',
resolve: {
index: function() {
return index;
}
}
});
};
Now you can access index in your MyModalCtrl's scope by injecting index:
angular.module('myModule', []).controller('MyModalCtrl', function($scope, index) {
$scope.index = index;
});
Since, you are getting the index value outside model then you can also use ng-click and then call a function in your controller and store the index value in a temporary variable and then when you are using submit button then just take make another variable and assign the value of temporary variable to your variable. for example:
<button type="button" data-ng-show="editMode" data-ng-click="editMode = false; updateItem($index)" class="btn btn-default">Save</button>
and then make a function in your controller
$scope.updateItem = functon(index)
{
$scope.tempVar = index;
}
now use the value of tempVar in you function
$scope.uploadAttachment = function executeUploadAttachment(index, type) {
var index = tempVar; //assign the value of tempvar to index
var listname = "Risk Register";
var id = $scope.items[index].Id;
console.log(indexID);
readFile("uploadControlId").done(function(buffer, fileName) {
uploadAttachment(type, id, listname, fileName, buffer).done(function() {
alert("success");
}).fail(function() {
alert("error in uploading attachment");
})
}).fail(function(err) {
alert("error in reading file content");
});
}