How to change ng-include inside firebase firestore function - html

When I click on continue button it checks clients ID in firestore database and if ID does'nt exist then $scope.filePath = "createClient.htm" is called. everything is working fine but when I call this piece of code inside firebase function nothing happens
Inside HTML
<div ng-include="filePath" class="ng-scope">
<div class="offset-1 offset-sm-2 col-11 col-sm-7">
<h2>Enter Client ID</h2>
<br>
<div class="form-group">
<label for="exampleInputEmail1">ID</label>
<input id="client_id" type="text" class="form-control" placeholder="Client ID">
</div>
<div class="float-right">
<button type="button" class="btn btn-danger">Cancel</button>
<button type="button" ng-click="searchClient()" class="btn btn-success">Continue</button>
</div>
</div>
</div>
Internal Script
<script>
$scope.searchClient = function()
{
//$scope.filePath = "createClient.htm"; it works here
var id= document.getElementById('client_id').value;
db.collection("clients") // db is firestore reference
.where("c_id","==",id)
.get()
.then(function(querySnapshot)
{
querySnapshot.forEach(function(doc)
{
if(!doc.exists)
{
console.log("Client Does'nt Exist");
$scope.filePath = "createClient.htm"; // but doesnt works here inside this firebase function
}
}
);
}
);
}
};
</script>
when console.log is shown and firebase function are fully executed then if I click on "Continue" Button again it works fine and content of createClient.htm is shown inside ng-include="filePath". why i need to click twice ?

Related

Modal ajax.form validation ASP.NET MVC, error message not showing, modal not closing after succesful submit

i'm new to the ASP.net and i get easilly confused when jquery and Ajax get in the middle of a code.
I have a popup bootstrap Modal that show when i click on a button, the Modal contains an Ajax.form that allows me to create projects, i'm using HTML.validation to check if my form is filled correctly. I have two main problems :
When I enter valid informations in my form and i submit the form, the project is created succesfully but the Modal doesn't close automaticlly.
When i enter non-valid informations when i submit no message error apear, nonetheless when I close the modal and open it again, the errors apear.
I need your help to :
Close the modal once the submit form is valid.
Have the error message show in my modal form.
*This is a part of my main view :
enter code here
<!--validation script -->
<script src="~/Scripts/jquery.unobtrusive-ajax.min.js"></script>
<script src="~/Scripts/jquery.validate.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.js"></script>
<!-- Button trigger modal -->
<div>
<div>
<a class="btn btn-red ms-auto my-auto h-50"
href="#Url.Action("createProject", "ProjectSelection")" title="Nouveau projet"
data-bs-toggle="modal" data-bs-target="#Modal_NewProject"
ajax-target-id="Body_NewProject" data-bs-loader="Loader_NewProject">
<i class="feather-16" data-feather="plus"></i>
Créer projet
</a>
</div>
</div>
<br />
<!-- Modal View -->
<div class="modal fade" id="Modal_NewProject" tabindex="-1"
aria-labelledby="Label_NewProject" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="Label_NewProject">
Créer un Projet</h5>
<button type="button" class="btn-close"
data-bs-dismiss="modal" aria-label="Close"></button>
</div>
#using (Ajax.BeginForm("createProjectPost",
"ProjectSelection", new AjaxOptions { HttpMethod = "POST",
UpdateTargetId = "Body_NewProject" }, new { id = "projectForm" }))
{
<div id="Body_NewProject">
<div class="spinner-border" role="status"
id="Loader_NewProject">
<span class="visually-hidden">Loading...</span>
</div>
<!-- partial view "createProject" -->
</div>
}
</div>
</div>
</div>
<!---->
*And this is my partial view that containts the elements of the form
<div class="modal-body" id="frmProject">
<div class="input-group mb-3" id="">
#Html.DropDownListFor(m => m.Project.Domain,
new SelectList(Model.Domains, "IdDomain", "Name"),"Selectionner un domaine",
new { #class = "w-100", #id = "DomainSelection" })
#Html.ValidationMessageFor(m => m.Project.Domain, null,
new { style = "color: red;" })
</div>
<div class="input-group mb-3 mb-3 " id="teamSelection">
#Html.DropDownListFor(m => m.Project.Teams,
new SelectList(Model.Teams.Select(teamElement => teamElement.Name).ToList()),
"Selectionner une équipe", new { #class = "w-100" })
#Html.ValidationMessageFor(m => m.Project.Teams, null,
new { style = "color: red;" })
</div>
<div class="form-floating mb-3">
<input class="form-control " data-val-required="Le champ Projet est requis."
id="Project.Name" name="Project.Name" type="text" value="">
<label for="Project.Name" class="">Nom du projet</label>
#Html.ValidationMessageFor(m => m.Project.Name, null,
new { style = "color: red;" })
</div>
</div>
<div class="modal-footer mb-0">
<div class="panel-footer">
<button class="btn btn-secondary" data-bs-dismiss="modal"
type="button">Annuler</button>
<button type="submit" form="projectForm"
class="btn btn-red">Valider</button>
<div class="col-xs-10" id="lblstatus"></div>
</div>
</div>
*This is my Controller code
public ActionResult createProject()
{
//initialization code
return PartialView();
}
[HttpPost]
[ValidateAntiForgeryToken]
[HandleError]
public ActionResult createProjectPost(Project project)
{
#region Variable verification
if (!ModelState.IsValid)
{
Session["Error"] = true;
if (project.Domain == null)
{
Session["DomainError"] = true;
}
if (project.Teams == null)
{
Session["TeamError"] = true;
}
if (project.Name == null)
{
Session["NameError"] = true;
}
ViewData["project"] = "create";
//return View("ProjectSelectionPage");
return PartialView(project);
}
#endregion
#region Initialisation
//initilization code
#endregion
#region Check possible copy of the project
if (projectDB.Exist(project.Name))
{
//Check that this project doesn't exist in the database
//Create a session variable that will trigger an error message
Session["Error"] = true;
Session["NameCopy"] = true;
ViewData["project"] = "create";
return PartialView(project);
}
#endregion
#region Project to database and generate name
//Add the project to the database
#endregion
return PartialView();
}
It's been several days since i'm searching for an answer, i either missed one or didn't use it correctly.
enter image description here
Thank you

