I have a piece of html like this:
<div class="row well">
<form method="POST">
<ol id="velArea">
<li> Layer velocity: (m/s) <input type="text" name="source[]"> </li>
</ol>
<input type="button" value="Add another layer" name="velocity" onClick="addVel('velArea');">
</form>
</div>
and a javascript function that adds html to the area
function addVel(area)
{
var field_area = document.getElementById(area);
field_area.innerHTML += "<li> Layer velocity: (m/s) <input type='text' name='velocity'> <a style='cursor:pointer;color:grey;' onclick='this.parentNode.parentNode.removeChild(this.parentNode);''>delete</a> </li>";
}
I need to read the value of each input field in a rails function. And have no idea about how to do that. I've lost days going through active model in rails, thinking that was the way until I finally figured out that is better to keep the browser-related and server related things separated. So I learned a little javascript and made a few functions. Yes, I'm new to web development. I'm using rails 3.2.
The function that I want to uses the fields info is called by a button:
<%= button_to "Run single inversion", {:action => "my_func", }, {:remote => true, :form => { "data-type" => "json" }, :class => "btn btn-primary"} %>
and the function on the controller is:
def my_func
render :nothing => true
vel = params[:velocity]
puts vel.class
puts 'Hi'
end
the output I get is
NilClass
Hi
so I'm clearly not passing the arguments right. I'm guessing I need to pass the velocity array in the post method when I use the button_to, but have no idea about how to do that.
Also, I'm need the value of the input, not anything database oriented so I cannot look it up using activeRecord properties.
in your rails controller, you should be able to access a params[:model_name] when the javascript submits the form to whatever method you need it to go to. you can also access a params[:id] or params[:firstname]
i'm also a bit confused as to what you are doing with
<input type='text'> </input>
that doesnt have a name attribute, which is needed by the model to identify it and associate its value with a column. it also isnt the proper way do an input.
<input type="text" name="column_name"/>
is closer to what you want
I am not sure why your code is so complicated. But basically there are a few things, that are not the RailsWay. First, you should have a look to the Rails Form Helpers. If you are using the conventions, you will receive a params hash like this:
params[:velocities][:velocity]
params[:velocities][:source]
The form tags would look like this:
<input type="text" name="velocities[velocity]" id="velocities_velocity" value="">
<input type="text" name="velocities[source]" id="velocities_source" value="">
In your above code you are expecting a value for vel. The resulting NilClass is because ther is nil in params[:velocity], so vel is nil. You should check the following:
puts params.inspect
Or have a look inside the log when running the Rails application.
And please recheck the name attributes of both the button and the input filed. They name attribute is both 'velocity'. If the button is the latter which is submitted, then the value of params[:velocity] is for sure empty ...
Related
I've been self-teaching coding for the last 3 months or so and I have a couple of issues with a page I'm trying to make. I think my problems are a bit basic so I'm a little ashamed to ask. Any guidance would be very useful. Thank you!
I have a page that accepts recipes. Each recipe has a set number of instructions or ingredients.
The form that accepts the new recipe by default shows 3 fields to add instructions and 3 fields to add ingredients.
I'd like to implement a button that allows the user to add an extra ingredient or an extra step to the instructions.
This is what the New view file looks like in the instruction segment. It's pretty much the same for ingredients give or take a few things.
<div class="mb-3">
<label class="form-label" for="instructions" id="labelInstructions">instructions</label>
<% for(let i = 0; i<3; i++){ %>
<div class="input-group" id="instructionGroup">
<div class="input-group-prepend">
<span class="input-group-text">Step <%= i+1 %> </span>
</div>
<textarea class="form-control" aria-label=<%=`Instructions-Step-${i +1}`%> name=<%=`recipe[instructions][${i}][body]` %> id="instructions"></textarea>
</div>
<div class="valid-feedback">Looks good!</div>
<% } %>
I tried adding an onclick function to a
<button onclick="addInstruction()">+</button>
I required the file on the template and the file attempted to add the appropriate amount of divs and modify the classes and innertext, etc, etc.
But I got stuck here:
function addInstruction() {
console.log('clicked')
const label = document.getElementById('labelInstructions')
const tempDiv = document.createElement('div')
label.insertAdjacentElement("afterend", tempDiv)
}
In the console it shows that it is being clicked but it doesn't add the div I created. I know the rest of the logic isn't there yet I just wanted to see if I could see the div first, but I can't see anything.
Then I started thinking it would be easier to just add one to the loop limit. But that loop is written inside an EJS tag, I was wondering if there was a way to modify that through an onclick event. Or if there's just an entirely better way of doing this that I'm missing.
I'm very new to this, any help is appreciated. Thank you!
I think you are asking how to add some sort of div inside the DOM when a user clicks a button. To do this I would just use the .appendChild() method and append the div as a child element of the form for example document.querySelector("form").appendChild(<Div Variable>)
Whenever any non-readonly input in my form changes and the form is valid, I want to do certain action. Let's say, my form looks like
<form name="form" novalidate>
<input ng-model='input.a' required/>
<input ng-model='input.b' required/>
<input value='{{output.p | number: 2}}' readonly/>
<input value='{{output.q | number: 2}}' readonly/>
</form>
Now upon any change of input, I want to do something, whenever input.a and input.b are valid. I tried $watch(input), but it didn't work. Watching all its members does, but it feels stupid. Adding ng-change to all fields feels better, but still pretty stupid (non-DRY). What's the proper way?
The other question is how to find out if the input is valid. If I had a button, I could do simply
<button ng-click="doIt()" ng-disabled="form.$invalid">
but how can I access form.$invalid in the controller (it's not contained in $scope)?
You should be able to access form.$invalid by doing
$scope.form.$invalid
See here: AngularJs can't access form object in controller ($scope)
To watch for changes in the form, you should be able to do:
$scope.$watchCollection('input')
#dave has already answered your first question, but for the second I have a solution that I consider more elegant:
In your controller you have declare an object, for example:
$scope.forms = {};
Then you form name must be nested inside that object:
<form name="forms.someForm">
...
Finally in your controller you can do things like this:
if($scope.forms.someForm.$invalid) {
...
}
I'm having problems trying to send input fields values to a Jasper report. I know how to send parameters to a report but I always did this using the show.gsp view because it was quite simple to do something like this:
<g:jasperReport controller="liquidacionDeEstano" action="crearReporte" jasper="liquidacion_estano" format="PDF" name="ReporteLiquidacion${liquidacionDeEstanoInstance.lote}">
<input type="hidden" name="LIQ_SN_ID" value="${liquidacionDeEstanoInstance.id}" />
</g:jasperReport>
Where LIQ_SN_ID is a "static" parameter used by the report.
But now I want to fill some input fields and use this values as parameters. So, what I'm doing is to use some input fields out of the jasperReport tags and hidden fields inside the jasperReport tags. Then I copy the values from the input fields to the hidden fields using JavaScript.
To generate the report I'm just using SQL and the parameters passed are used for filtering.
This is my controller closure to create the report (I think I don't need anything else but the parameters):
def crearReporte = {
chain(controller:'jasper',action:'index',params:params)
}
This is the code in the GSP form to invoke the report:
<g:jasperReport controller="reporteLotesRecepcionados" action="crearReporte" jasper="reporte_recepcion_fechas" format="PDF" name="ReportePorFechas">
<input type="hidden" id="ELEMENTO_1" name="ELEMENTO_1" />
<input type="hidden" id="ELEMENTO_CLASS_1" name="ELEMENTO_CLASS_1" />
<input type="hidden" id="FECHA_INICIAL_1" name="FECHA_INICIAL_1"/>
<input type="hidden" id="FECHA_FINAL_1" name="FECHA_FINAL_1"/>
<input type="hidden" id="ESTADO_LOTE_1" name="ESTADO_LOTE_1"/>
</g:jasperReport>
I checked that all the parameters are correct (hidden fields values) using Firebug and a Web Developer extension for Firefox but when I click the link to the report this error is produced:
Timestamp: 23/12/2013 07:20:00 p.m.
Error: TypeError: link.parentNode._format is undefined
Source File: http://localhost:8080/Liquidaciones/reporteLotesRecepcionados/create
Line: 660
Following the link to the error this automatic generated code is shown:
<script type="text/javascript">
function submit_reporterecepcionfechas(link) {
link.parentNode._format.value = link.title;
link.parentNode.submit();
return false;
}
</script>
I don't know what I'm doing wrong. In fact this is the first time I try to generate a report using values as parameters from input fields.
Please help me with this.
Thank you in advance.
I know this have been here for 11 months withuoth an answer so...
Jasper tags uses their own form and since html forbids to have nested forms:
Content model: Flow content, but with no form element descendants.
(HTML)
Jasper documentation says : "Note that the jasperReport tag should not be nested with a form element, as it uses a form element in its implementation, and nesting of forms is not allowed."
Finally I solved it but I'm not sure how I did it. Ok, here is what I did:
As you know, since Grails 2 (I think) there is a form.gsp used by the create.gsp and edit.gsp views. I was using just the create.gsp (and, in consequence, the form.gsp) view to have the input fields to obtain parameters to generate reports. Initially I located the code:
<g:jasperReport controller="reporteLotesRecepcionados" action="crearReporte" jasper="reporte_recepcion_fechas" format="PDF" name="ReportePorFechas">
<input type="hidden" id="ELEMENTO_1" name="ELEMENTO_1" />
<input type="hidden" id="ELEMENTO_CLASS_1" name="ELEMENTO_CLASS_1" />
<input type="hidden" id="FECHA_INICIAL_1" name="FECHA_INICIAL_1"/>
<input type="hidden" id="FECHA_FINAL_1" name="FECHA_FINAL_1"/>
<input type="hidden" id="ESTADO_LOTE_1" name="ESTADO_LOTE_1"/>
</g:jasperReport>
INSIDE the <g:form></g:form> tags. So, I tried, as an experiment, to copy the code to declare the input fields and the code to generate the report from form.gsp file to create.gsp, OUTSIDE the <g:form></g:form> tags (I'm not using the form.gsp file anymore). And that was all. It's working perfectly now.
As I told you I don't know how this problem has been solved. Maybe it is mandatory to have the tags outside any <g:form></g:form> tags...
...but why?
PD.: I created a domain class to have the form to enter the values that were going to be parameters. All of you must be thinking this was completely unnecessary and that having an ordinary HTML form was enough , well, I'm a Grails newbie, sorry.
I am not a JavaScript person really, I write in ASP and use a SQL database in the backend. But our marketing director requested a change that will use JavaScript.
On our view cart page, we're currently displaying an input box with a modify button to allow customers to change the quantity of the listed item (in that row... there could be multiple products in their cart, each having their own quantity input).
<form method="post" action="updateitem.asp">
<input type="hidden" name="product_id" value="<%= PRODUCT_ID %>">
Quantity: <input type"text" name="quantity">
<input type="image" name="Submit" src="/graphics/modify.gif" align="middle" border="0" alt="Continue">
</form>
What I'd like to make work is something like this. Hrm, assuming I need to do my form/div name differently for each product? I can easily write the product_id into the id tags but then assuming I'd also need to loop through my function for each one. I've gotten this far in writing the replacement code:
Get Dataset from Database (items in cart) and loop through:
<form method="post" action="updateitem.asp" id="updateitems<%= PRODUCT_ID %>">
Quantity: <input type="text" name="qty<%= PRODUCT_ID %>" OnChange="Javascript:UpdateQty()")
<div id="showlink<%= PRODUCT_ID %>">
<br /><span class="BodyTiny">update</span>
</div>
</form>
END LOOP
So if the quantity changes, it displays the word "update" where they can click and it passes whatever quantity that is in the quantity field to the updateitem.asp (in a way I can then update it in the database in ASP/SQL). In the code above, if we could just insert the new # in the a href statement after quantity=, then I could fix it in the updateitems.asp page without a problem.
I'm not sure where to even begin honestly, I have this so far:
LOOP through dataset so each product has its own function
<script Language="JavaScript">
<!--
function UpdateQty(updateitems<%= PRODUCT_ID %>) {
Show div updateitems<%= PRODUCT_ID %>
Replace NEWQUANT within that div with the value in the input field qty<%= PRODUCT_ID %>
}
//-->
</script>
END LOOP
I'm having a few problems...
I am not sure how to write the function UpdateQty. It should A) display the stuff in div id=showlink, and B) add the # from the input named quantity quantity to the href so I can update it in the database on the next page
If they have JavaScript turned off, they should be able to enter a new quantity and just hit enter for it to submit the form. I believe this will work as its a form with 1 text input and 1 hidden one, so just hitting enter in the text input should submit it. But that should still work with whatever JavaScript is added to make the showlink div show if it changes.
Do I need to add a class to my CSS for showlink? If so, what do I need to put in it?
Any help would be greatly appreciated!
Mahalo!
so what you can do for updateQty is have one function that will be correct for all products in a list just by making a function that finds all the necessary elements by relative paths.
//in this function the context is the element, so the
//`this` variable can be used rather than a param
//for the product id
function updateQty() {
//show the update link
var parent = this.parentNode;
//assumes only the update text uses the class bodyTiny, and that there
//is only one element using it. obviously making this invariant true
//would be trivial by adding a different class name
var updateText = parent.getElementsByClassName("bodyTiny")[0];
updateText.style.display = 'block';
var updateLink = updateText.parentNode
, updateHref = updateLink.href;
//next we find the current quantity and replace it with the input
updateHref = updateHref.replace(/qty=(\d*)/, 'qty='+this.value);
//then we set the link element's attribute
updateLink.href = updateHref;
//now when you mouse over the link you should see the url has changed
}
You can also set your form to POST the equivalent data, and then I guess on the server side you will have your OnGetPage and OnPostback both delegate to the same method with the parameters either parsed out of the query string or out of the post data.
You can see it running on jsfiddle. Hopefully this helps!
I am trying to get value from javascript using getElementbyId but i am not getting it.
If i put,
<input type="text" id="disprice<% =pID %>" value="<%=disprice%>" name="Price" />
like this then i am getting value from java script in my text box.
But if i try to get that same thing like this,
<span class="productListPrice" id="disprice<% =pID %>">
then i am not getting the value..
Please help me if possible.
Mitesh
Your texbox needs an id.
More details http://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_doc_getelementbyid
#mitesh: Here's some sample code that should help --
JavaScript:
var price = document.getElementById('Price');
ASP:
Dim iPrice
iPrice = Request.Form("Price")
HTML:
<input type="text" id="Price" name="Price" value="<%=iPrice %>">
Only input values are transmitted back to the server on a postback and the name is used (not the id). The id is primarily for doing things in JavaScript client-side.
Also, in both cases, getElementById will return the element with the given id. However, the element itself is different (a span as no inherent value). This step may require some more troubleshooting to determine "what" isn't working.