Yii2 Dynagrid: How to implement Sortable to sort the rows - yii2

In Dynagrid it is possible to use Sortable to sort the columns. I need to enable sorting rows, which should work similarly:
Is there a way to implement such sorting directly in Dynagrid or do I have to programm the sorting separately?

To enable the sorting is simple:
$('tbody').sortable();
The only problem is to save the sorting to the database. I have decided to save it after a click on a button (and not with ajax) in views/sorted-table/index.php:
if (strpos(Url::current(), 'sort') === false) {
$form = ActiveForm::begin([
'id' => 'sort-form',
]);
echo '<input type="hidden" id="field-sort" name="sort" value="">';
if (isset($sortMessage) && $sortMessage != '') {
echo '<p>' . $sortMessage . '</p>';
}
echo Html::submitButton(Icon::show('floppy-o') . 'Sortierung speichern', ['class' => 'btn btn-primary']);
ActiveForm::end();
DynagridSortAsset::register($this);
}
The positions of rows are saved in the hidden input field by jQuery:
$('.btn-primary').mousedown(function() {
var sorting = "";
$('.sortable-row').each( function (index, value) {
sorting += $(this).attr('data-id') + ':' + $(this).attr('data-sortierung') +',';
});
$('#field-sortierung').val(sorting);
});
The values are then in controller processed and saved to the database.

Related

How to update multiple image and remove old images in Laravel 5.4?

It is difficult for me to update and replace several images. How to save multiple images, I understand, but I can not update and remove old images.
The are 3 tables:
portfolios
photos
portfolio_photo (pivot)
HTML Form Update
{!! Form::model($portfolio, ['route' => ['portfolio.update', $portfolio->id], 'method' => 'PUT', 'files' => 'true' ]) !!}
<input type="file" id="portfolio_photos" name="portfolio_photos[]" class="form-control" multiple>
{{!! Form::close() !!}}
Controller, I do not know how to do a method update.
public function store(PortfolioValidation $request){
$portfolio = new Portfolio();
$portfolio->portfolio_title = $request->portfolio_title;
$portfolio->portfolio_slug = str_slug($request->portfolio_title);
$portfolio->apartment_project = $request->apartment_project;
$portfolio->apartment_area = $request->apartment_area;
$portfolio->type_repair = $request->type_repair;
$portfolio->year_implementation = $request->year_implementation;
$portfolio->deadline = $request->deadline;
$portfolio->save();
if($request->hasFile('portfolio_photos')){
foreach($request->portfolio_photos as $portfolio_photo){
$fileName = rand() . '.' . $portfolio_photo->getClientOriginalExtension();
$path = public_path('img/portfolio/' . $fileName);
Image::make($portfolio_photo)->resize(1280, 960)->save($path);
$newFile = new Photo();
$newFile->portfolio_photos = $fileName;
$newFile->save();
$portfolio->photos()->save($newFile);
}
}
Session::flash('success', 'Success!');
return redirect()->route('portfolio.index');
}

Way to make row count be 0 if no date match and second,third,etc while loop row counts

<?php
if($result = $db->query("SELECT * FROM table")) {
if($count = $result->num_rows) {
echo '<p class="lead">Number of callbacks for today is: ', $count, '</p>';
while($row = $result->fetch_assoc()) {
if ( $row['field'] == date("Y-m-d") ) {
echo $row['otherfield'], '<br>';
}else{
echo "Nothing", '' , '<br>';
}
}
}
}
?>
I have a simple field date verses server date test used in conjunction with a while loop to bring up any callbacks each day if they are due. My issue is that the row will show a nothing for every row so I'll have twenty(example) rows of the text 'nothing' display. I know I could simply place everything in a function and then use the if/else statement outside of the function to display callbacks or not display callbacks....but is there a way to reset the loop counter to zero if the first if/else test fails? I tried placing the $count = 0; in the second else clause but this did not work.

Add class to bootstrap textbox - yii2