EditForm in Blazor app have multiple submit buttons

I have a simple Blazor Editform where i have multiple buttons with different navigations & toast notifications. I have OnValidSubmit attached to Editform. Now the validations are working for all the buttons. I have added onclick() to trigger button functions but I want onclick to be triggered only if user has entered all the details. Hope I have explained well. Please let me know for additional input.
Current output for Forward or Next buttons are : if No values entered -> Correct validation(asked to fill in details) -> forward notification displayed.
Expected output :
if No values entered -> Correct validation(asked to fill in details).
if All values entered -> Correct validation -> forward notification displayed.
Here is some code:
<EditForm EditContext="#editContext" OnValidSubmit="HandleValidSubmit" #onreset="HandleReset">
<DataAnnotationsValidator />
<div class="form-row">
<div class="form-group col">
<label>Role</label><br />
<InputRadioGroup #bind-Value="model.Role" class="form-control">
#foreach (var option in rdOptions)
{
<InputRadio Value="option" /> #option
<text> </text>
}
</InputRadioGroup>
<ValidationMessage For="#(() => model.Role)" />
</div>
<div class="form-group col">
<label>Company Name</label>
<InputSelect id="txtCompanyName" class="form-control" #bind-Value="#model.CompanyName">
<option selected value="-1">-Select-</option>
<option value="CompanyName1">CompanyName1</option>
<option value="CompanyName2">CompanyName2</option>
</InputSelect>
<ValidationMessage For="#(() => model.CompanyName)" />
</div>
</div>
<div class="form-row">
<div class="text-left col-3">
<button type="submit" class="btn btn-primary btn-success">Save</button>
</div>
<div class="text-right col-3">
<button type="submit" class="btn btn-primary" #onclick="#Forward">Forward</button>
</div>
<div class="text-right col-3">
<button type="submit" class="btn btn-primary" #onclick="#Review">Next</button>
</div>
<div class="text-right col-3">
<button type="reset" class="btn btn-secondary">Clear</button>
</div>
</div>
</EditForm>
code section:
#code {
private Model model = new Model();
private EditContext editContext;
List<Model> models = new();
protected override void OnInitialized()
{
editContext = new EditContext(model);
}
private void HandleValidSubmit()
{
var modelJson = JsonSerializer.Serialize(model, new JsonSerializerOptions { WriteIndented = true });
JSRuntime.InvokeVoidAsync("alert", $"SUCCESS!! :-)\n\n{modelJson}");
toastService.ShowSuccess("saved successfully!");
}
private void Forward()
{
toastService.ShowInfo("Forwarded!!");
}
private void Review()
{
toastService.ShowInfo("Review!!");
}
private void HandleReset()
{
model = new Model();
editContext = new EditContext(model);
}
}
Change type="submit" to type="button"
Except maybe for the Save button.
You can do validation manually in your button event handlers and then not use the EditForm OnValidSubmit, and set the button types to button.
...
if (editContext.Validate())
go
else
alert
...
FYI - The relevant bit of code from EditForm looks like this:
private async Task HandleSubmitAsync()
{
Debug.Assert(_editContext != null);
if (OnSubmit.HasDelegate)
{
// When using OnSubmit, the developer takes control of the validation lifecycle
await OnSubmit.InvokeAsync(_editContext);
}
else
{
// Otherwise, the system implicitly runs validation on form submission
var isValid = _editContext.Validate(); // This will likely become ValidateAsync later
if (isValid && OnValidSubmit.HasDelegate)
{
await OnValidSubmit.InvokeAsync(_editContext);
}
if (!isValid && OnInvalidSubmit.HasDelegate)
{
await OnInvalidSubmit.InvokeAsync(_editContext);
}
}
}
In my opinion you will need to use JavaScript to check the inputs were filled or not and based on that you can disable or enable the submit button

