set_relation_n_n and multiple selection
- Single Page
Posted 27 March 2012 - 20:00 PM
first thx for the work! great tool!
Is there a way to use a n-n relation plugin and manage multiple selection ?
For example i have a command table , a product table and relation table between them (n-n relation). I would like to be able to add x times a product on a command, but with the plugin after a choixe the product is not available anymore ...
am i missing somethine ?
Thx in advance.
Posted 27 March 2012 - 20:54 PM
Posted 27 March 2012 - 20:58 PM
any clue where/how i can handle/add this feature ? do you know a jquery plugin that would do something like that ?
Posted 28 March 2012 - 00:20 AM
Posted 29 March 2012 - 06:47 AM
Posted 29 March 2012 - 13:01 PM
I've found an ungly one but fast solution. Smth like:
$crud->callback_field('ordered', array($this, '_ordered_field_callback'));
function _ordered_field_callback($value, $oid) {
//print_r($value);
if(is_numeric($oid)) {
$this->db->where('oid', $oid);
$items = $this->db->get('zp_shop_ordered_items');
if($items->num_rows() != 0) {
$items = $items->result_array();
$items_json = array();
foreach($items as $item) {
if($item['item_quantity'] == null) $item['item_quantity'] = 1;
$items_json[$item['iid']] = $item['item_quantity'];
}
$items_json = json_encode($items_json);
}
else $items_json = '{}';
}
else $items_json = '{}';
$data['items_json'] = $items_json;
$data['items'] = $this->db->get('zp_shop_items')->result_array();
$form = $this->load->view('control_panel/orders_hook.php', $data, true); //here's some js for adding and setting qantity
return $form;
}
in short:
1. callback changes the field, ignoring value. the value in the hidden field is set in json format (like {"item_id": "quantity"}
2. js thing changes this json object on adding or deleting items
3. another callback unsets the form value and changes data in sql table after saving
can share the full code if anyone need it:)
screenshot:
[img]http://www.webpagescreenshot.info/i/789156-329201225953pm.png[/img]
Posted 05 April 2012 - 16:14 PM
Is it possible to share the full code with us ? (i've already pm you) I would appreciate to see your solution in detail
Thx
Posted 06 April 2012 - 19:38 PM
here's the view:
[color=#008800]orders_hook.php[/color]
<input type="hidden" name="ordered_json" id="ordered-multiselect" value='<?=$items_json?>' />
<span style="display: inline-block; width: 523px; font-size: 18px; padding-left: 8px;">Корзина:</span>
<script>
var result = $.parseJSON($('#ordered-multiselect').val());
var zp_shop_items = <?=json_encode($items)?>;
var zsi_select_box = $("<ul />");
zsi_select_box
.css('display', 'inline-block')
.width(512)
.height(300)
.css('overflow-y', 'scroll')
.css('border-radius', '4px')
.css('border', '1px solid lightGrey')
.css('padding', '3px')
.css('margin', '5px')
.addClass('zsi_select_box');
$.each(zp_shop_items, function(i, val) {
var this_qnty = 0;
if(result[val.iid] != undefined) this_qnty = result[val.iid];
zsi_select_box.append('<li class="zsi-item"><span>'+val.item_title+'</span>'+
'<input value="+" class="plusbtn" type="button" onclick="iplus(this); return false;" />'+
'<input class="zsi-item-qnty" value="'+this_qnty+'" rel="'+val.iid+'" type="text" onkeyup="countItemsToOrder(this);" style="width: 32px; float: right;" />'+
'<input value="−" class="minusbtn" type="button" onclick="iminus(this); return false;" />'+
'</li>');
});
var zsi_qsearch = $('<input type="text" />');
zsi_qsearch.attr('placeholder', 'БыÑтрый поиÑк');
jQuery.expr[':'].Contains = function(a, i, m) {
return jQuery(a).text().toUpperCase().indexOf(m[3].toUpperCase()) >= 0;
}; //case insensetive :contains func;
zsi_qsearch.keyup(function() {
zsi_select_box.children('li').css('display', 'none');
zsi_select_box.children('li:Contains("'+zsi_qsearch.val()+'")').css('display', 'block');
});
var zsi_selected_box = $('<ul />');
zsi_selected_box
.css('display', 'inline-block')
.width(512)
.height(300)
.css('overflow-y', 'scroll')
.css('border-radius', '4px')
.css('border', '1px solid lightGrey')
.css('padding', '3px')
.css('margin', '5px')
.addClass('zsi_selected_box');
$('#ordered-multiselect').parent().append(zsi_qsearch);
$('#ordered-multiselect').parent().append('<br />');
$('#ordered-multiselect').parent().append(zsi_selected_box);
$('#ordered-multiselect').parent().append(zsi_select_box);
itemsToSelected();
function countItemsToOrder(inputEl) {
var qnty = $(inputEl).val();
var iid = $(inputEl).attr('rel');
if(qnty > 0) result[iid] = qnty;
else delete result[iid];
$('#ordered-multiselect').val(JSON.stringify(result));
itemsToSelected();
}
function itemsToSelected(result) {
$('li.zsi-item').each(function(i) {
if($(this).children('input.zsi-item-qnty').val() > 0) {
if($(this).parent().attr('class') != zsi_selected_box.attr('class'))zsi_selected_box.prepend(this);
}
else zsi_select_box.append(this);
});
var elems = zsi_select_box.children('li').remove();
elems.sort(function(a,{
var compA = $(a).text().toUpperCase();
var compB = $(.text().toUpperCase();
return (compA < compB) ? -1 : (compA > compB) ? 1 : 0;
});
zsi_select_box.append(elems);
}
function iplus(btn) {
var val = $(btn).siblings('input.zsi-item-qnty').val();
val = parseInt(val);
if(isNaN(val) || val == '') val = 0;
if(val == 0) {
zsi_qsearch.val('');
zsi_qsearch.trigger('keyup');
}
$(btn).siblings('input.zsi-item-qnty').val(val + 1).trigger('keyup');
}
function iminus(btn) {
var val = $(btn).siblings('input.zsi-item-qnty').val();
val = parseInt(val);
if(isNaN(val) || val == '') val = 0;
if(val > 0) $(btn).siblings('input.zsi-item-qnty').val(val - 1).trigger('keyup');
else $(btn).siblings('input.zsi-item-qnty').val(val).trigger('keyup');
}
</script>
Posted 06 April 2012 - 19:41 PM
For example fn [color=#000000][size=2]JSON[/size][/color][color=#666600][size=2].[/size][/color][color=#000000][size=2]stringify [/size][/color]should be replaced. There a lot of jquery libs doing the same.
Posted 06 April 2012 - 19:44 PM
public function orders() {
$this->grocery_crud
->set_subject('заказ')
->set_table('zp_shop_orders')
->columns('oid', 'clid', 'order_status', 'ordered', 'order_created', 'order_last_update')
->add_fields('clid', 'ordered', 'order_last_update', 'order_created')
->edit_fields('clid', 'order_status', 'ordered', 'order_last_update')
->required_fields('clid')
->callback_field('ordered', array($this, '_ordered_field_callback'))
->change_field_type('order_last_update', 'hidden', null)
->change_field_type('order_created', 'hidden', null)
->display_as('oid','ID')
->display_as('clid','Клиент')
->display_as('ordered','Заказ')
->display_as('order_created','Дата заказа')
->display_as('order_last_update','ПоÑледнее обновление')
->display_as('order_status','СтатуÑ');
$this->grocery_crud->callback_before_insert(array($this, '_add_order_callback'));
$this->grocery_crud->callback_before_update(array($this, '_update_order_callback'));
$this->grocery_crud->callback_after_insert(array($this, '_order_callback_set_clid'));
$this->grocery_crud->callback_after_update(array($this, '_order_callback_set_clid'));
$this->grocery_crud
->set_relation('clid','zp_clients','{client_name} (id: {clid})')
->set_relation_n_n('ordered', 'zp_shop_ordered_items', 'zp_shop_items', 'oid', 'iid', 'item_title')
;
$output = $this->grocery_crud->render();
//print_r($output);
$this->crud_output($output);
}
function _add_order_callback($post) {
//
$time = date("Y-m-d H:i:s");
$post['order_last_update'] = $time;
$post['order_created'] = $time;
//$rand_ind = base_convert(time() - strtotime('01/01/2012'), 10, 32);
//$post['oid'] = $post['clid'].'_'.$rand_ind;
print_r($post);
return $post;
}
function _update_order_callback($post) {
$time = date("Y-m-d H:i:s");
$post['order_last_update'] = $time;
return $post;
}
function _order_callback_set_clid($post, $oid) {
print_r($post);
//$this->db->where('oid', $oid);
//$this->db->update('zp_shop_ordered_items', array('clid' => $post['clid']));
$ordered = json_decode($post['ordered_json'], true);
print_r($ordered);
foreach($ordered as $iid => $qnty) {
$item = $this->db->get_where('zp_shop_ordered_items', array('iid' => $iid, 'oid' => $oid));
if($item->num_rows() != 0) {
$this->db->where(array('iid' => $iid, 'oid' => $oid));
if($qnty != 0) $this->db->update('zp_shop_ordered_items', array('item_quantity' => $qnty, 'clid' => $post['clid']));
else $this->db->delete('zp_shop_ordered_items');
}
else {
if($qnty != 0) $this->db->insert('zp_shop_ordered_items', array('oid' => $oid, 'iid' => $iid, 'item_quantity' => $qnty, 'clid' => $post['clid']));
}
}
}
function _ordered_field_callback($value, $oid) {
//print_r($value);
if(is_numeric($oid)) {
$this->db->where('oid', $oid);
$items = $this->db->get('zp_shop_ordered_items');
if($items->num_rows() != 0) {
$items = $items->result_array();
$items_json = array();
foreach($items as $item) {
if($item['item_quantity'] == null) $item['item_quantity'] = 1;
$items_json[$item['iid']] = $item['item_quantity'];
}
$items_json = json_encode($items_json);
}
else $items_json = '{}';
}
else $items_json = '{}';
$data['items_json'] = $items_json;
$data['items'] = $this->db->get('zp_shop_items')->result_array();
$form = $this->load->view('control_panel/orders_hook.php', $data, true);
return $form;
}
Posted 06 April 2012 - 19:48 PM
li.zsi-item {
background-color: #FAFAFA;
border: 1px solid #CCC;
border-radius: 3px;
box-shadow: rgba(0, 0, 0, 0.0976563) 0px 1px 3px 0px inset;
color: #444;
cursor: auto;
display: block;
height: 33px;
letter-spacing: normal;
margin: 3px;
padding: 5px;
text-align: -webkit-auto;
text-indent: 0px;
text-shadow: none;
vertical-align: baseline;
width: 478px;
word-spacing: 0px;
}
li.zsi-item span{
display: table-cell;
float: left;
vertical-align: middle;
width: 320px;
height: 30px;
overflow: hidden;
}
input.minusbtn, input.plusbtn {
margin: 0 5px;
background-attachment: scroll;
background-clip: border-box;
background-color: #E6E6E6;
background-image: url(../assets/grocery_crud/css/ui/simple/images/ui-bg_glass_75_e6e6e6_1x400.png);
background-origin: padding-box;
border-radius: 4px;
border: 1px solid lightGrey;
box-sizing: border-box;
color: #555;
cursor: pointer;
display: inline-block;
float: right;
font-family: Verdana, Arial, sans-serif;
font-size: 15px;
font-weight: normal;
height: 32px;
letter-spacing: normal;
line-height: normal;
overflow-x: visible;
overflow-y: visible;
padding-bottom: 6px;
padding-left: 15px;
padding-right: 15px;
padding-top: 6px;
position: relative;
text-align: center;
text-decoration: none;
text-indent: 0px;
text-shadow: none;
text-transform: none;
vertical-align: baseline;
white-space: pre;
word-spacing: 0px;
zoom: 1;
}
input.minusbtn:hover, input.plusbtn:hover {
border: 1px solid #999;
color: #000;
background-image: url(../assets/grocery_crud/css/ui/simple/images/ui-bg_glass_75_dadada_1x400.png);
}
.zsi_select_box input.minusbtn, .zsi_select_box input.zsi-item-qnty {
display: none!important;
}
Posted 07 April 2012 - 08:33 AM
I'll try to test it !
Posted 11 July 2012 - 18:31 PM
It's possible post the database struct...