In my user registration workflow, I ask the user to select a pre-defined list of classifications (which I use a series of checkboxes for). Currently, I update my model with those values (or a blank value if the box isn't checked) when they move to the next step. These are not currently structured as an array, rather as a separate and distinct checkbox.
My 2 questions are as follows:
1) I read that if I save the checkboxes as an array I won't be able to easily search the database for users with a particular classification.
2) If that's true, I'm fine with my current structure, but I need to properly validate (server-side) that at least one of the checkboxes is selected otherwise provide an error. I have tried the following, but it doesn't return anything and the database record is created with nothing in each column.
if ($request->all() === "")
{
return Request::json('you must select one');
}
Database Table Migration:
Schema::create('user_type', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id');
$table->string('games');
$table->string('art');
$table->string('music');
$table->string('building_stuff');
$table->string('educational');
$table->timestamps();
});
Javascript: (I submit as AJAX)
$('.modal-type-btn').click(function(e){
e.preventDefault();
if($('.checkbox-games').is(':checked'))
{
var games = "games";
} else {
var games = "";
}
if($('.checkbox-art').is(':checked'))
{
var art = "art";
} else {
var art = "";
}
if($('.checkbox-music').is(':checked'))
{
var music = music;
} else {
var music = "";
}
if($('.checkbox-building-stuff').is(':checked'))
{
var buildingStuff = "buildingstuff";
} else {
var buildingStuff = "";
}
if($('.checkbox-educational').is(':checked'))
{
var educational = "educational";
} else {
var educational = "";
}
$.ajax({
type: "POST",
url: "/profile/setup/1",
data: {games:games, art:art, music:music, buildingStuff:buildingStuff, educational:educational},
error: function(data){
console.log(data);
},
success: function(data){
console.log(data);
}
});
Thanks!
So, firstly you're much better of using them as an array and doing something like:
html:
<input type="checkbox" name="options[games]" value="1" />
that way, you can just get the form data and pass that into your $.ajax call:
...
data: $('form').serialize(),
....
and then in your controller, checking that the length of options is at least one:
$options = Input::get('options');
if(count($options) > 0){ ... }
You'll also probably want to define a list of "allowed" options and then use that to build your query:
private $_allowed_options = array('education', 'buildingStuff' ...);
public function update()
{
$options = Input::get('options');
foreach($this->_allowed_options as $allowed_options){
if(array_key_exists($allowed_option, $option)){
// add this option to our sql to add it to our user
// as they have selected it
}else{
// the user didn't select this one, so add it to be removed
// from the users
}
}
}
Related
I am using dexie.js to interface with IndexedDB. I am wondering if it is possible to orderby or sortby using more than one index at once (eg. db.people.orderBy( index1, desc : index2, asc )...
If it is possible, what is the correct syntax?
Either use compound indexes, or use Collection.and().
If you can live with only targeting Chrome, Firefox or Opera, you can use compound indexes. If it must work on Safari, IndexedDBShim, Edge or IE, you cannot use compound indexes today. There's a shim that enables it for IE/Edge though, but it is still in beta, so I would recommend to instead use Collection.and() for those cases.
Let' say you have a form where users can fill in various attributes of friends:
<form>
<input name="name"/>
<input name="age"/>
<input name="shoeSize" />
</form>
Using Collection.and()
First, pick the most probably index to start your search on. In this case, "name" would be a perfect index that wouldn't match so many items, while age or shoeSize would probably match more friends.
Schema:
db.version(X).stores({
friends: "id, name, age, shoeSize"
});
Query:
function prepareQuery () {
// Pick a good index. The picked index will filter out with IndexedDB's built-in keyrange
var query;
if (form.name.value) {
query = db.friends.where('name').equals(form.name.value);
} else if (form.age.value) {
query = db.friends.where('age').equals(parseInt(form.age.value));
} else if (form.shoeSize.value) {
query = db.friends.where('shoeSize').equals(parseInt(form.shoeSize.value));
} else {
query = db.friends.toCollection();
}
// Then manually filter the result. May filter a field that the DB has already filtered out,
// but the time that takes is negligible.
return query.and (function (friend) {
return (
(!form.name.value || friend.name === form.name.value) &&
(!form.age.value || friend.age == form.age.value) &&
(!form.shoeSize.value || friend.shoeSize == form.shoeSize.value));
});
}
// Run the query:
form.onsubmit = function () {
prepareQuery() // Returns a Collection
.limit(25) // Optionally add a limit onto the Collection
.toArray(function (result) { // Execute query
alert (JSON.stringify(result, null, 4));
})
.catch (function (e) {
alert ("Oops: " + e);
});
}
Using compound indexes
As written above, compound indexes code will only work on mozilla- and chromium based browsers.
db.version(x).stores({
friends: "id, name, age, shoeSize," +
"[name+age+shoeSize]," +
"[name+shoeSize]," +
"[name+age]," +
"[age+shoeSize]"
});
The prepareQuery() function when using compound indexes:
function prepareQuery() {
var indexes = []; // Array of Array[index, key]
if (form.name.value)
indexes.push(["name", form.name.value]);
if (form.age.value)
indexes.push(["age", parseInt(form.age.value)]);
if (form.shoeSize.value)
indexes.push(["shoeSize", parseInt(form.shoeSize.value)]);
var index = indexes.map(x => x[0]).join('+'),
keys = indexes.map(x => x[1]);
if (indexes.length === 0) {
// No field filled in. Return unfiltered Collection
return db.friends.toCollection();
} else if (indexes.length === 1) {
// Single field filled in. Use simple index:
return db.friends.where(index).equals(keys[0]);
} else {
// Multiple fields filled in. Use compound index:
return db.friends.where("[" + index + "]").equals(keys);
}
}
// Run the query:
form.onsubmit = function () {
prepareQuery() // Returns a Collection
.limit(25) // Optionally add a limit onto the Collection
.toArray(function (result) { // Execute query
alert (JSON.stringify(result, null, 4));
})
.catch (function (e) {
alert ("Oops: " + e);
});
}
Using arrow functions here to make it more readable. Also, you're targeting chromium or firefox and they support it already.
I'm working with Zend 1 with dojo and do not know how to use ajax . In my particular case that when selecting a select , whether made in consultation ajax back from the database information. To enter a ID from user print the information from user by ajax.In my work I can't use jquery.
Good question!
Not is very productive work with dojo, but is possible make exactly how do you want. You will create p element with information captured in data base
In your form, add attribute 'onChange'
$form->setAttrib('onChange', 'recoveryData()');
In js file do you have a function recoveryData(), something as:
dojo.require("dojo.html");
// clean data
var myNewElement = dojo.byId('myNewElement');
if (myNewElement != null) {
dojo.empty("myNewElement");
}
dojo.xhrPost({
content: {id: dojo.attr(dojo.byId("myElement"), "value")},
url: 'your-base-path/recovery-data/',
load: function (response) {
if (response != false) {
// converte to obj
var obj = dojo.fromJson(response);
// creat new element
var node = dojo.create("span", {
innerHTML: obj.NomeServidor,
id: "myNewElement",
'class': 'row'
}
);
dojo.place(node, dojo.byId("myElement"), "after");
}
}
});
Now, you need create an Action "recoveryDataAction()" in your Controller like this:
$data = $this->getrequest()->getPost();
$id = $data['id'];
if ($this->getrequest()->isXmlHttpRequest()) {
// disable layout
$this->_helper->layout()->disableLayout();
// disable view render
$this->_helper->viewRenderer->setNoRender();
$yourTable = new Project_Model_YourTable();
$row = $yourTable->fetchRow($id);
if ($infos != null) {
echo Zend_Json::encode($row);
return;
}
echo false;
}
I have the following code on my site which sending data to Ajax and works normal. It is about add to cart.
public function adding()
{
$id_lap=$this->input->post('id_lap');
$num_items=$this->input->post('num_items');
$price=$this->input->post('price');
if($id_lap !='')
{
$this->session->set_userdata('num_items',$num_items);
$this->session->set_userdata('price_new',$price);
$response=array(
'status'=>1,
'num_items'=>$num_items,
'price_new'=>$price
);
} else {
$response=array(
'status'=>0
);
}
echo json_encode($response);
}
When I want to send data to model also where I want to write data into database along with IP adress which I will collect with model. When I add new row anywhere my Ajax crashed. Part of code which I want to add is:
$this->users_mod->AddSesija($id_lap,$price);
And Ajax code which I am using is :
function Addtocart(id,prices)
{
var id_lap=id;
var ajaxURL= BASE_URL +'home/adding';
var num_items = parseInt($('#num_items').html()) + 1;
var price = parseInt($('#price_b').html());
var price_new = price + prices;
/*console.log(id_lap +' '+num_items+' '+price_new);
$('#num_items').html(num_items);
$('#price_b').html(price_new); */
$.ajax({
url:ajaxURL,
type:'POST',
data:{'id_lap':id_lap,'num_items':num_items,'price':price_new},
success:function(response)
{
var parsed = JSON.parse(response);
if(parsed.status ==1)
{
$('#num_items').html(parsed.num_items);
$('#price_b').html(parsed.price_new);
}
}
}
)
}
I am agree with Vladimir Glisovic in concept. we know that for adding or inserting group of data we should bind them into an array.
Sample:
$data=array( 'ip_adress'=>$ip_adress, 'id_lap'=>$id_lap, 'cena'=>$price );
N.b: get IP address from PHP code keep in $ip_address.
Then pass the data to model with the CI syntax.
Model calling in Controller:
$this->users_mod->AddSesija($data);
Now write the inserting code in the model file as
public function AddSesija($data){
insertion code here.....
}
Hope it will help you.
Thanks!
Amadercode
I have an image map on my frontend and from there I need to access some images that are stored on different folders under the fileadmin directory. And I'm trying to do it with eID, following this example:
[http://www.alexanderschnitzler.de/2011/06/howto-ajax-requests-with-extbase-and-fluid/][1]
But my problem is that I can only access one directory. I haven't been able to access different directories based on the user selection from my front end.
This is the code of what I been trying to do:
On my Controller I have an ajaxAction, where I need to give the full path of one directory, because I haven't figure it out how pass the directory id on to my ajaxAction, here might be my question and maybe the solution:
/**
* #return void
*/
public function ajaxAction() {
$image_file_path = "fileadmin/Images/Sattic/Amik/small";
//$image_file_path = "fileadmin/Images/Sattic/'+$id+'";
$d = dir($image_file_path) or die("Wrong path: $image_file_path");
while (false !== ($entry = $d ->read())) {
if($entry != '.' && $entry != '..' && !is_dir($dir.$entry))
$images[] = $entry;
}
$d->close();
rsort($images);
return json_encode($images);
}
On my index.html I have a map tag where the function updateImage(id) is called, when the user clicks on the different areas and my updataImage(id) function looks like this:
function updateImageGallery(id) {
console.log(id);
var ajaxUrl = "{f:uri.action(action:'ajax', pageType:'100101')}";
$.getJSON(ajaxUrl, function(data) {
var items1 = [];
var items2 = [];
$data = data;
console.log('dataLength: ' + $data.length);
console.log('dataArray: ' + $data);
$.each($data.slice(0, 4), function(key, val) {
valLink = val.replace("small.", "");
items1.push('<td><img width="145" height="145" id="" src="fileadmin/Images/Sattic/' + id +'/small/'+ val +'"/></td>');
});
$('<tr/>', {
html: items1.join('')
}).appendTo('#glRegion');
$.each($data.slice(4, 8), function(key, val) {
valLink = val.replace("small.", "");
items2.push('<td><img width="145" height="145" id="" src="fileadmin/Images/Sattic/' + id +'/small/'+ val +'"/></td>');
});
$('<tr/>', {
html: items2.join('')
}).appendTo('#glRegion');
});
return false;
}
I would like to be able to pass from updateImageGallery(id) function, the id of the directory, so I could get the images for each directory.
Is it possible to do this? I hope so, I have 30 different regions and if I solve my problem the way I'm doing now I would need to use 30 different eID's. I guess it might be a smarter way to solve this.
Any sugestions?
You can use t3lib_div::_GET('myid') to access the myid get variable.
I guess you can use var ajaxUrl = "{f:uri.action(action:'ajax',**myid:id,** pageType:'100101')}"; to set it.
Anyway, sure to generate a list of valid paths/ids inside you PHP script and check the get parameter agains those.
I would like to overwrite the value of the "password" field before submiting a form on Jquery using AjaxSubmit function.
I know I can just update the value on the input field but, I don't want the user to see this transformation. In other words, I just want to send a custom value to the password field and keep the current value on the screen...
How could I do that?
My current code:
var loginoptions = {
success: mySuccessFuction,
dataType: 'json'
}
$('#My_login_form').submit(function(e) {
e.preventDefault();
var pass=$("#My_login_form_password").val();
if (pass.length>0){
loginoptions.data={
password: ($.sha1($("#My_login_form_csrf").val()+$.sha1(pass)))
}
$("#My_login_form").ajaxSubmit(loginoptions);
delete loginoptions.data;
});
The problem with this code is that it is sending a "password" POST variable with the form field value and, a duplicated one with the value I set on "loginoptions.data".
Building off of Cristiano's answer, I was able to get this to work. If you use :beforeSubmit(), the changed value doesn't post, but if you use the :beforeSerialize(), it posts the changed value.
$('#ff').ajaxForm({
beforeSerialize:function(jqForm, options){
var serializedForm = decodeURIComponent(jqForm.serialize());
options.data = serializedForm.deserializeToObject();
options.data.tPassword = MD5($("#tPassword").val())
},
success:function(data){
// do stuff
}
});
If you want to do it anyhow then I think you can use callback function beforeSubmit: function(contentArray, $form, options){}
beforeSubmit: function(contentArray, $form, options){
for(var i=0; i<contentArray.length; i++){
if(contentArray[i].name == "password") {
contentArray[i].value = ($.sha1($("#My_login_form_csrf").val()+$.sha1(pass)))
}
}
}
It seems that ajaxSubmit uses the serialize() function of jquery on the form and then, adds the extra data serialized too. So, if I have a field named "password" with the value "1234" and then try to change that to "abcd", using "loginoptions.data.password", it will serialize everything and put the "options.data" like this:
"password=1234&field_2=value_2&password=abcd"
After many tries, I gave up on using ajaxSubmit function and decided to use ajax function to submit the form:
var the_form=$('form#My_login_form');
loginoptions.url=the_form.attr("action");
loginoptions.type=the_form.attr("method");
var serializedForm=decodeURIComponent(the_form.serialize());
loginoptions.data=serializedForm.deserializeToObject();
var pass=$("#My_login_form_password").val();
if (pass.length>0){
loginoptions.data.password= ($.sha1($("#My_login_form_csrf").val()+$.sha1(pass)));
}
$.ajax(loginoptions);
Here is the deserializeToObject() function:
function deserializeToObject (){
var result = {};
this.replace(
new RegExp("([^?=&]+)(=([^&]*))?", "g"),
function($0, $1, $2, $3) { result[$1] = $3; }
)
return result;
}
String.prototype.deserializeToObject = deserializeToObject;