Controller not recognized by HTML after $state.go()

I'm fairly new to Angular and very new to using the ui-router, so I could be missing something obvious.
If I launch my results.html page on its own, everything from the Web API is bound correctly through the controller and shows up as expected.
When I start from index.html and click on the button that calls $state.go(), I am navigated to the results.html page .. but none of the data from the controller shows up. The controller & service are still being called though - because I put console.log() statements to verify that the object I want is being returned after $state.go() and it is - the template just isn't registering it.
Here is my code for my ui-router and main controller:
// script.js
var app = angular.module('BN', ['ui.router']);
// configure our routes
app.config(function ($locationProvider, $stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('');
$stateProvider
.state('default',{
url:'/',
templateURL:'index.html',
controller: 'MainController'
})
.state('results', {
url:'/results',
controller: 'ResultsController',
controllerAs: 'vm',
templateUrl: 'Results/Results.html'
})
.state('instructor', {
url:'/api/instructors/:id',
templateUrl: 'Instructors/Instructor.html'
});
$locationProvider.html5Mode(true);
});
app.controller('MainController', MainController);
function MainController ($state) {
var vm = this;
vm.Submit=function( ){
$state.go('results');
};
}
So Results.html renders perfectly fine launched on it's own, but when navigated to - the controller is called but not bound to the html template.
You have your index.html file set up properly, but after that you're using ui-router incorrectly.
In your index.html file where you have:
<body ui-view>
this tells ui-router to load the contents of your templates into the body of your document, so your templates should just be snippets of html to be rendered within your body tag. So you should delete everything from results.html until all that remains is this:
<div id="headerBar" >
<div class="form-group" id="headerBar" >
<input class="form-control input-lg" type="text" id="inputlg" placeholder="Zipcode" />
<button id="sub" class="btn btn-default btn-lg" type="submit" ng-click="vm.getInstructors()">Find an Instructor!</button>
</div>
</div>
<table>
<tr ng-repeat="Instructors in vm.instructors">
<td style="padding-top:5px;">
<div>
<nav class="navbar">
<div class="container-fluid">
<form class="navbar-form navbar-left" role="search">
<div class="form-group">
<input type="text" class="form-control" placeholder="Search" name="searchString" >
</div>
<button type="submit" class="btn btn-default" value="Filter">Search</button>
</form>
</div><!-- /.container-fluid -->
</nav>
</div>
</td>
</tr>
</table>
<div class="col-md-8">
</div>
<aside class="sidebar" ui-view="map">MAP</aside>
A few other things. You have the controller setup in your routes, so you don't need to specify it anywhere in results.html. Also you should not be able to navigate to results.html. Instead you would just navigate to (your domain)/results.

Angular html not loading properly

