jQuery File Upload: using counter inside of $.each - counter

I'm using jQuery-File-Upload's fileuploaddone callback to insert hidden inputs to the form to send it to the server:
$('#fileupload').bind('fileuploaddone', function (e, data) {
$.each(data.files, function (index, file) {
$('<input type="hidden" name="file' + index + '" value="' + file.name + '">').appendTo('#fileupload');
});
});
The problem is that counter index doesn't increment. That what is inserted into my form:
<input type="hidden" name="file0" value="filename.png">
<input type="hidden" name="file0" value="filename2.png">
etc
I tried to use a separate counter:
$('#fileupload').bind('fileuploaddone', function (e, data) {
var i = 0;
$.each(data.files, function (index, file) {
$('<input type="hidden" name="file' + i + '" value="' + file.name + '">').appendTo('#fileupload');
i++;
});
});
But result is the same. What is the trick?

Your collections data.files only contain 1 object each, hence why your counters/index never increment.
Take a look at the following line.
$('#fileupload').bind('fileuploaddone', function (e, data) {
The event 'fileuploaddone' is occurring for each file.

Related

Thymeleaf dynamic form action url

<thymeleaf.version>3.0.9.RELEASE</thymeleaf.version>
<thymeleaf-layout-dialect.version>2.2.2</thymeleaf-layout-dialect.version>
Springboot
How to construct expression for th:action "action url" in form? Url depends on "name" variable.
I'm trying like this, but it's not working:
<form method="get"
th:action="#{'/' + {baseUrl}(baseUrl=${#strings.isEmpty(name) ? '' : 'user/find/'})}">
<input type="text" th:value="${name}"/>
<button type="submit">Find</button>
<button type="button"
th:classappend="${#strings.isEmpty(name)}?'hidden':''"
onclick="clearSearch()">X</button>
</form>
and I tried this, doesn't work too:
<form th:with="baseUrl=(${#strings.isEmpty(name) ? '/' : '/user/find/'})"
th:action="#{${baseUrl}}" method="get">
Oh sorry. I realized Thymeleaf is not for dynamically handling input field.
I just write a JS code.
$(document).ready(function () {
var searchForm = $(this).find('#searchForm');
searchForm.on('click', '#searchButton', function (event) {
var form = $('#searchForm');
var name = $('#searchInputName').val();
var addUrl = (name === '') ? '/' : '/user/find/';
form.attr('action', addUrl);
});
});
after that I realized I can realize it simpler in my controller :)
#GetMapping("/user/find/")
public String getNextPage(Model model, Pageable pageable,
#RequestParam(name = "name") String name) {
if (name.isEmpty()) return "redirect:/";
....
}
You can write dynamic url like below
th:action="#{${#strings.isEmpty(name) ? '/' : '/user/find'}}"
If you want you can add dynamic value to your urls like below
th:action="#{${#strings.isEmpty(name) ? '/' : '/user/find' + name}}"

JSfiddle number guessing game

I have put together a number guessing game in Jsfiddle, im having trouble getting the random number stored into an array. i need to program to pic a random number and store it untill the number is either guessed or the game ends
here is my fiddle link https://jsfiddle.net/e64gt4sv/
any help would be appreciated thanks
HTML code:
<h1>The Guesssing Game</h1> Pick a number between 1 and 1000:
<input id="myAssumption" type="text" />
<input type="submit" id="byBtn" onclick="checkMyAnswer()" value="Click To See If your Correct" />
Js code:
var numberOfSteps = 1;
function checkMyAnswer() {
var actual = Math.floor(Math.random() * 1000) + 1;
var myAnswer = document.getElementById("myAssumption").value; //getting user value
if (myAnswer < actual) { //checking less tha answer
alert("Guessed " + myAnswer + " too low");
numberOfSteps++;
} else if (myAnswer > actual) { //checking grater than answer
alert("Guessed " + myAnswer + " too high");
numberOfSteps++;
} else { //you got answer
alert("Guessed " + myAnswer + " Got it!!");
alert("It tool " + numberOfSteps + " steps");
}
}
I edited the jsfiddle. Check it out https://jsfiddle.net/e64gt4sv/3/.
var numberOfSteps = 1;
var actual = Math.floor(Math.random() * 1000) + 1;
var guesses = [];
function checkMyAnswer() {
...
}
Jeremy is right, each time you call the checkMyAnswer, you regenerated the actual number. Instead, if you set it outside the function, you can still get the value inside the function, but it will only be set each time the actual javascript file loads (meaning each time the page is loaded / reloaded).
Also, I added something to store each guess in an array. The array guesses is a global variable, and then when you call checkMyAnswer(), the value that the user inputted is added to the array by doing
var myAnswer = document.getElementById("myAssumption").value; //getting user value
guesses.push(myAnswer);

Derbyjs v0.6 app.fn() doesn't exist

I'm following the Multi-Payer Notepad game tutorial on youtube and can't get the x-bind to work, because I get the following error:
app.fn('startGame', function(e, el) {
^
TypeError: Object #<App> has no method 'fn'
I'm assuming this method was changed in v0.6, since it just came out. Does anyone know the new way to complete this binding? This is what app.fn is doing:
app.fn('startGame', function(e, el) {
var userId = model.get('_session.userId');
this.model.set('_page.story.ready.' + userId, true);
});
app.component('story', Story);
function Story(){};
Story.prototype.startGame = function() {
alert('clicked!');
var userId = this.model.get('_session.userId');
this.model.set('_page.story.ready.' + userId, true);
};
story.html
<button type="button" on-click="startGame()">Click when you're ready</button>
You can also add the function to app.proto, like this:
app.proto.startGame = function (){
alert('clicked!');
var userId = this.model.get('_session.userId');
this.model.set('_page.story.ready.' + userId, true);
};
This is based on how a helper function is added in the TODO example.

recall form value not working for textareas

Im trying to modify this script
http://www.dynamicdrive.com/dynamicindex16/formremember2.htm
to work for textareas, and not just input text boxes. Heres what im guessing are the relevant parts of the script, i just cant figure it out myself
rememberForm.prototype.savevalues=function(){ //get form values and store in cookie
for (var i=0; i<this.fields.length; i++){
if (this.fields[i].type=="text")
this.cookiestr+=this.fields[i].fname+":"+escape(this.fields[i].value)+"#"
}
if (typeof this.togglebox!="undefined"){ //if "remember values checkbox" is defined
this.persistdays=(this.togglebox.checked)? this.persistdays : -1 //decide whether to save form values
this.cookiestr=(this.togglebox.checked)? this.cookiestr+"toggleboxid:on;" : this.cookiestr
}
else //if checkbox isn't defined, just remove final "#" from cookie string
this.cookiestr=this.cookiestr.substr(0, this.cookiestr.length-1)+";"
setCookie(this.cookiename, this.cookiestr, this.persistdays)
}
rememberForm.prototype.recallvalues=function(){ //populate form with saved values
var cookievalue=getCookie(this.cookiename)
if (cookievalue!=""){ //parse cookie, where cookie looks like: field1:value1#field2:value2...
var cookievaluepair=cookievalue.split("#")
for (var i=0; i<cookievaluepair.length; i++){
if (cookievaluepair[i].split(":")[0]!="toggleboxid" && this.getfield(cookievaluepair[i].split(":")[0]).type=="text")
this.getfield(cookievaluepair[i].split(":") [0]).value=unescape(cookievaluepair[i].split(":")[1])
else //else if name in name/value pair is "toggleboxid"
this.togglebox.checked=true
}
}
The method persistfields(id, ...) sets the fields you want to persist in the cookie. The fields are looked up by id so I guess adding a textarea with an id attribute would suffice.
For example:
<form id="myFormId">
<input type="text" id="someInputId" />
<textarea id="textareaId"></textarea>
</form>
<script>
var f = new rememberForm('myFormId');
f.persistfields('someInputId', 'textareaId');
</script>
This will add the input and textarea to the rememberForm instance fields property.
UPDATE
The problem lies in this method of rememberForm. I formatted the code for readability since the original source has horrible formatting.
rememberForm.prototype.savevalues = function() {
for (var i = 0; i < this.fields.length; i++) {
// PROBLEM: only allows type="text"
if (this.fields[i].type == "text") {
this.cookiestr += this.fields[i].fname + " : " + escape(this.fields[i].value) + "#"
}
if (typeof this.togglebox != "undefined") {
this.persistdays = (this.togglebox.checked) ? this.persistdays : -1;
this.cookiestr = (this.togglebox.checked) ? this.cookiestr + "toggleboxid:on;" : this.cookiestr
} else {
this.cookiestr = this.cookiestr.substr(0, this.cookiestr.length - 1) + ";"
setCookie(this.cookiename, this.cookiestr, this.persistdays)
}
}
}
As mentioned in my comment it will test the type of the input element to be 'text'. If you'd like to add textareas in the cookie you could change that line to:
if (this.fields[i].type == "text" || this.fields[i].type == 'textarea') {
That should work.

Zend_Form with Ajax/json

I'm a bit lost using Zend_Form with Ajax. I have a form in a class extending Zend_Form called from my controller, that way :
GoodAddGroup.php
class Default_Form_GoodAddGroup extends Zend_Form {
(...)
public function init()
{
$this->setMethod('post');
$this->setAction("process-add-group");
$this->setName("addgroupgood");
// Load Elements class
require "Form/Elements.php";
$magElements = new Elements();
// Category
$categoryElement = $magElements->getCategorySelectField();
$categoryElement->setDecorators($this->elementDecorators);
// Barcode
$barcodeElement = $magElements->getGoodBarcodeTextField();
$barcodeElement->setDecorators($this->elementDecorators);
(...)
// Add elements to the form
$this->addElements(array(
$categoryElement,
//$codeElement,
$barcodeElement,
$serialElement,
$warehouseElement,
$submitButtonElement
));
$this->setDecorators($this->formDecorators);
}
}
In GoodsController.php
private function getAddGroupForm()
{
return new Default_Form_GoodAddGroup();
}
public function addGroupAction()
{
// Initialize the form for the view.
$this->view->form = $this->getAddGroupForm();
}
public function processAddGroupAction()
{
$form = $this->getAddGroupForm();
(...)
if ($_POST)
{
if ($form->isValid($_POST))
{
// Do things
} else {
$this->view->form = $form;
}
}
}
Basically, the form has a category select field, when selecting a category, a second "code" selector is added filled with the items related to this category. When the page with the form is displayed (http://myapp/goods/add-group), everything works fine, the ajax call does its job, the second select field is added and well fed, but as you can see, the form processing is done with the processAddGroupAction(), this method get the instance of the form to get its values and to re-display it in case of problem. But that way, my "new" select field doesn't exist anymore, so i can never validate the form.
It's my first attempt using ajax/json with Zend, i think i need help at this poind.
Thank you.
EDIT : added the view code as requested
<script>
$(function(){
$("#cats").change(function(){
getSelectBox(this);
});
$("#code").parent().parent().css('display', 'none');
getSelectBox($("#cats"));
});
function getSelectBox(element)
{
if($(element).val() != '')
{
$("#code").parent().parent().css('display', 'block');
if ($('#code').length <= 0) {
$("#cats").after('<select name="code" id="code" style="margin-left:10px"></select>');
}
$.getJSON("/goods/json-get-codes-from-category", {id: $(element).val(), ajax: "true"}, function(j){
console.log(j);
var options = "";
jQuery.each(j, function(i, val) {
options += '<option value="' + i + '">' + i + val + '</option>';
});
$("#code").html(options);
});
}
}
</script>
<?php echo $this->form; ?>
You can add the select element 'code' in the form, but don't display it in the view (it will be created from the js). So when the form is posted the 'code' will also be validated since it is in the $_POST.
After post you have to display the select box without $("#cats").change({..}). You can accomplish it by spiting the js code into functions
<script>
$(function(){
$("#cats").change(function(){
getSelectBox(this);
});
getSelectBox($("#cats"));
});
function getSelectBox(element)
{
if($(element).val() != '')
{
if ($('#code').length <= 0) {
$("#cats").after('<select name="code" id="code" style="margin-left:10px"></select>');
}
$.getJSON("/goods/json-get-codes-from-category", {id: $(element).val(), ajax: "true"}, function(j){
console.log(j);
var options = "";
jQuery.each(j, function(i, val) {
options += '<option value="' + i + '">' + i + val + '</option>';
});
$("#code").html(options);
});
}
}
</script>
Hope this helps
Ok, i found the solution! I post it in case it can be useful for other people.
I knew what was the problem, but unable to know how to achieve it.
At form processing time, the new select element does not exist for the action as it has been added in the view with javascript. To fix this, we need to inform the action about the new field, to do so, we first need to override the method “isValid” of Zend_Form in the form class :
public function isValid($values)
{
$values = $this->_modifyElements($values);
return parent::isValid($values);
}
Then create a method "_modifyElements" that will modify the form by adding the new element :
protected function _modifyElements($values)
{
// Search for codes
$dbu = new DbUtils();
$codes = $dbu->getCodesFromCategory($values['cats']);
// Remove the current code element
$this->removeElement('code');
// Create a new element
$codeElement = new Zend_Form_Element_Select('code', array());
$codeElement->setLabel(_('Code :'));
$codeElement->setRequired(true);
$codeElement->addMultiOptions($codes);
$codeElement->setValue($values['code']);
$codeElement->setDecorators($this->elementDecorators);
$this->addElement($codeElement);
return $values;
}
We have to override the method "populate" too :
public function populate(array $values)
{
$values = $this->_modifyElements($values);
return parent::populate($values);
}
And voilà. It works for me ;>
All the credits about this go to Mohamed : http://jamandcheese-on-phptoast.com/2009/12/13/on-fly-elements-in-zend_form/