I have a form in yii2. In that I have a input field like below.
<input type="text" class="form-control" id="productsales-<?= $i ?>-value">
It's inside a dynamic form andno coming from any model.It's just to hold some calculated value. And the idea is to calculate the values fileed by users in this field to another textbox like below -
<?= $form->field($model, 'amount')->textInput(['maxlength' => true, 'class' => 'sum']) ?>
I already have the javascript code to calculate the total amount like below -
<?php
/* start getting the total amount */
$script = <<<EOD
var getSum = function() {
var items = $(".item");
var sum = 0;
items.each(function (index, elem) {
var priceValue = $(elem).find(".sumPart").val();
//Check if priceValue is numeric or something like that
sum = (parseFloat(sum) + parseFloat(priceValue)).toFixed(2);
});
//Assign the sum value to the field
$(".sum").val(sum);
};
//Bind new elements to support the function too
$(".container-items").on("change", ".sumPart", function() {
getSum();
});
EOD;
$this->registerJs($script);
/*end getting the total amount */
?>
Please note that I have a class sum in the second textbox which comes from a model. My question is that how can I add a class(sumPart) like this(sum) in the first textbox which is not coming from a model.
Update after discussion with Insane Skull
I have a dynamic form like below
I want to calculate sum of all the entries in Value and pass it to amount.
The code of Value is -
<input type="text" class="form-control sumPart" id="productsales-<?= $i ?>-value">
The code of Amount is -
<?= $form->field($model, 'amount')->textInput(['maxlength' => true, 'class' => 'sum']) ?>
The javascript I've tried is already given above.
The problem with this code is the calculated "value" is not passing to amount textbox.
Update: A little issue
Modify JS :
$this->registerJs('
function getSum() {
var sum = 0;
var items = $(".item");
items.each(function (index, elem) {
var priceValue = $(elem).find(".sumPart").val();
sum = parseFloat(sum) + parseFloat(priceValue);
});
if(isNaN(sum) || sum.length == 0) {
sum = 0;
}
$(".sum").val(sum);
}
$(".container-items").on("change", function() {
getSum();
});
jQuery(".dynamicform_wrapper").on("afterDelete", function(e) {
getSum();
});
');
I am little unsure about the problem you are facing. If you want to add a class to a input field, you can easily do so in the class attribute of the input tag. And the class attribute does support multiple values, so you can write something like this:
<input type="text" class="form-control sumPart" id="productsales-<?= $i ?>-value">
**UPDATE -- based on comment by OP **
#Tanmay, I understand that you may not be getting the desired output. However, it should not really matter if we are rendering the fields using $form->field() or plain HTML. If the fields have the proper classes assigned, then the JS code posted by Kostas in your referenced link should work - irrespective of how the class name was added to the input field.
Can you please confirm (by using Inspect Element) if the sumPart class is actually assigned to the relevant fields once the page loads? Maybe some JS is overwriting the class attribute again?
If the classes are assigned properly, please check if there are any other JS errors in console which may prevent the sum calculation JS from working properly.

$index as a parameter : multiple if statement issue

Please take a look at this function :
function my_func($index_bis) {
if (!is_int($index_bis) || $index_bis > 5 || $index_bis < 0) return;
elseif ($index_bis = 5) : echo 'This';
elseif ($index_bis = 1) : echo 'That';
endif;
}
What's wrong with this? I actually can't understand where is the mistake...
Thank you for your help.
What is this? PHP?
And what are you attempting to do?
How about this:
function my_func($index_bis) {
if (!is_int($index_bis) || $index_bis > 5 || $index_bis < 0){
$str = $index_bis;
}
elseif ($index_bis == 5) {
$str='This';
}
elseif ($index_bis == 1) {
$str='That';
}
return $str;
}
It's pretty atypical to put anything after "return"; and I think "return" stops the function, effectively.
Edit: FOREACH method.
If you are building html from two related variables, FOREACH is a great method for handling them, as you can set a data "key" and "value" for each item in the array.
By default, the "key" in PHP is assigned a number, starting from 0 and progressing through increasing integers. You have the option of naming these keys, instead of using the PHP-assigned default.
So consider setting up your array as such:
$newArray = (
'tab name' => 'label name',
'apples' => 'red',
'oranges' => 'orange',
);
Wherein the item to the left of the "=>" is always the key, and the item to the right is always the value.
Then, you can add more elements to this array in your code by using this line:
$newArray['bananas'] = 'yellow';
Note the key (tab) name, with square brackets (because it is the key name) and single quotes (because it is a string).
Now that you have an array, you can "walk" it using a FOREACH loop and echoing the html. Here is the code:
foreach($newArray as $key => $value) {
echo "<tab>$key</tab> : ";
echo "<label>$value</label>
echo "<br /";
}
This will output the html below:
<tab>tab name</tab> : <label>label name</label><br />
<tab>apples</tab> : <label>red</label><br />
<tab>oranges</tab> : <label>orange</label><br />
<tab>bananas</tab> : <label>yellow</label><br />
Very useful. Have fun!
Note: There are likely better ways to do this, but I'm sharing this one as a simple solution. And also, because you shouldn't go further without understanding both FOREACH and simple arrays.
Note: If you want to incorporate more than two variables, you will need a more complex data structure. In PHP, these are called "multidimensional arrays". Give it a read. Beyond that, there are still more methods for handling data (ie. "objects").

Dynamically created checkboxes using ajax from sql result set

I am looking to use ajax to dynamically create checkboxes each time you change your selection from a <select> tag, see the below screenshot for a section of the form that is relevant:
NOTE: The checkboxes under "Queues" should be dynamic.
At the moment, when you change the value for Team it grabs the team name (in this case "Test"), then using ajax (POST) it returns the Manager name for that team.
What I want it to do is look up another table that has a list of the "queues" associated with each team; I am going to add an "onchange" attribute in the tags for the "Manager Name" field.
Below is the code I'm currently using to accomplish the Team => Manager Name dynamic filling:
<script>
window.onload = function() {
getManager($("#team").val());
}
function getManager(team) {
$.ajax({
type: "POST",
url: "getManager.php",
data: {team:team}
}).done(function( manager ) {
$("#manager_name").val(manager);
});
}
</script>
And here is the getManager.php file that it uses:
<?php
require("../../database/db.php");
$mysqli = new db("nab_reporting");
if ($mysqli->connect_errno) {
printf("Connect failed: %s\n", $mysqli->connect_error);
exit();
}
$team=$mysqli->real_escape_string($_POST['team']);
$result = $mysqli->query("SELECT manager_name FROM team WHERE teamname = '".$team."'");
$row = $result->fetch_assoc();
echo $row['manager_name'];
mysqli_close($mysqli);
?>
Keeping in mind that the above works; I now need a way to use the onchange attribute of the Manager Name field that will use ajax (similar to above), passing another php page the value that is currently in the field (in this case Kane Charles) and will return a result set (array or JSON maybe?) containing a list of all queues in the database that match up with that Team name.
Below is the html code for each of the different bits:
TEAM
<select name="team" id="team" required="required" onchange="getManager(this.value)">
<?php
include(__DIR__ . "/../../database/db.php");
$db = new db("nab_reporting");
$result = $db->query("SELECT teamname FROM team");
while ($row = $result->fetch_assoc()) {
echo "
<option value=\"" . $row['teamname'] . "\">" . $row['teamname'] . "</option>
";
}
$db->close();
?>
</select>
MANAGER NAME
<input type="text" name="manager_name" id="manager_name" required="required" onchange="getQueues(this.value)">
QUEUES
<label>
Queues
</label>
<div id="queue_options">
<!-- queues dynamically created here -->
</div>
I need the contents of queue-options to be erased and reset to only the queues associated with the current team; I haven't done a great deal with ajax, hence why I'm posting on here.
This revision should match what you are asking about
PHP
// make an array to hold the queues
$data = Array();
// Fetch the rows of all the queues
$res = $mysqli->query("SELECT * FROM the_queue_table WHERE manager='" . $_GET["manager"] . "'");
// loop through all the rows and push the queues into the data array
while(($row = mysql_fetch_object($res)) !== false)
{
array_push($data, $row->queue);
}
// return the data array as a json object
echo json_encode($data);
JavaScript
// get the page and send the manager name to filter with
$.get("file.php?manager=" + managerName, function(page)
{
// parse the json into an object
var data = $.parseJSON(page);
// remove existing checkboxes
$("#queue_options").children().remove();
// add checkboxes to the div
for (var item in data){
$("#queue_options").append("<input type=\"checkbox\" value=\"" + item + "\" />" + item + "<br />");
}
});