I am new to web development maybe the problem I am trying to solve is a very basic one but I have googled a lot for a solution couldn't find one.
I have two web pages one and two
The below is one.html
<form id="requestForm" #requestForm ngNoForm action="{{requestUrl}}" method="POST">
<div *ngIf="requestmodel">
<button class="btn-flat waves-effect waves-light transparent regNrmS2BN" type="submit" id="submitForm" style="color: transparent; background-color: transparent;">Pay</button>
<input type="hidden" name="name" [ngModel]="requestmodel.name" />
</div>
</form>
This above form gets automatically posted to the next web page two.html and below is the code for that which is written in ComponentOne
ngOnInit(): void {
this.requestmodel = this.requestService.getRequest();
this.requestUrl = 'http://localhost:3000/two';
this.submitMe();
}
submitMe() {
let me = this;
if ($('#submitForm') && $('#submitForm')[0])
$('#submitForm')[0].click();
else
setTimeout(function () { me.submitMe(); }, 100);
}
The problem is how do I read the form data in ComponentTwo and the requirement is I should not use Service for this else there wouldn't be any problem at all.
So how can I accomplish this without a service class?
You probably will have to use EventEmitter and #Output to access to this event outside. Then use it in another html file as event and pass variables to your typescript file as $event. I hope I got your question right and didn't mislead you
Related
I’m using CFS for files upload in my Meteor App, almost everything works fine, except because when I try to upload another image, I see my previous sended image in the form, so I need to clear that form after submit the image. I've tried with .reset but it doesn't work. This is my code right now. Thanks for the help.
NewImage.html
<template name="newImage">
<div align="center">
<form align="center">
<div>
<div>
<span class="btn btn-success btn-file">
<input type="file" accept=".gif,.jpg,.png" class="myFileInputimagepub" id="image"/>
</span>
</div>
<div>
<img src="{{currentUser.profile.image}}" alt="Image" width="60px" height="60px" class="img-circle avatar-upload" value=''/>
</div>
</div>
</form>
</div>
</template>
NewImage.js
import './newImage.html';
Template.NewImage.events({
'change .myFileInputimagepub':function(evt,tmpl){
FS.Utility.eachFile(event,function(file){
fileImagespub.insert(file,function(err,fileObj){
if(!err){
var userId = Meteor.userId();
var imageurl = {
'profile.image':'/cfs/files/fileimages/' + fileObj._id
};
setTimeout(function(){
Meteor.users.update(userId,{$set:imageurl});
},2000);
}
})
})
},
'submit form':function(event,template){
event.preventDefault();
template.find("form").reset();
}
});
If the image in question is the one with class .img-circle, the issue is that its src attribute is being dynamically provided. Currently it is currentUser.profile.image. This won't clear just by resetting the form and manually clearing the image's src value would be fighting the framework.
Option 1 (Not Ideal):
If you don't want to keep the image, unset the database change made after the file upload by running something like this:
Meteor.users.update(userId, { $set: { 'profile.image': null }});
This is not ideal as it enables you to continue modifying the database with an image which may not be needed long-term.
Additionally, I'm assuming you're currently using the autopublish/insecure packages. You'll want to remove these before going public with your app as they allow any user to change the database without restriction.
Option 2:
You could save the returned value from your 'change .myFileInputimagepub' event as a ReactiveVar, then only actually run Meteor.users.update (preferably on the server using a Method) when your user submits the form. At that point you could clear the reactive variable.
Using a ReactiveVar will allow you to provide the saved URL to the src attribute via a helper, and then change the ReactiveVar's value when you wish to clear the form.
There's a simple example of manipulating ReactiveVars here: https://gist.github.com/ahoereth/a75d2d6528b1844ad503
I need some help in implementing a basic ajax request through vue to my laravel back-end, I have a boolean named completed on a table called courses, and I have a view that fetches all courses assigned to a specific user and allows them to press a button to change the current status of the course, either completed or not, that's it, that's all I wanna do, right now I can do it normally through get and post requests, obviously results in a refresh of the page, I want that to be dynamic with just refreshing the dom, I am so frustrated that I couldn't figure this out on my own because I think It should be easy, turns out I know nothing when it comes to using vuejs.
Here is the significant part of my CoursesController:
public function toggling($name)
{
$course = Course::where(['name' => $name])->first();
$course->completed = !$course->completed;
$course->save();
// return redirect()->back();
return response()->json(['course' => $course], 202);
}
And here is the significant part of the view that provides the courses to the user, it's a part of a table:
<td>
<form method="POST" #submit.prevent="onSubmit" action="{{ route('course.completed', $course->name) }}" id="form-submit">
{{-- {{ method_field('PUT') }} --}}
{{ csrf_field() }}
#if ($course->completed == true)
<button type="submit" class="btn btn-sm" id="coursetogglingtrue">Done!</button>
#else
<button type="submit" class="btn btn-sm" id="coursetogglingfalse">Not Yet!</button>
#endif
</form>
</td>
For some reason the #submit.prevent method is not working, it worked a couple of times but then It just didn't, and the form kept submitting as usual.
These are the scripts inside app.blade.php, I don't know how/where should I compile this, it's just sitting there in the main layout of my project, should I transfer it to public/js/app.js? or compile it using gulp? if you have something in mind please let me know:
<!-- Scripts -->
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script src="https://unpkg.com/vue#2.1.10/dist/vue.js"></script>
<script src="/js/app.js"></script>
<script>
new Vue({
el: '#app',
data: {
course: {}
},
methods: {
onSubmit() {
// course = $event.target;
axios.post('/MyCourses/{{course.name}}').then(console.log(course));
}
}
});
</script>
I want to have course be equal to whatever value of the request was, so that I can then target the value of the name of the course that was submitted and inject it to the route as I'm trying to do, but I'm not sure how to do that, I tried a few different things, all failed.
And here is routes/api.php
Route::post('/MyCourses/{name}', 'CoursesController#toggling')->name('course.completed');
ofc right now this is not working, the form is submitting, and I'm redirected to a route where I get back the json response, and that's it, I just want to refresh the dom so that the button would have the new id depending on that status of the course, and the course itself to be updated and saved in the background without refreshing the page.
I am fairly new to this, I understand that the form should probably be re-written, and I know I've done a lot of mistakes, but I just want it to work, so help would be very appreciated.
UPDATE
After a lot of hours of trial and error, I'm done with the ajax part and I'm almost there with the rest I just need to do a few things, this is what I've managed to do so far,
In the view:
<form method="POST" #click.prevent="onSubmit" action="{{ route('course.completed', $course->name) }}" id="form-submit">
{{ csrf_field() }}
#if ($course->completed == true)
<button type="button" class="btn btn-sm" id="coursetogglingtrue">Done!</button>
#else
<button type="button" class="btn btn-sm" id="coursetogglingfalse">Not Yet!</button>
#endif
Changing the type of the button from submit to button allowed the .prevent method to actually fire, now the form doesn't submit anymore, the form still needs work in order to output the proper class depending on the status of the course but regardless,
This is the script that I have now:
<script>
new Vue({
el: '#app',
data: {
course: {
name: '',
bool: false
}
},
methods: {
onSubmit: function() {
this.course.bool = !this.course.bool,
axios.post('/MyCourses/{{$course->name}}')
.then(function (response){
// {{$course->completed}} = response.course.completed;
});
}
}
});
</script>
Somehow right now, I'm actually sending the post request to the correct route, but there's a problem which has the highest priority right now, $course is referencing the latest course that was added to the page, and not the course that I chose by pressing on the button, now whichever button I press, the last course gets injected to $course, and then ofc to the route in axois, I don't know how to figure that out yet, but so far that course gets updated, and if I inspected the network tab in chrome, I see the response and that value of the completed column gets updated, I believe that there are still some mistakes in the code, but I'll keep trying, if you can point out some more things please let me know, thanks
An improvement to the answer above would be to use Template Literals introduced in ES6.
Instead of:
axios.post('/MyCourses/' + course.name).then(console.log(course));
You can do:
axios.post(`/MyCourses/${course.name}`).then(console.log(course));
More information on Template Literals functionality and syntax can be found here:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals
The syntax you are using is wrong in following line:
axios.post('/MyCourses/{{course.name}}').then(console.log(course));
It should be :
axios.post('/MyCourses/' + course.name).then(console.log(course));
At this stage I'm mostly used to backend Javascript and server side Java, so my HTML is not as savvy as it needs to be.
I've built several applications that require user input with Apps script, but I was using the now deprecated UI service, as I'm not a designer and this provided an easy way to design simple pages to pass data back and forth. With the UI service having been deprecated for some time, I'm begging the arduous task of migrating these services to the HTML service, and I'm noticing some difference in behavior.
For example, when submitting a form, the entire page refreshes to a blank page, and I can't seem to prevent that. The UI service would remain static for information re-entry, and I can't find a working method to get the HTML service to either stop refreshing or reload the form.
Simple code to reproduce my issue:
function doGet() {
return HtmlService.createHtmlOutputFromFile('test')
.setSandboxMode(HtmlService.SandboxMode.IFRAME);
}
function logValues(value){
Logger.log('Something worked....');
}
With the index file being:
<form>
<input type="submit" value="Book Meeting" onclick="google.script.run
.logValues()">
</form>
Some things I've tried:
1) Adding a callback to the 'doGet' function, to attempt to get the page to load again.
2) Adding a whole new function to try and call a NEW HTML page.
The issue here is my poor understanding of the HTML service, but is there a simple way for me to just clear the form for re-submission, or alternatively just reload the page? None of the other questions I've found on SO adequately answer this question in a way I can understand.
Since you're technically submitting your form by clicking the submit button, then that creates the page refresh. You need to cancel the submit event with the preventDefault function, which "Cancels the event if it is cancelable, without stopping further propagation of the event."
See the docs here: https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault
So maybe you can try something along these lines (straight from the docs):
function stopDefAction(evt) {
evt.preventDefault();
}
document.getElementById('my-checkbox').addEventListener('click', stopDefAction, false);
Another option is to remove the form/input elements and simply use a button element instead, which doesn't trigger a page refresh on click.
It's an interesting ride switching old UI services across, I just did that with one of my applications and it has really improved the readability of the code. I posted a copy of a basic version of what I was doing in another question
Once you get your head around it all it becomes a lot simpler. This is a really basic example of using multiple HTML files similar to your example using the HTMLService when submitting forms (you can pass in parameters instead)
Code.gs
function doGet() {
return HtmlService.createTemplateFromFile('Main')
.evaluate()
.setSandboxMode(HtmlService.SandboxMode.NATIVE);
}
function onLogin(form) {
if (form.username == "fuzzyjulz") {
var template = HtmlService.createTemplateFromFile('Response');
//Setup any variables that should be used in the page
template.firstName = "Fuzzy";
template.username = form.username;
return template.evaluate()
.setSandboxMode(HtmlService.SandboxMode.NATIVE)
.getContent();
} else {
throw "You could not be found in the database please try again.";
}
}
function include(filename) {
return HtmlService.createTemplateFromFile(filename)
.evaluate()
.setSandboxMode(HtmlService.SandboxMode.IFRAME)
.getContent();
}
Main.html
<?!= include('CSS'); ?>
<script>
function loadPage(htmlOut) {
var div = document.getElementById('content');
div.innerHTML = htmlOut;
document.getElementById('errors').innerHTML = "";
}
function onFailure(error) {
var errors = document.getElementById('errors');
errors.innerHTML = error.message;
}
</script>
<div id="errors"></div>
<div id="content">
<?!= include('Login'); ?>
</div>
CSS.html
<style>
p b {
width: 100px;
display: inline-block;
}
</style>
Login.html
<script>
function onLoginFailure(error) {
var loginBtn = document.getElementById('loginBtn');
loginBtn.disabled = false;
loginBtn.value = 'Login';
onFailure(error);
}
</script>
<div class="loginPanel">
<form>
<p>
<b>Username: </b>
<input type="text" name="username"/>
</p>
<input type="button" id="loginBtn" value="Login" onclick="this.disabled = true; this.value = 'Loading...';google.script.run
.withSuccessHandler(loadPage)
.withFailureHandler(onLoginFailure)
.onLogin(this.parentNode)"/>
</form>
</div>
Response.html
<div class="text">
Hi <?= firstName ?>,<br/>
Thanks for logging in as <?= username ?>
</div>
I need to use an asp.mvc form post. I use some angularjs on the client side. I know this question is not doing everything the "angular way".
What I need to do is set a variable $scope.IsUploadingData when the post happens so I can disable the buttons and show something to indicate progress. I have tried using ng-click, but it seems to stop the post from happening. Is there anyway to set the variable without interrupting the form post?
#using (Html.BeginFormAntiForgeryPost(Url.Action("Accept", "Members", new { area = "Testing" })))
{
other form stuff here
<span class="input-group-btn">
<button ng-disabled="IsUploadingData == true" name="accept" type="submit">Submit</button>
<button class="btn btn-default" ng-disabled="IsUploadingData == true" name="reject" type="submit">Reject</button>
<img ng-show="IsUploadingData" src="/SiteMedia/spinner[1].gif" />
</span>
}
It looks like you could use ng-submit to control the submission process and set $scope.IsUploadingData in the function you call from ng-submit. This is a decent write-up on ng-submit: http://learnwebtutorials.com/angularjs-tutorial-submitting-form-ng-submit
big problem here! I know the title is kinda fuzzy, but it's all day long I've got this problem and cannot figure out how to solve it.
I'll try to be the more specific in the less messy way.
Long story short, I have a Controller (LeadController) with a method (Search) for a search:
public ActionResult Search(string prov = null, string city = null)
{
//if no field is compiled, return an empty view
if (String.IsNullOrWhiteSpace(prov) && String.IsNullOrWhiteSpace(city))
return View();
var leads = from l in db.Leads
select l;
if (!String.IsNullOrWhiteSpace(prov))
{
leads = leads.Where(l => l.Prov == prov).OrderBy(l => l.RagioneSoc);
}
if (!String.IsNullOrWhiteSpace(city))
{
leads = leads.Where(l => l.Comune == city).OrderBy(l => l.RagioneSoc);
}
return View(leads);
}
Then I have the Search View (displaying the fields to fill for the search AND the result after the post action) with 2 submit forms: the first one to execute the search
#using (Html.BeginForm()){
Sigla Provincia: #Html.TextBox("prov", null, new { #style = "width: 50px;"})
Città: #Html.TextBox("city", null, new { #style = "width: 150px;" })
<input type="submit" value="Ricerca" data-icon="search" data-role="button" data-mini="true" data-inline="true" />}
and the 2nd one to generate a document from the leads result of the search action
<input type="submit" title="create doc" value="Create document" onclick="javascript:postData()" id="doc" />
This last submit should call a javascript function to encode the model:
<script type="text/javascript">
function postData() {
var urlact = '#Url.Action("createDoc")';
var model = '#Html.Raw(Json.Encode(Model))';
$.ajax({
...
...
});
}
</script>
Now, the problem is: when I call the first submit, the one which should execute the research, it performs the research but it also keeps going on, calling the postData() javascript function (even if I never "tell" him to do that). And the site stop working in var model = #Html.Raw(Json.Encode(Model))';, with an InvalidOperationException.
If someone understood my question, is there a way to avoid this behaviour and to force the 1st submit only to pass the controller the parameters to execute the search action?
Hope someone can help me,
thank you in advance for your consideration!
SOLVED
Well, the problem is gone. Apparently, I didn't know so well the View & Javascript behaviour. Long story shirt, it seems the View, loading itself, enters the js function in order to kind of cache the Model encoding, but it doesn't fully runs the function! And I had a problem within the interested Model.
I don't know if I explained myself, but the warning is: be careful for your Model consistency before doing anything else.
Thanks to anyone who helped me, before I realized I get it totally wrong!
Here is how you should handle multiple submit buttons
Below is a form with two submit buttons. Note that both these submit buttons have the same name i.e “submitButton”
#Html.BeginForm("MyAction", "MyController"); %>
<input type="submit" name="submitButton" value="Button1" />
<input type="submit" name="submitButton" value="Button2" />
}
Now over to the Controller, the Action takes in an input parameter called string stringButton and the rest is pretty self-explanatory.
public ActionResult MyAction(string submitButton) {
switch(submitButton) {
case "Button1":
// do something here
case "Button2":
// do some other thing here
default:
// add some other behaviour here
}
...
}
Hope this helps you !
UPDATE :
from your comments,
Hi, I do know this workaround, my issue is the 2nd submit doesn't have to pass through the Controller: it has to call the javascript function in the View. The 1st post to a Controller in the right way, but THEN it runs the javascript function, too.
Ok, instead of having two submit buttons, you can have one submit button and other as a normal button.
Eg: -
#Html.BeginForm("MyAction", "MyController"); %>
<input type="submit" name="submitButton" value="Button1" />
<input type="button" id="otherButton" value="Button2" />
}
and then using some simple jquery, you can make a call to the javascript funcion postData().
<script type="text/javascript">
$("#otherButton").bind("click", function () {
console.log("do your stuff here");
postData();
});
</script>
Try changing your second submit from <input type="submit" to <input type="button"