Sorry if this has a really obvious answer, I'm fairly new to Angular JS and this is something that I have been stuck on for an annoyingly long time.
To give you a bit of background, I am calling ng-repeat on a directive as follows:
<div ng-controller = 'salesctrl'>
<salecell ng-repeat = "kpi in kpis" kpi ="kpi"></salecell>
</div>
With the directive being described as follows:
.directive("salecell", function(){
return{
templateUrl: "sale-cell-template.html" ,
restrict: 'E',
scope: {
kpi: '='
},
link: function(scope){
return scope;
},
controller: function($scope){
if(typeof $scope.kpi != 'undefined'){
$scope.kpi.value = 0;
$scope.increment = function(){
$scope.kpi.value++;
}
$scope.decrement = function(){
if($scope.kpi.value != 0){
$scope.kpi.value--;
}
}
}
}
};
})
and the attached controller:
.controller("salesctrl", function($scope, $rootScope, SalesSvc){
SalesSvc.query().$promise.then(function(data){
$scope.kpis = data;
});
$scope.submit = function(){
SalesSvc.save($scope.kpis).$promise.then(function(){
for(var i = 0; i < $scope.kpis.length; i++){
$scope.kpis[i].value = 0;
}
});
$rootScope.$emit('salecreate');
}
})
The issue that I am having is that, regardless of the contents of my associated template, only the outer element is being rendered. For example if I have:
<tr>
<div class="col-md-6"> <label class="control-label">{{kpi.title}}</label></div>
<div ng-show="!kpi.dollar" class="col-md-6">
<div id="spinner4">
<div class="input-group" style="width:150px;">
<div class="spinner-buttons input-group-btn">
<button ng-click="decrement()" type="button" class="btn spinner-up btn-warning">
<i class="fa fa-minus"></i>
</button>
</div>
<input ng-model="kpi.value" type="text" class="spinner-input form-control" maxlength="3" >
<div class="spinner-buttons input-group-btn">
<button ng-click="increment()" type="button" class="btn spinner-down btn-primary">
<i class="fa fa-plus"></i>
</button>
</div>
</div>
</div>
</div>
<div ng-show="kpi.dollar" class="col-md-6">
<div class="input-group m-bot15" style="width: 150px;">
<span class="input-group-addon">$</span>
<input ng-model="kpi.value" type="text" class="form-control">
</div>
</div>
Nothing will load on the page, and likewise, if I have:
<tr>
<h1> Hello World! </h1>
</tr>
Nothing is loaded either.
Things I have already checked:
-I have made sure that both $scope.kpis and $scope.kpi are defined
-I have ensured that the template is actually being called (both by inspecting elements and by calling a console.log from within the template)
-A bit of searching around suggested that it might be an error within the template, but this seems strange given that it doesn't work even with a near-empty template.
The only other thing that I can think to add is that when I was using console.log in the template that was visible in the element inspector (Chrome), but nothing else has been.
Let me know if you need anything else, and once again I hope this isn't something really stupid that I have missed.
Ensure that the content inside the table are wrapped in <td> tags. Currently they are directly inside <tr> tags and is invalid HTML.
<tr>
<td>
<div class="col-md-6"> <label class="control-label">{{kpi.title}}</label></div>
...
</td>
</tr>

Knockout Clone Whole Item In foreach

I am trying to clone elements when clicking a button. I was trying to use ko.toJS. On page load it works fine, but when I want clone the items, it is unable to bind the items (like, value, Text, etc.).
Here is the HTML:
<div class="stockItems-inner" data-bind="foreach: StockItems">
<div data-bind="if: Type=='Input'">
<div class="stock_container_input">
<input type="text" data-bind="value: Value" />
</div>
</div>
<div data-bind="if: Type=='Radio'">
<div class="stock_container_control">
<div data-bind="foreach: Options">
<div class="stockLbl">
<input type="radio" data-bind="text: Text, checked:$parent.Value, attr:{'id':Id, 'name': $parent.Text, 'value': Value}" />
<label data-bind="attr:{'for':Id}, text: Text"></label>
</div>
</div>
</div>
</div>
</div>
<div class="addItem">
<button type="button" data-bind="click: CloneItem"><img src="images/add.png" alt="" /></button>
</div>
The View Model:
ConfigurationStockViewModel = function() {
var self = this;
this.StockItems = ko.observableArray();
this.ApplyData = function(data){
self.StockItems(data.Items);
}
this.CloneItem = function(StockItems){
self.StockItems.push(ko.toJS(StockItems));
};
};
When clicking the button, an error is thrown: Unable to process binding. I am using JSON data for binding.
Not exactly sure what end result you want without working code, but sounds like you want to clone the last item in array and add to array?
If so, I think you have an error - your add button click binding will never pass anything to the function you defined, since it is outside the foreach. You need something like this:
this.CloneItem = function() {
var toClone = self.StockItems()[self.StockItems().length - 1]
self.StockItems.push(toClone);
};
Here is a simplified example without radio buttons, etc:
http://jsfiddle.net/5J47L/